Skip to content

Disclosure scripts ​

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

Collection-notice script library (ADR #219): immutable versions per tenant, approved by a sealed event.

Endpoints ​

MethodPathSummary
GET/v1/disclosure-scriptsThe tenant's collection-notice script versions, with their status
POST/v1/disclosure-scriptsWrite a DRAFT version of a collection-notice script
POST/v1/disclosure-scripts/{id}/approveApprove a draft version (sealed in the compliance chain)
POST/v1/disclosure-scripts/{id}/retireRetire an approved version (sealed in the compliance chain)

The tenant's collection-notice script versions, with their status ​

http
GET /v1/disclosure-scripts

Every version of every selector, ordered by jurisdiction, debt_type and then the newest version first. The status comes from the sealed events, never from the version row: a version with no approved event is a draft and never reads as approved. jurisdiction, debt_type and status filter. Readable by any tenant-scope token (a dd_ key or a dashboard login).

Parameters

NameInTypeRequiredDescription
jurisdictionquerystringno
debt_typequerystringno
statusquerydraft · approved · retiredno

Responses

200 ​

The versions.

FieldTypeRequiredDescription
scriptsarray of DisclosureScriptyes
scripts[].idstring (uuid)yes
scripts[].tenant_idstring (uuid)yes
scripts[].kindcollection_noticeyes
scripts[].jurisdictionstringyes
scripts[].debt_typestringyes
scripts[].versionintegeryesPer tenant and selector.
scripts[].textstringyes
scripts[].text_sha256stringyesSHA-256 (lower hex) of text, derived by core.
scripts[].legal_refstringyes
scripts[].authored_bystringyes
scripts[].statusdraft · approved · retiredyesRead from the sealed events; no approved event means draft.
scripts[].approvalDisclosureScriptEvent | nullno
scripts[].retirementDisclosureScriptEvent | nullno
scripts[].created_atstring (date-time)no

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"
  }
}

403 — Forbidden ​

The tenant is suspended. A dashboard session (ddu_) of a tenant whose login policy (ADR 227) is in mode enforce answers 403 with the code login_policy_denied on a request from an address or at an hour the policy does not allow — the same body for both; the session is not revoked and a later request inside the policy goes through. A widget token (ddw_) of a seat is held to the same policy on every request (core#2406, flag widget_login_honors_policy). A synthetic (demo) tenant answers 403 with the code synthetic_tenant on every route that would reach a third party — manual dial, external transfer or conference leg, SMS send (core#2251, ADR #280 addendum). No payment changes it.

json
{
  "error": {
    "code": "forbidden",
    "message": "tenant is suspended"
  }
}

Write a DRAFT version of a collection-notice script ​

http
POST /v1/disclosure-scripts

Creates an immutable draft for the selector (jurisdiction, debt_type); the version number is assigned by core (max + 1 per tenant and selector). A draft is NOT an approved script: it needs POST .../approve. text is at most 10 000 bytes; text_sha256 is derived by core from the text and is never accepted from the client. legal_ref (the citation of the rule or opinion the text rests on) is required and not blank. jurisdiction is a USPS state code or *; debt_type is other, student_loan or *. Unknown fields are 400. The platform does not judge the legal content of the text. Needs a dd_ key or a dashboard login with the account_admin role.

Request body (JSON, required)

FieldTypeRequiredDescription
kindcollection_noticeno
jurisdictionstringyesA USPS state code (upper case) or * for any.
debt_typeother · student_loan · *yes* for any.
textstringyesAt most 10 000 BYTES; not blank.
legal_refstringyesThe citation of the rule or opinion the text rests on; not blank.
json
{
  "jurisdiction": "*",
  "debt_type": "*",
  "text": "Texto del aviso redactado y revisado por el despacho del tenant.",
  "legal_ref": "Dictamen interno 2026-10 del despacho"
}

Responses

201 ​

The draft.

FieldTypeRequiredDescription
scriptobject (DisclosureScript)yesOne immutable version of a collection-notice script and its status.
script.idstring (uuid)yes
script.tenant_idstring (uuid)yes
script.kindcollection_noticeyes
script.jurisdictionstringyes
script.debt_typestringyes
script.versionintegeryesPer tenant and selector.
script.textstringyes
script.text_sha256stringyesSHA-256 (lower hex) of text, derived by core.
script.legal_refstringyes
script.authored_bystringyes
script.statusdraft · approved · retiredyesRead from the sealed events; no approved event means draft.
script.approvalDisclosureScriptEvent | nullno
script.retirementDisclosureScriptEvent | nullno
script.created_atstring (date-time)no

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"
  }
}

