Skip to main content

Opt-Out Lists API

Opt-Out Lists endpoints exposed by the Devotel CPaaS API Base path: /api/v1/messaging/opt-out-lists Endpoint count: 5

title: “Errors worth branching on” description: “Per-endpoint failure templates matching the envelope — what actually fires, what to retry, what to surface to the operator.”

Errors worth branching on

These five failures cover the opt-out add (POST /api/v1/opt-out-lists//entries), hammered from inbound STOP handlers. Each block below is a full { error, meta } envelope as the API returns it, and the matrix at the bottom answers retry vs surface for the same five classes. For the platform-wide decision table these branches plug into, see the error handling guide.

401 — Unauthorized

A 401 on this page is the bearer key failing before the route ran — it never means the resource is wrong. Rotate the key or re-mint the scoped token; retrying the same request changes nothing.

403 — Forbidden

A 403 means the key authenticated but the operation is gated by scope — check the key’s scopes on the developer page; a 403 is never a data-not-found shape.

422 — Schema

A 422 means the payload did not match the request schema — branch on error.details.field and resend with the recipient in E.164 form instead of blind-retrying the same body.

429 — Rate

The Retry-After header and error.details.retry_after are both set on every 429 — resend the SAME request after the lower of the two.

409 — Conflict

Treat as a no-op — the suppression already took; do not surface it as a send-stopper.

60-second retry matrix


List opt-out lists

GET /api/v1/messaging/opt-out-lists
List the tenant’s opt-out lists newest-first with keyset pagination: each list carries its label plus the custom STOP / HELP / START keyword arrays and auto-response copy that a messaging service’s opt_out_list_id merges additively into the platform-default, carrier-mandated keyword sets. Pass limit (default 50, max 100; an over-cap value is clamped), follow meta.pagination.next_cursor for the next page, and set include_deleted=true to also see soft-deleted lists. Use it to hydrate a picker before attaching a list to a messaging service. Empty data is returned when no lists exist yet.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Get opt-out list

GET /api/v1/messaging/opt-out-lists/{id}
Fetch a single opt-out list by id, returning its label, the custom STOP / HELP / START keyword arrays, the per-event auto-response copy overrides, the default response language, the brand tag, and the soft-delete flag with timestamps. Use it to hydrate a detail or edit view, or to validate the opt_out_list_id you set on a messaging service. Returns 404 when the id is not an opt-out list in this tenant.
string
required
—
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Create opt-out list

POST /api/v1/messaging/opt-out-lists
Create an opt-out list — a named bundle of custom STOP / HELP / START keywords plus the auto-reply copy each event answers with — that a messaging service references through opt_out_list_id. The keyword matcher merges these arrays additively into the platform-default, carrier-mandated sets, so lists can only widen the trigger surface, never narrow it (TCPA / CTIA require STOP to stay). Each keyword array is capped at 32 entries of up to 64 chars and each response at 1600 chars; set default_lang (en, tr, de, es, fr, pt, it, ar, nl) and an optional brand tag. Owner / admin only; a duplicate active label returns 409. The returned id is what you store on a messaging service.
string
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the Idempotency-Replay: true response header.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.
string
Display name for the list (1–200 chars, required; unique among active lists).
string[]
Extra keywords that trigger an opt-out (0–32 entries, 1–64 chars each).
string[]
Extra keywords that trigger a help response.
string[]
Extra keywords that opt a contact back in.
string | null
Auto-reply copy sent when STOP matches (up to 1600 chars / 10 SMS segments).
string | null
Auto-reply copy sent when HELP matches.
string | null
Auto-reply copy sent when START matches.
string | null (enum: en|tr|de|es|fr|pt|…)
Default response language for keyword matching.
string | null
Optional brand tag (1–64 chars) stamped into the default response copy.

Update opt-out list

PATCH /api/v1/messaging/opt-out-lists/{id}
Update mutable fields on an opt-out list in place — send only the fields you want to change and at least one is required, so an empty body returns 422. Nullable fields (the three response texts, default_lang, brand) accept null to clear them; keyword arrays replace wholesale, so pass the full intended set. Changes take effect on the next inbound keyword match through the messaging services that reference this list. Owner / admin only; returns 404 when the id is not an opt-out list in this tenant and 409 when the new label collides with an active list.
string
required
—
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.
string
—
string[]
—
string[]
—
string[]
—
string | null
—
string | null
—
string | null
—
string | null (enum: en|tr|de|es|fr|pt|…)
—
string | null
—

Delete opt-out list

DELETE /api/v1/messaging/opt-out-lists/{id}
Soft-delete an opt-out list. The row stays referenceable so messaging services that still point at it and historic audit rows keep resolving the list metadata, while the active-label uniqueness check frees the label for reuse. Use it to retire a list before re-creating a fresh configuration under the same label. Owner / admin only; returns 404 when the id is not an opt-out list in this tenant (or is already deleted) and 204 No Content on success.
string
required
—
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.
Response: 204 No Content