Short answer: to trigger an IVR call from your app, send one POST to https://voice-api.edesy.in/v1/ivr/calls with your API key in X-API-Key, the published flow_id, the customer's number in to, and any variables the flow speaks. You get back 202 Accepted with a call_sid, and the call runs your flow. You do not have to write the request yourself: the Use via API button in the flow builder generates it in cURL, Node.js, Python and PHP for that exact flow.
This post is the copy-paste version. For idempotency, callbacks, signatures and error handling in depth, read the IVR outbound call API guide.
The request in four languages
Each example places one call. Replace the flow ID, key and number with yours. The body is the same JSON in every language.
cURL
curl -X POST 'https://voice-api.edesy.in/v1/ivr/calls' \
-H 'X-API-Key: YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"flow_id": "YOUR_FLOW_ID",
"to": "+919876543210",
"variables": { "name": "Ravi", "order_id": "A123" }
}'Node.js (18+, built-in fetch)
const res = await fetch("https://voice-api.edesy.in/v1/ivr/calls", {
method: "POST",
headers: { "X-API-Key": process.env.EDESY_API_KEY, "Content-Type": "application/json" },
body: JSON.stringify({
flow_id: "YOUR_FLOW_ID",
to: "+919876543210",
variables: { name: "Ravi", order_id: "A123" },
}),
});
console.log(res.status, await res.json());Python
import os, requests
res = requests.post(
"https://voice-api.edesy.in/v1/ivr/calls",
headers={"X-API-Key": os.environ["EDESY_API_KEY"]},
json={"flow_id": "YOUR_FLOW_ID", "to": "+919876543210",
"variables": {"name": "Ravi", "order_id": "A123"}},
timeout=15,
)
print(res.status_code, res.json())PHP
<?php
$ch = curl_init('https://voice-api.edesy.in/v1/ivr/calls');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 15,
CURLOPT_HTTPHEADER => ['X-API-Key: ' . getenv('EDESY_API_KEY'), 'Content-Type: application/json'],
CURLOPT_POSTFIELDS => json_encode(['flow_id' => 'YOUR_FLOW_ID', 'to' => '+919876543210',
'variables' => ['name' => 'Ravi', 'order_id' => 'A123']]),
]);
$body = curl_exec($ch);
echo curl_getinfo($ch, CURLINFO_HTTP_CODE), ' ', $body, PHP_EOL;That is the whole integration for a one-way call. A successful response looks like:
{ "data": { "call_sid": "a1b2c3d4-...", "status": "queued" } }202 means the call is queued for dialling, not that the customer answered. The outcome comes later.
The fields you will use
| Field | Required | What it is |
|---|---|---|
flow_id |
Yes | The flow to run. It must be published |
to |
Yes | Indian number: 9876543210, 919876543210 or +919876543210 |
from |
No | One of your numbers as caller ID. Default: your IVR number |
variables |
No | Values the flow uses as {{var.name}}, such as a name or order ID |
reference_id |
No | Your own ID, echoed back in callbacks |
status_callback_url |
No | https:// URL that receives the result when the call ends |
Add an Idempotency-Key header with a value unique to the business event, such as order-A123-confirm. Reusing the same key within 24 hours returns the first call instead of dialling again, so a network retry never rings the customer twice.
Let the builder write it for you
Open any flow in the builder and press Use via API. The panel is built from that flow, so nothing is generic:
- Flow ID with a copy button.
- Variables: every
{{var.name}}token the flow uses, with editable example values. Change an example and the code updates. - Call to, Caller ID, reference_id and status_callback_url fields, which also feed the code.
- API key: create a new key from the panel.
- Request tabs for cURL, Node.js, Python and PHP, ready to copy.
- What the flow sends to your system: each HTTP Request step, how long it waits and how it is retried.
- Copy for your developer: a plain-text hand-off with the endpoint, flow ID, variables and an example. It never contains an API key.
The feature page is Use via API and the step-by-step doc is Use a flow via API.
The readiness checklist
Most failed first calls are not code problems. The panel checks the account before you send anything and shows "All set" or what to fix:
| Check | Fails with | Fix |
|---|---|---|
| Flow published | 409 flow_not_published |
Publish the flow; API calls run the published version |
| Caller ID | no_caller_id |
Pick a caller ID, or connect a number to IVR (buying one needs approved KYC) |
| Wallet | 402 insufficient_balance |
Keep at least Rs 1.50 in the wallet |
| API key | Requests are refused without a key | Create a key in the panel |
| Signing secret | Your system cannot verify requests | Generate one so you can check X-Edesy-Signature |
| Calling hours | 422 outside_calling_hours |
Call between 09:00 and 21:00 IST |
Try it: a real call before any code
The Try it button places a real call to the number you typed in "Call to", using the same request the code would send. Pick up, press keys, and the panel shows the call's status and, live, every request the flow sent: HTTP Request steps to your API and the status callback at the end. If a step fails, you see it there rather than in production.
Use your own phone first. Try-it calls are normal calls billed from your wallet.
Ten lines, then what?
Once the call goes out, most teams add two things:
- A status callback so your system learns the result: status, duration, keys pressed and your
reference_id. Requests carryX-Edesy-Signature,X-Edesy-TimestampandX-Edesy-Idempotency-Key; verify the signature with your signing secret. See HTTP signing secret. - An HTTP Request step on a key press, so "press 1 to confirm" updates your database while the customer is still on the line. See the HTTP Request node guide.
The full reference is Outbound IVR calls, and the product overview is the outbound IVR API.
What it costs
API calls are priced like any IVR call: Rs 1 per minute, minutes rounded up, no per-call fee, unanswered calls free. Text-to-speech adds Rs 0.50 (Standard voices) or Rs 2.00 (Premium voices) per 1,000 characters spoken. Prices exclude 18% GST. Estimate a campaign with the IVR cost calculator or count a prompt with the TTS character counter. Full details on IVR pricing.
FAQ
Do I have to write the request myself?
No. Open your flow in the builder and press Use via API. It shows ready-to-run code in cURL, Node.js, Python and PHP with your flow ID and variables already filled in. Paste in an API key and it runs.
Which header carries the API key?
The generated code sends X-API-Key. The API also accepts Authorization: Bearer with the same key.
Why does my request fail with 409, 402 or 422?
409 flow_not_published means the flow is still a draft. 402 insufficient_balance means the wallet has less than Rs 1.50. 422 outside_calling_hours means the request came outside 09:00 to 21:00 IST. The panel's readiness checklist shows all three before you call.
Can I test without writing any code?
Yes. The Try it button in the panel places a real call to the number you enter and shows, live, the requests the flow sends to your system, such as HTTP Request steps and the status callback.
Can I send the setup to a developer without sharing my key?
Yes. Copy for your developer gives plain text with the endpoint, flow ID, variables and an example request. It never contains an API key; the developer creates or receives one separately.
What does each API call cost?
The same as any IVR call: Rs 1 per minute, minutes rounded up, no per-call fee, unanswered calls free, plus text-to-speech at Rs 0.50 (Standard) or Rs 2.00 (Premium) per 1,000 characters. Prices exclude 18% GST.
Place your first API call
Build or pick a flow, publish it, press Use via API and hit Try it. New accounts get Rs 20 free credit with no card needed, enough for your first test calls. Start free on Edesy IVR, or read the IVR API overview.