Guide

How to Set Up Call Masking - Step by Step Guide

Step-by-step guide to setting up call masking for your business. From choosing a provider to going live with API integration.

Number masking at a glance

ShopifyAmazonStripeSlackNotionVercel

What is call masking and why do you need it

Call masking (also called number masking, privacy calling, or anonymous calling) is a service that sits between two parties on a phone call and shows them a virtual number instead of each other's real number. Neither party sees the other's actual phone number — both see the masked number as caller ID.

The most common setup pattern is click-to-call bridging: your application calls a masking API with two phone numbers. The API dials Party A first, and when they answer, it dials Party B and bridges both legs. Both parties talk normally, but both see the masked virtual number as caller ID. When the call ends, the connection is severed.

Teams set this up for one of three reasons:

  • User privacy — marketplaces, classifieds, ride-hailing, food delivery, real estate, and dating platforms need buyer-seller or driver-rider calls without exposing personal mobile numbers.
  • Agent privacy / spam reduction — sales reps, support agents, recruiters, and field staff need to call leads or customers without leaking their personal mobile numbers.
  • Call tracking and compliance — every masked call routes through your provider, which means you can log it, record it, and tie it to a record in your CRM. That's hard to do when agents use their own SIMs.

This guide walks you through choosing a provider, integrating the API, going live, and handling the operational details — webhooks, error codes, recording retention, and compliance.

The full setup, in 7 steps

From signup to first masked call in production

  1. Step 1 of 7: Choose a provider

    Evaluate India-focused providers (Edesy, Exotel, Knowlarity, MSG91, Plivo, Twilio India) on price, billing currency, GST handling, contract terms, integration ergonomics, and compliance posture.

  2. Step 2 of 7: Sign up and fund a wallet

    Create an account. With a prepaid provider like Edesy, complete business KYC (about 24 hours) and fund an INR wallet via Razorpay; new Edesy accounts get a Rs 20 welcome credit, no card needed to sign up. With contract-based providers, sign a service agreement and wait for onboarding.

  3. Step 3 of 7: Generate an API key

    In the portal, create an API key tied to your organization. Store it as an environment variable in your application — never commit keys to git.

  4. Step 4 of 7: Build the API call

    From your application server, POST two phone numbers to the masking endpoint. Get back a call_sid. The system dials Party A first, then bridges Party B on answer.

  5. Step 5 of 7: Set up webhooks

    Configure an event webhook URL in the portal or with PUT /v1/masking/event-webhook. Edesy POSTs JSON events (session.created, call.incoming, call.connected, call.ended, call.missed, session.expired) to your endpoint. Verify the HMAC signature before processing.

  6. Step 6 of 7: Handle errors gracefully

    Watch for insufficient_balance, invalid_numbers, and rate_limited errors. Use status polling or webhook events to track outcomes (completed, failed, no-answer). Retry where appropriate.

  7. Step 7 of 7: Monitor and tune

    Track success rate (answered vs no-answer vs failed), call duration distribution, and cost per call. Review recordings periodically for quality. Iterate on retry logic and call flow.

Choosing a provider

The decision usually comes down to four factors: pricing model, geographic focus, integration ergonomics, and compliance fit.

Pricing models you'll encounter

  • Prepaid / pay-as-you-go — fund a wallet, pay per minute, stop anytime, no minimum commitment. Best for variable usage and teams that want to evaluate before committing. Edesy is in this category at Rs 1.50/min plus number rental (Rs 499/month mobile, Rs 449/month landline).
  • Postpaid contract — monthly platform fee plus per-minute charges, often with annual commitment. Common with Exotel, Knowlarity, and similar India cloud telephony providers. Best when you have predictable high volume and want a dedicated account manager.
  • USD billing (Twilio, Plivo) — global providers that bill in USD. Works fine technically but adds FX risk and can complicate GST Input Tax Credit. Compare the effective INR cost per minute, including per-number monthly fees, before deciding.

Geographic focus

If your call volume is India-only, an India-native provider (Edesy, Exotel, Knowlarity, MSG91) is usually simpler for INR billing and GST invoices. If you need international masking, global providers (Twilio, Plivo) are necessary. Many teams run hybrid: India provider for India traffic, global provider for the rest.

