Graine API
A voice-AI calling API — build an agent, place a call, and follow that one call from the dial to the transcript with a single id.
The Graine API places real phone calls conducted by a conversational voice agent, and gives you everything the call produced afterwards — status, duration, cost, transcript and recording.
Four resources cover the whole surface:
- Agents — the configuration that decides what the agent says and how it sounds.
- Calls — one outbound call, now or scheduled, tracked end to end.
- Campaigns — a contact list dialled by one agent, with the policy that governs it: caller IDs, calling hours, retries and follow-ups. Pause, resume and cancel.
- Account — who your key belongs to, what it has spent, and key management.
Base URL
Every path in these docs is relative to that URL. The version lives in the path,
so /v2 is a stable prefix — not a header, not a query parameter.
Your first request
If that returns your organization, your key works and you are ready for the Quickstart.
Explore
Quickstart
Key to first completed call in five requests, with the real JSON at every step.
Authentication
gat_ bearer keys, the eight scopes, how organizations are resolved, and why a dashboard session is refused.
API reference
All 58 endpoints, generated from the spec the API itself emits — with a request panel that calls the live API from the page.
Webhooks
One consolidated event per call: subscribing, testing an endpoint, signature verification and the retry ladder.
Agents
Create, read, update, clone and archive agents, and list the calls an agent has run.
Calls
Place, schedule, list, stop. Then read the transcript and the recording.
Campaigns
One request: upload a contact list as JSON or CSV, set the calling policy, and start dialling.
Account
Identity, concurrency capacity, wallet balance, usage aggregates and API keys.
Errors
One envelope, thirteen stable integer codes, and the HTTP status each maps to.
Rate limits
Per-organization sliding windows, the X-RateLimit headers, and what happens when Redis blinks.
Enterprise
Concurrency, tenancy isolation and the operational guarantees behind the surface.
Conventions
These hold on every endpoint, so they are stated once here rather than repeated on each page.
| Concern | Rule |
|---|---|
| Authentication | Authorization: Bearer gat_... — the only accepted form. X-API-Key and X-API-DEV are not read on /v2. |
| Organization | Taken from the key. The optional ?organization_id= query parameter must match the key's own organization or the request is refused. |
| Errors | Always {"error": <integer>, "message": "<sentence>"}. A success response never carries error. |
| Timestamps | ISO-8601 UTC, millisecond precision, literal Z — 2026-08-26T10:15:30.123Z. |
| Phone numbers | E.164, 7 to 15 digits, for example +14155550123. |
| Request bodies | Unknown keys are rejected with error 1001, so a typo'd field name fails loudly instead of silently doing nothing. |
| Rate limit headers | X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset are on every response, success or failure. |
Pagination
Every list endpoint takes page (1-indexed, default 1) and page_size
(default 20, maximum 100), and returns the same envelope:
Page until has_more is false rather than dividing total yourself. On
very large collections total is a capped estimate, and on GET /v2/agents
it is corrected for hidden internal records on the page being returned.
Identifiers
| Id | Where it comes from | What it is for |
|---|---|---|
agent_id | POST /v2/agents | Naming the agent on a call, a campaign, or a clone. |
execution_id | POST /v2/calls, or a contact in a campaign | One call, for its whole life — scheduled, ringing, in progress, finished. Transcript, recording and stop all key off it. |
campaign_id | POST /v2/campaigns | Pausing, resuming, cancelling and reporting on a contact list. |
key_id | GET /v2/api-keys | Revoking a key. Never the key itself. |
execution_id is minted before the call is placed and handed back immediately,
which is what makes the API safe to integrate against: even if a dial request
times out, the id you already hold answers GET /v2/calls/{execution_id}. Poll
it — never redial.
Rate limits at a glance
Limits are per organization, not per key, so minting more keys does not buy more quota.
| Bucket | Endpoints | Limit |
|---|---|---|
calls.create | POST /v2/calls, POST /v2/campaigns | 500 / minute |
executions.list | GET /v2/calls, GET /v2/agents/{id}/executions | 500 / minute |
default | Everything else | 1000 / minute |
Exceeding a limit returns 429 with error code 1300 and a Retry-After
header. See Rate limits for the sliding-window details.

