Criyx documentation

Everything Criyx does and how each feature works, from creating your first voice agent to running campaigns.

About Criyx

Criyx is an AI automation company. We build services that take over repetitive business work, and our main product is voice AI agents: agents that answer and make phone calls for your business, in your words, any hour of the day.

  • Answer inbound calls: greet callers, take their name, answer questions and book appointments.
  • Make outbound calls: follow-ups, reminders and lead calls, one by one or to thousands of contacts.
  • Hand over to a person when the caller asks, or when your instructions say so.
  • Remember each caller, and keep a recording and details of every call.

How it works

  1. Add credits by buying a plan (the 25K or the 50K plan). ₹1 is 1 credit.
  2. Create an agent and pick its model: V1, V2 or V3.
  3. Write its instructions, choose a voice and language, and add knowledge or tools.
  4. Publish. The agent is live and uses your phone number.
  5. Receive calls, or start a batch or campaign to call a list of contacts.
  6. Watch the dashboard and call history: minutes used, outcomes and recordings.

Calls are billed per minute, rounded up to the next whole minute (1:01 counts as 2 minutes).

The next five sections walk through each flow in detail.

Create a V1 agent

V1 is the quickest way to get a calling agent live, at the lowest price.

  1. 1Open Agents and click Create Agent. Type the agent name and choose Criyx V1.
  2. 2Pick the Language and the Voice. V1 has one voice.
  3. 3Instructions tab: write what the agent is, what it must do and how it should talk.
  4. 4Outputs tab (optional): list the details you want back from each call, such as the caller's name or interest. Each one has a key and a short description.
  5. 5Memory tab (optional): tell the agent what to remember about the caller.
  6. 6Settings: set the greeting (Say hello), whether the caller can interrupt, the maximum call duration, and the voicemail and call-too-long messages.
  7. 7Advanced: add a webhook URL to receive call results, and turn on call forwarding with the number to forward to.
  8. 8Tools (optional): add the actions the agent can take during the call.
  9. 9Save, then use Test Agent to make a test call, inbound or outbound. When it sounds right, go live.

Create a V2 agent

V2 is set up exactly like V1, with premium voices and a faster response.

  1. 1Open Agents and click Create Agent. Type the agent name and choose Criyx V2.
  2. 2Pick the Language, then choose from all premium voices.
  3. 3Fill in Instructions, Outputs and Memory the same way as for V1.
  4. 4Use Settings and Advanced for the greeting, interruption, call limits, webhook and call forwarding.
  5. 5Add Tools if the agent must do something during the call.
  6. 6Run a test call, inbound and outbound, then go live.

Create a V3 agent

V3 opens a full workspace. Each part of the agent has its own tab.

  1. 1Open Agents and click Create Agent. Type the agent name and choose Criyx V3. The workspace opens.
  2. 2Instructions: write the Greeting first (required), then the role, objective, personality, conversation flow, business rules, dos and don'ts, escalation and call closing.
  3. 3Voice: choose the language, or All languages so the agent follows the caller. Open the voice picker to search the 176 voices and filter by gender, language and use.
  4. 4Pronunciations (Voice tab): add the words the agent mispronounces, such as a brand or a name, and how to say them. Use the popup to add, edit or delete words, or import and export a CSV or JSON file.
  5. 5Knowledge: add the documents and pages the agent should answer from.
  6. 6Memory and variables: add variables such as the caller's name and use them in the greeting and instructions.
  7. 7Tools and call forwarding: add actions, and set the number to forward to when the caller asks for a person.
  8. 8Test Agent: make a test call to check the greeting and the flow.
  9. 9Publish. If your inbound number is live, it moves to the new version, so the agent speaks the new instructions.
  10. 10Changed something later? Edit, publish again, or use Redeploy.

Run a batch (V1, V2)

A batch makes the same agent call a list of contacts. V1 and V2 agents use batches.

  1. 1Open Batches and click New Batch/Campaign. Pick the V1 or V2 agent and give the batch a name.
  2. 2Upload a CSV with a contact_name column and a contact_phone column.
  3. 3Check the result: rows found, valid numbers, invalid numbers and duplicates.
  4. 4Settings (optional): timezone, the hours calls start and stop each day, max retries, how long to wait before a retry, and how many calls run at once.
  5. 5Start the batch. Open it to watch live progress and each call's details and recording.
  6. 6Pause, resume, duplicate or delete a batch from the list.

Run a campaign (V3)

A campaign is built for V3 agents. It carries each contact's own details into the call.

  1. 1Open Campaigns and click New Batch/Campaign. Pick the V3 agent and name the campaign.
  2. 2Upload a CSV with contact_name and contact_phone. Any extra column becomes a variable the agent can use.
  3. 3Map columns: choose what each column means and its variable key.
  4. 4Validate: see the valid, invalid and duplicate numbers before anything is dialled.
  5. 5Schedule: pick the timezone, the daily start and stop time, and whether to start now or on a chosen date.
  6. 6Retries and concurrency: set max retries (0 means none), the wait before a retry, and how many calls run at once.
  7. 7Launch. Follow live progress, answered calls and success rate, and open any call for its recording.

