Graine AI

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

https://api.graine.ai/v2

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

curl https://api.graine.ai/v2/user/me \
  -H "Authorization: Bearer gat_7f3c9a21b4e85d0c6a19f2734b8e5c60"

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.

Embed on your website

Two script tags put a voice or chat agent on your site, restricted to your domains and handed context from the page.

In-app agents

The agent inside your mobile app — it sees the screen the customer is on, acts on it, and takes or makes calls like WhatsApp. React Native, Android, iOS, Flutter.

Flow agents

Build an agent as steps and paths: fixed lines said word for word, rules that branch on your data, and events from your own systems.

Outreach workflows

What happens to each contact across calls, waits and your own systems: call, try again, tell your CRM, wait for its answer, and end with an outcome you can count.

Memory

Each person remembered across phone calls, chats and in-app calls, for prompt agents and flow agents: what the agent reads, the settings, and the lines that make it use what it knows.

Your design

Choose how the agent looks in the dashboard; the website and every SDK draw it, typeface included, with nothing in your code.

Authentication

gat_ bearer keys, the eleven scopes, how organizations are resolved, and why a dashboard session is refused.

API reference

All 69 operations and the three webhook payloads, 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 windows, the X-RateLimit headers, and how many calls can run at once.

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.

ConcernRule
AuthenticationAuthorization: Bearer gat_... — the only accepted form. A key sent in any other header is not read.
OrganizationTaken from the key. The optional ?organization_id= query parameter must match the key's own organization or the request is refused.
ErrorsAlways {"error": <integer>, "message": "<sentence>"}. A success response never carries error.
TimestampsISO-8601 UTC, millisecond precision, literal Z — 2026-08-26T10:15:30.123Z.
Phone numbersE.164, 7 to 15 digits, for example +14155550123.
Request bodiesAn unknown top-level key is rejected with error 1001, so a typo'd field name fails loudly instead of silently doing nothing. Two exceptions: the objects nested inside an agent's configuration accept keys they do not know without an error, and the POST /v2/transliterate body ignores them.
Rate limit headersX-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset are on every response after your key is authenticated, 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:

{
  "data": [],
  "pagination": {
    "page": 1,
    "page_size": 20,
    "total": 137,
    "total_pages": 7,
    "has_more": true
  }
}

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 leaves out agents that are hidden from the list.

Identifiers

IdWhere it comes fromWhat it is for
agent_idPOST /v2/agentsNaming the agent on a call, a campaign, or a clone.
execution_idPOST /v2/calls, or a contact in a campaignOne call, for its whole life — scheduled, ringing, in progress, finished. Transcript, recording and stop all key off it.
campaign_idPOST /v2/campaignsPausing, resuming, cancelling and reporting on a contact list.
key_idGET /v2/api-keysRevoking 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.

GroupEndpointsLimit
Placing callsPOST /v2/calls, its stop and transfer, POST /v2/campaigns600 / minute (500 sustained)
Reading callsGET /v2/calls and the per-call reads, GET /v2/agents/{id}/executions, GET /v2/usage600 / minute (500 sustained)
Knowledge-base uploadsThe two knowledge-base uploads20 / minute
TransliterationPOST /v2/transliterate60 / minute
Everything elseEvery other endpoint1000 / minute

Exceeding a limit returns 429 with error code 1300 and a Retry-After header. See Rate limits for the sliding-window details.

On this page