--- name: apollo description: | Apollo.io API integration with managed OAuth. Search and enrich people and companies, manage contacts and accounts. Use this skill when users want to prospect, enrich leads, or manage sales data. For other third party apps, use the api-gateway skill (https://clawhub.ai/byungkyu/api-gateway). compatibility: Requires network access and valid Maton API key metadata: author: maton version: "1.0" clawdbot: emoji: 🧠 requires: env: - MATON_API_KEY --- # Apollo Access the Apollo.io API with managed OAuth authentication. Search people and organizations, enrich contacts, and manage your sales pipeline. ## Quick Start ```bash # Search for people at a company python <<'EOF' import urllib.request, os, json data = json.dumps({'q_organization_name': 'Google', 'per_page': 10}).encode() req = urllib.request.Request('https://gateway.maton.ai/apollo/v1/mixed_people/api_search', data=data, method='POST') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF ``` ## Base URL ``` https://gateway.maton.ai/apollo/{native-api-path} ``` Replace `{native-api-path}` with the actual Apollo API endpoint path. The gateway proxies requests to `api.apollo.io` and automatically injects your API key. ## Authentication All requests require the Maton API key in the Authorization header: ``` Authorization: Bearer $MATON_API_KEY ``` **Environment Variable:** Set your API key as `MATON_API_KEY`: ```bash export MATON_API_KEY="YOUR_API_KEY" ``` ### Getting Your API Key 1. Sign in or create an account at [maton.ai](https://maton.ai) 2. Go to [maton.ai/settings](https://maton.ai/settings) 3. Copy your API key ## Connection Management Manage your Apollo connections at `https://ctrl.maton.ai`. ### List Connections ```bash python <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://ctrl.maton.ai/connections?app=apollo&status=ACTIVE') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF ``` ### Create Connection ```bash python <<'EOF' import urllib.request, os, json data = json.dumps({'app': 'apollo'}).encode() req = urllib.request.Request('https://ctrl.maton.ai/connections', data=data, method='POST') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') req.add_header('Content-Type', 'application/json') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF ``` ### Get Connection ```bash python <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://ctrl.maton.ai/connections/{connection_id}') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF ``` **Response:** ```json { "connection": { "connection_id": "21fd90f9-5935-43cd-b6c8-bde9d915ca80", "status": "ACTIVE", "creation_time": "2025-12-08T07:20:53.488460Z", "last_updated_time": "2026-01-31T20:03:32.593153Z", "url": "https://connect.maton.ai/?session_token=...", "app": "apollo", "metadata": {} } } ``` Open the returned `url` in a browser to complete OAuth authorization. ### Delete Connection ```bash python <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://ctrl.maton.ai/connections/{connection_id}', method='DELETE') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF ``` ### Specifying Connection If you have multiple Apollo connections, specify which one to use with the `Maton-Connection` header: ```bash python <<'EOF' import urllib.request, os, json data = json.dumps({'q_organization_name': 'Google', 'per_page': 10}).encode() req = urllib.request.Request('https://gateway.maton.ai/apollo/v1/mixed_people/api_search', data=data, method='POST') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') req.add_header('Maton-Connection', '21fd90f9-5935-43cd-b6c8-bde9d915ca80') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF ``` If omitted, the gateway uses the default (oldest) active connection. ## API Reference ### People #### Search People ```bash POST /apollo/v1/mixed_people/api_search Content-Type: application/json { "q_organization_name": "Google", "page": 1, "per_page": 25 } ``` #### Enrich Person by Email ```bash POST /apollo/v1/people/match Content-Type: application/json { "email": "john@example.com" } ``` #### Enrich Person by LinkedIn ```bash POST /apollo/v1/people/match Content-Type: application/json { "linkedin_url": "https://linkedin.com/in/johndoe" } ``` ### Organizations #### Search Organizations ```bash POST /apollo/v1/organizations/search Content-Type: application/json { "q_organization_name": "Google", "page": 1, "per_page": 25 } ``` #### Enrich Organization ```bash POST /apollo/v1/organizations/enrich Content-Type: application/json { "domain": "google.com" } ``` ### Contacts #### Search Contacts ```bash POST /apollo/v1/contacts/search Content-Type: application/json { "page": 1, "per_page": 25 } ``` #### Create Contact ```bash POST /apollo/v1/contacts Content-Type: application/json { "first_name": "John", "last_name": "Doe", "email": "john@example.com", "organization_name": "Acme Corp" } ``` #### Update Contact ```bash PUT /apollo/v1/contacts/{contactId} Content-Type: application/json { "first_name": "Jane" } ``` ### Accounts #### Search Accounts ```bash POST /apollo/v1/accounts/search Content-Type: application/json { "page": 1, "per_page": 25 } ``` #### Create Account ```bash POST /apollo/v1/accounts Content-Type: application/json { "name": "Acme Corp", "domain": "acme.com" } ``` ### Sequences #### Search Sequences ```bash POST /apollo/v1/emailer_campaigns/search Content-Type: application/json { "page": 1, "per_page": 25 } ``` #### Add Contact to Sequence ```bash POST /apollo/v1/emailer_campaigns/{campaignId}/add_contact_ids Content-Type: application/json { "contact_ids": ["contact_id_1", "contact_id_2"] } ``` ### Labels #### List Labels ```bash GET /apollo/v1/labels ``` ## Search Filters Common search parameters: - `q_organization_name` - Company name - `q_person_title` - Job title - `person_locations` - Array of locations - `organization_num_employees_ranges` - Employee count ranges - `q_keywords` - General keyword search ## Code Examples ### JavaScript ```javascript const response = await fetch( 'https://gateway.maton.ai/apollo/v1/mixed_people/api_search', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${process.env.MATON_API_KEY}` }, body: JSON.stringify({ q_organization_name: 'Google', per_page: 10 }) } ); ``` ### Python ```python import os import requests response = requests.post( 'https://gateway.maton.ai/apollo/v1/mixed_people/api_search', headers={'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}'}, json={'q_organization_name': 'Google', 'per_page': 10} ) ``` ## Notes - Pagination uses `page` and `per_page` in POST body - Most list endpoints use POST with `/search` suffix - Email enrichment consumes credits - `people/search` and `mixed_people/search` are deprecated - use `mixed_people/api_search` - IMPORTANT: When using curl commands, use `curl -g` when URLs contain brackets (`fields[]`, `sort[]`, `records[]`) to disable glob parsing - IMPORTANT: When piping curl output to `jq` or other commands, environment variables like `$MATON_API_KEY` may not expand correctly in some shell environments. You may get "Invalid API key" errors when piping. ## Error Handling | Status | Meaning | |--------|---------| | 400 | Missing Apollo connection | | 401 | Invalid or missing Maton API key | | 429 | Rate limited (10 req/sec per account) | | 4xx/5xx | Passthrough error from Apollo API | ### Troubleshooting: API Key Issues 1. Check that the `MATON_API_KEY` environment variable is set: ```bash echo $MATON_API_KEY ``` 2. Verify the API key is valid by listing connections: ```bash python <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://ctrl.maton.ai/connections') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF ``` ### Troubleshooting: Invalid App Name 1. Ensure your URL path starts with `apollo`. For example: - Correct: `https://gateway.maton.ai/apollo/v1/mixed_people/api_search` - Incorrect: `https://gateway.maton.ai/v1/mixed_people/api_search` ## Resources - [Apollo API Overview](https://docs.apollo.io/reference/introduction) - [Search People](https://docs.apollo.io/reference/people-api-search.md) - [Enrich Person](https://docs.apollo.io/reference/people-enrichment.md) - [Search Organizations](https://docs.apollo.io/reference/organization-search.md) - [Enrich Organization](https://docs.apollo.io/reference/organization-enrichment.md) - [Create Contact](https://docs.apollo.io/reference/create-a-contact.md) - [LLM Reference](https://docs.apollo.io/llms.txt) - [Maton Community](https://discord.com/invite/dBfFAcefs2) - [Maton Support](mailto:support@maton.ai)