Skip to content

Consumers ​

Generated from DialerDigital/core commit 0fc18008b3c8 — spec openapi/dialer-v1.yaml v0.134.0. Do not edit by hand; see How this reference is built. Download the OpenAPI spec.

Español

Debtor card by consumer_ref: debts, DNC / cease-and-desist, Reg F counter and next permitted window, derived from the append-only sources.

Endpoints ​

MethodPathSummary
GET/v1/consumers/{id}Debtor card (debts, DNC / cease-and-desist, Reg F counter, next permitted window)

Debtor card (debts, DNC / cease-and-desist, Reg F counter, next permitted window) ​

http
GET /v1/consumers/{id}

The card of ONE debtor, keyed by consumer_ref — the string core already counts Reg F under ({tenant, consumer_ref, debt_key}). core has no consumers entity and this adds none: the path id is the consumer_ref the CMS sent on POST /v1/debts/import, so the card and the Reg F gate cannot disagree about who "the same debtor" is. "" is the absence of a consumer, never a card.

Everything is DERIVED at request time from the append-only sources (call_attempts, conversations, cease_and_desist, the DNC lists); no counter or cache is added. Each debt is the public projection of GET /v1/debts (masked phone, no account_number) plus the debtor's name (debtor_name, core#1529), its Reg F counter and its own next window. No phone number is published: DNC state is counts per list.

window / next_window answer "when is the next time a call to this debtor is permitted?", in UTC and in the destination's local time. They come from running the REAL gates listed in evaluated_gates over a read-only snapshot, so the instant given is one the dialer itself would permit. They do NOT cover not_evaluated_gates (consent, AI / artificial voice, campaign state, DNC provisioning proofs), which depend on the campaign or on the dial. The answer is fail-closed: permitted_now / scheduled only when a gate run positively permitted that instant; undecidable (with reason) when it cannot decide — unresolvable destination time zone, no contacts, too many numbers to check, a gate that failed, nothing permitted inside the 9-day horizon — and suppressed / not_dialable when the debtor must not be called.

A consumer who exists only in another tenant is 404, indistinguishable from one that does not exist.

Parameters

NameInTypeRequiredDescription
idpathstringyesThe debtor's consumer_ref (1 to 128 characters, not blank, without NUL bytes).

Responses

200 ​

The card.

FieldTypeRequiredDescription
consumerobject (ConsumerCard)yes
consumer.idstringyesThe consumer_ref.
consumer.identityconsumer_refyesWhich key identifies the consumer. core has no consumers entity; this is the key Reg F counts under.
consumer.generated_atstring (date-time)yesThe compliance-clock instant every figure was evaluated at.
consumer.debtsarray of ConsumerDebtyes
consumer.debts_truncatedbooleanyesTrue when the consumer has as many debts as the page cap; the windows are then undecidable (debts_truncated).
consumer.cease_and_desistobjectyes
consumer.cease_and_desist.on_filebooleanyesAny record for the consumer suppresses contact on every debt, as the consent gate reads it.
consumer.cease_and_desist.recordsarray of objectyes
consumer.cease_and_desist.records[].scopeconsumer · debtyes
consumer.cease_and_desist.records[].debt_external_refstringyes
consumer.cease_and_desist.records[].received_atstring (date-time)yes
consumer.dncobjectyesCounts of the consumer's distinct phone numbers on each list. No number is published.
consumer.dnc.contacts_totalintegeryes
consumer.dnc.contacts_checkedintegeryes
consumer.dnc.contacts_listedintegeryes
consumer.dnc.listsobjectyes
consumer.dnc.lists.federalintegeryes
consumer.dnc.lists.stateintegeryes
consumer.dnc.lists.internal_tenantintegeryes
consumer.dnc.lists.internal_globalintegeryes
consumer.dnc.truncatedbooleanyesTrue when the consumer has more numbers than the card checks.
consumer.next_windowobject (ConsumerWindow)yesThe next instant a call is permitted by the time-dependent gates (ConsumerCard.evaluated_gates), or why there is none.
consumer.next_window.statuspermitted_now · scheduled · suppressed · not_dialable · undecidableyespermitted_now: the gates permit a call at generated_at. scheduled: the earliest permitted instant is at. suppressed: a DNC listing or a cease-and-desist forbids contact. not_dialable: the debt's state is not dialable. undecidable: the card cannot decide and says why in reason; it is never read as permission.
consumer.next_window.reasonstring | nullyesNull for permitted_now / scheduled. Otherwise a code such as dnc_listed, cease_and_desist, debt_state_closed, no_contacts, tz_unresolved, too_many_contacts, debts_truncated, none_within_horizon, or the rule_id of the gate that blocked.
consumer.next_window.atstring (date-time) | nullyesEarliest permitted instant (UTC); null when there is none.
consumer.next_window.destination_timezonestring | nullyesIANA zone the quiet-hours gate evaluated first at at.
consumer.next_window.destination_local_timestring (date-time) | nullyesat in destination_timezone, with its UTC offset.
consumer.negotiation_boundsNegotiationBounds | nullyesActive negotiation policy for this tenant's AI agent, or null if none.
consumer.promise_max_horizon_daysintegeryesThe tenant's promise_max_horizon_days (90 by default) — how many days ahead a promise-to-pay may be dated, counted from the current UTC day. Lets a client offer only dates the wrap-up will accept.
consumer.evaluated_gatesarray of stringyesRule ids window / next_window are derived from.
consumer.not_evaluated_gatesarray of stringyesGates window / next_window do NOT cover.

400 — BadRequest ​

Malformed request (shape/type errors, invalid filters, bad timestamps).

json
{
  "error": {
    "code": "bad_request",
    "message": "from must be RFC-3339"
  }
}

401 — Unauthorized ​

Missing, unknown or revoked API key (or, on /v1/admin/*, a bad/unset admin token; on webhooks, a bad/missing signature). A dashboard session (ddu_) that a newer login of the same person ended answers the code session_superseded instead (tenant flag single_session_enforced), so the screen can say why it was signed out; a logout, an expired or an unknown token stay unauthorized.

json
{
  "error": {
    "code": "unauthorized",
    "message": "invalid or revoked API key"
  }
}

404 — NotFound ​

Unknown id, malformed (non-UUID) id OR another tenant's id — RLS returns zero rows, so all three are indistinguishable by design (no existence leak, never a 403 for foreign ids).

json
{
  "error": {
    "code": "not_found",
    "message": "resource not found for this tenant"
  }
}

429 — ApiKeyRateLimited ​

This API key is over its request quota, or the tenant's keys together are over the tenant ceiling (core#2503) (code rate_limited). The request was not processed. Wait Retry-After seconds and retry; a refusal is not counted against the budget, so that wait is always enough. Bounded per API key and, above the keys, per tenant (api_tenant_requests_per_minute): a sibling key is unaffected until the tenant's keys together reach that ceiling. The quota applies to every operation reachable with a dd_ key, so the operations that name a more specific 429 (call control, dispositions, SMS, …) can ALSO answer this one with its X-RateLimit-* headers.

json
{
  "error": {
    "code": "rate_limited",
    "message": "API key request quota exceeded; retry after the interval in Retry-After"
  }
}

Nothing in these docs is legal advice — always confirm compliance posture with your own counsel.