Create an agent
Create an agent.
Create an agent.
display_name is the only required field. Send as much or as little of
the rest as you like: an agent created with nothing but a name is a valid
empty DRAFT, and you can fill in its prompts, voice and policies later with
PATCH.
How this runs. Creating an agent allocates it and then configures it, in
that order and through the same write path PATCH uses — so a control
means exactly the same thing on create as it does on update, and there is
only one place that decides what a control does. Two consequences worth
knowing:
- a newly created agent comes back at version 2, not 1;
- if the configuring write fails, the half-made agent is archived rather than left behind, and you get the error from the write.
The agent is created at status DRAFT. It must be deployed before it can
place calls, and an ACTIVE agent must be set back to INACTIVE before it
can be edited or archived.
Latency is variable. Configuring extraction can require the agent service to derive a schema with a model call, so this request is allowed up to 45 seconds rather than the usual 15.
Rate limit: 1000 requests per minute per organization (bucket default). Exceeding it returns 429 with Retry-After; the X-RateLimit-* response headers report your remaining allowance on every call.
v2/agentsAuthorization
AuthorizationRequiredBearer <token>
Your Graine API key. Create one in the dashboard under Developers, or via POST /v2/api-keys. Send it as Authorization: Bearer <key>.
In: header
Request Body
application/jsonRequireddisplay_nameRequiredDisplay Name
The agent's name. Letters, digits, spaces and - _ . ( ) only.
1Maximum length: 100summarySummary | null
Your own note about what this agent is for.
2000greeting_messageGreeting Message | null
The first line the agent speaks. May contain {variables}.
20000statusStatus | null
DRAFT | ACTIVE | INACTIVE | ARCHIVED. Uppercase.
categoryCategory | null
What kind of work this agent does.
labelsLabels | null
Replaces the whole list of labels.
promptsPrompts
The agent's instructions.
variablesVariables
Prompt placeholders.
analyticsAnalytics
Per-call extraction.
integrationsIntegrations | null
webhook.url sets the status callback; webcall enables browser calling; mcp connects tools. Send mcp: null to disconnect them.
knowledge_baseKnowledge Base
Attach a knowledge base, or send null to detach.
calling_guardCalling Guard
The hours this agent may ring people. Applies to POST /v2/calls only; a call outside the window is rescheduled for the next opening, not rejected. Send {"enabled": false} to remove it.
conversation_configConversation Config | null
The flat view of the ten most-changed controls. Writing one here is the same as writing it in its policy bucket.
configurationConfiguration
How this agent runs a call.
settingsSettings
Agent-wide switches.
follow_up_configFollow Up Config
Follow-up behaviour.
multilingualMultilingual | null
Per-language voices and prompts. Sending this REPLACES the stored block; send null to go back to a single language.
Query Parameters
organization_idOrganization Id
Accepted for symmetry with the rest of the API. It must match the organisation the API key belongs to; any other value is rejected.
Response Body
201
The created agent, at status DRAFT.
agent_idRequiredAgent Id
Stable identifier for this agent. Use it everywhere else in the API.
org_idOrg Id | null
The organisation this agent belongs to. Always the organisation your API key belongs to.
display_nameDisplay Name | null
The agent's name, as it appears in the dashboard.
summarySummary | null
A short note about what this agent is for. Yours to write; never shown to a caller.
greeting_messageGreeting Message | null
The first line the agent speaks. May contain {variables}.
statusStatus | null
DRAFT | ACTIVE | INACTIVE | ARCHIVED. An agent must be ACTIVE to place calls, and INACTIVE to be edited or archived.
categoryCategory | null
What kind of work this agent does. Yours to choose; it groups agents in the dashboard and changes nothing at call time.
versionVersion
Incremented on every successful update. Read it back after a write to confirm the change landed.
1timestampsTimestamps
When this agent was created and last changed.
labelsLabels
Free-form labels for your own filtering.
@minItems 0
@minItems 0
promptsPrompts
The agent's instructions. Empty on a list row — prompts are not fetched while listing.
variablesVariables
Placeholders the greeting and prompts may use.
analyticsAnalytics
What is extracted from every call, beyond the summary.
integrationsIntegrations
Where this agent is wired up: a status callback under webhook, browser calling under webcall, connected tools under mcp. Only what is configured appears.
knowledge_baseKnowledge Base
The knowledge base this agent answers from. Null when none is attached, and null on a list row — it is not fetched while listing.
conversation_configConversation Config | null
A flat view of the ten most-changed controls from the policy buckets below — the same values, not a second set. Change either.
configurationConfiguration
How this agent runs a call.
settingsSettings
Agent-wide switches.
follow_up_configFollow Up Config
What happens after a call, when a follow-up is warranted.
multilingualMultilingual | null
Per-language voices and prompts, when the agent switches language mid-call. Null when it speaks one language.
calling_guardCalling Guard | null
The hours this agent may ring people, or null when it may call at any time. Applies to POST /v2/calls only — a call outside the window is rescheduled for the next opening rather than refused.
dropped_languagesDropped Languages | null
Returned after an update that sent a language which could not be saved — usually a missing voice. Those languages were not stored.
@minItems 0
@minItems 0
400
1000 — malformed or contradictory input. 1002 — a required parameter is missing.
errorRequiredError
Stable integer code from the /v2 error table. Branch on this.
messageRequiredMessage
One human-readable sentence. Wording may change; the code will not.
401
1100 — missing, unknown or inactive API key. 1101 — a browser session token was presented instead of an API key.
errorRequiredError
Stable integer code from the /v2 error table. Branch on this.
messageRequiredMessage
One human-readable sentence. Wording may change; the code will not.
403
1102 — the key is valid but lacks the scope this endpoint requires, or names another organization. GET /v2/scopes reports what a key holds.
errorRequiredError
Stable integer code from the /v2 error table. Branch on this.
messageRequiredMessage
One human-readable sentence. Wording may change; the code will not.
422
1001 — the body or query failed validation; the message names the first offending field.
errorRequiredinteger
Stable integer code from the error table. Branch on this, not on the message.
messageRequiredstring
One human-readable sentence. Wording may change; the code will not.
429
1300 — the per-organization request rate or concurrent-call limit was reached. Carries Retry-After.
errorRequiredError
Stable integer code from the /v2 error table. Branch on this.
messageRequiredMessage
One human-readable sentence. Wording may change; the code will not.
503
1501 — a service this endpoint depends on is unreachable or returned a 5xx.
errorRequiredError
Stable integer code from the /v2 error table. Branch on this.
messageRequiredMessage
One human-readable sentence. Wording may change; the code will not.
504
1502 — a service this endpoint depends on did not answer in time.
errorRequiredError
Stable integer code from the /v2 error table. Branch on this.
messageRequiredMessage
One human-readable sentence. Wording may change; the code will not.
The created agent, at status DRAFT.

