POST /v1/calls, scriptId) is replaced by the Requests API
(POST /v1/requests, schemaId). Legacy endpoints sunset on October 1, 2026.
The dialing capability is the same. What changes is the shape of the integration: a
request replaces a call as the unit of work, a
schema replaces a script, and results come back as schema-defined named
fields instead of question-indexed answers.
Several things you might assume are new already exist in the legacy API: the GET /v1/auth token
exchange, structured errors, and definition listing. This guide calls those out so you don’t rebuild
what you already have.
1. At a glance
The base host does not change:
https://robodialer-service-api-9nc4t1p9.uc.gateway.dev. Sandbox and
production continue to use separate credentials against that one host.
2. Authentication
Authentication is unchanged. Both APIs use the sameGET /v1/auth exchange: trade your
long-lived key and secret for a short-lived bearer token, then attach that token to every subsequent
request.
Authorization: Bearer <token>. Tokens are valid for one hour.
No change required if you already exchange credentials at
GET /v1/auth and cache the token
(up to about 55 minutes, refreshing before expiry). Keep your key and secret in a secret store: they are long-lived,
the token is not. See Production vs Sandbox for which
key to use when.3. Submitting work
RenamescriptId to schemaId, post to /v1/requests, and move the dialed number into
inputs.phoneNumber. internalId, internalTag, and webhookUrl carry over unchanged.
Legacy: POST /v1/calls
New: POST /v1/requests
scriptId to schemaId, to to inputs.phoneNumber, callId to requestId,
batchId to requestBatchId. inputs, internalId, and internalTag carry through unchanged.
webhookUrl remains an optional per-request override.
The create response also always carries a payerLookup object describing how the payer and number
were resolved. See Creating a Request for the full
field list.
Batch submission
Rename the wrapper keycalls to requests.
error instead of a
requestId, so check every element. Note two differences from legacy: the per-item error key is
singular error (legacy used plural errors), and the aggregate status code is not simply 207. A
batch returns 200 when every item succeeds, 500 if any item failed with a server error, 207 for
a mix of successes and client errors, and 400 when every item failed with a client error. Treat 500
as “partial results may still be present” rather than “nothing was created”. See
Batch.
4. Discovering inputs and schemas
You can enumerate your provisioned schemas programmatically. This is not new capability: the legacy API already exposesGET /v1/scripts, which returns your scripts as
[{ "id", "type", "name", "createdAt" }]. GET /v1/schemas is its direct replacement. Map id to
schemaId and type to requestType.
phoneNumber appears in
requiredInputs.fields, not as a separate top-level parameter. See
Schemas.
5. Retrieving results
The largest data-model change is the results shape. Legacy answers were keyed by question index. New results are named fields defined by your schema, which removes the positional coupling.Legacy: GET /v1/calls/
New: GET /v1/requests/
Replace any code that reads
results["0"].answer or relies on resultsByAlias or
highLevelOutputs with code that reads named fields from results (for example
results.claimStatus). Use GET /v1/schemas/{schemaId}/required-inputs and your schema
definition to know which field names to expect.data_completeness really is
snake_case among camelCase siblings, and today it is either "minimum" or null. And to is
omitted from the response entirely when SuperDial resolved the number on your behalf, so treat it as
optional rather than always present. See
Single-request vs list response shapes.
States and errors
Legacy was not binary either. Alongside
success and failure it returned processing, plus
cancelled and paused. The mapping is processing to PROCESSING, success to SUCCESS,
failure to FAILURE. The genuinely new state to start handling is PARTIAL.
Note also that PROCESSING is where anything non-terminal lands, including internal error and
cancelled states. A request sitting in PROCESSING indefinitely is not necessarily still dialing.
When a request fails, inspect the structured error:
MEMBER_NOT_FOUND, CLAIM_NOT_FOUND, IVR_FAILURE,
CLAIM_NUMBER_MISSING, and MEMBER_ID_INCORRECT.
errorCategory is one of exactly two values, NOT_FOUND or SYSTEM_ERROR. errorCode is
open-ended: new codes are added over time, so treat an unrecognized code as unclassified rather
than validating against a fixed list. Missing-input codes follow the {FIELD}_MISSING pattern and
incorrect-input codes follow {FIELD}_INCORRECT, which lets you auto-correct and resubmit (for
example re-prompt for a member ID) instead of treating every non-success as a dead end.
Do not construct error codes from field names. The mapping is a fixed table, not a string
transform, and several pairs are asymmetric: the provider address field yields
PROVIDER_FACILITY_LOCATION_MISSING but PROVIDER_ADDRESS_INCORRECT. Match on the codes you
receive, listed in Concepts.error string and an errors object:
errorClass carries values such as OTHER and BAD_NUMBER. Map errorClass to errorCode and
errorCategory, errorJustification to errorMessage, and relevantInputKeys to the new
missingFields. The type change matters: legacy error is a string,
new error is an object. Code that logs error directly will start printing an object.
Listing
GET /v1/requests takes dateFrom and dateTo (YYYY-MM-DD), and the legacy batchId query
parameter is renamed requestBatchId. With no date range and no batch ID, the default window is
today only.
The new endpoint also adds pagination, which legacy did not have: pass pageSize (default 100,
maximum 500) and pageToken, and follow nextPageToken until it is absent. See
Pagination.
As before, transcripts and recording URLs are returned only when fetching a single request by ID,
not in the list. Note that callSummary is present in list responses, so a summary field
appearing in a list is expected rather than a sign you fetched detail.
6. Webhooks
Webhooks still fire on terminal states. The payload field names change, but the signature scheme is unchanged, so your existing verifier keeps working.Configure the Request webhook URL
Set it before you cut production traffic over. In the SuperDial portal, go to API, find the Webhooks section, and fill in Request webhook. Your existing legacy URL appears below it as Legacy webhook URL (/v1/calls), collapsed, and it keeps serving any traffic still going toPOST /v1/calls. Both can be set at once during a phased cutover.
To confirm delivery is working, the same panel shows Recent deliveries (7 days), filterable by
Request ID. If you have submitted requests and that list is empty, the URL is not configured
correctly.
You can also pass webhookUrl in the body of POST /v1/requests to direct a single request
elsewhere. A per-request value wins over the account-level setting, and it is frozen when the
request is created: later changes to the account-level URL do not apply to requests already in
flight. Full detail in Webhooks → Configuration.
If neither is set, poll GET /v1/requests/{requestId} to get results.
Payload
callId to requestId, batchId to requestBatchId, and read state instead of status,
remembering the uppercase values and the new PARTIAL. Both payloads echo internalId and
internalTag only when you supplied them.
Payloads omit timestamps and results. On receipt, call GET /v1/requests/{requestId} to fetch the
full record. Dedupe on requestId (legacy: callId).
Signature verification
Unchanged: HMAC-SHA256 over the raw request body, sent in theX-Webhook-Signature header as a
bare hex digest. The server sends the body already sorted, so you can HMAC the raw request bytes
directly and the same verifier works for both legacy and new webhooks.
The signing secret depends on which credentials created the request. Production requests use your
account webhookSecret if you have set one, otherwise your production API key. Sandbox requests
use your sandbox API key and ignore webhookSecret entirely, which is a common cause of signature
failures when testing.
Because the server emits the body already sorted (json.dumps(payload, sort_keys=True)), re-parsing
and re-serializing with sort_keys=True yields the same bytes as the raw request. That is why one
verifier covers both legacy and new webhooks: you only need to read the renamed fields out of the
parsed payload. Worked Python and Node examples are in
Webhooks → Signature verification.
Delivery and retries
Delivery has two layers. On a 5xx or a connection failure we retry inline up to 3 more times (4 attempts total) with 0.5s, 1s, 2s backoff and a 10 second timeout per attempt. If those fail, the delivery is retried later: a request gets up to 3 delivery rounds within 7 days of reaching its terminal state.Only 400 and 404 stop delivery permanently. Other 4xx responses, including 401 and 403, are
retried across the remaining rounds, because a rotated credential can change the answer. If your
guide or notes say “4xx is terminal”, that is not how it behaves.
7. New capabilities worth adopting
- Modality.
modalitytells you how a result was obtained:digital_only,phone_only,digital_plus_phone, ornullwhen nothing has been dispatched yet. Some requests are now satisfied digitally with no phone call at all. - Idempotency. Resubmitting with the same
internalIdreturns the previously createdrequestIdinstead of duplicating work. See Correlation and idempotency. - Partial results.
PARTIALplusmissingFieldslets you recover the fields that were captured instead of discarding the whole request.
8. Migration checklist
- Set the Request webhook URL in the portal under API, Webhooks, Request webhook. This is separate from your legacy webhook URL and silently sends nothing until configured.
- Auth is unchanged (
GET /v1/auth, one-hour token). Reuse your existing token fetch and cache. - Repoint endpoints:
/v1/callsto/v1/requests,/v1/calls/{id}to/v1/requests/{id},/v1/scripts/...to/v1/schemas/.... - Rename request fields:
scriptIdtoschemaId, batch wrappercallstorequests. - Move the dialed number from top-level
tointoinputs.phoneNumber. - Rename response fields:
callIdtorequestId,batchIdtorequestBatchId, and the list query parameterbatchIdtorequestBatchId. - Rewrite result parsing: read named fields from
resultsinstead of question-index keys,resultsByAlias, orhighLevelOutputs. - Handle
PARTIAL, and readmissingFieldson it rather thanerror, which isnullthere. - Re-read errors from the new
errorobject. It is an object, not a string, anderrorCodeis open-ended. - Handle batch status codes 200, 207, 400 and 500, and read the singular per-item
errorkey. - Add pagination to any list polling:
pageSize,pageToken,nextPageToken. - Update your webhook handler for the new field names and
statevalues. Signature verification needs no change. Dedupe onrequestId. - Validate end to end against sandbox credentials before moving production traffic.