Integration ergonomics

Look for:

  • A clean REST API with JSON requests and responses
  • Webhook events for call lifecycle (not just polling)
  • HMAC-signed webhook payloads for security
  • Indian DID provisioning included in the rate (no per-number monthly fees)
  • Recording included or available as a clear add-on
  • A low minimum top-up or welcome credit so you can evaluate without commitment

Compliance fit

If you're in healthcare, banking/lending, or payment processing, ask each provider exactly which controls and certifications they have, and get the answer in writing. Edesy provides masked numbers, expiring sessions, a per-number recording toggle, encrypted recording storage with signed links and workspace roles; it does not hold HIPAA, PCI DSS or SOC 2 certification or sign BAAs. Verify fit with your compliance team before signing; this is not legal advice.

API integration walkthrough

With Edesy as the example provider, the integration is three API calls plus webhook handling. Full code examples for the initiate-call endpoint in cURL, Node.js, and Python live in the API reference.

Step 1 — Initiate a call

POST two 10-digit Indian mobile numbers to /v1/masking/calls with a Bearer token in the Authorization header. Body: { "party_a": "9876543210", "party_b": "9123456789" }. The response returns immediately with a call_sid and the masked number that will be shown to both parties.

Step 2 — Track call status

You have two options:

  • Webhook events (recommended for sessions) — set one event-webhook endpoint and receive session.created, call.incoming, call.connected, call.ended, call.missed and session.expired as signed JSON. No polling and no rate-limit consumption. Events are sent once, so reconcile from call logs if your endpoint was down.
  • Status polling — GET /v1/masking/calls/{call_sid} every 2-3 seconds until status reaches a terminal state. Simpler to implement but consumes API rate-limit budget and adds latency. Use only if your stack can't accept inbound webhooks.

Step 3 — Fetch the recording (optional)

If recording is on for the number, GET /v1/masking/calls/{call_sid}/recording after the call ends. Recordings are served from encrypted storage through signed links, so fetch them when you need them rather than storing public URLs.

When recording.ready fires, the webhook payload includes a recording_url. Alternatively, GET /v1/masking/calls/{call_sid}/recording to retrieve a signed URL valid for 1 hour. Store the recording reference against your call/order record for audit and dispute resolution.

Webhook verification

When you set a secret, each delivery carries an X-Edesy-Signature header of the form sha256=<hex>: an HMAC-SHA256 of the raw request body. Recompute it with your secret over the exact bytes you received and compare with a constant-time check before trusting the payload. Respond with a 2xx within 5 seconds.

Every webhook POST includes an X-Edesy-Signature header with an HMAC SHA-256 signature of the request body, signed with your webhook secret. Verify this on every event before processing — otherwise an attacker who knows your webhook URL can spoof events. Reject any request that fails verification with HTTP 401.

Error handling at a glance

Status Code What to do
400 invalid_numbers Validate Indian mobile format and de-dupe Party A vs Party B before calling the API
401 unauthorized Rotate the API key and update the env var
402 insufficient_balance Top up the wallet; consider implementing a low-balance alert at Rs 50
404 not_found The call_sid doesn't exist or recording isn't ready yet — re-check after a delay
429 rate_limited Back off with exponential delay (the default limit is 100 requests/minute per key); contact sales if you need more

Common setup pitfalls to avoid

Mistakes we've seen teams make on their first masking integration

Polling instead of webhooks

Polling every 2 seconds for 100 concurrent calls = 50 req/sec, far above a 100 requests/minute limit. Use webhook events for state transitions; reserve polling for one-off lookups.

Not verifying webhook signatures

Without HMAC verification, anyone who knows your webhook URL can spoof events and cause downstream chaos. Verify the signature on every event before processing.

Hard-coding the API key

Use environment variables. Rotate periodically. Store secrets in a vault (AWS Secrets Manager, HashiCorp Vault, 1Password) — never commit to git, even in private repos.

Skipping the wallet low-balance alert

Insufficient balance blocks new calls with a 402. Check GET /v1/masking/billing on a schedule and alert your own ops channel before the balance runs out.

Recording retention without policy