Agents: V1, V2, V3

You choose a model per agent. Each one can take both inbound and outbound calls on the same number.

Criyx V1

Lowest price

₹25,000 plan
₹2.5 / min
₹50,000 plan
₹2 / min
  • 200–300 ms latency
  • 1 voice
  • Instructions, voice & tools
  • Memory and telephony built in
  • Call forwarding
  • Inbound and outbound on one number

Criyx V2

Premium voices

₹25,000 plan
₹3.5 / min
₹50,000 plan
₹3 / min
  • 100–200 ms latency
  • All premium voices
  • Everything in V1
  • Call forwarding
  • Inbound and outbound on one number

Criyx V3

Most capable

₹25,000 plan
₹4.5 / min
₹50,000 plan
₹4 / min
With call forwarding
₹5.5 / ₹5
  • under 100 ms latency
  • 176 voices, 12 languages or All languages
  • Structured instructions and variables
  • Knowledge base
  • Pronunciation dictionary: say names and brands your way
  • Call forwarding (+₹1/min on every call)
  • Campaigns with per-contact variables

Instructions

In V3 the instructions page is split into clear parts, so each thing the agent must do has a place. The greeting is required: you cannot publish without it.

Greeting
Required. The first thing the agent says on every call.
Role & objective
Who the agent is and what it must achieve on the call.
Personality
Tone, accent and manner of speaking.
Conversation instructions
The flow of the call, step by step.
Business rules
Hours, prices, appointment rules and anything the agent must follow.
Dos and don'ts
Hard rules the agent always keeps or never breaks.
Escalation & closing
When to hand over to a person and how to end the call.

Variables such as the caller's name can be used inside the instructions and the greeting, for example “Hi {{caller_name}}”. Add them once and the agent fills them in on each call.

Voices & languages

  • V1 has one voice (Praveshika) and speaks Hindi, English, Punjabi, Bengali, Tamil or Multilingual. V2 includes every premium voice and all 12 languages plus Multilingual.
  • V3 offers 176 Criyx V4 voices. The voice picker shows each voice with its gender, the language it is best for and what it was made for (for example Conversational or Customer Support), and has search and filters.
  • V3 speaks 12 languages. Pick one language, or choose All languages and the agent follows the caller's language through the call.
  • Choose accent and tone in the instructions, for example a Canadian or an American way of speaking.

Knowledge, memory & tools

  • Knowledge (V3): add your documents, pages and FAQs. The agent answers from them instead of guessing.
  • Memory: the agent remembers the caller and what was said, so a returning caller is not asked again.
  • Tools: let the agent do things during the call, such as sending your team the details of an appointment request.

Inbound, outbound & forwarding

  • Inbound: callers dial your number and the agent answers. You can pause and resume inbound at any time.
  • Outbound: the agent calls your contacts. Start one call, or use batches and campaigns.
  • Redeploy: after you change instructions, publish. The live inbound number is moved to the new version, so the agent speaks the new instructions.
  • Additional telephony provider (V3): in the Inbound tab, click Additional telephony provider and send a request. It is available only when the Criyx team approves it. Once approved, you see the one number given to that agent and can add it. Calls on it cost more (see the charge below).
  • Silence nudges (V3): in the Voice tab, set what the agent says after the caller has been quiet for a few seconds (up to 5 nudges, in order), and whether to hang up if they still do not answer.
  • Voicemail (V3): when an outbound call reaches a voicemail box, the agent leaves your message (up to 1000 characters).
  • Call forwarding (V1, V2, V3): turn it on and set the number. When the caller says “connect me to a person”, or your instructions say so, the call is forwarded to that number.
  • Test call: try the agent yourself before it goes live, inbound and outbound, on V1, V2 and V3.

Forwarding charge: a V3 agent with call forwarding switched on costs ₹1 extra per minute on every call of that agent, not only the forwarded ones, from the moment you publish it. That is ₹5 per minute on the 50K plan and ₹5.5 per minute on the 25K plan.

External telephony charge: a V3 agent that uses an additional telephony provider costs ₹2 extra per minute, on every call of that agent, starting from the moment you publish the agent with that number. Until then the normal rate applies. The V3 rate goes from ₹4.5 to ₹6.5 per minute on the 25K plan, and from ₹4 to ₹6 per minute on the 50K plan. Agents that do not use it are billed at the normal rate.

Dashboard & call history

  • Dashboard and agent summary update as calls finish: calls, minutes, spend and outcomes.
  • Every call has its own page with the details and a recording you can play or download.
  • Billing shows your credits, plan, 30-day cycle and invoices.

V1 vs V2 vs V3

