Agentive
Agentive
  • Cloud TelephonyIndian numbers, IVR and dialers. No hardware.
  • IVR SystemVisual call-flow builder and smart routing.
  • Call Center SoftwareMulti-agent panel, dialer and live monitoring.
  • Call MaskingConnect customers and agents, numbers stay private.
  • Voice BroadcastingSend a voice message to your whole list.
  • Bulk SMSTransactional and promotional SMS at scale.
  • WhatsApp Marketing SuiteBroadcasts and automation on the WhatsApp Business platform.
  • AI Voice AgentHindi + English AI that answers your phones, 24/7.
  • AI Chat AgentAI chat on your website + WhatsApp, 24/7.
AboutContact
80056 80053

Which dashboard?

  • AI Chat AgentWebsite + WhatsApp dashboard
  • AI Voice & TelephonyVoice agent + cloud telephony dashboard
Book a demo
Agentive
Agentive

One platform for every Indian business. Cloud telephony, a built-in CRM, an AI voice agent, an AI chat agent, SMS and the WhatsApp Business API, all in one place. Answer every call and message, and keep every lead in one place.

Follow Us

Product

  • Cloud Telephony
  • IVR System
  • Call Center Software
  • Call Masking
  • Voice Broadcasting
  • Bulk SMS
  • AI Voice Agent
  • AI Chat Agent
  • WhatsApp Marketing Suite

Company

  • About Us
  • Contact Us
  • Disclaimer

Legal

  • Privacy Policy
  • Data Deletion
  • Terms of Service
  • Refund Policy
  • Shipping Policy
Meta Business PartnerAvailable on Google PlayAvailable on the App Store

© 2026 Agentive. Owned and operated by Mannan Technologies Private Limited.

HomeDevelopersAPI Reference
API ReferenceWebhooks

On this page

Introduction
Base URL
Authentication
Response format
Error codes
Rate limits
Endpoints
Place a callTrigger a campaignSend a code (OTP)Verify a codeGet call statusList callsDownload a recordingList campaignsGet account balancePlace an AI agent callGet a call transcriptGet call analysisList AI agentsNumbers and inbound binding
The call object
Status and end reasons
Phone number format
Reference IDs
Calling hours
Idempotency
Quick start

API Reference

Voice 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.

Base URL
https://voice.agentive.co.in/api/public/v1
Format
JSON over HTTPS
Currency / time
INR / IST

Introduction

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.

One reference, several products
This page covers placing calls (including AI voice agent calls) and checking status. To receive call and verification events in real time instead of polling, see the Webhooks reference.
API access is enabled per account
API access is enabled per account. If you get a 403 saying the API is not enabled, contact support. Each endpoint also requires its product to be enabled on your account: the voice broadcast endpoints need the broadcast features, the AI endpoints need the AI voice agent feature, recording download needs call recording, and account balance needs the wallet feature. A request against a product that is not enabled returns HTTP 403 with "This feature is not enabled for your account."

Base URL

Every endpoint path below is relative to this base URL.

Base URL
https://voice.agentive.co.in/api/public/v1

Authentication

Every request must be authenticated with two credentials issued to your account.

CredentialWhat it isHow to send it
Publishable keyYour account's public lookup handle. Starts with pk_live_.x-api-key request header
Secret keyYour 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.

HTTP Basic authentication

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
curl https://voice.agentive.co.in/api/public/v1/account \
  -u pk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx:sk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Keep the secret server-side
Never embed the secret key in a browser, mobile app, or any client a customer can inspect. All requests must be over HTTPS. If a key is exposed, rotate it from the dashboard at once.

Example: authenticated request

cURL
curl 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 }'

Authentication failures

SituationHTTPdetails message
No publishable key sent401Missing API key. Send your publishable key in the x-api-key header.
Unknown publishable key401Invalid API credentials.
Known key, wrong or missing secret403Invalid API credentials.
Account is not active403This account is not active. Please contact support.
API access not enabled for the account403The API is not enabled for this account. Please contact support.
The endpoint's product is not enabled for the account403This 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.

Response format

Every response is JSON and uses one consistent envelope.

JSON
{
  "status": "success",
  "code": 200,
  "unique_id": "run_4821",
  "reference_id": "order-99213",
  "details": "Call queued."
}
FieldTypeDescription
statusstring"success" or "error".
codenumberA numeric result code. Mirrors the HTTP status (see Error codes).
unique_idstring | nullOur identifier for the resource created by this call. Use it with Get call status. For OTP requests this is the verification request id.
reference_idstring | nullEchoes the reference_id you sent, so you can correlate the response with your own records. null if you did not send one.
detailsstringA 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).

