Skip to main content

Integrations

On v1? Migrate by 30-June-2026

The v1 integration webhook (/webhook/integration/<uuid> — no /v2/ in the path) is deprecated and will stop processing leads after 30-June-2026. Follow the Migrate v1 → v2 guide to switch over.

The Integrations API lets external systems (server-to-server) push leads into Superfone in real time.

Each Superfone account can configure one or more Integrations in the dashboard. Every integration has a unique webhook URL (containing a webhook_uuid) and a signing secret that you use to authenticate every request. The integration's configuration controls what happens after the lead lands: which lead stage / lead group / labels are applied, which team member is assigned (round-robin across a configured pool), and whether a follow-up task is auto-created.

This API is the recommended path for inbound lead data. For server-to-server reads/writes against your CRM (lookups, updates, assignment changes), use the Customer Management Enterprise API instead.

Endpoints

MethodPathDescription
POST/v2/webhook/integration/:webhook_uuidPush a lead into Superfone

Base URL

https://prod-api.superfone.co.in/superfone

A complete webhook URL looks like:

https://prod-api.superfone.co.in/superfone/v2/webhook/integration/8f4e2a31-2b6d-4c3a-9f1e-7a0b6c2d4e5f

Authentication

Every request is authenticated with an HMAC-SHA256 signature computed from your integration's signing secret. Both the webhook URL and the signing secret are issued in the dashboard when you create the integration.

Every request must carry these headers:

HeaderRequiredDescription
x-webhook-signatureYessignature=<hex> — HMAC-SHA256 of the signing string (see Signing).
x-webhook-timestampYesUnix timestamp in seconds when the request was created. Must be within ±5 minutes of Superfone's clock.
idempotency-keyYesUnique per delivery (e.g. UUIDv4). See Idempotency.
x-request-idNoOptional client-supplied trace ID. Echoed back in x-request-id response header.
content-typeYesMust be application/json.
  • Get the webhook URL and signing secret from the integration's settings in the Superfone dashboard.
  • Treat the signing secret like a password: store it in a secret manager, never commit it to a repository, and never expose it in client-side code. CORS is allowed on this endpoint, but it's intended for server-to-server use — calling it from a browser would leak the signing secret.
  • If the signing secret is leaked, rotate it from the dashboard.

See Signing a request for the exact algorithm and language-specific code samples.

Idempotency

Every request must include an idempotency-key header — a unique string per delivery attempt (UUIDv4 is a good default). Superfone caches the key for 24 hours and uses it to dedupe retries:

  • First time with a given key → accepted, returns a new event_id.
  • Replay with the same key + same body → returns the original event_id and status: "duplicate". The lead is not processed again.
  • Same key, different body409 Conflict. This indicates a caller bug — reuse only happens when you intentionally retry the same delivery.

When retrying a failed request (network error, 5xx), reuse the same idempotency-key so the deduplication logic protects against double-processing.

Async processing

The endpoint returns 202 Accepted as soon as Superfone has durably accepted your payload. Actual lead matching, creation, assignment, and downstream actions happen in a background worker — usually within a few seconds.

{
"event_id": "ev_01HXYZK7QF2A3B4C5D6E7F8G9H",
"status": "accepted",
"request_id": "req_a1b2c3d4e5f6"
}

The HTTP response does not carry the processed lead, the assigned agent, or whether it was a new vs. updated lead. To observe the outcome, check the event activity log in the dashboard — every delivery is recorded against your integration with the request body, processing result, and the event_id for correlation.

What happens after a lead is accepted

Once the worker picks up the queued event, Superfone:

  1. Looks up existing leads by every phone number in the payload.
  2. Updates any matching leads. First and last name on an existing lead are preserved if the incoming first_name looks like a phone number, or if the existing lead's name field is non-numeric (we don't overwrite a real name with sparser data).
  3. Creates a new lead if no match exists. The new lead is round-robin assigned to one of the user IDs configured on the integration (when assignment is allowed by your subscription).
  4. Applies defaults from the integration's configuration: if the payload omits lead_stage_id, lead_group_id, label_ids, source, or source_type, the values from the integration setting are used.
  5. Creates a follow-up task if the integration has a task config.

If the worker rejects the payload (no valid phone, no active subscription, lead storage full), the failure is recorded in the activity log — you've already received the 202 Accepted over HTTP.

Rate limits

ScopeLimitNotes
Per webhook50 burst / 20 sustained rpsSustained is averaged over a 5-second window. Per-webhook limits can be raised — contact support.
Per source IP200 rpsBackstop applied across all webhooks from a single IP.

When a limit is hit, the API returns 429 Too Many Requests with Retry-After: 60. Treat 429 as a transient error and back off — your idempotency-key will continue to protect against double-delivery when you retry.

Conventions

Phone number format

customer_phone should be a phone number in E.164 format (international, with + prefix).

Valid: +918000000001, +14155552671

Plain 10-digit national numbers are tolerated but you'll get the most reliable lead matching with E.164.

Identifying a lead

The webhook identifies a lead by phone number. If the payload's phone matches any existing lead's phone list (primary or secondary), that lead is updated. Otherwise, a new lead is created.

Catalog references

When you pass lead_stage_id, lead_group_id, or label_ids directly, they must be numeric IDs from your account's catalog. To discover IDs by name, use the Customer Management lookup endpoints:

If you'd rather pass names than IDs (and update an existing lead by phone), use Create or Update Lead on the Enterprise API instead.

HTTP Status Codes

StatusMeaning
202 AcceptedPayload was authenticated and queued for processing. Response includes event_id.
400 Bad RequestMissing a required header, invalid x-webhook-timestamp, or malformed JSON.
401 UnauthorizedInvalid signature, unknown webhook_uuid, or timestamp outside the ±5 min window (unified to prevent UUID enumeration).
403 ForbiddenWebhook is disabled in the dashboard.
409 Conflictidempotency-key was reused with a different body.
413 Payload Too LargeBody exceeds 512 KB.
429 Too Many RequestsPer-IP or per-webhook rate limit hit. Response includes Retry-After.
500 Internal Server ErrorUnexpected server error.