FeatureCriyx V1Criyx V2Criyx V3
Best forLow-cost, fast callingNatural, premium voicesFull agent workspace
Voices1 voiceAll premium voices176 voices with gender, language and use-case tags
LanguagesHindi, English, Punjabi, Bengali, Tamil, Multilingual12 languages and Multilingual12 languages, or All languages
Instructions, voice & tools
Memory & telephony built in
Structured instructions (role, rules, dos & don'ts)
Knowledge base
Pronunciation dictionary (import / export)
Variables (caller name and more)
Calls forwarded to a human
Batches & campaigns
Inbound and outbound on one number
Test call: inbound
Test call: outbound
Latency200–300 ms100–200 msunder 100 ms
Try now Try now Try now

25K and 50K plans

Pay once, get the same amount in credits, use them for 30 days. Unused credits expire after 30 days. Prices are per minute. Rupee prices are exclusive of 18% GST, which is added at payment.

Changes the plan, phone number and wallet prices on this page.

₹25,000 plan

25,000 credits · 30 days

ModelPer minuteMinutes
Criyx V1₹2.510,000
Criyx V2₹3.57,142
Criyx V3₹4.55,555
V3 with call forwarding₹5.54,545
V3 with an external telephony provider₹6.53,846

Each rate includes ₹0.5 per minute of telephony.

₹50,000 plan

50,000 credits · 30 days

ModelPer minuteMinutes
Criyx V1₹225,000
Criyx V2₹316,666
Criyx V3₹412,500
V3 with call forwarding₹510,000
V3 with an external telephony provider₹68,333

Each rate includes ₹0.5 per minute of telephony.

Phone numbers

Each agent needs its own number for inbound and outbound calls. A number costs ₹300 for 30 days, you can hold up to 30, and one number serves one agent. Numbers renew by autopay.

Top-up wallet

Add money that never expires. It is used only when your plan or phone numbers renew, and you always get exactly the credits listed. Rupee prices are exclusive of 18% GST, added at payment.

₹25,000 plan wallet

Store up to 75,000 credits in one top-up

Credits addedYou pay
25,000 credits₹25,000 + 18% GST
50,000 credits₹50,000 + 18% GST
75,000 credits₹75,000 + 18% GST

₹50,000 plan wallet

Store up to 1,00,000 credits in one top-up

Credits addedYou pay
50,000 credits₹50,000 + 18% GST
1,00,000 credits₹1,00,000 + 18% GST

Phone numbers have their own wallet: top up for at least 3 numbers at ₹300 each. It pays number renewals first, and gives a new agent its number.

Criyx API

Everything you do in the dashboard for a V1, V2 or V3 agent, you can do with the API: create and edit agents, place calls, run batches, read every call with its transcript and recording, read your plan and credits, and get a webhook the moment a call or batch happens. Your customers only ever see your name; Criyx stays behind the API.

Getting started

  • Sign in, open Criyx API in the menu and click Create API key. Each account has one key. It is shown once; Regenerate gives a new key and the old one stops working at once.
  • Send it on every request as Authorization: Bearer YOUR_API_KEY. The base URL is shown on the Criyx API page; every path below goes after it.
  • Every answer is { success: true, data } or { success: false, error: { code, message } }. Lists also carry meta: { page, pageSize, total }.
  • Limit: 120 requests per minute for each key. Past that you get 429 RATE_LIMITED and a Retry-After header.
  • Billing: calls made with the key use the same credits and plan rates as the dashboard. Plans and phone numbers are bought in the dashboard; read your credits and usage with the key (see Plans, credits and usage).
  • V1, V2 and V3 agents all use this same key. V3 has a few extra steps (workspace, publish, tools, campaigns): see Criyx V3 at the end.
  • Dashboard only: signing in, your profile, credit top-ups, releasing numbers, and creating or regenerating the key.
  • Idempotency: send an Idempotency-Key header (up to 64 characters) when you place a call. A retry with the same key and body returns the first answer and no second call is made. A key is remembered for 24 hours.
  • Errors: 400 VALIDATION_ERROR (details lists the fields), 401 bad or missing key, 402 not enough credits or no free number (INSUFFICIENT_BALANCE, INSUFFICIENT_NUMBERS), 403 dashboard-only action, 404 not found, 429 too many requests, 503 REVIEW_REQUIRED (publishing a V3 agent is waiting for the Criyx team: contact Criyx support).
Your first request
bash
curl https://YOUR_API_HOST/api/agents \  -H "Authorization: Bearer YOUR_API_KEY"

V1 and V2 at a glance

plan: "basic" (Criyx V1)agentLowest price. One voice (Praveshika). Languages: Hindi, English, Punjabi, Bengali, Tamil and Multilingual. Instructions, outputs, memory, call forwarding.
plan: "core" (Criyx V2)agentEverything in V1, with every premium voice. Voices are checked by plan: a V1 agent cannot use a V2 voice, and a V2 agent cannot use the V1 voice.
Numberper agentEach agent has ONE number, used for both inbound and outbound calls. It is shown as outDid on the agent.
Same APIbothCreate, edit, call, batch and call-history endpoints are identical for V1 and V2. Only plan and the voice list differ.

1. Create an agent

First read the languages and voices for the plan, then create the agent with their ids.

Languages and voices for a plan
bash
# V1: one voice (Praveshika). V2: every premium voice.curl "https://YOUR_API_HOST/api/agents/options?plan=basic" -H "Authorization: Bearer YOUR_API_KEY"curl "https://YOUR_API_HOST/api/agents/options?plan=core"  -H "Authorization: Bearer YOUR_API_KEY"
Response
json
{  "success": true,  "data": {    "languages": [{ "id": "5192579b-d99c-45b3-8353-5806311ac94d", "name": "Multilingual" }],    "voices": [{ "id": "012f3534-17c4-410f-b62c-c38b1abc6d52", "name": "Mahika (F) - best at Indian English" }]  }}
Create a V2 agent
bash
curl -X POST https://YOUR_API_HOST/api/agents \  -H "Authorization: Bearer YOUR_API_KEY" \  -H "Content-Type: application/json" \  -d '{    "name": "Clinic reception",    "plan": "core",    "languageId": "5192579b-d99c-45b3-8353-5806311ac94d",    "voiceId": "012f3534-17c4-410f-b62c-c38b1abc6d52",    "instructions": "You are the receptionist of Sunrise Clinic. Greet the caller and book appointments.",    "sayHello": true,    "allowInterruption": true,    "maxCallDurationMins": 10,    "allowCallTransfer": true,    "transferDestinationPhone": "9876543210"  }'
namestringRequired. Up to 120 characters.
planbasic | corebasic is V1, core is V2. Defaults to basic.
languageId, voiceIduuidFrom /agents/options for the plan. The voice and the language must belong to the plan, otherwise you get 400. Leave them out and the agent starts on Hindi with Praveshika (V1) or Aanchal (V2). They cannot be cleared later.
instructionsstringWhat the agent is and how it talks. Plain text.
outputFields{ key, description }[]Details you want back from each call, such as the caller's name. Up to 30. They come back as callOutput.
outputInstructionsstringHow to fill the output fields.
sayHellobooleanWhether the agent speaks first.
allowInterruption, minUserSpeechToInterruptboolean, secondsLet the caller cut in, and how long they must speak first.
requiredSilenceAfterSpeech, allowedSilenceBeforeNudge, allowedSpeechBeforeNudgesecondsPause and nudge timing.
maxCallDurationMins1 to 120The call ends at this length.
voicemailMsg, callDurationExceedMessagestringWhat is said when voicemail answers, and when the call runs too long.
memoryEnabled, memoryInstructionsboolean, stringLet the agent remember a caller, and what to remember.
allowCallTransfer, transferDestinationPhoneboolean, 10-digit stringForward the call to a person when asked.
Response
json
{  "success": true,  "data": {    "id": "033ded41-b21c-456d-bbaf-2098f1f21454",    "name": "Clinic reception",    "plan": "core",    "status": "active",    "languageId": "5192579b-d99c-45b3-8353-5806311ac94d",    "voiceId": "012f3534-17c4-410f-b62c-c38b1abc6d52",    "outDid": "918044484499",    "createdAt": "2026-10-19T14:41:33.457141+00:00"  }}
  • The number is given automatically. If your account has no free number the answer is 402 INSUFFICIENT_NUMBERS: buy a number in the dashboard (Billing), then create the agent.
  • Creating an agent needs credits on the account, like in the dashboard.

2. Read, edit and delete agents

GET/agentsYour agents (page, pageSize).
GET/agents/:idOne agent with its full setup: instructions, outputs, memory, language, voice, call forwarding, outDid and inDid.
PATCH/agents/:idChange any of the create fields. Send only what changes. An empty string clears voicemailMsg and callDurationExceedMessage.
DELETE/agents/:idDelete the agent.
GET/agents/:id/summaryCalls, minutes and important calls for the last 7 days.
Edit an agent
bash
curl -X PATCH https://YOUR_API_HOST/api/agents/AGENT_ID \  -H "Authorization: Bearer YOUR_API_KEY" \  -H "Content-Type: application/json" \  -d '{ "instructions": "New instructions.", "voicemailMsg": "" }'

3. One number, inbound and outbound

  • Inbound: callers dial the agent's number (outDid). There is nothing to switch on: the agent answers with its instructions and greeting.
  • Outbound: POST /calls with the agent and the number to call. The call goes out from the same number.
  • toNumber is digits only (6 to 15). countryCode is separate, for example 91 for India. variables is optional: key/value text for this one call, such as { "contact_name": "Rahul" }. It is sent to the agent with the call (V1, V2 and V3).
  • A call needs credits. Without them the answer is 402.
Place a call
bash
curl -X POST https://YOUR_API_HOST/api/calls \  -H "Authorization: Bearer YOUR_API_KEY" \  -H "Content-Type: application/json" \  -H "Idempotency-Key: booking-1042" \  -d '{ "agentId": "AGENT_ID", "countryCode": "91", "toNumber": "9876543210" }'
Response
json
{  "success": true,  "data": {    "criyxCallId": "ac19365a-0f86-4b08-8de0-20020d5ac162",    "message": "Call initiated.",    "agentLocalId": "033ded41-b21c-456d-bbaf-2098f1f21454",    "toNumber": "9876543210",    "countryCode": "91"  }}

Use criyxCallId to read the call, its transcript and its recording once it has ended.

4. Batches

A batch makes one agent call a list of people. It is created as a Draft and calls nobody until you start it.

POST/batches/contacts/validateCheck a list first: valid rows, invalid rows with the reason, and duplicates.
POST/batchesCreate a batch with its contacts and settings. Returns status Draft.
POST/batches/:id/startStart calling. The body can carry settings, or be {}.
POST/batches/:id/stopStop a running batch.
GET/batchesYour batches and their progress.
GET/batches/:idOne batch: status, completion, call stats, schedule, retries.
PATCH/batches/:idRename: { batchName }.
PATCH/batches/:id/settingsChange schedule, retries or concurrency before starting.
GET · POST/batches/:id/contactsList contacts with their status, or add one: { contact_name, contact_phone, country_code? }.
PATCH · DELETE/batches/:id/contacts/:contactIdEdit or remove a contact.
DELETE/batches/:idDelete the batch.
GET/calls?batchId=:idEvery call the batch made, with outcome, transcript and recording.
contactsarray, 1 to 10,000contact_name (required: letters, spaces and periods only), contact_phone (10 digits for India, or any number with country_code).
settings.scheduleobjectdays (1 Monday to 7 Sunday), start_time and end_time as HH:MM, and a timezone such as Asia/Kolkata. Calls only go out inside this window.
settings.maxRetries0 to 20How many times to try again when nobody picks up.
settings.retryAfterHrshoursHow long to wait before a retry.
settings.maxConcurrentCalls1 to 100How many calls run at the same time.
1. Validate the list
bash
curl -X POST https://YOUR_API_HOST/api/batches/contacts/validate \  -H "Authorization: Bearer YOUR_API_KEY" \  -H "Content-Type: application/json" \  -d '{ "contacts": [    { "contact_name": "Asha Verma", "contact_phone": "9876543210" },    { "contact_name": "Ravi Kumar", "contact_phone": "12" }  ] }'
Response
json
{  "success": true,  "data": {    "rows": 2,    "valid": 1,    "invalid": [{ "row": 2, "field": "contact_phone", "value": "12",      "message": "Phone must be exactly 10 digits (India) or include a country_code." }],    "duplicates": []  }}
2. Create the batch
bash
curl -X POST https://YOUR_API_HOST/api/batches \  -H "Authorization: Bearer YOUR_API_KEY" \  -H "Content-Type: application/json" \  -d '{    "agentId": "AGENT_ID",    "batchName": "October reminders",    "contacts": [      { "contact_name": "Asha Verma", "contact_phone": "9876543210" },      { "contact_name": "John Smith", "contact_phone": "4165550123", "country_code": "1" }    ],    "settings": {      "schedule": { "days": [1, 2, 3, 4, 5], "start_time": "10:00", "end_time": "18:00", "timezone": "Asia/Kolkata" },      "maxRetries": 2,      "retryAfterHrs": 3,      "maxConcurrentCalls": 2    }  }'
Response
json
{  "success": true,  "data": {    "id": "5a5491a0-b330-457b-a22e-760552a640ca",    "name": "October reminders",    "status": "Draft",    "totalContacts": 2,    "createdAt": "2026-10-25T23:12:05.321135+00:00"  }}
3. Start it
bash
curl -X POST https://YOUR_API_HOST/api/batches/BATCH_ID/start \  -H "Authorization: Bearer YOUR_API_KEY" \  -H "Content-Type: application/json" \  -d '{}'

Then poll GET /batches/:id for progress, and read the calls it made with GET /calls?batchId=:id.

5. Calls: details, transcript and recording

GET/callsCall history. Filters: agentId, batchId, status, direction (inbound or outbound), search, page, pageSize.
GET/calls/:idOne call: outcome, times, duration, credits, output fields, transcript and recording.
GET/calls/:id/transcriptThe whole conversation as turns of { role, content }.
GET/calls/:id/recordingWhether a recording exists, its status and a link to the audio.
GET/calls/:id/audioThe recording itself. Supports Range for seeking. Add ?download=1 to get it as a file.
List calls
bash
curl "https://YOUR_API_HOST/api/calls?agentId=AGENT_ID&batchId=BATCH_ID&status=Completed&page=1&pageSize=25" \  -H "Authorization: Bearer YOUR_API_KEY"
One item of the list
json
{  "uuid": "ac19365a-0f86-4b08-8de0-20020d5ac162",  "agentLocalId": "033ded41-b21c-456d-bbaf-2098f1f21454",  "agentName": "Clinic reception",  "toNumber": "+919968466342",  "outcome": "Completed",  "startedAt": "2026-10-22T20:26:18.627+00:00",  "endedAt": "2026-10-22T20:28:39.815+00:00",  "durationSeconds": 140,  "hasRecording": true,  "batchId": null,  "billedMinutes": 3,  "creditsUsed": 9}
Call details
bash
curl https://YOUR_API_HOST/api/calls/CALL_ID -H "Authorization: Bearer YOUR_API_KEY"
Response
json
{  "success": true,  "data": {    "criyxCallId": "ac19365a-0f86-4b08-8de0-20020d5ac162",    "contactPhone": "+919968466342",    "outcome": "Completed",    "durationSeconds": 140,    "billedMinutes": 3,    "creditsUsed": 9,    "callOutput": null,    "hasTranscript": true,    "transcript": [      { "role": "assistant", "content": "Hello, this is Sunrise Clinic. May I know your name?" },      { "role": "user", "content": "Hi, I want an appointment." }    ],    "recording": {      "available": true,      "url": "https://YOUR_API_HOST/api/calls/ac19365a-0f86-4b08-8de0-20020d5ac162/audio",      "status": "AVAILABLE"    }  }}
Full transcript
bash
curl https://YOUR_API_HOST/api/calls/CALL_ID/transcript -H "Authorization: Bearer YOUR_API_KEY"
Recording
bash
# The link (and its status)curl https://YOUR_API_HOST/api/calls/CALL_ID/recording -H "Authorization: Bearer YOUR_API_KEY"
# The audio itself (supports Range, so a player can seek). Add ?download=1 to get it as a file.curl -o call.wav "https://YOUR_API_HOST/api/calls/CALL_ID/audio?download=1" -H "Authorization: Bearer YOUR_API_KEY"
  • Outcome, duration, transcript and recording are filled in once the call has ended.
  • The call details leave out a very long transcript. GET /calls/:id/transcript always returns the whole of it.
  • The recording link points at the Criyx audio endpoint, so send your key when you fetch it. billedMinutes and creditsUsed show what the call cost.

Flagged numbers (advice)

When the customer on a finished call asks not to be called again (in English, Hindi or Hinglish), or is abusive or talks about something illegal, Criyx flags the call and its number for 30 days, the time calls are kept. A flag is a recommendation only: nothing is blocked, and what you do next is your decision.

GET/flagsEvery number that is flagged right now.
POST/flags/check{ numbers: [...] } returns the ones that are flagged. Check before you call or add numbers to a batch.
POST/flags{ callId, type } flags a call's number by hand. type is do_not_call or abusive_illegal.
DELETE/flags/:idClears the flag of that number.
  • GET /calls: a flagged call has flags: [{ id, type, expiresAt }]. GET /calls/:id also gives the customer's own words in evidence.
  • POST /calls: the answer carries numberFlags (empty when the number is fine).
  • POST /batches/contacts/validate: the answer carries flagged, the contacts that are on the list. POST /batches and POST /campaigns answer with flaggedContacts, a count.

6. Plans, credits and usage

Your plan, credits and phone numbers are bought in the Criyx dashboard (Billing), because paying takes the Razorpay popup in a browser. With the API key you read everything you need to run your own billing: how many credits are left, what each call used, and the plan rates.

GET/billing/packagesThe 25K and 50K plans: price, per-minute rates for V1 and V2, GST, and your current plan.
GET/billing/accountYour plan, days left, numbers you own, and when each number renews.
GET/billing/balanceCredits left and the account status.
GET/billing/transactionsCredit history for the last 30 days: every call's usage and every credit added.
GET/dashboard/summaryThe numbers behind your dashboard: credits, calls, minutes, usage by day.
  • A plan is 30 days. 25K gives 25,000 credits and 50K gives 50,000; prices are before 18% GST.
  • Credits are shared by everything you run with the key: when they end, calls, campaigns and new agents stop for all of your customers until the plan is renewed. Check GET /billing/balance and top up before it reaches zero.
  • Each number renews with its own 30 days, and every agent needs one.

7. Webhooks

Add a URL once and Criyx sends your server a POST the moment something happens to a V1 or V2 agent. You never have to poll for call results.

GET/webhooks/endpointsYour webhook URLs.
POST/webhooks/endpointsAdd a URL: { url, events? }. Leave events out to receive every event. The secret is returned once.
DELETE/webhooks/endpoints/:idRemove a URL.
call.startedeventA call was placed with POST /calls (or from the dashboard). data: callId, agentId, agentName, toNumber, countryCode.
call.answeredeventA call was picked up and has finished. Sent just before call.completed.
call.completedeventA call has finished. Also used for a call nobody picked up: read data.outcome (Completed or Unanswered).
call.failedeventThe call could not be made (outcome Failure or Invalid).
batch.startedeventYou started a batch. data: batchId, name, agentId, status, totalContacts.
batch.completedeventA batch is no longer running (finished or stopped). Read data.status.
batch.failedeventA batch ended with a failure status.
campaign.started, campaign.completed, campaign.failedeventThe same moments for a V3 campaign. data: campaignId, name and status.
V3 call eventsnotecall.started comes from POST /calls. call.answered, call.completed and call.failed follow when the call ends, with callId, status and campaignId when the call belongs to a campaign.
Add a URL
bash
curl -X POST https://YOUR_API_HOST/api/webhooks/endpoints \  -H "Authorization: Bearer YOUR_API_KEY" \  -H "Content-Type: application/json" \  -d '{ "url": "https://yourapp.com/criyx-events", "events": ["call.completed", "call.failed", "batch.completed"] }'
What your server receives (call.completed)
json
{  "id": "3f1c0a52-8c1e-4f43-9d0b-6d6a6f1d2a10",  "type": "call.completed",  "createdAt": "2026-10-26T09:41:07.120Z",  "data": {    "callId": "ac19365a-0f86-4b08-8de0-20020d5ac162",    "agentId": "033ded41-b21c-456d-bbaf-2098f1f21454",    "agentName": "Clinic reception",    "toNumber": "+919968466342",    "outcome": "Completed",    "startedAt": "2026-10-26T09:38:41.000Z",    "endedAt": "2026-10-26T09:41:01.000Z",    "durationSeconds": 140  }}
Check the signature before you trust an event
javascript
import { createHmac, timingSafeEqual } from "node:crypto";
// rawBody is the request body exactly as received (before JSON.parse).function isFromCriyx(rawBody, signatureHeader, secret) { const expected = "sha256=" + createHmac("sha256", secret).update(rawBody).digest("hex"); const a = Buffer.from(expected); const b = Buffer.from(signatureHeader ?? ""); return a.length === b.length && timingSafeEqual(a, b);}
  • Call events for V1 and V2 are sent within about half a minute of the call ending, once per call. V3 events arrive as the call finishes.
  • Each event is sent once, with no retry. Answer with a 2xx quickly and keep your own copy. Redirects are not followed, and the URL must be a public address.
  • x-criyx-event names the event, and x-criyx-signature is sha256= and an HMAC-SHA256 of the raw body made with your secret. Use the event id to ignore a repeat.
  • To get the details of a call, read it with GET /calls/:id using the callId from the event.

Criyx V3

V3 agents are the fastest and the most natural. They work with the same key, the same calls, the same webhooks and the same billing as V1 and V2. The difference is that a V3 agent is set up in its workspace and goes live when you publish it.

Create, set up and publish a V3 agent
bash
# 1. Create the agent (V3 is plan "premium"). It stays a draft until you publish it.curl -X POST https://YOUR_API_HOST/api/agents \  -H "Authorization: Bearer YOUR_API_KEY" \  -H "Content-Type: application/json" \  -d '{ "name": "Clinic reception", "plan": "premium" }'
# 2. Set it up in its workspace. Send only the parts that change.curl -X PATCH https://YOUR_API_HOST/api/agents/AGENT_ID/workspace \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "config": { "instructions": { "role": "You are Riya, the front desk of Sunrise Dental Clinic.", "objective": "Book appointments and answer questions about fees." }, "voice": { "language": "Hindi", "voice": "Kavya - Conversational Voice", "greeting": "Namaste, Sunrise Dental Clinic mein aapka swagat hai.", "maxCallDurationMins": 10 }, "memory": { "enabled": true, "contextTurns": 10 }, "variables": [{ "key": "clinic_city", "value": "Pune", "description": "City of the clinic" }], "knowledge": { "sources": [{ "id": "fees", "name": "Fees", "type": "text", "content": "Root canal costs 7500 rupees." }] }, "pronunciations": { "Hindi": { "Sunrise": "सनराइज़" } }, "inbound": { "transferEnabled": true, "transferNumber": "9876543210" } } }'
# 3. Publish: this is what makes the setup live.curl -X POST https://YOUR_API_HOST/api/agents/AGENT_ID/publish -H "Authorization: Bearer YOUR_API_KEY"
Response of publish
json
{  "success": true,  "data": { "status": "published", "version": 3, "warnings": [], "message": "Configuration published." }}
GET/agents/options?provider=premiumThe languages and voices a V3 agent can use.
GET/agents/voice-previewListen to a voice before you choose it.
POST/agentsCreate the agent with plan: premium. It is a draft until published.
GET/agents/:id/workspaceThe whole setup: instructions, voice, memory, knowledge, variables, pronunciations, inbound and publish state.
PATCH/agents/:id/workspaceChange name, description or any part of config. Send only what changes. Lists (variables, knowledge sources, pronunciations) are replaced as a whole.
POST/agents/:id/publishMake the current setup live. Run it again after every change.
POST/agents/:id/testCheck the setup and run your tools once before real calls. Body: { variables, includeToolTests }.
GET/agents/:id/toolsThe tools the agent can call during a conversation.
POST/agents/:id/toolsAdd a tool: a web address of yours the agent calls to look something up or save something.
PATCH/agents/:id/tools/:toolIdChange a tool.
DELETE/agents/:id/tools/:toolIdRemove a tool.
POST/agents/:id/tools/:toolId/testRun one tool with sample values.
POST/agents/:id/inboundConnect, pause or resume the inbound number. Body: { action: "deploy" | "pause" | "resume" }.
GET/phone-numbersThe numbers you can attach to a V3 agent.
POST/callsPlace one call (see Calls). variables fill the agent's variables for that call.
GET/calls, /calls/:id, /calls/:id/transcript, /calls/:id/recordingSame call history, transcript and recording as V1 and V2.
GET/campaigns, /campaigns/:idYour campaigns and one campaign with its progress.
POST/campaignsCreate a campaign: a V3 agent calls a list of people. It is scheduled the moment it is created and starts by itself at startAt, or when the calling window opens.
POST/campaigns/contacts/validateCheck a list of contacts before you create the campaign.
PATCH/campaigns/:id and /campaigns/:id/settingsRename it, or change schedule, retries and how many calls run at once.
POST/campaigns/:id/start, /campaigns/:id/stopStop ends the campaign. Start resumes a paused campaign; a campaign that is still waiting for its time cannot be started earlier.
GET, POST, PATCH, DELETE/campaigns/:id/contactsRead, add, edit and remove the people in a campaign.
DELETE/campaigns/:idDelete a campaign.
config.instructionsobjectrole, objective, personality, conversation, businessRules, dos, donts, escalation, closing, additional. Plain text. At least a role or an objective (20 characters) is needed to publish.
config.voiceobjectlanguage, voice (a name from /agents/options), speed, pitch, greeting, allowInterruption, maxCallDurationMins (1 to 60), temperature, backgroundSound, voicemailEnabled, voicemailMessage (up to 1000 characters), nudgeEnabled, nudges (up to 5 of {seconds, message}) and endAfterNudges. The greeting is the first thing every caller hears and is required to publish.
config.memoryobjectenabled and contextTurns: how many of the latest turns the agent keeps in mind.
config.variables{ key, value, description }[]Values the agent can use as {{key}} in its instructions and greeting. Up to 50. A call can override them with variables.
config.knowledge.sources{ id, name, type, content | fileName + fileBase64 }[]Documents the agent searches while it talks. Text, PDF, TXT, MD, CSV, DOC or DOCX, up to 1.5 MB together. Editing a source replaces its old text.
config.pronunciations{ Language: { word: how to say it } }How the agent says names and words. Up to 500 words.
config.inboundobjectphoneNumber, startTime, endTime, allowedDays (1 to 7), timezone, transferEnabled and transferNumber (10 digits for India, or the country code first).
Add a tool
bash
curl -X POST https://YOUR_API_HOST/api/agents/AGENT_ID/tools \  -H "Authorization: Bearer YOUR_API_KEY" \  -H "Content-Type: application/json" \  -d '{    "name": "Find booking",    "description": "Looks up a booking by phone number",    "method": "GET",    "url": "https://your-server.example.com/bookings",    "queryParams": [{ "name": "phone", "type": "string", "required": true, "description": "Caller phone" }],    "maxWaitSeconds": 8  }'
Place a V3 call
bash
curl -X POST https://YOUR_API_HOST/api/calls \  -H "Authorization: Bearer YOUR_API_KEY" \  -H "Content-Type: application/json" \  -H "Idempotency-Key: reminder-1042" \  -d '{    "agentId": "AGENT_ID",    "countryCode": "91",    "toNumber": "9876543210",    "variables": { "clinic_city": "Pune", "contact_name": "Rahul" }  }'
Run a campaign
bash
curl -X POST https://YOUR_API_HOST/api/campaigns \  -H "Authorization: Bearer YOUR_API_KEY" \  -H "Content-Type: application/json" \  -d '{    "agentId": "AGENT_ID",    "batchName": "October reminders",    "contacts": [{ "contact_name": "Rahul", "contact_phone": "9876543210", "country_code": "91" }],    "settings": { "maxRetries": 2, "maxConcurrentCalls": 5, "startAt": "2026-11-02T10:00:00+05:30" }  }'
# Stop it at any time (this ends the campaign)curl -X POST https://YOUR_API_HOST/api/campaigns/CAMPAIGN_ID/stop -H "Authorization: Bearer YOUR_API_KEY"
  • Publishing makes your setup live. If it is waiting for the Criyx team, publish and the other publishing steps answer 503 REVIEW_REQUIRED with this message. Your setup is saved either way: contact Criyx support and publish again.
  • After you change instructions or the greeting, publish again. A connected inbound number is moved onto the new version for you. Stop running campaigns and calls first: the number is briefly reconnected, so a call arriving at that moment can fail.
  • Check your contacts with POST /campaigns/contacts/validate first: a campaign with real numbers starts calling on its own, so create it only when you mean it.
  • Webhooks work the same for V3: call.started, call.answered, call.completed, call.failed and the campaign events (see Webhooks).
  • Calls are billed with the same credits and plan rates as V1 and V2.
Answer while publishing is waiting for review
json
{  "success": false,  "error": {    "code": "REVIEW_REQUIRED",    "message": "Publishing needs a quick review by the Criyx team first. Please contact Criyx support to publish your instructions."  }}