Skip to content

Agency Keys & Cross-Org Targeting

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

FieldTypeRequiredDescription
namestringYesHuman-readable label for the key
is_agencybooleanNoSet true to mint an agency-scoped key. Omit or set false for a normal key

Example

Terminal window
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

StatusMeaning
400Org is not a recognized agency (no linked client orgs, not flagged is_agency)
403Caller 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

RequestResult
Agency key, no X-Target-Org-Id200 — 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 ID200 — operates the agency org
Agency key + X-Target-Org-Id for an org outside the agency’s authorized set403 — not authorized for that target
Normal key + X-Target-Org-IdHeader ignored — resolves to the key’s own org (no error)

Notes

  • X-Target-Org-Id is 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-Id is distinct from X-Org-Id. X-Org-Id remains a same-org safety guard; X-Target-Org-Id is 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 any X-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

Terminal window
# 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

Terminal window
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"
}
}
FieldTypeDescription
agency_org_idstringThe org ID of the agency itself
agency_org_namestringDisplay name of the agency org
is_agencybooleanAlways true for a valid agency key
client_countintegerNumber of client orgs this key is authorized to target
target_headerstringThe header name to use for cross-org targeting (X-Target-Org-Id)

Errors

StatusMeaning
403Key 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

Terminal window
curl "https://be.graph8.com/api/v1/agency/clients" \
-H "Authorization: Bearer $AGENCY_KEY"

Response

{
"data": [
{ "org_id": "org_client123" },
{ "org_id": "org_client456" }
]
}
FieldTypeDescription
org_idstringClient org ID. Use this value as X-Target-Org-Id to operate that org

Errors

StatusMeaning
403Key is not an agency-scoped key