HTTP status
A successful request returns HTTP 200 with 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.

Error codes

HTTPcodeMeaningWhen it happens
200200SuccessThe request was accepted.
400400Bad requestA required field is missing or invalid (a malformed number, an unknown type, a missing audio_id, or a missing code on verify).
401401UnauthorizedThe publishable key is missing or unknown, or (on verify) the submitted code is incorrect.
402402Balance too lowYour account balance is too low to place the call. Top up and retry.
403403ForbiddenThe secret is wrong, the account is not active, API access is not enabled, or the endpoint's product is not enabled for your account.
404404Not foundThe 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.
409409ConflictA 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.
422422Idempotency key reuseThe same Idempotency-Key was sent with a different request body. Use a fresh key for a new request.
429429Too many requestsYou exceeded the rate limit, or placed too many calls to one number in a short window. Wait, then retry.
5xx5xxTemporary problemThe 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."

Example error response

JSON
{
  "status": "error",
  "code": 400,
  "unique_id": null,
  "reference_id": "order-99213",
  "details": "A valid Indian mobile number is required."
}

Rate limits

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:

JSON
{
  "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.

Per-number call cap
All calls placed through the API to the same destination number (broadcast, Interactive Voice, verification, and AI agent calls alike) are capped at 3 calls per 10 minutes per account. Exceeding the cap returns HTTP 429 with a message asking you to wait and retry. A 429 always means wait; only 5xx responses are safe to retry immediately.

Endpoints

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.

Place a call

POST/calls

Place a single outbound call immediately. Three call types are supported.

typeWhat it doesRequired fields
audio_blastPlays a pre-recorded audio clip from your library to the number, then ends.audio_id
press1Places 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
otpPlaces a verification call that reads out a code.none beyond number

Request fields

FieldTypeRequiredDescription
typestringRequiredOne of audio_blast, press1, otp.
numberstringRequiredThe recipient's Indian mobile number. See Phone number format.
audio_idnumberOptionalFor audio_blast and press1. The id of a clip in your audio library. Must belong to your account.
dtmf_mapobjectOptionalpress1 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_idstringOptionalThe 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.
codestringOptionalotp only. Supply your own numeric code. If omitted, a code is generated.
lengthnumberOptionalotp only. Length of the generated code, 4 to 8 digits. Default 4.
ttlnumberOptionalotp only. Seconds the code stays valid. Default 600 (10 minutes).
messagestringOptionalotp only. A custom spoken message. Use {code} where the code should be read out.
reference_idstringOptionalYour own correlation key. Echoed back and in webhooks.

Response (audio_blast / press1)

JSON
{
  "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.

Retries are safe with an Idempotency-Key
This endpoint accepts an Idempotency-Key header. Send one on every request so a network retry can never place a second billed call. See Idempotency.

Examples

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

Interactive Voice (press1) example body

JSON
{
  "type": "press1",
  "number": "9812345678",
  "audio_id": 18,
  "dtmf_map": { "1": "connect", "2": "decline" },
  "reference_id": "promo-march"
}

Trigger a saved campaign

POST/campaigns/:id/trigger

Run 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).

Path parameter

ParameterDescription
idThe numeric id of the campaign to trigger.

Request fields

FieldTypeRequiredDescription
numberstringRequiredThe recipient's Indian mobile number.
reference_idstringOptionalYour own correlation key.

Response

JSON
{
  "status": "success",
  "code": 200,
  "unique_id": "run_4822",
  "reference_id": "lead-5567",
  "details": "Call queued."
}

Error cases

SituationHTTPdetails
Campaign not found for your account404Campaign not found.
Campaign is a verification-code campaign400This is a verification-code campaign. Use the OTP endpoints to send a code.
Campaign type cannot be triggered for one number400This campaign type cannot be triggered for a single number.
Campaign has no audio configured400This campaign has no audio configured.

Examples

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

Send a verification code (voice OTP)

POST/otp/send

Place 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.

The code is never returned
The code is generated for you (or you may supply your own). It is stored hashed; the plain code is never returned in any response and never written to any log. To check what the recipient entered, use Verify a code.

Request fields

FieldTypeRequiredDescription
numberstringRequiredThe recipient's Indian mobile number.
codestringOptionalSupply your own numeric code (4 to 8 digits). If omitted, one is generated.
lengthnumberOptionalLength of the generated code, 4 to 8. Default 4.
ttlnumberOptionalSeconds the code stays valid. Default 600 (10 minutes).
max_attemptsnumberOptionalHow many verify attempts are allowed. Default 3.
messagestringOptionalCustom spoken message. Use the token {code} where the digits should be read. If omitted, a default sentence is used.
reference_idstringOptionalYour own correlation key.

Response

JSON
{
  "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 fieldDescription
request_idThe verification request id. Use it (or the number) when calling verify. Same value as unique_id.
expires_in_secSeconds 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.

Examples

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

Verify a code

POST/otp/verify

Check 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.

Request fields

FieldTypeRequiredDescription
codestringRequiredThe code the recipient entered.
request_idstringOptionalOne of request_id or number. The id returned by send.
numberstringOptionalOne of request_id or number. The recipient's number, used to find the most recent pending request.
reference_idstringOptionalYour own correlation key.

Response (correct code)

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

Response (incorrect code)

JSON
{
  "status": "error",
  "code": 401,
  "details": "Incorrect code.",
  "verified": false,
  "attempts_left": 2
}
SituationHTTPdetails
Code is correct200Code verified.
Code is incorrect401Incorrect code.
Code has expired400This code has expired.
Too many incorrect attempts400Too many incorrect attempts.
Code already used400This code has already been used.
Request not found400Verification failed.
Missing code or identifier400A 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.

Examples

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

Get call status

GET/calls/:unique_id

Check the current status of a call you placed, or a verification request.

Path parameter

ParameterDescription
unique_idThe 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.

Response (a placed call)

JSON
{
  "status": "success",
  "code": 200,
  "unique_id": "run_4821",
  "reference_id": null,
  "details": "answered",
  "call_status": "answered",
  "duration_sec": 17
}

Response (a verification request)

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

Response (a raw call id)

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.

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

Call status values

ValueMeaning
queuedAccepted and waiting to be placed.
ringingThe recipient's phone is ringing.
answeredThe recipient answered and the call is in progress.
completedThe call finished after being answered.
failedThe call ended without connecting.

Verification status values

ValueMeaning
pendingCode sent, not yet verified or expired.
verifiedThe correct code was confirmed.
expiredThe validity window passed.
failedThe 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.".

Listing calls in bulk
This endpoint reports a single call or verification request you started. To page through your call history (including inbound calls), use List calls, which returns the richer call object with the enumerated status and end_reason values.

Examples

curl https://voice.agentive.co.in/api/public/v1/calls/run_4821 \
  -H "x-api-key: pk_live_..." \
  -H "x-api-secret: sk_live_..."

List calls

GET/calls

Page 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.

Query parameters

ParameterTypeDefaultDescription
pagenumber1The page of results to return.
per_pagenumber50Results per page. Maximum 100.
directionstringnoneFilter by inbound or outbound.
statusstringnoneFilter by a call status: queued, ringing, in_progress, completed, failed, or missed.
fromstringnoneInclude calls created on or after this ISO 8601 date or timestamp.
tostringnoneInclude calls created before this ISO 8601 date or timestamp.
numberstringnoneMatch calls where this number appears as either the caller or the recipient.

Response

JSON
{
  "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
  }
}
FieldTypeDescription
dataarrayA page of call objects.
pagination.pagenumberThe current page.
pagination.per_pagenumberResults per page for this response.
pagination.totalnumberTotal calls matching your filters.
pagination.total_pagesnumberTotal number of pages.

The response carries only the public call object fields. end_reason is always one of the enumerated end reasons.

Examples

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_..."

Download a call recording

GET/calls/:unique_id/recording

Download 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.

Path parameter

ParameterDescription
unique_idThe call's unique_id (for example run_4821) or its call_id. Must belong to your account.

Response

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:

JSON
{
  "status": "error",
  "code": 404,
  "details": "No recording is available for this call."
}
Get notified when it is ready
A recording is typically ready a short time after the call ends. To be notified the moment it is ready, subscribe to the recording.available webhook, which carries the same download URL.

Examples

# -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

List campaigns

GET/campaigns

List the campaigns on your account that can be triggered through the API. Use a campaign id from this list with Trigger a saved campaign.

Response

JSON
{
  "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" }
  ]
}
FieldTypeDescription
idnumberThe campaign id. Use it with Trigger a saved campaign.
namestringThe name you gave the campaign.
typestringaudio_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.
statusstringThe campaign's current state.

