Part of the Edesy Business Telephony Suite
Developers

Edesy Developer Hub: Voice, SIP, IVR and Messaging APIs

Edesy's developer APIs share one base URL, https://voice-api.edesy.in/v1, and one API key that works as a Bearer token, an X-API-Key header or Twilio-style Basic auth. They cover calls, Indian numbers, SIP trunks, media streams, Conversation Relay, IVR, voice OTP, masking, missed calls, forwarding, collections, COD order calls, contact center, WebRTC and WhatsApp.

1

Base URL for REST APIs

3

Ways to send your key

HMAC-SHA256

Signed webhooks

INR

Wallet and GST invoices

Twilio-style Basic auth

Signed, retried webhooks

API console with cURL

Self-serve portals

Base URL and authentication

Base URL https://voice-api.edesy.in/v1 (all REST APIs below, except where a row says otherwise)
API key Create one in the portal. Keys look like sk_...
Header options Authorization: Bearer sk_..., or X-API-Key: sk_...
Twilio-style Authorization: Basic base64(AccountSid:AuthToken), for example curl -u "$ACCOUNT_SID:$AUTH_TOKEN"
Format JSON request and response bodies
Accounts One login across every Edesy app; workspaces, team roles and API keys per workspace
Billing Prepaid INR wallet (Razorpay), GST invoices, real-time deduction
curl https://voice-api.edesy.in/v1/phone-numbers \
  -H "Authorization: Bearer $EDESY_API_KEY"

From sign-up to your first API call

The same path for every product

  1. Step 1 of 4: Sign in once

    One Edesy login covers every portal. Create a workspace and invite your team with roles.

  2. Step 2 of 4: Verify and fund

    Finish KYC (PAN and Aadhaar, about 24 hours) before buying numbers, and top up the INR wallet with Razorpay.

  3. Step 3 of 4: Create an API key

    Generate an sk_ key in the portal, or use your Account SID and Auth Token for Basic auth.

  4. Step 4 of 4: Call the API and watch it

    Place a call or bind a number, then follow the request in the API logs, the per-call event timeline and the webhook delivery log.

Every Edesy API

