Skip to main content
Use the durable API when a batch is larger than the synchronous limit or may need to wait for a country service. The public API always accepts JSON arrays; CSV remains a panel-only workflow.

Choose the API

The v1 execution budget is 15 seconds. A v1 request that cannot finish within that budget fails as a complete unit; it does not become a hidden background job. Submit the same logical work to v2 when it needs durable execution. The v2 admission budget is 5 seconds. It covers authentication, validation, entitlement, Customer Quota reservation, and enqueueing only; it does not include country execution or internal retries.

Submit a job

Colombia is enabled for durable jobs. After the initial invoice is paid, the organization’s Colombia Country Purchase becomes active immediately and a valid request can return 202 Accepted; no manual activation is required. Normal entitlement, quota, maintenance, and temporary provider-availability checks still apply at admission.
The API returns 202 Accepted:
The identifier is an opaque lowercase UUID. Do not infer a country, organization, tenant, provider, or execution state from it. Tenant identity is internal and is never returned in the public job resource. An exact retry uses the same idempotency key, country, and array. It returns the same job identity and does not reserve Customer Quota again. Active jobs replay as 202; jobs that have already terminalized replay as 200. Reusing the key with a different payload returns 409 idempotency_key_reused.

Poll status

The public state machine is:
queued and running are non-terminal. succeeded, failed, cancelled, and expired are terminal. expired means the job did not terminalize before the 24-hour active-job/input hard cap: Customer Quota is released and input is due for exact-identity cleanup or already verified absent. expires_at is state-dependent: admission plus 24 hours while queued or running; successful terminalization plus 7 days for a succeeded job; and terminalization plus 30 days for failed, cancelled, or expired metadata. A status response never includes provider names, attempt counts, chunks, costs, balances, credentials, or raw provider errors. Poll with bounded backoff and honor Retry-After when it is present. Do not create a new job on every poll or retry an admission with a new key unless you intend to submit a new logical batch.

Retrieve the result

Only a succeeded job has a result. The result uses the same prohibited_numbers_to_call, safe_numbers_to_call, invalid_numbers, and summary model as v1. A job is always complete: the API never presents an internal chunk that failed as a partial success.
  • 409 job_result_not_ready: the job is queued, running, failed, or cancelled. It may include a Retry-After header while queued or running; failed and cancelled jobs are terminal and have no complete result to retrieve. A failed status always includes a JobError; a cancelled status never includes one because cancellation is not an error.
  • 410 job_expired: the job did not terminalize before its 24-hour hard cap; its reservation was released and input cleanup is due or already verified.
  • 410 job_result_expired: the successful result exceeded its seven-day retention window.
  • 404 job_not_found: the job does not exist or belongs to another organization. Both cases intentionally look the same to prevent cross-tenant enumeration.
Unlike v1, v2 temporarily stores the input and successful result encrypted so the job can survive a request ending. An attached input is eligible for purge when the job terminalizes. If an upload finishes with an unknown outcome, its exact canonical object becomes due for revalidation at the 24-hour hard cap. A failed cleanup remains retryable and observable until exact absence is verified. Results and non-phone metadata are purged according to the TTLs above. Every v2 response, including errors, exposes x-retention: transient-encrypted; technical v2 responses also expose the effective per-organization X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset, while 429 responses include Retry-After. The safe technical default is 60 requests per 60-second window; operator overrides are bounded from 1 to 60,000 and are independent of Customer Quota. The public contract does not claim that a government retains or deletes data on the same schedule.

Complete polling example

The API does not deliver webhooks; polling the status resource is the integration model. The examples below submit a batch, poll until the job is terminal while honoring Retry-After and applying bounded backoff with jitter, and retrieve the result only after succeeded.
Generate one idempotency key per logical batch and persist it with your own job record before the first admission attempt. The examples require that persisted value through DNC_LATAM_IDEMPOTENCY_KEY; reuse it only to retry the exact same country and phone array.

Cancel a job

Cancellation is an explicit, idempotent action. A queued job can be cancelled immediately. If a government call is already in progress, cancellation is accepted but the job remains running until its external effect is reconciled. Once reconciliation establishes the provider call’s outcome, the job becomes cancelled, its complete result is discarded, and Customer Quota is released. A job that was already terminal keeps its terminal state. The API never claims that an uncertain call was cancelled, never returns a partial result, and never charges Customer Quota for an incomplete batch.

Country failures and quota

If a country is in a known maintenance window, the job fails with country_service_maintenance. Other temporary country failures use country_service_temporarily_unavailable. Both errors include the country, may include Retry-After, return no partial result, and consume no Customer Quota. A paid country that is still pending_activation is deliberately reported as country_service_temporarily_unavailable; the API never exposes that state, Registry Capacity, provider balance, or prepaid credits. Internal durable classifications map to a closed public error vocabulary: Admission and provider-capacity failures map to the same generic public country/platform errors above. The public contract never exposes provider names, balances, costs, credentials, capacity causes, or raw internal error codes.