API Reference
API Reference
Section titled “API Reference”This reference covers all available endpoints for the GraphADV enrichment API v2.
Base URL & Authentication
Section titled “Base URL & Authentication”export BASE_URL="https://api.graphadv.com"export GRAPHADV_API_KEY="YOUR_API_KEY"All requests require the X-Api-Key header:
X-Api-Key: YOUR_API_KEYCommon Workflows
Section titled “Common Workflows”These recipes show how to chain API calls for common GTM use cases.
Full Account Research
Section titled “Full Account Research”Research a target company with leadership and buying signals in a single request.
# Full research: company + leadership + signals (9 units)curl -X POST "$BASE_URL/v2/enrich/company" \ -H "X-Api-Key: $GRAPHADV_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "domain": "anthropic.com", "include_leadership": true, "include_signals": true }'Then poll for results:
# Check task statuscurl "$BASE_URL/v2/tasks/$TASK_ID" -H "X-Api-Key: $GRAPHADV_API_KEY"
# Get full results when completecurl "$BASE_URL/v2/tasks/$TASK_ID/result" -H "X-Api-Key: $GRAPHADV_API_KEY"Build a Prospect List
Section titled “Build a Prospect List”Find companies matching your ICP, then enrich with leadership contacts.
import requests
API_KEY = "your_api_key"BASE_URL = "https://api.graphadv.com"
# Step 1: Search for target companiescompanies = requests.get( f"{BASE_URL}/v2/companies", headers={"X-Api-Key": API_KEY}, params={ "industry": "Financial Services", "state": "CA", "in_formadv": True, "limit": 50 }).json()["companies"]
# Step 2: Enrich with leadership (5 units per company)domains = [c["domain"] for c in companies if c.get("domain")]task = requests.post( f"{BASE_URL}/v2/search/leadership", headers={"X-Api-Key": API_KEY, "Content-Type": "application/json"}, json={"domains": domains[:10], "max_per_company": 5}).json()
print(f"Task ID: {task['task_id']}")print(f"Units charged: {task['units_charged']}")Monitor Accounts for Buying Signals
Section titled “Monitor Accounts for Buying Signals”Scan your target accounts for recent news signals (funding, hiring, product launches).
# Get your TAL companiestal = requests.get( f"{BASE_URL}/v2/clients/me/tal/companies", headers={"X-Api-Key": API_KEY}, params={"limit": 50}).json()
domains = [c["domain"] for c in tal["companies"]]
# Run signal discovery (3 units per company)task = requests.post( f"{BASE_URL}/v2/discover/signals", headers={"X-Api-Key": API_KEY, "Content-Type": "application/json"}, json={ "domains": domains, "max_articles_per_company": 10 }).json()
# Poll for results, then retrieve signals# GET /v2/companies/{domain}?include=signalsEnrich Contacts Before Outreach
Section titled “Enrich Contacts Before Outreach”Validate and enrich a list of contacts before adding to your sequences.
# Enrich contacts by emailemails = ["ceo@acme.com", "cfo@acme.com", "cto@acme.com"]
for email in emails: task = requests.post( f"{BASE_URL}/v2/enrich/person", headers={"X-Api-Key": API_KEY, "Content-Type": "application/json"}, json={"email": email} ).json() print(f"Enriching {email}: {task['task_id']}")
# After tasks complete, fetch enriched datafor email in emails: # Hash the email to get the person person = requests.get( f"{BASE_URL}/v2/persons", headers={"X-Api-Key": API_KEY}, params={"query": email, "include": "contact,profile"} ).json()Bulk Enrich Target Account List
Section titled “Bulk Enrich Target Account List”Add companies to your TAL and enrich them all at once.
# Step 1: Add companies to TALdomains = ["stripe.com", "notion.so", "figma.com", "linear.app"]requests.post( f"{BASE_URL}/v2/clients/me/tal/companies", headers={"X-Api-Key": API_KEY, "Content-Type": "application/json"}, json={"domains": domains, "source": "api_import"})
# Step 2: Enrich all TAL companies that need ittask = requests.post( f"{BASE_URL}/v2/clients/me/tal/enrich", headers={"X-Api-Key": API_KEY, "Content-Type": "application/json"}, json={ "max_age_days": 30, # Re-enrich if data older than 30 days "force": False }).json()
print(f"Enriching {task['companies_to_enrich']} companies")print(f"Skipping {task['companies_skipped']} (already fresh)")Companies
Section titled “Companies”Companies are the primary entity in GraphADV. Each company has firmographic data, LinkedIn information, and enrichment metadata.
Get Company
Section titled “Get Company”Retrieve a single company by domain.
GET /v2/companies/{domain}Cost: Free (rate-limited)
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
include | string | Comma-separated field groups: formadv, leadership, signals, all |
include_provenance | boolean | Include data source attribution |
curl "$BASE_URL/v2/companies/stripe.com" \ -H "X-Api-Key: $GRAPHADV_API_KEY"
# With optional fieldscurl "$BASE_URL/v2/companies/stripe.com?include=leadership,signals" \ -H "X-Api-Key: $GRAPHADV_API_KEY"response = requests.get( f"{BASE_URL}/v2/companies/stripe.com", headers={"X-Api-Key": API_KEY})company = response.json()
# With optional fieldsresponse = requests.get( f"{BASE_URL}/v2/companies/stripe.com", headers={"X-Api-Key": API_KEY}, params={"include": "leadership,signals"})const response = await fetch(`${BASE_URL}/v2/companies/stripe.com`, { headers: { 'X-Api-Key': API_KEY }});const company = await response.json();
// With optional fieldsconst response = await fetch( `${BASE_URL}/v2/companies/stripe.com?include=leadership,signals`, { headers: { 'X-Api-Key': API_KEY } });Response:
{ "domain": "stripe.com", "name": "Stripe", "linkedin_url": "https://linkedin.com/company/stripe", "industry": "Financial Services", "employee_count": 8000, "employee_range": "5001-10000", "headquarters_city": "San Francisco", "headquarters_state": "CA", "headquarters_country": "USA", "enrichment_status": "complete", "enriched_at": "2026-01-15T10:30:00Z"}Search Companies
Section titled “Search Companies”Search and filter companies.
GET /v2/companiesCost: Free (rate-limited)
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
query | string | Search by name or domain |
state | string | Filter by headquarters state |
industry | string | Filter by industry |
in_formadv | boolean | Filter by FormADV presence |
enrichment_status | string | Filter by enrichment status |
include | string | Field groups: formadv, leadership, signals, all |
limit | number | Max results (default: 50, max: 200) |
offset | number | Pagination offset |
curl "$BASE_URL/v2/companies?query=fintech&state=CA&limit=10" \ -H "X-Api-Key: $GRAPHADV_API_KEY"response = requests.get( f"{BASE_URL}/v2/companies", headers={"X-Api-Key": API_KEY}, params={"query": "fintech", "state": "CA", "limit": 10})result = response.json()companies = result["companies"]const params = new URLSearchParams({ query: 'fintech', state: 'CA', limit: '10' });const response = await fetch(`${BASE_URL}/v2/companies?${params}`, { headers: { 'X-Api-Key': API_KEY }});const { companies } = await response.json();Get Company Persons
Section titled “Get Company Persons”Retrieve persons associated with a company.
GET /v2/companies/{domain}/personsCost: Free (rate-limited)
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
include | string | Field groups: contact, profile, formadv, history, all |
limit | number | Max results (default: 50, max: 200) |
curl "$BASE_URL/v2/companies/stripe.com/persons?include=contact" \ -H "X-Api-Key: $GRAPHADV_API_KEY"response = requests.get( f"{BASE_URL}/v2/companies/stripe.com/persons", headers={"X-Api-Key": API_KEY}, params={"include": "contact"})persons = response.json()["persons"]const response = await fetch( `${BASE_URL}/v2/companies/stripe.com/persons?include=contact`, { headers: { 'X-Api-Key': API_KEY } });const { persons } = await response.json();Get Company History
Section titled “Get Company History”Get change history for a company (audit trail).
GET /v2/companies/{domain}/historyCost: Free (rate-limited)
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
limit | number | Max events (default: 50, max: 200) |
offset | number | Pagination offset |
field | string | Filter to specific field (e.g., “employee_count”) |
since | string | ISO timestamp - only changes after this time |
curl "$BASE_URL/v2/companies/stripe.com/history?field=employee_count" \ -H "X-Api-Key: $GRAPHADV_API_KEY"response = requests.get( f"{BASE_URL}/v2/companies/stripe.com/history", headers={"X-Api-Key": API_KEY}, params={"field": "employee_count", "limit": 20})history = response.json()["events"]const response = await fetch( `${BASE_URL}/v2/companies/stripe.com/history?field=employee_count`, { headers: { 'X-Api-Key': API_KEY } });const { events } = await response.json();Persons
Section titled “Persons”Persons are individuals with contact information, employment history, and enrichment data.
Search Persons
Section titled “Search Persons”Search and filter persons in the database.
GET /v2/personsCost: Free (rate-limited)
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
query | string | Search by name |
company_domain | string | Filter by company domain |
title | string | Filter by title (contains) |
seniority | string | Filter by seniority level (executive, director, manager, etc.) |
include | string | Field groups: contact, profile, formadv, history, all |
limit | number | Max results (default: 50, max: 200) |
offset | number | Pagination offset |
# Search by namecurl "$BASE_URL/v2/persons?query=john&limit=10" \ -H "X-Api-Key: $GRAPHADV_API_KEY"
# Filter by companycurl "$BASE_URL/v2/persons?company_domain=stripe.com" \ -H "X-Api-Key: $GRAPHADV_API_KEY"
# Filter by title and senioritycurl "$BASE_URL/v2/persons?title=ceo&seniority=executive" \ -H "X-Api-Key: $GRAPHADV_API_KEY"# Search by nameresponse = requests.get( f"{BASE_URL}/v2/persons", headers={"X-Api-Key": API_KEY}, params={"query": "john", "limit": 10})persons = response.json()["persons"]
# Filter by companyresponse = requests.get( f"{BASE_URL}/v2/persons", headers={"X-Api-Key": API_KEY}, params={"company_domain": "stripe.com"})
# Filter by title and seniorityresponse = requests.get( f"{BASE_URL}/v2/persons", headers={"X-Api-Key": API_KEY}, params={"title": "ceo", "seniority": "executive"})// Search by nameconst params = new URLSearchParams({ query: 'john', limit: '10' });const response = await fetch(`${BASE_URL}/v2/persons?${params}`, { headers: { 'X-Api-Key': API_KEY }});const { persons } = await response.json();
// Filter by companyconst response = await fetch( `${BASE_URL}/v2/persons?company_domain=stripe.com`, { headers: { 'X-Api-Key': API_KEY } });Response:
{ "persons": [ { "email_hash": "a1b2c3d4e5f6g7h8", "email": "john@acme.com", "full_name": "John Smith", "title": "CEO", "seniority": "executive", "company_domain": "acme.com", "company_name": "Acme Corp" } ], "total": 1, "limit": 50, "offset": 0}Get Person
Section titled “Get Person”Retrieve a person by email hash.
GET /v2/persons/{email_hash}Cost: Free (rate-limited)
Email Hash Format: The API uses email hashes (first 16 characters of SHA256 of the lowercased email) as identifiers for privacy.
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
include | string | Field groups: contact, profile, formadv, history, all |
include_provenance | boolean | Include data source attribution |
# Calculate email hashEMAIL="patrick@stripe.com"EMAIL_HASH=$(echo -n "$EMAIL" | tr '[:upper:]' '[:lower:]' | shasum -a 256 | cut -c1-16)
curl "$BASE_URL/v2/persons/$EMAIL_HASH" \ -H "X-Api-Key: $GRAPHADV_API_KEY"import hashlib
def get_email_hash(email: str) -> str: """Calculate email hash (first 16 chars of SHA256).""" return hashlib.sha256(email.lower().encode()).hexdigest()[:16]
email_hash = get_email_hash("patrick@stripe.com")response = requests.get( f"{BASE_URL}/v2/persons/{email_hash}", headers={"X-Api-Key": API_KEY})person = response.json()async function getEmailHash(email) { const encoder = new TextEncoder(); const data = encoder.encode(email.toLowerCase()); const hashBuffer = await crypto.subtle.digest('SHA-256', data); const hashArray = Array.from(new Uint8Array(hashBuffer)); const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join(''); return hashHex.substring(0, 16);}
const emailHash = await getEmailHash('patrick@stripe.com');const response = await fetch(`${BASE_URL}/v2/persons/${emailHash}`, { headers: { 'X-Api-Key': API_KEY }});const person = await response.json();Response:
{ "email_hash": "a1b2c3d4e5f6g7h8", "email": "patrick@stripe.com", "first_name": "Patrick", "last_name": "Collison", "full_name": "Patrick Collison", "title": "CEO", "seniority": "executive", "department": "executive", "company_domain": "stripe.com", "company_name": "Stripe", "linkedin_url": "https://linkedin.com/in/patrickcollison", "enrichment_status": "complete", "enriched_at": "2026-01-15T10:35:00Z"}Get Person History
Section titled “Get Person History”Get change history for a person (audit trail).
GET /v2/persons/{email_hash}/historyCost: Free (rate-limited)
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
limit | number | Max events (default: 50, max: 200) |
offset | number | Pagination offset |
field | string | Filter to specific field (e.g., “title”) |
since | string | ISO timestamp - only changes after this time |
Enrichment
Section titled “Enrichment”Enrichment endpoints consume units and run asynchronously. Submit a request, receive a task ID, then poll for results.
Enrich Company
Section titled “Enrich Company”Enrich a company with firmographics, LinkedIn data, and optionally leadership/signals.
POST /v2/enrich/companyCost:
- Base enrichment: 1 unit
- With
include_leadership: +5 units (6 total) - With
include_signals: +3 units (4 total) - With both: +8 units (9 total)
Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
domain | string | Yes | Company domain (e.g., “stripe.com”) |
include_leadership | boolean | No | Also discover leadership team (adds 5 units) |
include_signals | boolean | No | Also discover buying signals from news (adds 3 units) |
force | boolean | No | Re-enrich even if fresh data exists |
callback_url | string | No | Webhook URL for completion notification |
# Company only (1 unit)curl -X POST "$BASE_URL/v2/enrich/company" \ -H "X-Api-Key: $GRAPHADV_API_KEY" \ -H "Content-Type: application/json" \ -d '{"domain": "stripe.com"}'
# Company + Signals (4 units)curl -X POST "$BASE_URL/v2/enrich/company" \ -H "X-Api-Key: $GRAPHADV_API_KEY" \ -H "Content-Type: application/json" \ -d '{"domain": "stripe.com", "include_signals": true}'
# Company + Leadership (6 units)curl -X POST "$BASE_URL/v2/enrich/company" \ -H "X-Api-Key: $GRAPHADV_API_KEY" \ -H "Content-Type: application/json" \ -d '{"domain": "stripe.com", "include_leadership": true}'# Company only (1 unit)response = requests.post( f"{BASE_URL}/v2/enrich/company", headers={"X-Api-Key": API_KEY, "Content-Type": "application/json"}, json={"domain": "stripe.com"})task = response.json()
# Company + Signals (4 units)response = requests.post( f"{BASE_URL}/v2/enrich/company", headers={"X-Api-Key": API_KEY, "Content-Type": "application/json"}, json={"domain": "stripe.com", "include_signals": True})task = response.json()
# Company + Leadership (6 units)response = requests.post( f"{BASE_URL}/v2/enrich/company", headers={"X-Api-Key": API_KEY, "Content-Type": "application/json"}, json={"domain": "stripe.com", "include_leadership": True})task = response.json()
print(f"Task ID: {task['task_id']}")print(f"Units charged: {task['units_charged']}")// Company only (1 unit)const response = await fetch(`${BASE_URL}/v2/enrich/company`, { method: 'POST', headers: { 'X-Api-Key': API_KEY, 'Content-Type': 'application/json' }, body: JSON.stringify({ domain: 'stripe.com' })});const task = await response.json();
// Company + Signals (4 units)const response = await fetch(`${BASE_URL}/v2/enrich/company`, { method: 'POST', headers: { 'X-Api-Key': API_KEY, 'Content-Type': 'application/json' }, body: JSON.stringify({ domain: 'stripe.com', include_signals: true })});const task = await response.json();
// Company + Leadership (6 units)const response = await fetch(`${BASE_URL}/v2/enrich/company`, { method: 'POST', headers: { 'X-Api-Key': API_KEY, 'Content-Type': 'application/json' }, body: JSON.stringify({ domain: 'stripe.com', include_leadership: true })});const task = await response.json();
console.log(`Task ID: ${task.task_id}, Units charged: ${task.units_charged}`);Response:
{ "task_id": "task_abc123", "status": "queued", "message": "Enrichment queued for stripe.com", "units_charged": 6, "units_remaining": 994}Enrich Person
Section titled “Enrich Person”Enrich a person with verified email, LinkedIn profile, and employment history.
POST /v2/enrich/personCost: 1 unit
Request Body (at least one identifier required):
| Field | Type | Description |
|---|---|---|
email | string | Person’s email address |
linkedin_url | string | Person’s LinkedIn profile URL |
full_name | string | Full name (requires company_domain) |
company_domain | string | Company domain (requires full_name) |
force | boolean | Re-enrich even if fresh data exists |
# By emailcurl -X POST "$BASE_URL/v2/enrich/person" \ -H "X-Api-Key: $GRAPHADV_API_KEY" \ -H "Content-Type: application/json" \ -d '{"email": "patrick@stripe.com"}'
# By LinkedIn URLcurl -X POST "$BASE_URL/v2/enrich/person" \ -H "X-Api-Key: $GRAPHADV_API_KEY" \ -H "Content-Type: application/json" \ -d '{"linkedin_url": "https://linkedin.com/in/patrickcollison"}'
# By name and companycurl -X POST "$BASE_URL/v2/enrich/person" \ -H "X-Api-Key: $GRAPHADV_API_KEY" \ -H "Content-Type: application/json" \ -d '{"full_name": "Patrick Collison", "company_domain": "stripe.com"}'# By emailtask = requests.post( f"{BASE_URL}/v2/enrich/person", headers={"X-Api-Key": API_KEY, "Content-Type": "application/json"}, json={"email": "patrick@stripe.com"}).json()
# By LinkedIn URLtask = requests.post( f"{BASE_URL}/v2/enrich/person", headers={"X-Api-Key": API_KEY, "Content-Type": "application/json"}, json={"linkedin_url": "https://linkedin.com/in/patrickcollison"}).json()
# By name and companytask = requests.post( f"{BASE_URL}/v2/enrich/person", headers={"X-Api-Key": API_KEY, "Content-Type": "application/json"}, json={"full_name": "Patrick Collison", "company_domain": "stripe.com"}).json()// By emailconst task = await fetch(`${BASE_URL}/v2/enrich/person`, { method: 'POST', headers: { 'X-Api-Key': API_KEY, 'Content-Type': 'application/json' }, body: JSON.stringify({ email: 'patrick@stripe.com' })}).then(r => r.json());
// By LinkedIn URLconst task = await fetch(`${BASE_URL}/v2/enrich/person`, { method: 'POST', headers: { 'X-Api-Key': API_KEY, 'Content-Type': 'application/json' }, body: JSON.stringify({ linkedin_url: 'https://linkedin.com/in/patrickcollison' })}).then(r => r.json());Batch Enrichment
Section titled “Batch Enrichment”Enrich multiple companies and/or persons in a single request.
POST /v2/enrich/batchCost: 1 unit per domain + 1 unit per email
Request Body:
| Field | Type | Description |
|---|---|---|
domains | string[] | List of company domains |
emails | string[] | List of person emails |
curl -X POST "$BASE_URL/v2/enrich/batch" \ -H "X-Api-Key: $GRAPHADV_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "domains": ["stripe.com", "notion.so"], "emails": ["patrick@stripe.com"] }'task = requests.post( f"{BASE_URL}/v2/enrich/batch", headers={"X-Api-Key": API_KEY, "Content-Type": "application/json"}, json={ "domains": ["stripe.com", "notion.so"], "emails": ["patrick@stripe.com"] }).json()const task = await fetch(`${BASE_URL}/v2/enrich/batch`, { method: 'POST', headers: { 'X-Api-Key': API_KEY, 'Content-Type': 'application/json' }, body: JSON.stringify({ domains: ['stripe.com', 'notion.so'], emails: ['patrick@stripe.com'] })}).then(r => r.json());Leadership Discovery
Section titled “Leadership Discovery”Discover leadership teams at target companies (founders, C-suite, VPs).
POST /v2/search/leadershipCost: 5 units per company
Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
domains | string[] | Yes | Company domains to research (max 10) |
max_per_company | number | No | Max people per company (1-10, default: 5) |
enrich_via_linkedin | boolean | No | Deep LinkedIn enrichment (default: true) |
callback_url | string | No | Webhook URL for completion notification |
# Single company (5 units)curl -X POST "$BASE_URL/v2/search/leadership" \ -H "X-Api-Key: $GRAPHADV_API_KEY" \ -H "Content-Type: application/json" \ -d '{"domains": ["stripe.com"]}'
# Multiple companies (10 units)curl -X POST "$BASE_URL/v2/search/leadership" \ -H "X-Api-Key: $GRAPHADV_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "domains": ["stripe.com", "notion.so"], "max_per_company": 5 }'# Single company (5 units)task = requests.post( f"{BASE_URL}/v2/search/leadership", headers={"X-Api-Key": API_KEY, "Content-Type": "application/json"}, json={"domains": ["stripe.com"]}).json()
# Multiple companies with custom paramsdomains = ["stripe.com", "notion.so"]task = requests.post( f"{BASE_URL}/v2/search/leadership", headers={"X-Api-Key": API_KEY, "Content-Type": "application/json"}, json={ "domains": domains, "max_per_company": 5, "enrich_via_linkedin": True }).json()
print(f"Discovering leadership for {len(domains)} companies")print(f"Units charged: {task['units_charged']}")// Single company (5 units)const task = await fetch(`${BASE_URL}/v2/search/leadership`, { method: 'POST', headers: { 'X-Api-Key': API_KEY, 'Content-Type': 'application/json' }, body: JSON.stringify({ domains: ['stripe.com'] })}).then(r => r.json());
// Multiple companies with custom paramsconst domains = ['stripe.com', 'notion.so'];const task = await fetch(`${BASE_URL}/v2/search/leadership`, { method: 'POST', headers: { 'X-Api-Key': API_KEY, 'Content-Type': 'application/json' }, body: JSON.stringify({ domains, max_per_company: 5, enrich_via_linkedin: true })}).then(r => r.json());
console.log(`Discovering leadership for ${domains.length} companies`);console.log(`Units charged: ${task.units_charged}`);Response:
{ "task_id": "task_xyz789", "status": "queued", "message": "Leadership discovery queued for 2 companies", "units_charged": 10, "units_remaining": 990}Signal Discovery
Section titled “Signal Discovery”Automatically discover buying signals from news and public sources for target companies.
POST /v2/discover/signalsCost: 3 units per company
Signal Types Detected:
| Signal Type | Description |
|---|---|
| Funding | Investment rounds, fundraising announcements |
| Expansion | Office openings, market entry, geographic growth |
| Leadership Change | Executive moves, promotions, departures |
| Product Launch | New products, features, releases |
| Partnership | Strategic partnerships, integrations |
| Acquisition | M&A activity, company purchases |
| Hiring | Key hires, team expansion signals |
| Award | Industry recognition, rankings |
| Regulatory | Compliance updates, certifications |
| Technology | Tech stack changes, platform migrations |
Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
domains | string[] | Yes | Company domains to monitor (max 50) |
max_articles_per_company | number | No | Max articles to analyze per company (1-25, default: 10) |
callback_url | string | No | Webhook URL for completion notification |
# Discover signals for multiple companies (6 units)curl -X POST "$BASE_URL/v2/discover/signals" \ -H "X-Api-Key: $GRAPHADV_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "domains": ["anthropic.com", "openai.com"], "max_articles_per_company": 10 }'# Discover signals for target companiesdomains = ["anthropic.com", "openai.com"]task = requests.post( f"{BASE_URL}/v2/discover/signals", headers={"X-Api-Key": API_KEY, "Content-Type": "application/json"}, json={ "domains": domains, "max_articles_per_company": 10 }).json()
print(f"Signal discovery queued for {len(domains)} companies")print(f"Units charged: {task['units_charged']}")// Discover signals for target companiesconst domains = ['anthropic.com', 'openai.com'];const task = await fetch(`${BASE_URL}/v2/discover/signals`, { method: 'POST', headers: { 'X-Api-Key': API_KEY, 'Content-Type': 'application/json' }, body: JSON.stringify({ domains, max_articles_per_company: 10 })}).then(r => r.json());
console.log(`Signal discovery queued for ${domains.length} companies`);console.log(`Units charged: ${task.units_charged}`);Response:
{ "task_id": "task_sig123", "status": "queued", "message": "Signal discovery queued for 2 companies", "units_charged": 6, "units_remaining": 994}Tasks (Async Operations)
Section titled “Tasks (Async Operations)”All enrichment operations are asynchronous. Poll task endpoints to check status and retrieve results.
List Tasks
Section titled “List Tasks”GET /v2/tasksQuery Parameters:
| Parameter | Type | Description |
|---|---|---|
status | string | Filter by status (queued, running, completed, failed) |
limit | number | Max results (1-100, default: 20) |
curl "$BASE_URL/v2/tasks?status=completed&limit=10" \ -H "X-Api-Key: $GRAPHADV_API_KEY"response = requests.get( f"{BASE_URL}/v2/tasks", headers={"X-Api-Key": API_KEY}, params={"status": "completed", "limit": 10})tasks = response.json()["tasks"]const response = await fetch( `${BASE_URL}/v2/tasks?status=completed&limit=10`, { headers: { 'X-Api-Key': API_KEY } });const { tasks } = await response.json();Get Task Status
Section titled “Get Task Status”GET /v2/tasks/{task_id}Response:
{ "id": "task_abc123", "task_type": "enrich_company_with_leadership", "status": "completed", "progress": 1.0, "created_at": "2026-01-15T10:30:00Z", "completed_at": "2026-01-15T10:32:15Z"}Status values: queued, running, completed, failed
Get Task Result
Section titled “Get Task Result”GET /v2/tasks/{task_id}/resultReturns the enriched data once the task is complete.
Response (Leadership Search):
{ "id": "task_abc123", "task_type": "leadership_search", "status": "completed", "input_data": { "domains": ["stripe.com"], "max_per_company": 5 }, "output_data": { "leadership": [ { "domain": "stripe.com", "contacts": [ { "full_name": "Patrick Collison", "email": "patrick@stripe.com", "title": "CEO", "linkedin_url": "https://linkedin.com/in/patrickcollison", "seniority": "executive" } ] } ] }}Target Account Lists (TAL)
Section titled “Target Account Lists (TAL)”Manage lists of target companies for ABM campaigns and sales outreach.
List TAL Companies
Section titled “List TAL Companies”GET /v2/clients/{client_id}/tal/companiesCost: Free
Add to TAL
Section titled “Add to TAL”POST /v2/clients/{client_id}/tal/companiesCost: Free
Request Body:
| Field | Type | Description |
|---|---|---|
domains | string[] | Company domains to add |
source | string | Source tag (e.g., “manual”, “import”) |
curl -X POST "$BASE_URL/v2/clients/my-client-id/tal/companies" \ -H "X-Api-Key: $GRAPHADV_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "domains": ["stripe.com", "notion.so", "figma.com"], "source": "manual" }'response = requests.post( f"{BASE_URL}/v2/clients/my-client-id/tal/companies", headers={"X-Api-Key": API_KEY, "Content-Type": "application/json"}, json={ "domains": ["stripe.com", "notion.so", "figma.com"], "source": "manual" })await fetch(`${BASE_URL}/v2/clients/my-client-id/tal/companies`, { method: 'POST', headers: { 'X-Api-Key': API_KEY, 'Content-Type': 'application/json' }, body: JSON.stringify({ domains: ['stripe.com', 'notion.so', 'figma.com'], source: 'manual' })});Remove from TAL
Section titled “Remove from TAL”DELETE /v2/clients/{client_id}/tal/companiesRequest Body:
{ "domains": ["acme.com"]}Enrich TAL
Section titled “Enrich TAL”POST /v2/clients/{client_id}/tal/enrichCost: 1 unit per company enriched (skips fresh companies)
Request Body:
| Field | Type | Description |
|---|---|---|
force | boolean | Re-enrich even if fresh data exists |
max_age_days | number | Consider data stale after N days |
dry_run | boolean | Preview what would be enriched without charging |
Usage & Stats
Section titled “Usage & Stats”Get Usage
Section titled “Get Usage”Check your current plan and unit balance.
GET /v2/usageResponse:
{ "plan": "growth", "units_remaining": 847, "units_used_this_period": 153, "period_started_at": "2026-01-01T00:00:00Z", "period_ends_at": "2026-01-31T00:00:00Z", "overage_allowed": false}Get Stats
Section titled “Get Stats”Get platform statistics.
GET /v2/statsResponse:
{ "companies": { "total": 25000, "enriched": 20000, "from_formadv": 24000 }, "persons": { "total": 85000, "enriched": 60000, "from_formadv": 80000 }}Error Handling
Section titled “Error Handling”GraphADV returns standard HTTP status codes:
| Code | Description |
|---|---|
200 | Success |
400 | Bad request (invalid parameters) |
401 | Unauthorized (missing API key) |
402 | Payment required (insufficient units) |
403 | Forbidden (trial expired) |
404 | Not found |
422 | Unprocessable entity (validation failed) |
429 | Rate limit exceeded |
500 | Server error |
Error Response:
{ "detail": "Insufficient credits. Required: 5, Available: 2"}Related Reading
Section titled “Related Reading”- Getting Started - Make your first request
- Pricing - Understand unit costs
- Examples - Real-world use cases