Call the Edesy number masking REST API from Java with plain HTTP: create a masked session, place a click-to-call and verify signed event webhooks. There is no Java SDK to install; any HTTP client works.
Number masking at a glance
From API key to first masked call
Sign up at masking.edesy.in, complete KYC and create an API key (it starts with vp_). The full key is shown once, so store it in an environment variable.
Enroll a number from your Edesy account for masking. One number can serve many sessions at once.
POST /v1/masking/sessions with party_a, party_b and your reference, using java.net.http.HttpClient. Give the returned virtual_number to both parties.
Set your endpoint with PUT /v1/masking/event-webhook and verify the X-Edesy-Signature header before trusting an event.
Create a masked session and verify an event webhook. Replace the numbers with real 10-digit Indian mobiles.
// Java 15+ (text blocks): plain HTTP with java.net.http. No SDK or Maven artifact to install.
import java.net.URI;
import java.net.http.*;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
public class EdesyMasking {
static final String API = "https://voice-api.edesy.in/v1";
// 1. Create a two-way masked session
public static String createSession() throws Exception {
String json = """
{"party_a":"9876543210","party_b":"9123456789",
"reference":"ORD-4821","expiry_minutes":60}""";
HttpRequest req = HttpRequest.newBuilder(URI.create(API + "/masking/sessions"))
.header("Authorization", "Bearer " + System.getenv("EDESY_API_KEY")) // vp_...
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(json))
.build();
HttpResponse<String> res = HttpClient.newHttpClient()
.send(req, HttpResponse.BodyHandlers.ofString());
return res.body(); // {"data":{"virtual_number":"...", "session_id":"..."}}
}
// 2. Verify an event webhook: X-Edesy-Signature = "sha256=" + hex(HMAC-SHA256(rawBody))
public static boolean verify(byte[] rawBody, String header, String secret) throws Exception {
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), "HmacSHA256"));
StringBuilder hex = new StringBuilder("sha256=");
for (byte b : mac.doFinal(rawBody)) hex.append(String.format("%02x", b));
return header != null && MessageDigest.isEqual(
hex.toString().getBytes(StandardCharsets.UTF_8),
header.getBytes(StandardCharsets.UTF_8));
}
}JSON in, JSON out. Use java.net.http.HttpClient or any HTTP client you already have.
Send Authorization: Bearer vp_... on every request. Missing or invalid keys get 401.
Events are signed with HMAC-SHA256 over the raw body, sent as sha256=<hex>. Verify with javax.crypto.Mac and MessageDigest.isEqual.
Errors come back as JSON with a code and message, for example insufficient_balance (402) or rate_limited (429).
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.
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.