API Reference
Place voice calls, drive AI voice agents, run verification (OTP) calls, trigger saved campaigns, and check call status directly from your own systems over a simple JSON REST API.
The Agentive Voice API gives your application programmatic access to the same calling stack that powers the dashboard. Place a single outbound call, have an AI voice agent make a call for you, read a verification code out to a customer, run a saved campaign for one number, or poll the result of any call you started.
Every amount is in Indian Rupees (INR). Every timestamp is in Indian Standard Time (IST), in ISO 8601 format. Every request is authenticated with a publishable key and a secret, and every response uses one consistent JSON envelope so your integration code stays simple.
Every endpoint path below is relative to this base URL.
https://voice.agentive.co.in/api/public/v1Every request must be authenticated with two credentials issued to your account.
| Credential | What it is | How to send it |
|---|---|---|
| Publishable key | Your account's public lookup handle. Starts with pk_live_. | x-api-key request header |
| Secret key | Your account's private proof. Starts with sk_live_. Treat it like a password. | x-api-secret request header (preferred), or a secret field in the JSON body |
View and rotate both keys from the API tab in your dashboard. The secret is shown in full exactly once, when it is first generated or rotated. It is stored hashed on our side, so it can never be shown again, by you or by us. If you lose it, rotate to generate a new pair, and the old secret stops working immediately.
The header form is recommended because it keeps the secret out of request bodies and most log formats. If you send the secret in both the header and the body, the header value is used. There is a single set of live credentials per account; both keys begin with a _live_ prefix and every call is processed against your live account.
As an alternative to the two headers, you may send the credentials with HTTP Basic auth, using the publishable key as the username and the secret as the password. This is the familiar curl -u form. When an x-api-key header is present it takes precedence; otherwise the Basic credentials are used.
curl https://voice.agentive.co.in/api/public/v1/account \
-u pk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx:sk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxcurl https://voice.agentive.co.in/api/public/v1/calls \
-H "x-api-key: pk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-H "x-api-secret: sk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{ "type": "audio_blast", "number": "9812345678", "audio_id": 12 }'| Situation | HTTP | details message |
|---|---|---|
| No publishable key sent | 401 | Missing API key. Send your publishable key in the x-api-key header. |
| Unknown publishable key | 401 | Invalid API credentials. |
| Known key, wrong or missing secret | 403 | Invalid API credentials. |
| Account is not active | 403 | This account is not active. Please contact support. |
| API access not enabled for the account | 403 | The API is not enabled for this account. Please contact support. |
| The endpoint's product is not enabled for the account | 403 | This feature is not enabled for your account. |
The wording is intentionally the same for an unknown key and a wrong secret, so that credentials cannot be probed.
Every response is JSON and uses one consistent envelope.
{
"status": "success",
"code": 200,
"unique_id": "run_4821",
"reference_id": "order-99213",
"details": "Call queued."
}| Field | Type | Description |
|---|---|---|
| status | string | "success" or "error". |
| code | number | A numeric result code. Mirrors the HTTP status (see Error codes). |
| unique_id | string | null | Our identifier for the resource created by this call. Use it with Get call status. For OTP requests this is the verification request id. |
| reference_id | string | null | Echoes the reference_id you sent, so you can correlate the response with your own records. null if you did not send one. |
| details | string | A short human-readable description of the result. |
Successful responses may include extra fields alongside the envelope. These are documented per endpoint (for example request_id and expires_in_sec on OTP send, verified on verify, call_status on status).
status: "success". A failed request returns the matching HTTP error status (400, 401, 403, 404, 429, or 5xx) with status: "error", and the same value in the code field.| HTTP | code | Meaning | When it happens |
|---|---|---|---|
| 200 | 200 | Success | The request was accepted. |
| 400 | 400 | Bad request | A required field is missing or invalid (a malformed number, an unknown type, a missing audio_id, or a missing code on verify). |
| 401 | 401 | Unauthorized | The publishable key is missing or unknown, or (on verify) the submitted code is incorrect. |
| 402 | 402 | Balance too low | Your account balance is too low to place the call. Top up and retry. |
| 403 | 403 | Forbidden | The secret is wrong, the account is not active, API access is not enabled, or the endpoint's product is not enabled for your account. |
| 404 | 404 | Not found | The campaign id, call id, agent, number, or verification request could not be found for your account. Also returned by transcript and analysis reads before the artifact is ready. |
| 409 | 409 | Conflict | A request with the same Idempotency-Key is still being processed (retry in a moment), all AI call channels are in use, or the request arrived outside calling hours. |
| 422 | 422 | Idempotency key reuse | The same Idempotency-Key was sent with a different request body. Use a fresh key for a new request. |
| 429 | 429 | Too many requests | You exceeded the rate limit, or placed too many calls to one number in a short window. Wait, then retry. |
| 5xx | 5xx | Temporary problem | The call could not be placed right now. Safe to retry after a short pause. |
The split between 429 and 5xx matters for retry logic: a 429 means a limit was hit, so wait before retrying; a 5xx means a temporary problem on our side, so an immediate retry after a short pause is safe (and, with the same Idempotency-Key, can never double-place the call).
Error responses never include internal infrastructure detail. A failed call placement returns a neutral message such as "Could not place the call right now. Please retry."
{
"status": "error",
"code": 400,
"unique_id": null,
"reference_id": "order-99213",
"details": "A valid Indian mobile number is required."
}Requests are limited per account to 120 requests per minute. The limit is keyed to your account, so traffic from one account never throttles another, and an office behind a single shared IP is not treated as one caller.
When you exceed the limit you receive HTTP 429 with:
{
"status": "error",
"code": 429,
"details": "Too many requests. Please slow down and retry shortly."
}Standard rate-limit headers (RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset) are returned on responses so you can pace your requests.
The write endpoints place a call, place an AI agent call, trigger a saved campaign, send a voice verification code, verify a code, and bind a number to an AI agent. The read endpoints fetch a single call's status, list your calls, download a recording, read a call's transcript and analysis, list your campaigns and AI agents and numbers, and report your account balance.
/callsPlace a single outbound call immediately. Three call types are supported.
| type | What it does | Required fields |
|---|---|---|
| audio_blast | Plays a pre-recorded audio clip from your library to the number, then ends. | audio_id |
| press1 | Places an Interactive Voice call: plays a clip, then acts on the key the recipient presses (connect them onward, capture their response, or record an opt-out). Calls placed inline this way respond to keypad presses only; spoken yes/no responses are available by triggering a saved campaign configured for them. | audio_id |
| otp | Places a verification call that reads out a code. | none beyond number |
| Field | Type | Required | Description |
|---|---|---|---|
| type | string | Required | One of audio_blast, press1, otp. |
| number | string | Required | The recipient's Indian mobile number. See Phone number format. |
| audio_id | number | Optional | For audio_blast and press1. The id of a clip in your audio library. Must belong to your account. |
| dtmf_map | object | Optional | press1 only. Maps a pressed digit to an action: connect (bridge the call onward), interest (record the response, then continue), or decline (record an opt-out). Defaults to { "1": "connect" }. |
| caller_id | string | Optional | The caller number to display. Must be one of the numbers on your account (or its number pool); anything else is rejected with HTTP 400 and "caller_id must be one of the numbers on your account." Defaults to your account default. |
| code | string | Optional | otp only. Supply your own numeric code. If omitted, a code is generated. |
| length | number | Optional | otp only. Length of the generated code, 4 to 8 digits. Default 4. |
| ttl | number | Optional | otp only. Seconds the code stays valid. Default 600 (10 minutes). |
| message | string | Optional | otp only. A custom spoken message. Use {code} where the code should be read out. |
| reference_id | string | Optional | Your own correlation key. Echoed back and in webhooks. |
{
"status": "success",
"code": 200,
"unique_id": "run_4821",
"reference_id": "order-99213",
"details": "Call queued."
}For the otp type the response is the same as Send a verification code.
Idempotency-Key header. Send one on every request so a network retry can never place a second billed call. See Idempotency.curl https://voice.agentive.co.in/api/public/v1/calls \
-H "x-api-key: pk_live_..." \
-H "x-api-secret: sk_live_..." \
-H "Content-Type: application/json" \
-d '{
"type": "audio_blast",
"number": "9812345678",
"audio_id": 12,
"reference_id": "order-99213"
}'{
"type": "press1",
"number": "9812345678",
"audio_id": 18,
"dtmf_map": { "1": "connect", "2": "decline" },
"reference_id": "promo-march"
}/campaigns/:id/triggerRun an existing API campaign for a single number. The trigger uses the campaign exactly as configured in your dashboard, including its audio clips, response mode (keypad, keypad plus spoken yes/no, or spoken only), guided flow steps, voicemail detection, ring timeout, custom response labels, key map and wait times, and caller number. Audio Blast, Interactive Voice, and AI agent campaigns can be triggered this way. For an AI agent campaign the trigger dials the number and the campaign's AI agent handles the conversation; the response is the usual run_... id. Verification-code campaigns use the OTP endpoints instead. Like all billed POST endpoints, the trigger accepts an Idempotency-Key header (see Idempotency).
| Parameter | Description |
|---|---|
| id | The numeric id of the campaign to trigger. |
| Field | Type | Required | Description |
|---|---|---|---|
| number | string | Required | The recipient's Indian mobile number. |
| reference_id | string | Optional | Your own correlation key. |
{
"status": "success",
"code": 200,
"unique_id": "run_4822",
"reference_id": "lead-5567",
"details": "Call queued."
}| Situation | HTTP | details |
|---|---|---|
| Campaign not found for your account | 404 | Campaign not found. |
| Campaign is a verification-code campaign | 400 | This is a verification-code campaign. Use the OTP endpoints to send a code. |
| Campaign type cannot be triggered for one number | 400 | This campaign type cannot be triggered for a single number. |
| Campaign has no audio configured | 400 | This campaign has no audio configured. |
curl https://voice.agentive.co.in/api/public/v1/campaigns/57/trigger \
-H "x-api-key: pk_live_..." \
-H "x-api-secret: sk_live_..." \
-H "Content-Type: application/json" \
-d '{ "number": "9812345678", "reference_id": "lead-5567" }'/otp/sendPlace a call that reads a numeric verification code out to the recipient. The code is read digit by digit and spoken twice, then the call ends. There is no agent and no human on the call.
| Field | Type | Required | Description |
|---|---|---|---|
| number | string | Required | The recipient's Indian mobile number. |
| code | string | Optional | Supply your own numeric code (4 to 8 digits). If omitted, one is generated. |
| length | number | Optional | Length of the generated code, 4 to 8. Default 4. |
| ttl | number | Optional | Seconds the code stays valid. Default 600 (10 minutes). |
| max_attempts | number | Optional | How many verify attempts are allowed. Default 3. |
| message | string | Optional | Custom spoken message. Use the token {code} where the digits should be read. If omitted, a default sentence is used. |
| reference_id | string | Optional | Your own correlation key. |
{
"status": "success",
"code": 200,
"unique_id": "5f3c8b2a-1d4e-4a9c-9e7b-2c6f0a1b3d8e",
"reference_id": "signup-7781",
"details": "Verification call queued.",
"request_id": "5f3c8b2a-1d4e-4a9c-9e7b-2c6f0a1b3d8e",
"expires_in_sec": 600
}| Extra field | Description |
|---|---|
| request_id | The verification request id. Use it (or the number) when calling verify. Same value as unique_id. |
| expires_in_sec | Seconds until the code expires. |
Defaults: code length 4, validity 10 minutes, 3 attempts.
Spoken message: by default the call says "Your verification code is 1 2 3 4. Again, 1 2 3 4." If you pass a message with a {code} token, your text is read with the spaced digits substituted in.
curl https://voice.agentive.co.in/api/public/v1/otp/send \
-H "x-api-key: pk_live_..." \
-H "x-api-secret: sk_live_..." \
-H "Content-Type: application/json" \
-d '{ "number": "9812345678", "length": 4, "ttl": 300, "reference_id": "signup-7781" }'/otp/verifyCheck a code the recipient gives you against a verification request. Identify the request by its request_id (returned from send) or by the recipient's number (the most recent pending request for that number is used).
Each verify attempt is counted whether right or wrong. Once the attempt cap is reached the request can no longer be verified, and you must send a fresh code.
| Field | Type | Required | Description |
|---|---|---|---|
| code | string | Required | The code the recipient entered. |
| request_id | string | Optional | One of request_id or number. The id returned by send. |
| number | string | Optional | One of request_id or number. The recipient's number, used to find the most recent pending request. |
| reference_id | string | Optional | Your own correlation key. |
{
"status": "success",
"code": 200,
"unique_id": "5f3c8b2a-1d4e-4a9c-9e7b-2c6f0a1b3d8e",
"reference_id": "signup-7781",
"details": "Code verified.",
"request_id": "5f3c8b2a-1d4e-4a9c-9e7b-2c6f0a1b3d8e",
"verified": true
}{
"status": "error",
"code": 401,
"details": "Incorrect code.",
"verified": false,
"attempts_left": 2
}| Situation | HTTP | details |
|---|---|---|
| Code is correct | 200 | Code verified. |
| Code is incorrect | 401 | Incorrect code. |
| Code has expired | 400 | This code has expired. |
| Too many incorrect attempts | 400 | Too many incorrect attempts. |
| Code already used | 400 | This code has already been used. |
| Request not found | 400 | Verification failed. |
| Missing code or identifier | 400 | A code and either request_id or number are required. |
The verified field is always present (true or false). On a wrong code, attempts_left tells you how many tries remain.
curl https://voice.agentive.co.in/api/public/v1/otp/verify \
-H "x-api-key: pk_live_..." \
-H "x-api-secret: sk_live_..." \
-H "Content-Type: application/json" \
-d '{ "request_id": "5f3c8b2a-1d4e-4a9c-9e7b-2c6f0a1b3d8e", "code": "1234" }'/calls/:unique_idCheck the current status of a call you placed, or a verification request.
| Parameter | Description |
|---|---|
| unique_id | The unique_id returned when you placed the call or sent the code. For calls this looks like run_4821; for verification it is the request id. Raw call ids also resolve here: the id returned by Place an AI agent call and the call_id values from List calls. |
{
"status": "success",
"code": 200,
"unique_id": "run_4821",
"reference_id": null,
"details": "answered",
"call_status": "answered",
"duration_sec": 17
}{
"status": "success",
"code": 200,
"unique_id": "5f3c8b2a-1d4e-4a9c-9e7b-2c6f0a1b3d8e",
"reference_id": "signup-7781",
"details": "verified",
"call_status": "verified",
"verified": true,
"attempts": 1,
"max_attempts": 3
}When the path is a raw call id (the id from Place an AI agent call, or a call_id from List calls), the response also carries a call object: the standard call object plus agent_id (AI agent calls only), transcript_available and analysis_available booleans, and call_status with the enumerated status values. A freshly placed AI agent call reports queued, then in_progress, then its final status.
{
"status": "success",
"code": 200,
"unique_id": "a1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d",
"reference_id": "lead-8804",
"details": "completed",
"call_status": "completed",
"call": {
"unique_id": "a1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d",
"call_id": "a1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d",
"direction": "outbound",
"from_number": "07965318581",
"to_number": "+919812345678",
"status": "completed",
"end_reason": "completed",
"duration_sec": 63,
"agent_id": 30214,
"transcript_available": true,
"analysis_available": true,
"reference_id": "lead-8804",
"created_at": "2026-08-10T14:31:02+05:30"
}
}| Value | Meaning |
|---|---|
| queued | Accepted and waiting to be placed. |
| ringing | The recipient's phone is ringing. |
| answered | The recipient answered and the call is in progress. |
| completed | The call finished after being answered. |
| failed | The call ended without connecting. |
| Value | Meaning |
|---|---|
| pending | Code sent, not yet verified or expired. |
| verified | The correct code was confirmed. |
| expired | The validity window passed. |
| failed | The attempt cap was reached, or the call could not be placed. |
A unique_id that does not belong to your account returns HTTP 404 with "Call not found." or "Not found.".
curl https://voice.agentive.co.in/api/public/v1/calls/run_4821 \
-H "x-api-key: pk_live_..." \
-H "x-api-secret: sk_live_..."/callsPage through the calls on your account, most recent first. This returns the full call object for each call, with the enumerated status and end_reason values, so you can reconcile call results in bulk instead of polling each call by id.
| Parameter | Type | Default | Description |
|---|---|---|---|
| page | number | 1 | The page of results to return. |
| per_page | number | 50 | Results per page. Maximum 100. |
| direction | string | none | Filter by inbound or outbound. |
| status | string | none | Filter by a call status: queued, ringing, in_progress, completed, failed, or missed. |
| from | string | none | Include calls created on or after this ISO 8601 date or timestamp. |
| to | string | none | Include calls created before this ISO 8601 date or timestamp. |
| number | string | none | Match calls where this number appears as either the caller or the recipient. |
{
"status": "success",
"code": 200,
"data": [
{
"unique_id": "run_4821",
"call_id": "a1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d",
"direction": "outbound",
"from_number": "07965318581",
"to_number": "+919812345678",
"status": "completed",
"end_reason": "completed",
"duration_sec": 42,
"campaign_id": 4821,
"reference_id": "order-99213",
"created_at": "2026-06-04T21:42:08+05:30"
}
],
"pagination": {
"page": 1,
"per_page": 50,
"total": 137,
"total_pages": 3
}
}| Field | Type | Description |
|---|---|---|
| data | array | A page of call objects. |
| pagination.page | number | The current page. |
| pagination.per_page | number | Results per page for this response. |
| pagination.total | number | Total calls matching your filters. |
| pagination.total_pages | number | Total number of pages. |
The response carries only the public call object fields. end_reason is always one of the enumerated end reasons.
curl "https://voice.agentive.co.in/api/public/v1/calls?per_page=50&direction=outbound&status=completed" \
-H "x-api-key: pk_live_..." \
-H "x-api-secret: sk_live_..."/calls/:unique_id/recordingDownload the audio recording of a call. For most recordings the endpoint responds with an HTTP 302 redirect to a short-lived signed download URL, so your client must follow redirects (curl needs -L, PHP cURL needs CURLOPT_FOLLOWLOCATION; the Node.js fetch API follows automatically). Fetch the audio promptly after receiving the redirect; the signed URL expires after a few minutes, and you can always request a fresh one. Requires call recording to be enabled on your account.
| Parameter | Description |
|---|---|
| unique_id | The call's unique_id (for example run_4821) or its call_id. Must belong to your account. |
On success the endpoint returns HTTP 302 with a Location header pointing at the audio file; following it downloads the raw audio. The Content-Type of the download is audio/ogg or audio/wav depending on how the recording was stored. A small number of recordings are served directly (HTTP 200 with the audio body, with HTTP Range support); a client that follows redirects handles both transparently.
If there is no recording for the call (it never connected, or the audio is not available), the response is HTTP 404 with the standard error envelope:
{
"status": "error",
"code": 404,
"details": "No recording is available for this call."
}# -L follows the redirect to the short-lived download URL.
curl -L "https://voice.agentive.co.in/api/public/v1/calls/run_4821/recording" \
-H "x-api-key: pk_live_..." \
-H "x-api-secret: sk_live_..." \
--output call-4821.ogg/campaignsList the campaigns on your account that can be triggered through the API. Use a campaign id from this list with Trigger a saved campaign.
{
"status": "success",
"code": 200,
"data": [
{ "id": 57, "name": "March promo", "type": "audio_blast", "status": "active" },
{ "id": 61, "name": "Renewal interactive voice", "type": "press1", "status": "active" },
{ "id": 72, "name": "Signup verification", "type": "otp", "status": "active" },
{ "id": 84, "name": "Follow-up calls", "type": "ai_agent", "status": "active" }
]
}| Field | Type | Description |
|---|---|---|
| id | number | The campaign id. Use it with Trigger a saved campaign. |
| name | string | The name you gave the campaign. |
| type | string | audio_blast (Audio Blast), press1 (Interactive Voice), otp (verification), or ai_agent (AI agent campaign). Verification (otp) campaigns are configured here but delivered with the OTP endpoints. |
| status | string | The campaign's current state. |
curl https://voice.agentive.co.in/api/public/v1/campaigns \
-H "x-api-key: pk_live_..." \
-H "x-api-secret: sk_live_..."/accountReturn your account's current wallet balance in INR. Requires the wallet feature on your account.
{
"status": "success",
"code": 200,
"data": {
"balance_inr": 1842.5,
"currency": "INR"
}
}| Field | Type | Description |
|---|---|---|
| balance_inr | number | Your current wallet balance, in Indian Rupees. |
| currency | string | Always "INR". |
curl https://voice.agentive.co.in/api/public/v1/account \
-H "x-api-key: pk_live_..." \
-H "x-api-secret: sk_live_..."/ai/callsPlace a single outbound call that one of your AI voice agents handles end to end: it speaks, listens, and follows the script and behaviour you configured for the agent in your dashboard. After the call you can read the transcript and analysis. Requires the AI voice agent feature on your account.
| Field | Type | Required | Description |
|---|---|---|---|
| agent_id | number | Required | The id of the AI agent that should make the call. Find it with List AI agents. |
| to_number | string | Required | The recipient's Indian mobile number. Same accepted forms as everywhere else; see Phone number format. |
| from_number | string | Optional | The caller number to dial from. Must be a number on your account. If omitted, the platform picks one for you. |
| variables | object | Optional | A flat object of up to 20 key-to-value strings injected into the agent's script for this call (for example a customer name or an order id). Keys are lowercase a-z, 0-9, and _, at most 40 characters; values are strings of at most 200 characters. |
| reference_id | string | Optional | Your own correlation key. Echoed back and in webhooks. |
The standard envelope with unique_id set to the call id, plus extra fields describing the queued call:
{
"status": "success",
"code": 200,
"unique_id": "a1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d",
"reference_id": "lead-8804",
"details": "Call queued.",
"call_id": "a1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d",
"agent_id": 30214,
"to_number": "+919812345678",
"from_number": "07965318581",
"call_status": "queued"
}Poll Get call status with the returned call id (the status moves queued, then in_progress, then a final status), or subscribe to the webhooks to be told when the call finishes.
| Situation | HTTP | Meaning |
|---|---|---|
| Unknown agent, invalid number, or from_number not on your account | 400 | Fix the field named in details and resend. |
| Balance too low | 402 | AI agent calls need a balance of at least ₹5. Top up and retry. |
| Feature not enabled, or a trial account calling an unverified number | 403 | Enable the AI voice agent feature, or (on trial) call a verified number. |
| All AI call channels are in use | 409 | Retry once a running AI call finishes. |
| Too many calls to this number | 429 | The per-number cap (3 calls per 10 minutes) was hit. Wait, then retry. |
| The call could not be placed right now | 502 | Temporary problem. Safe to retry with the same Idempotency-Key. |
Idempotency-Key header. Send one on every request so a network retry can never place a second billed call. See Idempotency.curl https://voice.agentive.co.in/api/public/v1/ai/calls \
-H "x-api-key: pk_live_..." \
-H "x-api-secret: sk_live_..." \
-H "Content-Type: application/json" \
-H "Idempotency-Key: lead-8804-call-1" \
-d '{
"agent_id": 30214,
"to_number": "9812345678",
"variables": { "customer_name": "Asha", "order_id": "ORD-1142" },
"reference_id": "lead-8804"
}'/calls/:id/transcriptRead the turn-by-turn transcript of a finished AI agent call. The transcript becomes available shortly after the call ends; until then the endpoint returns HTTP 404. Requires the AI voice agent feature on your account.
{
"status": "success",
"code": 200,
"data": {
"call_id": "a1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d",
"turns": [
{ "role": "agent", "text": "Namaste, main Sharma Clinic ki taraf se bol rahi hoon. Kya main aapki kal ki appointment confirm kar sakti hoon?" },
{ "role": "caller", "text": "Haan, kal shaam 5 baje theek hai." },
{ "role": "agent", "text": "Perfect, kal shaam 5 baje confirm ho gayi. Dhanyavaad!" }
],
"created_at": "2026-08-10T14:32:08+05:30"
}
}| Field | Description |
|---|---|
| data.call_id | The call this transcript belongs to. |
| data.turns | The conversation in order. Each turn has a role ("caller" or "agent") and the text spoken. |
| data.created_at | When the transcript was produced, in IST. |
To know when a transcript is ready without polling, check the transcript_available boolean on Get call status.
curl https://voice.agentive.co.in/api/public/v1/calls/a1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d/transcript \
-H "x-api-key: pk_live_..." \
-H "x-api-secret: sk_live_..."/calls/:id/analysisRead the post-call analysis of an AI agent call: a summary, sentiment, the caller's intent, the outcome, and any answers the agent was configured to capture. The analysis is generated shortly after the call ends; until then the endpoint returns HTTP 404. Requires the AI voice agent feature on your account.
{
"status": "success",
"code": 200,
"data": {
"call_id": "a1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d",
"summary": "The caller confirmed their appointment for tomorrow at 5 pm.",
"sentiment": "positive",
"sentiment_score": 0.82,
"intent": "appointment_confirmation",
"outcome": "confirmed",
"extractions": {
"preferred_time": "5 pm tomorrow",
"callback_needed": "no"
},
"tags": ["appointment", "confirmed"],
"created_at": "2026-08-10T14:33:41+05:30"
}
}| Field | Description |
|---|---|
| data.summary | A short plain-language summary of the conversation. |
| data.sentiment | The caller's overall sentiment, with data.sentiment_score as a number from -1 to 1. |
| data.intent | What the caller wanted. |
| data.outcome | How the conversation ended, in the agent's own terms. |
| data.extractions | The answers to the data-capture questions configured on the agent, as a flat object keyed by question. |
| data.tags | Labels attached to the call by the analysis. |
| data.created_at | When the analysis was produced, in IST. |
The analysis_available boolean on Get call status tells you when it is ready.
curl https://voice.agentive.co.in/api/public/v1/calls/a1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d/analysis \
-H "x-api-key: pk_live_..." \
-H "x-api-secret: sk_live_..."/agentsList the AI voice agents on your account, read-only. Use an agent's id with Place an AI agent call or when binding a number. GET /agents/:id returns a single agent in the same shape. Agents are created and edited in the dashboard, not through the API.
{
"status": "success",
"code": 200,
"data": [
{ "id": 30214, "name": "Reception agent", "status": "active", "direction": "both", "languages": ["hinglish", "english"] },
{ "id": 41728, "name": "Renewal outreach", "status": "active", "direction": "outbound", "languages": ["hindi"] }
]
}| Field | Description |
|---|---|
| id | The agent id. |
| name | The name you gave the agent. |
| status | The agent's current state. Only active agents can take or make calls. |
| direction | inbound, outbound, or both: which way this agent is allowed to talk. |
| languages | The languages the agent speaks. |
curl https://voice.agentive.co.in/api/public/v1/agents \
-H "x-api-key: pk_live_..." \
-H "x-api-secret: sk_live_..."/numbersList the numbers on your account, with the AI agent (if any) currently answering inbound calls to each. bindable tells you whether the number can be pointed at an agent through the API.
{
"status": "success",
"code": 200,
"data": [
{ "number": "07965318581", "inbound_agent_id": 30214, "bindable": true },
{ "number": "07965318582", "inbound_agent_id": null, "bindable": false }
]
}curl https://voice.agentive.co.in/api/public/v1/numbers \
-H "x-api-key: pk_live_..." \
-H "x-api-secret: sk_live_..."/numbers/:numberBind or clear which AI agent answers inbound calls to a number. Send { "inbound_agent_id": <id> } to bind, or { "inbound_agent_id": null } to clear the binding. The agent must be active and inbound-capable (direction of inbound or both).
curl -X PATCH https://voice.agentive.co.in/api/public/v1/numbers/07965318581 \
-H "x-api-key: pk_live_..." \
-H "x-api-secret: sk_live_..." \
-H "Content-Type: application/json" \
-d '{ "inbound_agent_id": 30214 }'| Situation | HTTP | Meaning |
|---|---|---|
| The number is attached to a call flow, assigned to a team member, shared, or not AI-enabled | 400 | The number cannot be bound to an agent right now; details says why. |
| The agent is inactive or cannot take inbound calls | 400 | Pick an active, inbound-capable agent. |
| The number or agent is not on your account | 404 | Not found. |
List calls returns a data array of call objects. The same shape appears in the call.* webhook events.
| Field | Type | Description |
|---|---|---|
| unique_id | string | The call's public id. For calls placed through an API run this looks like run_4821; otherwise it is the call id. |
| call_id | string | null | Our internal identifier for the call. |
| direction | string | outbound or inbound. |
| from_number | string | null | The caller number shown. |
| to_number | string | null | The recipient number. |
| status | string | null | The call state. One of the enumerated status values. |
| end_reason | string | null | Why the call ended. One of the enumerated end reasons, or null while the call is still in progress. |
| duration_sec | number | null | Talk duration in seconds. |
| campaign_id | number | null | The run this call belongs to, matching the digits in unique_id. |
| agent_id | number | null | The AI agent that handled the call. Present on AI agent calls; null otherwise. |
| reference_id | string | null | The reference_id you supplied. |
| created_at | string | null | When the call was created, in IST. |
When you fetch a single call by its raw call id with Get call status, the returned call object additionally carries transcript_available and analysis_available booleans, so you know when to fetch the transcript and analysis.
status and end_reason are closed sets. New values are not added without notice, so you can write exhaustive handling.
| Value | Meaning |
|---|---|
| queued | Accepted and waiting to be placed. |
| ringing | The recipient's phone is ringing. |
| in_progress | The recipient answered and the call is connected. |
| completed | The call finished after being answered. |
| missed | The call rang but was never answered. |
| failed | The call ended without connecting. |
| Value | Meaning |
|---|---|
| completed | The call connected and the conversation happened. On AI agent calls this covers every normal close: either side hung up, the agent finished its script, the call reached its duration or cost limit, or a transfer wrapped up. |
| voicemail | A voicemail system answered the call. It was detected and the call was closed. |
| no_answer | The call rang but the recipient never picked up. Safe to retry later. |
| busy | The recipient was on another call. The number is reachable, so a retry can succeed. |
| rejected | The recipient actively declined the call. |
| canceled | The call was cancelled before it connected. |
| failed | The call could not be placed, for example an invalid number or a carrier problem. |
Read end_reason as: completed means the conversation happened, voicemail means a voicemail system answered, and everything else (no_answer, busy, rejected, canceled, failed) means the call did not connect.
queued, ringing, answered, completed, failed for calls). The enumerated status and end_reason above apply to the call object returned by List calls and sent in webhooks.Send Indian mobile numbers in any of these forms; they are all normalised:
9812345678919812345678+919812345678reference_id is an optional string you attach to any request, such as an order number, ticket id, or signup id. It is:
reference_id field, andUse it to match our events back to your own records without storing our ids. Reference IDs are capped at 120 characters; control characters are stripped.
Calls that reach a customer with a message or an agent are placed between 9:00 AM and 9:00 PM IST, every day. This applies to Audio Blast, Interactive Voice and AI agent calls, whether you place them with POST /calls, POST /ai/calls or by triggering a saved campaign. A request that arrives outside those hours is refused with HTTP 409 and a message naming the hours, so your system can queue it and retry in the morning rather than believing the call was placed.
POST /otp/send works around the clock, because a login or payment code has to reach someone whenever they are signing in.If your account has been approved for extended hours, your calls are not restricted and you will not see the 409.
Every billed POST endpoint (POST /calls, POST /campaigns/:id/trigger, POST /otp/send, and POST /ai/calls) accepts an Idempotency-Key header. Send a unique key with each logical request, and a network retry can never place a second billed call: if a request times out or the connection drops, simply resend the same request with the same key.
curl https://voice.agentive.co.in/api/public/v1/calls \
-H "x-api-key: pk_live_..." \
-H "x-api-secret: sk_live_..." \
-H "Content-Type: application/json" \
-H "Idempotency-Key: order-99213-call-1" \
-d '{ "type": "audio_blast", "number": "9812345678", "audio_id": 12, "reference_id": "order-99213" }'How it behaves:
idempotency-replayed: true.reference_id remains a correlation echo only; it never deduplicates anything. Use the Idempotency-Key header for retry safety and reference_id to match calls back to your records.id (evt_...) you can use to ignore repeats. See Ordering and idempotency in the webhook reference.curl https://voice.agentive.co.in/api/public/v1/calls \
-H "x-api-key: pk_live_..." \
-H "x-api-secret: sk_live_..." \
-H "Content-Type: application/json" \
-d '{ "type": "audio_blast", "number": "98XXXXXXXX", "audio_id": 12, "reference_id": "test-1" }'unique_id and poll status:curl https://voice.agentive.co.in/api/public/v1/calls/run_XXXX \
-H "x-api-key: pk_live_..." \
-H "x-api-secret: sk_live_..."