Examples

curl https://voice.agentive.co.in/api/public/v1/campaigns \
  -H "x-api-key: pk_live_..." \
  -H "x-api-secret: sk_live_..."

Get account balance

GET/account

Return your account's current wallet balance in INR. Requires the wallet feature on your account.

Response

JSON
{
  "status": "success",
  "code": 200,
  "data": {
    "balance_inr": 1842.5,
    "currency": "INR"
  }
}
FieldTypeDescription
balance_inrnumberYour current wallet balance, in Indian Rupees.
currencystringAlways "INR".

Examples

curl https://voice.agentive.co.in/api/public/v1/account \
  -H "x-api-key: pk_live_..." \
  -H "x-api-secret: sk_live_..."

Place an AI agent call

POST/ai/calls

Place 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.

Request fields

FieldTypeRequiredDescription
agent_idnumberRequiredThe id of the AI agent that should make the call. Find it with List AI agents.
to_numberstringRequiredThe recipient's Indian mobile number. Same accepted forms as everywhere else; see Phone number format.
from_numberstringOptionalThe caller number to dial from. Must be a number on your account. If omitted, the platform picks one for you.
variablesobjectOptionalA 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_idstringOptionalYour own correlation key. Echoed back and in webhooks.

Response

The standard envelope with unique_id set to the call id, plus extra fields describing the queued call:

