POST /v1/click-to-call rings your agent's phone first, showing your Edesy number. When the agent answers, Edesy dials the customer and bridges the two. Calls are recorded by default, every stage is sent to your endpoint as a signed Call Event, and recorded calls get an automatic transcript and summary. Indian numbers, Rs 1.50/min.
1 call
POST /v1/click-to-call
Rs 1.50
Per minute, 60 s pulse
8 events
Signed Call Events v1
On
Recording by default
Agent leg first
Standard Webhooks signatures
Transcript and summary
Your CRM IDs echoed back
| Endpoint | POST https://voice-api.edesy.in/v1/click-to-call |
| Auth | Authorization: Bearer <API key> with the calls:write permission |
| Order | Agent's phone rings first; the customer is dialled after the agent answers |
| Numbers | Indian numbers only (+91), for both agent and customer |
| Caller ID | caller_id must be an active number of your workspace; left out, your first active number is used |
| Recording | On by default (record: false turns it off). A short recording notice plays to the customer by default |
| Max duration | max_duration_sec 10 to 7,200, default 3,600 |
| Correlation | Up to 10 keys of your own (for example your CRM's call or lead ID), echoed on every Call Event |
| Hang up | POST /v1/click-to-call/{call_id}/hangup |
| Events | call.initiated, call.ringing, call.answered, call.completed, recording.ready, transcript.ready, call.analyzed, disposition.submitted |
| Signatures | Standard Webhooks: webhook-id, webhook-timestamp, webhook-signature: v1,<base64 HMAC-SHA256> |
| Price | Rs 1.50/min, 60-second pulse, plus number rental. No separate fee for events, transcripts or summaries |
Prices exclude 18% GST. New accounts get Rs 20 welcome credit.
From API key to your first logged call
Sign up at voice-app.edesy.in, complete KYC, buy an Indian number and create an API key with calls:write.
POST /v1/webhooks/subscriptions with format edesy.call.v1. Save the whsec_ secret it returns.
POST /v1/click-to-call with the agent's phone, the customer's phone and your own correlation IDs.
Verify each webhook-signature, then upsert the call by call.id. Every event carries the full snapshot, so arrival order doesn't matter.
Store the recording link from recording.ready and the summary from call.analyzed on your lead or ticket.
The response returns your call_id straight away. Everything else arrives as Call Events.
curl -X POST https://voice-api.edesy.in/v1/click-to-call \
-H "Authorization: Bearer $EDESY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"agent": {"phone": "+9198XXXXXXXX"},
"customer": {"phone": "+9197XXXXXXXX"},
"caller_id": "+9180XXXXXXXX",
"correlation": {"crm_call_id": "call_8812", "lead_id": "L-1042"}
}'
# 201 Created
# {"data": {"call_id": "...", "status": "initiated"}}A v1 subscription always has a signing secret. Leave it out and Edesy generates one, returned only in this response.
curl -X POST https://voice-api.edesy.in/v1/webhooks/subscriptions \
-H "Authorization: Bearer $EDESY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://crm.example.com/edesy/call-events",
"format": "edesy.call.v1",
"event_types": ["call.completed", "recording.ready", "call.analyzed"]
}'HMAC-SHA256 over id.timestamp.body, keyed with the base64 part of your whsec_ secret. Reject timestamps more than 5 minutes off.
const crypto = require('crypto');
function verify(secret, headers, rawBody) {
const id = headers['webhook-id'];
const ts = headers['webhook-timestamp'];
if (Math.abs(Date.now() / 1000 - Number(ts)) > 300) return false;
const key = Buffer.from(secret.replace(/^whsec_/, ''), 'base64');
const expected = crypto.createHmac('sha256', key)
.update(`${id}.${ts}.${rawBody}`).digest('base64');
const want = Buffer.from(expected);
return headers['webhook-signature'].split(' ').some((s) => {
const got = Buffer.from(s.slice(3));
return s.startsWith('v1,') && got.length === want.length && crypto.timingSafeEqual(got, want);
});
}The same API runs Edesy's LeadSquared and Zoho CRM connectors
The agent picks up before the customer's phone rings, so customers never answer to silence.
Every event carries everything known about the call so far. Upsert by call.id and ignore arrival order.
Pass your CRM's call and lead IDs in correlation. They come back on every Call Event.
recording.ready carries the recording URL, its expiry and a channel map of agent and customer.
transcript.ready brings speaker-labelled segments; call.analyzed brings a summary, sentiment, action items and a suggested disposition.
Failed deliveries are retried with backoff. webhook-id stays the same on every retry, so you can de-duplicate.
No code needed for these CRMs
Explore more comparisons, alternatives, and resources
Tell us what you're building and your expected call volume. We'll help you place the first call.
Create an API key, register a Call Events endpoint and place your first click-to-call. Rs 20 welcome credit, no card needed.