All docs
Start here
API basics
Agent setups
Resources
- Contacts
- Companies
- Lists
- Deals
- Tasks
- Notes
- Fields
- Quotes
- Stage Checklist Pipelines
- Sequences
- Sequence Lifecycle
- Inbox
- Meetings
- Appointments Management
- Voice & Dialer
- Skills (LLM + API)
- Workflows
- GTM Campaigns
- GTM Context
- GTM Knowledge Base
- Launch Helpers
- Landing Pages
- Intent & Signals
- Search
- Enrichment
- Assert / Upsert
- Agency Keys & Cross-Org Targeting
- CRM Syncs
- Audience Syncs
- Destinations
- Snippet
- Functions
Data pipeline
Webhooks
What's new
Agency Keys & Cross-Org Targeting
Mint a single agency-scoped API key to operate any client org across the entire Developer API without one key per client.
An agency is an org that manages a portfolio of client orgs linked in graph8 as parent → child. An agency can mint a single agency-scoped API key and use it to operate any of its client orgs through the entire Developer API — contacts, sequences, dialer, workflows, appointments, deals, everything — without minting one key per client.
Mint an Agency Key
POST /api-keys
Create an agency-scoped API key on the agency (parent) org by passing is_agency: true in the request body.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Human-readable label for the key |
is_agency | boolean | No | Set true to mint an agency-scoped key. Omit or set false for a normal key |
Example
cURL
curl -X POST "https://be.graph8.com/api/v1/api-keys" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "CIENCE agency ops",
"is_agency": true
}' Response
{
"data": {
"id": "key_abc123",
"name": "CIENCE agency ops",
"is_agency": true,
"token": "sk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}
}
Errors
| Status | Meaning |
|---|---|
400 | Org is not a recognized agency (no linked client orgs, not flagged is_agency) |
403 | Caller lacks API-key admin permission |
Cross-Org Targeting — X-Target-Org-Id
Once you have an agency key, send it with the X-Target-Org-Id header to act on a specific client org. The request then reads and writes that client org’s data.
Targeting Rules
| Request | Result |
|---|---|
Agency key, no X-Target-Org-Id | 200 — resolves to the agency’s own org |
Agency key + X-Target-Org-Id for an authorized client (case-insensitive) | 200 — operates that client org |
Agency key + X-Target-Org-Id set to the agency’s own org ID | 200 — operates the agency org |
Agency key + X-Target-Org-Id for an org outside the agency’s authorized set | 403 — not authorized for that target |
Normal key + X-Target-Org-Id | Header ignored — resolves to the key’s own org (no error) |
Notes
X-Target-Org-Idis honored on the Developer API (/api/v1/*) only. It is not used by in-app or customer-hub hybrid endpoints, which keep single-org semantics.X-Target-Org-Idis distinct fromX-Org-Id.X-Org-Idremains a same-org safety guard;X-Target-Org-Idis the agency selector. Do not conflate them. For an agency key,X-Org-Id(if sent) still checks against the agency’s own org, independent of anyX-Target-Org-Id.- The target is always clamped against the agency’s live authorized client set — a caller-supplied value can only select within that set, never widen it.
- Billing: credit-consuming actions performed in a client org are charged to that client org, not the agency.
- Cross-org writes are supported, with one exception: destructive marketplace operations (for example, approving an SDR invoice that fires a Stripe charge) still require a personal admin key and are refused for agency machine keys.
Example
cURL
# List contacts in a specific client org
curl "https://be.graph8.com/api/v1/contacts" \
-H "Authorization: Bearer $AGENCY_KEY" \
-H "X-Target-Org-Id: org_client123"
# Create a contact in a client org
curl -X POST "https://be.graph8.com/api/v1/contacts" \
-H "Authorization: Bearer $AGENCY_KEY" \
-H "X-Target-Org-Id: org_client123" \
-H "Content-Type: application/json" \
-d '{
"list_id": 5,
"first_name": "Jane",
"last_name": "Smith",
"work_email": "[email protected]"
}' Get Agency Credential Info
GET /agency/me
Describe the agency credential associated with the current API key. Returns metadata about the agency org and the number of client orgs the key can target.
Example
cURL
curl "https://be.graph8.com/api/v1/agency/me" \
-H "Authorization: Bearer $AGENCY_KEY" Response
{
"data": {
"agency_org_id": "org_agency123",
"agency_org_name": "CIENCE",
"is_agency": true,
"client_count": 52,
"target_header": "X-Target-Org-Id"
}
}
| Field | Type | Description |
|---|---|---|
agency_org_id | string | The org ID of the agency itself |
agency_org_name | string | Display name of the agency org |
is_agency | boolean | Always true for a valid agency key |
client_count | integer | Number of client orgs this key is authorized to target |
target_header | string | The header name to use for cross-org targeting (X-Target-Org-Id) |
Errors
| Status | Meaning |
|---|---|
403 | Key is not an agency-scoped key |
List Authorized Client Orgs
GET /agency/clients
List all client orgs this agency key is authorized to target. Each org_id in the response is a valid value for the X-Target-Org-Id header.
Example
cURL
curl "https://be.graph8.com/api/v1/agency/clients" \
-H "Authorization: Bearer $AGENCY_KEY" Response
{
"data": [
{ "org_id": "org_client123" },
{ "org_id": "org_client456" }
]
}
| Field | Type | Description |
|---|---|---|
org_id | string | Client org ID. Use this value as X-Target-Org-Id to operate that org |
Errors
| Status | Meaning |
|---|---|
403 | Key is not an agency-scoped key |