Skip to main content

FrequencyCaps API

Send-frequency throttling policy per contact / channel Base path: /api/v1/frequency-caps 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 frequency-cap upsert (POST /api/v1/frequency-caps), saved from every quiet-hours form. 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 one of minute, hour, day, week for the window 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

Patch the existing rule or narrow the scope — a retry creates no new rule.

60-second retry matrix


List per-org frequency-cap rules

GET /api/v1/frequency-caps
Returns every frequency-cap rule configured for the calling organization, newest first. Frequency caps throttle how many messages one contact may receive within a rolling time window (per-channel, or across all channels when scope is global). Use this to review the rules in effect before adding a new one.
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 a single frequency-cap rule

GET /api/v1/frequency-caps/{id}
Retrieve one frequency-cap rule by its id, scoped to the calling organization. Use this to inspect the rule’s window length, send quota, and channel scope before updating or deleting it.
string
required
Frequency-cap rule id.
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 a new frequency-cap rule

POST /api/v1/frequency-caps
Create a rule that limits how many messages a contact may receive within a rolling window. A channel-scoped rule (default) counts sends for one channel; a global rule aggregates the contact’s sends across every channel into one counter (e.g. no more than 3 marketing messages per day, regardless of channel). Optionally restrict the rule to message categories. Requires owner, admin, or developer role.
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.

Update a frequency-cap rule

PATCH /api/v1/frequency-caps/{id}
Update an existing frequency-cap rule — change its window length, send quota, category filter, or toggle it enabled/disabled. At least one field must be provided. Requires owner, admin, or developer role.
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.

Delete a frequency-cap rule

DELETE /api/v1/frequency-caps/{id}
Delete a frequency-cap rule by id. Deletion takes effect immediately (the service’s 30-second cap-list cache is invalidated). Requires owner, admin, or developer role. Returns 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.