JSON
{
  "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.

Error cases

SituationHTTPMeaning
Unknown agent, invalid number, or from_number not on your account400Fix the field named in details and resend.
Balance too low402AI agent calls need a balance of at least ₹5. Top up and retry.
Feature not enabled, or a trial account calling an unverified number403Enable the AI voice agent feature, or (on trial) call a verified number.
All AI call channels are in use409Retry once a running AI call finishes.
Too many calls to this number429The per-number cap (3 calls per 10 minutes) was hit. Wait, then retry.
The call could not be placed right now502Temporary problem. Safe to retry with the same Idempotency-Key.
Retries are safe with an Idempotency-Key
This endpoint accepts an Idempotency-Key header. Send one on every request so a network retry can never place a second billed call. See Idempotency.

Examples

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

Get a call transcript

GET/calls/:id/transcript

Read 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.

Response

JSON
{
  "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"
  }
}
FieldDescription
data.call_idThe call this transcript belongs to.
data.turnsThe conversation in order. Each turn has a role ("caller" or "agent") and the text spoken.
data.created_atWhen 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
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_..."

Get call analysis

GET/calls/:id/analysis

Read 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.

Response

JSON
{
  "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"
  }
}
FieldDescription
data.summaryA short plain-language summary of the conversation.
data.sentimentThe caller's overall sentiment, with data.sentiment_score as a number from -1 to 1.
data.intentWhat the caller wanted.
data.outcomeHow the conversation ended, in the agent's own terms.
data.extractionsThe answers to the data-capture questions configured on the agent, as a flat object keyed by question.
data.tagsLabels attached to the call by the analysis.
data.created_atWhen the analysis was produced, in IST.

The analysis_available boolean on Get call status tells you when it is ready.

cURL
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_..."

List AI agents

GET/agents

List 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.

Response

JSON
{
  "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"] }
  ]
}
FieldDescription
idThe agent id.
nameThe name you gave the agent.
statusThe agent's current state. Only active agents can take or make calls.
directioninbound, outbound, or both: which way this agent is allowed to talk.
languagesThe languages the agent speaks.
cURL
curl https://voice.agentive.co.in/api/public/v1/agents \
  -H "x-api-key: pk_live_..." \
  -H "x-api-secret: sk_live_..."

Numbers and inbound binding

GET/numbers

List 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.

JSON
{
  "status": "success",
  "code": 200,
  "data": [
    { "number": "07965318581", "inbound_agent_id": 30214, "bindable": true },
    { "number": "07965318582", "inbound_agent_id": null, "bindable": false }
  ]
}
cURL
curl https://voice.agentive.co.in/api/public/v1/numbers \
  -H "x-api-key: pk_live_..." \
  -H "x-api-secret: sk_live_..."
PATCH/numbers/:number

Bind 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
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 }'

Error cases

