ProviderCall
A ProviderCall is an admin-triggered outbound call placed through a specific SIP provider, bypassing normal dialroute selection. It is an audit record that captures the admin’s original request plus the IDs of the Call and Groupcall records produced by the underlying call-creation step.
API Reference: ProviderCall endpoints
Overview
Note
AI Context
Complexity: Medium
Cost: Chargeable. Each
POST /v1/providercallscreates one or more real outbound calls. Billing and outbound rate-limiting apply identically to customer-initiated calls; the admin’s own customer account is charged.Async: Yes. The
POSTresponse is aProviderCallaudit record that contains the IDs of the created Call and Groupcall records. Per-call state (dialing / ringing / answered / hangup reason) must be observed viaGET https://api.voipbin.net/v1.0/calls/{id}or the normal Call webhooks.Access: Admin-only. Requires
PermissionProjectSuperAdmin. Customer-tier users (PermissionCustomerAdmin,PermissionCustomerManager,PermissionCustomerAgent) cannot call this endpoint.
VoIPBIN’s ProviderCall API lets platform super-admins place a real outbound call through a specific SIP provider, forcing the routing decision instead of letting the normal customer / default dialroute merge choose one. Use cases:
Provider onboarding. Verify that a newly-configured provider actually accepts calls, routes to the PSTN, and returns a sensible SIP response — before live customer traffic touches it.
Routing debugging. When a provider is suspected of misbehaving, isolate it from normal dialroute priority so the admin can exercise it directly.
Post-config verification. After changing
hostname/tech_prefix/tech_postfix/tech_headerson an existing provider, confirm the new configuration actually works.
The endpoint triggers a call — it does not produce a pass/fail verdict. Admins interpret the resulting Call’s status, hangup reason, and SIP trace themselves.
How ProviderCalls Work
bin-api-manager is a thin gateway: it authenticates, verifies the provider_id exists, and forwards the full request to bin-route-manager. The orchestration happens inside route-manager (which owns the ProviderCall entity):
Optional temp-flow creation — when the admin supplies inline
actionswithout aflow_id, route-manager creates a temporary flow viaFlowV1FlowCreateand passes that flow’s id to call-manager. If any downstream step fails, the temp flow is cleaned up.Server-side metadata construction — two internal keys are attached to the Call:
route_provider_ids— tells call-manager / route-manager to return a synthetic dialroute that points at exactly the specified provider, bypassing the normal customer / default merge.skip_source_validation— tells call-manager to preserve the admin-supplied source number verbatim, instead of silently falling back to the customer’sDefaultOutgoingSourceNumberIDwhen the source is not owned by the customer. Necessary because providers commonly reject INVITEs whoseFrom/P-Asserted-Identitydoesn’t match a pre-allowlisted caller ID.
Create the underlying Call(s) — route-manager issues
CallV1CallsCreatesynchronously. Call-manager persists the Call(s), readsroute_provider_idsingetDialroutesand forwards them toDialrouteList, honorsskip_source_validationingetValidatedSourceForOutgoingCall.Persist the ProviderCall audit record — route-manager saves the admin’s request info (
customer_id,provider_id,flow_id,source,destinations,anonymous) alongside the IDs of the Call and Groupcall records that step 3 produced.
The response is the persisted ProviderCall.WebhookMessage — an atomic record (IDs only, no embedded Call/Groupcall objects, per the VoIPBIN atomic-API rule). Admin retrieves per-call state separately.
Internal-only metadata (not a customer-facing API field)
Call.Metadata is server-side-only on internal trust paths. No customer-facing POST endpoint accepts a metadata field in the request body. Both route_provider_ids and skip_source_validation are built server-side by the admin endpoint (never passed in by clients). The call-manager listen handler rejects unknown metadata keys with HTTP 400, so new keys must be declared in the typed-registry before they can be set.
Note
AI Implementation Hint
After POST /v1/providercalls returns, the ProviderCall record’s call_ids array contains one entry per destination. To observe per-destination outcome, iterate call_ids and call GET https://api.voipbin.net/v1.0/calls/{id} (or subscribe to webhooks) for each. Do not poll the ProviderCall record itself for call state — it is a summary, not a live status snapshot.
Provider Validation
Before the underlying call is created, the handler validates that the supplied provider_id exists and is not soft-deleted (via RouteV1ProviderGet). This fail-fast check prevents the scenario where a Call record is created with metadata pointing at a non-existent provider — route-manager would then return an error at dial-time, leaving behind a dead Call record.
Soft-Delete Semantics
DELETE /v1/providercalls/{id} is a soft-delete — it sets tm_delete on the audit record and returns the deleted ProviderCall object. The underlying Call records referenced by call_ids are not affected. Hard deletion of the historical audit trail is not supported.
Note
AI Implementation Hint
Deleting a ProviderCall is purely an audit-trail operation. If you need to terminate a call that’s currently in progress, use POST /v1/calls/{id}/hangup against the call_ids entry instead — the ProviderCall DELETE does not hang up or cancel anything on the wire.
ProviderCall
ProviderCall
A ProviderCall is a persisted audit record for an admin-triggered call placed through a specific SIP provider. It captures the admin’s original request (customer, provider, flow, source, destinations, anonymous option) plus the identifiers of the calls and groupcalls that were created by the underlying call-creation step. The ProviderCall itself does not embed the full Call/Groupcall records — use the IDs with GET https://api.voipbin.net/v1.0/calls/{id} to observe per-call progress.
{
"id": "<string>",
"customer_id": "<string>",
"provider_id": "<string>",
"flow_id": "<string>",
"source": {
"type": "<string>",
"target": "<string>",
"target_name": "<string>"
},
"destinations": [
{
"type": "<string>",
"target": "<string>",
"target_name": "<string>"
}
],
"anonymous": "<string>",
"call_ids": ["<string>"],
"groupcall_ids": ["<string>"],
"tm_create": "<string>",
"tm_update": "<string>",
"tm_delete": "<string>"
}
id(UUID): TheProviderCall’s unique identifier. Returned when creating viaPOST https://api.voipbin.net/v1.0/providercallsor listing viaGET https://api.voipbin.net/v1.0/providercalls.customer_id(UUID): The customer the record is attributed to. Set server-side from the authenticated admin’s own customer (from the JWT/accesskey); not settable via the request body.provider_id(UUID): The provider the call was forced through. Obtained from theidfield ofGET https://api.voipbin.net/v1.0/providers.flow_id(UUID): The flow executed after the destination answered.00000000-0000-0000-0000-000000000000when no flow was attached (inlineactionsor no post-answer logic).source(Object, nullable): The admin-supplied source address (caller ID). Preserved verbatim — the normal customer-ownership check on the source number is bypassed for this flow so a provider-allowlisted caller ID reaches the carrier unchanged.nullif the admin did not supply one.destinations(Array of Object, minItems: 1): The admin-supplied dial targets. OneCallorGroupcallis created per destination, depending on destination type.anonymous(enum string): The anonymous caller-ID option requested. See Anonymous.call_ids(Array of UUID): IDs of theCallrecords that the call-creation step produced. Use each ID withGET https://api.voipbin.net/v1.0/calls/{id}to observe per-call progress.groupcall_ids(Array of UUID): IDs of anyGroupcallrecords that were produced (when a destination resolved to a group-type address). Use each ID withGET https://api.voipbin.net/v1.0/groupcalls/{id}.tm_create(string, ISO 8601): Timestamp when theProviderCallrecord was created.tm_update(string, ISO 8601): Timestamp of the last update to the record.tm_delete(string, ISO 8601): Timestamp when theProviderCallwas soft-deleted. Remainsnulluntil aDELETEcall is made.
Note
AI Implementation Hint
The ProviderCall is a summary record — the actual per-call state (dialing, ringing, answered, hangup reason) lives on each Call referenced by call_ids. Do not poll the ProviderCall itself for call progress. Instead, iterate call_ids and poll GET https://api.voipbin.net/v1.0/calls/{id} (or listen for the corresponding webhooks) to determine outcome.
Example
{
"id": "b7d1c0f6-9a2e-4b3f-8e2a-1c7d5b8a9e0f",
"customer_id": "6a93f71e-8b2d-4e5f-9a1c-2d3e4f5a6b7c",
"provider_id": "4dbeabd6-f397-4375-95d2-a38411e07ed1",
"flow_id": "00000000-0000-0000-0000-000000000000",
"source": {
"type": "tel",
"target": "+14155551234",
"target_name": ""
},
"destinations": [
{
"type": "tel",
"target": "+821012345678",
"target_name": ""
}
],
"anonymous": "auto",
"call_ids": ["9f8e7d6c-5b4a-3c2d-1e0f-abcdef012345"],
"groupcall_ids": [],
"tm_create": "2026-04-21 23:15:00.000000",
"tm_update": "2026-04-21 23:15:00.000000",
"tm_delete": null
}
Anonymous
Controls whether the outbound caller ID is anonymized on the INVITE that leaves VoIPbin.
Value |
Description |
|---|---|
|
Always send anonymous caller ID (RFC 3323 Privacy header). The real source number is carried in the P-Asserted-Identity header (RFC 3325) so carriers can route and bill correctly while the called party sees “Anonymous”. |
|
Never anonymize. The source number is sent as-is. |
|
Default behavior. Today this resolves the same as |
|
Empty string. Equivalent to |
Tutorial
Before placing a providercall, you need:
A platform super-admin authentication token. Obtain one by logging in as a user with the
PermissionProjectSuperAdminpermission. Customer-tier tokens are rejected with 403.A provider ID (UUID). Obtain one from
GET https://api.voipbin.net/v1.0/providers. The provider must exist and must not be soft-deleted.A source address — typically a phone number in E.164 format that the provider’s carrier has pre-allowlisted as an acceptable
From/P-Asserted-Identity. Because this endpoint skips the normal customer-ownership check on the source, the admin is trusted to supply a value the provider will accept.At least one destination address — typically a phone number in E.164 format.
(Optional) A flow ID (UUID) from
GET https://api.voipbin.net/v1.0/flowsif you want a specific flow to execute after the destination answers.(Optional) A list of inline actions (see the Flow Action struct) to execute post-answer. A temporary flow is auto-created for the call if you supply actions without a
flow_id.
Note
AI Implementation Hint
The POST /v1/providercalls endpoint creates real, billable outbound calls. One Call record is created per entry in destinations. The admin’s own customer is charged. Existing outbound rate-limiting applies. Do not call this endpoint in automated CI — it will generate real PSTN traffic.
Place a providercall
The minimum required body is provider_id + at least one destination. source is strongly recommended (without it the call leaves with no caller ID, which most providers reject).
$ curl -k --location --request POST 'https://api.voipbin.net/v1.0/providercalls?token=<YOUR_AUTH_TOKEN>' \
--header 'Content-Type: application/json' \
--data-raw '{
"provider_id": "4dbeabd6-f397-4375-95d2-a38411e07ed1",
"source": {
"type": "tel",
"target": "+14155551234"
},
"destinations": [
{
"type": "tel",
"target": "+821012345678"
}
],
"anonymous": "auto"
}'
{
"id": "b7d1c0f6-9a2e-4b3f-8e2a-1c7d5b8a9e0f",
"customer_id": "6a93f71e-8b2d-4e5f-9a1c-2d3e4f5a6b7c",
"provider_id": "4dbeabd6-f397-4375-95d2-a38411e07ed1",
"flow_id": "00000000-0000-0000-0000-000000000000",
"source": {"type": "tel", "target": "+14155551234", "target_name": ""},
"destinations": [{"type": "tel", "target": "+821012345678", "target_name": ""}],
"anonymous": "auto",
"call_ids": ["9f8e7d6c-5b4a-3c2d-1e0f-abcdef012345"],
"groupcall_ids": [],
"tm_create": "2026-04-21 23:15:00.000000",
"tm_update": "2026-04-21 23:15:00.000000",
"tm_delete": null
}
Save call_ids[0] as call_id and poll it for per-call state.
Place a providercall with inline actions
If you want the call to execute a short post-answer sequence (e.g., play a TTS prompt and hang up), supply inline actions instead of a flow_id. A temporary flow is created for you.
$ curl -k --location --request POST 'https://api.voipbin.net/v1.0/providercalls?token=<YOUR_AUTH_TOKEN>' \
--header 'Content-Type: application/json' \
--data-raw '{
"provider_id": "4dbeabd6-f397-4375-95d2-a38411e07ed1",
"source": {"type": "tel", "target": "+14155551234"},
"destinations": [{"type": "tel", "target": "+821012345678"}],
"actions": [
{"type": "answer"},
{
"type": "talk",
"option": {
"text": "This is a provider verification call.",
"language": "en-US",
"gender": "female"
}
},
{"type": "hangup"}
]
}'
Observe call outcome
The ProviderCall record is an audit summary — it does not update as the call progresses. Use the standard call API with each ID in call_ids.
$ curl -k --location --request GET 'https://api.voipbin.net/v1.0/calls/9f8e7d6c-5b4a-3c2d-1e0f-abcdef012345?token=<YOUR_AUTH_TOKEN>'
{
"id": "9f8e7d6c-5b4a-3c2d-1e0f-abcdef012345",
"status": "progressing",
"hangup_reason": "",
"metadata": {
"route_provider_ids": ["4dbeabd6-f397-4375-95d2-a38411e07ed1"],
"skip_source_validation": true
},
...
}
Note
AI Implementation Hint
If the call never reaches progressing and ends with hangup_reason: failed immediately, the provider rejected the INVITE. Common causes: hostname unreachable, authentication failure on the provider’s end, source number not on the provider’s allowlist, or destination number not supported by the provider.
Get list of providercalls
Returns records scoped to the authenticated admin’s own customer. Optional provider_id filter narrows to a single provider.
$ curl -k --location --request GET 'https://api.voipbin.net/v1.0/providercalls?token=<YOUR_AUTH_TOKEN>&provider_id=4dbeabd6-f397-4375-95d2-a38411e07ed1'
{
"result": [
{
"id": "b7d1c0f6-9a2e-4b3f-8e2a-1c7d5b8a9e0f",
"provider_id": "4dbeabd6-f397-4375-95d2-a38411e07ed1",
"call_ids": ["9f8e7d6c-5b4a-3c2d-1e0f-abcdef012345"],
...
}
],
"next_page_token": "2026-04-21 23:15:00.000000"
}
Get detail of a providercall
$ curl -k --location --request GET 'https://api.voipbin.net/v1.0/providercalls/b7d1c0f6-9a2e-4b3f-8e2a-1c7d5b8a9e0f?token=<YOUR_AUTH_TOKEN>'
Delete (soft) a providercall
Removes the audit record from list results. Does not affect the underlying Call records.
$ curl -k --location --request DELETE 'https://api.voipbin.net/v1.0/providercalls/b7d1c0f6-9a2e-4b3f-8e2a-1c7d5b8a9e0f?token=<YOUR_AUTH_TOKEN>'
{
"id": "b7d1c0f6-9a2e-4b3f-8e2a-1c7d5b8a9e0f",
"tm_delete": "2026-04-22 00:00:00.000000",
...
}
Troubleshooting
- 403 Forbidden:
Cause: Token belongs to a customer-tier user. ProviderCalls require
PermissionProjectSuperAdmin.Fix: Log in as a platform super-admin or use an admin access key.
- 400 Bad Request — provider not found:
Cause: The supplied
provider_iddoes not exist, or has been soft-deleted.Fix: List providers with
GET /v1/providersand choose a current ID.
- Call immediately hangs up (``hangup_reason: failed``):
Cause: Provider rejected the INVITE. Common reasons: source not on allowlist, destination unsupported, provider auth failed, hostname unreachable.
Fix: Review the provider’s acceptance rules. Try a source number the provider is known to accept. Cross-check the provider’s SIP server health via
GET /v1/providers/{id}(health_statusfield).
- Call reports ``no_answer`` / ``busy``:
Cause: Signaling reached the provider and the destination, but the far-end did not answer or rejected the call.
Fix: This usually means the provider is working correctly — the destination phone’s state is the issue, not the routing.