Pull missed calls, summaries and CSV exports over REST, and receive every missed call in real time as a signed call.missed webhook. Built for teams wiring missed call leads into their own CRM, website or data pipeline.
Base URL https://voice-api.edesy.in/v1. Authenticate with a Bearer API key created in the portal. Full request and response details, plus curl, Node, Python and PHP samples, are in the docs.
# Base URL: https://voice-api.edesy.in/v1 Auth: Bearer API key from the portal
curl -H "Authorization: Bearer $EDESY_API_KEY" \
https://voice-api.edesy.in/v1/missed-calls
GET /missed-calls list missed calls
GET /missed-calls/summary totals, unique callers, per-day counts
GET /missed-calls/export.csv CSV export
GET /missed-calls/pricing current plan prices
GET /missed-calls/numbers your missed call numbers
POST /missed-calls/numbers/:id/enable switch missed-call routing on for a number
(plus plan endpoints for Pay as you go / Unlimited)
GET /webhooks/subscriptions manage call.missed webhook subscriptionsAdd a webhook URL in the portal (or via /webhooks/subscriptions) and every missed call is POSTed as JSON. Use the test button to send a sample event before going live.
{
"event": "call.missed",
"timestamp": "2026-10-20T10:42:13Z",
"data": {
"call_sid": "3f6c2a1e-8b4d-4c1a-9e2f-7d5b0a9c1e44",
"from": "+919876543210",
"to": "+918045678901",
"direction": "inbound",
"status": "missed",
"phone_number_id": "b21d7e90-5c3a-4f8e-a6d2-91c4e0f37a15",
"phone_number_name": "Diwali hoarding - Pune"
}
}When a signing secret is set, each request carries X-Edesy-Signature: sha256=<hex>, an HMAC-SHA256 of the raw request body. Compute it over the exact bytes received, before any JSON parsing, and compare in constant time.
// Node.js (Express): verify X-Edesy-Signature over the RAW body
const crypto = require("crypto");
app.post("/webhooks/missed-call", express.raw({ type: "application/json" }), (req, res) => {
const header = req.get("X-Edesy-Signature") || "";
const expected = "sha256=" +
crypto.createHmac("sha256", process.env.EDESY_WEBHOOK_SECRET)
.update(req.body) // Buffer, not re-serialised JSON
.digest("hex");
const ok = header.length === expected.length &&
crypto.timingSafeEqual(Buffer.from(header), Buffer.from(expected));
if (!ok) return res.status(401).end();
res.status(200).end(); // acknowledge fast (within 5 s)
const event = JSON.parse(req.body.toString("utf8"));
queueLead(event.data.call_sid, event.data.from); // dedupe on call_sid
});The same check in Python. If verification fails in your framework, the usual cause is hashing a re-serialised body instead of the raw bytes.
# Python (Flask): verify X-Edesy-Signature over the RAW body
import hmac, hashlib, os
from flask import Flask, request, abort
app = Flask(__name__)
SECRET = os.environ["EDESY_WEBHOOK_SECRET"].encode()
@app.post("/webhooks/missed-call")
def missed_call():
raw = request.get_data() # bytes exactly as sent
expected = "sha256=" + hmac.new(SECRET, raw, hashlib.sha256).hexdigest()
if not hmac.compare_digest(expected, request.headers.get("X-Edesy-Signature", "")):
abort(401)
event = request.get_json()
queue_lead(event["data"]["call_sid"], event["data"]["from"]) # dedupe on call_sid
return "", 200 # reply 2xx within 5 sHow the webhook behaves when things go wrong.
Acknowledge first and do slow work (CRM writes, enrichment) in a queue. Anything other than a 2xx within 5 seconds counts as a failed attempt.
Failed deliveries are retried up to 6 times with exponential backoff starting at 30 seconds, so a short outage on your side does not lose leads.
Retries and replays reuse the same call_sid. Store it with a unique constraint and ignore duplicates; that makes your handler idempotent.
Every attempt is in the delivery log. Replay one event or many in bulk after you fix a bug, without asking callers to call again.
On Pay as you go, each event delivered to your webhook costs Rs 0.30. If an event still fails after all retries, you are not charged for it.
Invite teammates with roles; API keys are managed in the portal under your workspace.
Missed call service is live and self-serve at missedcall.edesy.in: complete KYC, pick a number and start capturing callers the same day. Everything in the second list we set up for your account on request - tell us what you need.
Auto-reject missed call number
Calls are cut with a busy tone before they are answered, so callers are never charged.
Instant caller capture
Every missed call is logged with the caller number, time and the number they dialled.
Campaign dashboard and CSV export
Totals, unique callers and a daily chart per number; download every lead as CSV.
Real-time webhook
Signed call.missed events to your CRM or backend, with retries, replay and no charge for failed deliveries.
REST API
List, summarise and export missed calls and manage numbers and plans by API key.
Edesy CRM
Send every missed caller into Edesy CRM as a lead (free CRM plan available).
Pricing
Number Rs 499/month plus Rs 0.30 per missed call sent to your webhook - the missed-call list and CSV are free without a webhook. Unlimited plan Rs 1,498/month per number (fair use 1,00,000 calls, then Rs 0.10). Prepay 3, 6 or 12 months for up to 25% off. Prices exclude GST; KYC required before buying a number.
SMS or WhatsApp reply
Send a message back to every missed caller.
Automatic AI voice callback
An AI voice agent calls each missed caller back within a minute.
Salesforce, Zoho, HubSpot or in-house CRM
We connect missed-call leads to your CRM for you, usually within a few days.
Repeat-caller de-duplication
Count a caller once within a time window you choose.
Missed call verification
Verify a user by a missed call from their registered mobile instead of an OTP.
Toll-free and short / premium numbers
Easy-to-remember campaign numbers.
Explore more comparisons, alternatives, and resources
CRM
Missed call guides
Related products
Sign in, buy a number and create an API key in the portal.