Call recordings have privacy implications. Decide whether you need recordings at all, and how long you would keep them, before going live. On Edesy, recording is switched on or off per number.

No rollback path

Before cutting over from a previous provider, document the rollback: how do you flip traffic back if the new provider has an outage? Practice it. Keep both accounts live for at least 30 days.

Forgetting GSTIN at top-up

If you forget to add your GSTIN at the first Razorpay top-up, the invoice is issued without it and you lose Input Tax Credit on that top-up. Update GSTIN in the portal before the first top-up.

Ignoring 'no-answer' as a state

If you treat 'no-answer' as a failure and retry immediately, you'll harass users with rapid-fire calls. Build backoff: 5 mins, 30 mins, 4 hours, give up. Match retry policy to use case.

Going live: pre-launch checklist

Before flipping production traffic to the masking flow, walk through this list:

  1. End-to-end test on real numbers — call yourself and a colleague. Verify both see the masked number as caller ID. Verify the recording is fetchable. Verify the webhook fires.
  2. Load test against rate limits — if you expect 50 calls/min, simulate 100. Confirm you don't hit 429 errors under realistic load.
  3. Wallet headroom — fund the wallet to cover at least 7 days of expected usage, and alert yourself when the balance from the billing endpoint drops below Rs 500 or Rs 1,000.
  4. Webhook idempotency — test events, reconciliation jobs and your own replays can process the same event twice. Key handlers on call_sid plus event so a duplicate call.ended does nothing harmful.
  5. Recording access controls — recordings contain personal data. Invite only the people who need portal access, use workspace roles, and remove members who leave.
  6. Compliance sign-off — if you're in a regulated industry, get internal compliance or legal sign-off on the masking provider's data handling.
  7. Runbook for ops — document common failure modes (insufficient balance, webhook outage on your side, provider outage) and how on-call should respond.

Cost and ROI math

Most teams underestimate masking ROI because they only count direct cost (per-minute charges). The real ROI is in three buckets:

  • Reduced spam / fraud losses — exposed phone numbers leak to scrapers and end up in spam lists. Masking keeps personal numbers off your platform's calls, which removes one common source of leaks.
  • Higher trust — users may be more willing to call a seller, driver or provider when they know their number won't be shared. Measure this yourself with an A/B test on your own traffic.
  • Operational visibility — every call is tracked. Disputes get resolved with the recording. Sales/support QA gets real data. The value of "we can audit every customer-facing call" is significant for regulated teams.

An illustrative calculation: at Rs 1.50/min with 60-second pulses, a 90-second call bills as 2 minutes, so it costs Rs 3. 10,000 such calls a month = Rs 30,000, plus number rental and 18% GST. Compare that with your own estimate of what leaked numbers cost you in fraud, disintermediation and support time. The numbers here are an example, not a benchmark.

When to build vs buy the integration

If your team has 1-2 backend engineers comfortable with REST APIs and webhooks, building the integration takes 2-5 days. Time-to-live is fast and you own the code.

If you're a non-technical founder, an ops lead, or your engineering team is already over-allocated, Edesy can help with the integration as a quoted setup project. See setup services.

Either way, usage is billed the same: Rs 1.50/min plus number rental.

Key Questions Answered

Explore Number Masking

Discover solutions, integrations, and resources

Simple Per-Minute Pricing

Rs 1.50/min in 60-second pulses, 1-minute minimum, plus number rental (Rs 499/month mobile, Rs 449/month landline). Prices exclude 18% GST. New accounts get a Rs 20 welcome credit; no card needed to sign up.

Most Popular
Pay As You Go
₹1.50/ min
Prepaid INR wallet, billed per bridged minute
  • Two-way masking sessions
  • Extension codes and QR
  • Optional call recording
  • Analytics and CSV export
  • REST API and signed webhooks
  • Self-serve portal
  • Number rental billed separately
Get Started
Enterprise
Custom
For high volume and custom requirements
  • Everything in Pay As You Go
  • Volume pricing on request
  • Help with integration
  • GST invoices with your GSTIN
Contact Sales

Ready to Protect User Privacy?

Get started on the self-serve portal. Rs 1.50 per minute plus number rental. New accounts get a Rs 20 welcome credit; no card needed to sign up.