403 — DisclosureScriptWriteForbidden ​

A script write was refused. code role_forbidden: the caller is a member login (the route takes a dd_ key or an account_admin login). code forbidden: the tenant is suspended or the token is a widget token.

json
{
  "error": {
    "code": "role_forbidden",
    "message": "approving a disclosure script takes a dd_ key or a dashboard login with the account_admin role"
  }
}

Approve a draft version (sealed in the compliance chain) ​

http
POST /v1/disclosure-scripts/{id}/approve

Writes an append-only approved event and seals it in the tenant's compliance chain in the SAME transaction: if the seal fails nothing is written and the version stays a draft. reviewed_by (the person or firm that reviewed the text) is required. A version that is already approved or retired is 409. Another tenant's version, or a non-UUID id, is 404. Needs a dd_ key or an account_admin login.

Parameters

NameInTypeRequiredDescription
idpathstring (uuid)yesResource UUID. Malformed or cross-tenant ids read as 404.

Request body (JSON, required)

FieldTypeRequiredDescription
reviewed_bystringyes
json
{
  "reviewed_by": "Despacho de ejemplo"
}

Responses

200 ​

The version, now approved.

FieldTypeRequiredDescription
scriptobject (DisclosureScript)yesOne immutable version of a collection-notice script and its status.
script.idstring (uuid)yes
script.tenant_idstring (uuid)yes
script.kindcollection_noticeyes
script.jurisdictionstringyes
script.debt_typestringyes
script.versionintegeryesPer tenant and selector.
script.textstringyes
script.text_sha256stringyesSHA-256 (lower hex) of text, derived by core.
script.legal_refstringyes
script.authored_bystringyes
script.statusdraft · approved · retiredyesRead from the sealed events; no approved event means draft.
script.approvalDisclosureScriptEvent | nullno
script.retirementDisclosureScriptEvent | nullno
script.created_atstring (date-time)no

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"
  }
}

403 — DisclosureScriptWriteForbidden ​

A script write was refused. code role_forbidden: the caller is a member login (the route takes a dd_ key or an account_admin login). code forbidden: the tenant is suspended or the token is a widget token.

json
{
  "error": {
    "code": "role_forbidden",
    "message": "approving a disclosure script takes a dd_ key or a dashboard login with the account_admin role"
  }
}

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"
  }
}

409 — Conflict ​

Invalid state transition, uniqueness conflict, or a seat that is busy/reserved.

json
{
  "error": {
    "code": "conflict",
    "message": "invalid state transition"
  }
}

Retire an approved version (sealed in the compliance chain) ​

http
POST /v1/disclosure-scripts/{id}/retire

Writes an append-only retired event and seals it, like approval. Only an approved version is retired: a draft is 409 (it was never approved) and so is one already retired. reviewed_by is optional here. Another tenant's version, or a non-UUID id, is 404. Needs a dd_ key or an account_admin login.

Parameters

NameInTypeRequiredDescription
idpathstring (uuid)yesResource UUID. Malformed or cross-tenant ids read as 404.

Request body (JSON)

FieldTypeRequiredDescription
reviewed_bystringno

Responses

200 ​

The version, now retired.

FieldTypeRequiredDescription
scriptobject (DisclosureScript)yesOne immutable version of a collection-notice script and its status.
script.idstring (uuid)yes
script.tenant_idstring (uuid)yes
script.kindcollection_noticeyes
script.jurisdictionstringyes
script.debt_typestringyes
script.versionintegeryesPer tenant and selector.
script.textstringyes
script.text_sha256stringyesSHA-256 (lower hex) of text, derived by core.
script.legal_refstringyes
script.authored_bystringyes
script.statusdraft · approved · retiredyesRead from the sealed events; no approved event means draft.
script.approvalDisclosureScriptEvent | nullno
script.retirementDisclosureScriptEvent | nullno
script.created_atstring (date-time)no

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"
  }
}

403 — DisclosureScriptWriteForbidden ​

A script write was refused. code role_forbidden: the caller is a member login (the route takes a dd_ key or an account_admin login). code forbidden: the tenant is suspended or the token is a widget token.

json
{
  "error": {
    "code": "role_forbidden",
    "message": "approving a disclosure script takes a dd_ key or a dashboard login with the account_admin role"
  }
}

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"
  }
}

409 — Conflict ​

Invalid state transition, uniqueness conflict, or a seat that is busy/reserved.

json
{
  "error": {
    "code": "conflict",
    "message": "invalid state transition"
  }
}

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