All docs

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

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

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

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

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"
  }
}
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

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" }
  ]
}
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
Build with graph8