SituationHTTPMeaning
The number is attached to a call flow, assigned to a team member, shared, or not AI-enabled400The number cannot be bound to an agent right now; details says why.
The agent is inactive or cannot take inbound calls400Pick an active, inbound-capable agent.
The number or agent is not on your account404Not found.

The call object

List calls returns a data array of call objects. The same shape appears in the call.* webhook events.

FieldTypeDescription
unique_idstringThe call's public id. For calls placed through an API run this looks like run_4821; otherwise it is the call id.
call_idstring | nullOur internal identifier for the call.
directionstringoutbound or inbound.
from_numberstring | nullThe caller number shown.
to_numberstring | nullThe recipient number.
statusstring | nullThe call state. One of the enumerated status values.
end_reasonstring | nullWhy the call ended. One of the enumerated end reasons, or null while the call is still in progress.
duration_secnumber | nullTalk duration in seconds.
campaign_idnumber | nullThe run this call belongs to, matching the digits in unique_id.
agent_idnumber | nullThe AI agent that handled the call. Present on AI agent calls; null otherwise.
reference_idstring | nullThe reference_id you supplied.
created_atstring | nullWhen 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.

Call status and end reasons

status and end_reason are closed sets. New values are not added without notice, so you can write exhaustive handling.

status (current call state)

ValueMeaning
queuedAccepted and waiting to be placed.
ringingThe recipient's phone is ringing.
in_progressThe recipient answered and the call is connected.
completedThe call finished after being answered.
missedThe call rang but was never answered.
failedThe call ended without connecting.

end_reason (set on a final state)

ValueMeaning
completedThe 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.
voicemailA voicemail system answered the call. It was detected and the call was closed.
no_answerThe call rang but the recipient never picked up. Safe to retry later.
busyThe recipient was on another call. The number is reachable, so a retry can succeed.
rejectedThe recipient actively declined the call.
canceledThe call was cancelled before it connected.
failedThe 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.

Get call status reports a simpler set
Get call status reports a simpler set for a single call or verification request (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.

Phone number format

Send Indian mobile numbers in any of these forms; they are all normalised:

  • 10-digit local: 9812345678
  • With country code: 919812345678
  • With plus prefix: +919812345678
Mobile numbers only
The mobile number must begin with 6, 7, 8, or 9. Landline and clearly invalid numbers are rejected with HTTP 400 and "A valid Indian mobile number is required."

Reference IDs

reference_id is an optional string you attach to any request, such as an order number, ticket id, or signup id. It is:

  • echoed back in the response reference_id field, and
  • included in every webhook for the call or verification.

Use 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.

Calling hours

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.

Verification codes are the exception
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.

Idempotency

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
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:

  • The key is a string of 1 to 128 printable characters. Use something unique per action, such as a UUID or your own order id plus an attempt marker.
  • For 24 hours, sending the same key on the same account replays the original response instead of placing a second call. Replayed responses carry the header idempotency-replayed: true.
  • The same key with a different request body returns HTTP 422. A new request needs a new key.
  • The same key while the first request is still processing returns HTTP 409. Wait a moment and retry.
  • Responses with a 5xx status are not stored, so retrying a failed request with the same key is safe and will attempt the call again.
  • 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.
Webhook events are de-dupable
Each webhook event carries a stable id (evt_...) you can use to ignore repeats. See Ordering and idempotency in the webhook reference.

Quick start

  1. 1
    Open the API tab in your dashboard and copy your publishable key and secret. Reveal the secret once and store it securely.
  2. 2
    Pick or upload an audio clip in your audio library and note its id.
  3. 3
    Place a test call:
    cURL
    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" }'
  4. 4
    Note the unique_id and poll status:
    cURL
    curl https://voice.agentive.co.in/api/public/v1/calls/run_XXXX \
      -H "x-api-key: pk_live_..." \
      -H "x-api-secret: sk_live_..."
  5. 5
    To receive call results automatically instead of polling, set up a webhook.
  6. 6
    If your account has the AI voice agent feature, place an AI agent call the same way: pick an agent id from List AI agents and call Place an AI agent call, then read the transcript and analysis once it ends.
Billing
All calls are billed in INR against your account balance. Voice broadcast, Interactive Voice, and verification calls bill at your account's rate, with a one-minute minimum per answered call and per-second billing after the first minute. Interactive Voice calls that accept spoken responses carry a small per-minute surcharge. AI agent calls bill per minute at your account's AI rate, with a one-minute minimum per answered call. Timestamps in responses and webhooks are in IST.