API Endpoints Docs Portal
Voice API POST /v1/calls, /v1/calls/{sid}/events, /v1/recordings, /v1/transcriptions, /v1/applications, /v1/webhooks/subscriptions; Twilio-shaped /v1/Accounts/{sid}/Calls Voice API docs voice-app.edesy.in
Phone numbers /v1/phone-numbers (available, purchase), PUT /{id}/inbound, PATCH /{id}/routing, stats, webhook logs Inbound routing voice-app.edesy.in
SIP trunking /v1/sip-trunks; each trunk gets tk_<id>.trunk.edesy.in, port 5070, UDP or TCP SIP trunking docs voice-app.edesy.in
SIP for AI voice agents SIP URI targets and trunks for LiveKit, Vapi, Retell, Bolna, xAI Grok and Dograh Quickstarts voice-app.edesy.in
Media Streams stream_url on POST /v1/calls, target: media_stream on a number, POST /v1/stream-test Media Streams voice-app.edesy.in
Conversation Relay inbound_target_type: relay on a number, POST /v1/relay-test Conversation Relay voice-app.edesy.in
IVR outbound API POST /v1/ivr/calls, /v1/ivr/flows, /v1/ivr/call-logs, /v1/ivr/http-logs IVR docs ivr.edesy.in
Voice OTP POST /v1/voice-otp/send Voice OTP docs voice-otp.edesy.in
Number masking /v1/masking sessions, routing webhook, extension codes Masking docs masking.edesy.in
Missed call /v1/missed-calls (list, summary, CSV export, numbers) Missed call docs missedcall.edesy.in
Call forwarding /v1/forwarding/rules, call logs, stats, analytics Forwarding docs forwarding.edesy.in
Edesy Collect /v1/collect/ plans, pools, campaigns, contacts, payment webhook Collect docs collect.edesy.in
COD Order Calls Store webhook in: POST /v1/hooks/{token}; store events order.created, order.paid and more Order Calls docs orders.edesy.in
Contact center /v1/ccaas/* plus agent and supervisor WebSockets Contact center docs ccaas.edesy.in, ccaas-agent.edesy.in
WebRTC SDK Token: POST https://webrtc.edesy.in/api/v1/token with x-api-key; drop-in dialer script or @edesy/voice-sdk WebRTC docs webrtc.edesy.in
WhatsApp messaging /v1/whatsapp/messages; webhooks message.received, message.status WhatsApp number docs wa-connect.edesy.in

There are no server SDK packages: every REST API is plain HTTPS and JSON, and the Voice API console generates cURL for each request. The browser SDK is the exception.

Your first call

POST /v1/calls takes one of five instructions: text to speak, an answer URL returning VoiceML, inline VoiceML, a WebSocket stream_url, or an application ID.

# Your first call: speak a message to a phone
curl -X POST https://voice-api.edesy.in/v1/calls \
  -H "Authorization: Bearer $EDESY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "from": "+9180XXXXXXXX",
    "to":   "+9198XXXXXXXX",
    "url":  "https://myapp.example.com/answer",
    "status_callback": "https://myapp.example.com/call-status"
  }'

# Your answer URL returns VoiceML (JSON), not TwiML
{ "instructions": [ { "verb": "say", "text": "Hello from Edesy." }, { "verb": "hangup" } ] }

Webhook signing

Every scheme is HMAC-SHA256 with your signing secret. Compute it over the raw request bytes, before any JSON parsing, and compare in constant time.

Webhook Headers Signed message
Voice API status_callback X-Webhook-Timestamp, X-Webhook-Signature: v1=<hex> <timestamp>.<raw body>
Webhook subscriptions (call.initiated, call.ringing, call.answered, call.completed, call.failed, call.missed, recording.ready, disposition.submitted) X-Edesy-Signature: sha256=<hex> raw body
IVR status callbacks and HTTP Request steps X-Edesy-Timestamp, X-Edesy-Signature: sha256=<hex> (HTTP steps add X-Edesy-Idempotency-Key) <timestamp>.<raw body>
Number masking events and routing webhook X-Edesy-Signature: sha256=<hex> raw body
WhatsApp message.received, message.status X-Edesy-Signature: sha256=<hex> raw body
COD Order Calls store webhook (your store to Edesy) You send X-Edesy-Timestamp and X-Edesy-Signature: sha256=<hex> <timestamp>.<raw body>, within 5 minutes

Subscription webhooks are retried with backoff (30 s, 1 m, 2 m, 4 m, 8 m; 6 attempts in all), and every delivery is in a log you can replay from. Reject timestamped requests older than 5 minutes.

Verify a timestamped signature (Node.js)

Voice API status callbacks and IVR requests sign the timestamp, a dot and the raw body. Only the header names and the prefix differ.

// Timestamped schemes: Voice API status_callback (v1=) and IVR (sha256=)
const crypto = require("crypto");

function verifyTimestamped(rawBody, ts, header, secret, prefix /* "v1=" or "sha256=" */) {
  if (Math.abs(Date.now() / 1000 - Number(ts)) > 300) return false;   // 5 minutes
  const expected = prefix + crypto.createHmac("sha256", secret)
    .update(`${ts}.`).update(rawBody).digest("hex");
  return header.length === expected.length &&
    crypto.timingSafeEqual(Buffer.from(header), Buffer.from(expected));
}

// Voice API:  verifyTimestamped(body, req.get("X-Webhook-Timestamp"), req.get("X-Webhook-Signature"), SECRET, "v1=")
// IVR:        verifyTimestamped(body, req.get("X-Edesy-Timestamp"),  req.get("X-Edesy-Signature"),  SECRET, "sha256=")

Verify a body signature (Python)

Subscription webhooks, masking and WhatsApp sign the raw body alone. If verification fails, the usual cause is hashing re-serialised JSON instead of the bytes received.

# Body-only scheme: subscriptions, masking, WhatsApp (X-Edesy-Signature: sha256=<hex>)
import hmac, hashlib

def verify_body(raw: bytes, header: str, secret: str) -> bool:
    expected = "sha256=" + hmac.new(secret.encode(), raw, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, header or "")

# Flask: verify_body(request.get_data(), request.headers.get("X-Edesy-Signature"), SECRET)

Tools for debugging calls

See what the platform did, without opening a ticket

API console

Build a request in the portal and copy it as cURL. The Make a call screen shows the API request behind each test call.

Debugger

Recent calls and webhook deliveries side by side, with request and response.

API request logs

Every API request your workspace made, with status codes.

Per-call event timeline

GET /v1/calls/{sid}/events: ringing, answered, stream and relay events, completion, with SIP response code and hangup reason.

Preflight tests

POST /v1/stream-test and POST /v1/relay-test check your bot's WebSocket from Edesy's network before a real call.

Delivery log and replay

Failed webhooks are retried with backoff. Test a subscription, read each delivery and replay it once you've fixed your endpoint.

Start with a product

Edesy APIs: FAQ

Building something on Edesy?

Tell us what you're integrating and your expected volume. We'll point you at the right API and help with the first request.

One key. Every Edesy API.

Create an API key, place a test call from the console and watch the signed callback arrive.