How it works
Voxfra accepts inbound webhooks from voice AI providers (Vapi, Retell, Bland, etc.) on a per-client basis. Each client in your organization gets a unique webhook URL per provider. When a call ends, your provider posts the call report to that URL — Voxfra handles validation, normalization, and storage.| Part | Description |
|---|---|
provider | One of vapi, retell, bland, livekit, elevenlabs, custom |
slug | Client-specific identifier that maps to your organization and client |
Authentication
Each webhook URL uses a unique slug as its authentication mechanism. The slug is:- Unique across the entire platform
- Scoped to exactly one organization + client + provider combination
- Revocable from the admin console at any time
Processing flow
When a webhook arrives:- Slug resolved — maps to the correct organization and client
- Schema validated — provider-specific payload checked; returns
400on mismatch - Idempotency checked — duplicate call IDs within a 24-hour window are accepted but not reprocessed
- Normalized and stored — call data is extracted, normalized into a unified format, and written to Voxfra
- Available — the call appears in the admin console and via the Management API
Limits
| Parameter | Limit |
|---|---|
| Rate limit | 1,000 requests / minute per endpoint |
| Body size | 1 MB |
| Idempotency window | 24 hours (by call ID) |
Managing webhook URLs
Webhook endpoints are managed in the Voxfra admin console under Settings → Webhooks → Inbound for each client. You can:- Create a new URL for a provider
- Copy the URL to paste into your provider’s dashboard
- View
last_used_atandrequest_countper endpoint - Toggle an endpoint inactive without revoking it
- Revoke and replace a URL if it’s compromised
- Configure an IP allowlist or HMAC secret per endpoint
Responses
A successful ingestion returns:requestId for tracing:
| Status | Meaning |
|---|---|
200 | Accepted and processed |
400 | Payload failed schema validation |
404 | Slug not found or endpoint inactive |
429 | Rate limit exceeded — check Retry-After header |
500 | Internal error — contact support with requestId |