Skip to main content

Overview

External Compliance Checks are a per-organization product feature: your org can wire a custom HTTPS endpoint into Apten’s send pipeline. Before outbound sends on the channels you select, Apten POSTs a check request to your middleware. If your middleware says the contact is not allowed on that channel, Apten suppresses the send, writes an audit record, and surfaces a COMPLIANCE_BLOCKED event in the conversation timeline and events export. Use this when you have an internal compliance system (state DNC lists, litigator scrubbers, vendor-provided suppression sources, internal customer-preference databases) that must be the source of truth for whether a given lead can be contacted right now.
Apten-managed DNC runs on every outbound SMS and voice call, regardless of these settings. Numbers on Apten’s standing Do Not Contact list are blocked before send. Manage that list via the Do Not Contact API. This feature composes with — it does not replace — Apten’s built-in opt-out handling.

Setup

External compliance is configured per-organization in the Settings → Compliance tab. Only users with the Admin role can change these settings.

Apten-managed DNC

Apten always checks outbound SMS / RCS and voice against our standing DNC list. This is not configurable in the Compliance tab.

Enable the external API

Toggle External compliance API on to POST to your middleware before sends on selected channels.

External API channels

Select which channels (SMS / RCS, Voice, Email) should also be checked against your middleware. Channels you don’t select skip the external check. Unchecking all channels (or turning the external API off) does not disable Apten-managed DNC on SMS and voice.

Failure mode

You must explicitly choose how Apten behaves when your middleware is unreachable, returns a non-2xx response, or times out:
  • Fail Closed — block the send. Safer for regulatory compliance, but a middleware outage will pause outbound traffic. Fail-closed blocks are always temporary: the lead’s follow-up sequence keeps going, and the next send checks your middleware again.
  • Fail Open — allow the send. Avoids dropped sends during outages, but a malfunctioning middleware will not suppress contacts.
There is no system default — the trade-off depends on your regulatory posture.

Endpoint URL

The HTTPS URL of your middleware. Apten will POST every check request here. The URL must use https://.

Signing secret

Apten signs every request with an HMAC-SHA256 of the request body, using a shared secret you control. Your middleware uses this to verify that requests genuinely came from Apten. In the Signing Secret field you can:
  • Generate — produces a random 32-byte base64url secret in your browser and fills the field. Click before saving and copy the value to your middleware.
  • Paste — paste a secret you generated elsewhere.
  • View saved — appears once a secret has been saved. Click to fetch and display the currently saved secret so you can copy it to a new middleware deployment. (Saved secrets are encrypted at rest with AWS KMS and only revealed to admins on demand.)
  • Eye toggle / Copy — show or hide the secret in the field, or copy it to the clipboard.
Leave the field blank when saving to keep the existing secret unchanged.

Timeout

How long Apten waits for your middleware to respond before applying the failure mode. Default 1500ms, configurable from 100ms to 10000ms.

Compliance check API

For every gated send, Apten makes the following request to your endpoint:

Request properties

Only the identifier relevant to the channel is included. SMS / voice checks send only phone; email checks send only email. The unused field is null. This minimizes the PII surface forwarded to your middleware.

Expected response

Apten reads a required top-level allowed boolean and, when blocking, an optional blockType. The minimum valid response is:
or, to block the send:
or, to block only this send and check again next time:
A non-2xx status, a timeout, or a non-boolean allowed field is treated as a provider error — your org’s configured failure mode then decides whether the send proceeds.

Optional extra fields

Anything else you include in the JSON body is recorded verbatim in Apten’s audit row for your own debugging. Apten does not use these fields to make decisions. Two conventional fields:
  • reason — a short tag explaining why you blocked. Stored on Apten’s internal audit row so you can correlate the block back to your own systems if you ever request an audit export.
  • metadata — any additional context you want preserved alongside the audit row.
You don’t need to send these. Apten’s gating decision is allowed; blockType only decides whether a block carries over to future sends.

Permanent and temporary blocks

Every block is either permanent or temporary. Either way, the current send is suppressed and a COMPLIANCE_BLOCKED event is recorded with its blockType. They differ in what happens next: Apten does not schedule extra retries for a temporary block — “next time” means the next send the lead’s sequence or conversation would have made anyway. Blocks are per lead and per channel. A permanent SMS block does not stop email or voice follow-ups; each of those sends is still checked on its own. A permanent block stays in place even if your middleware later starts allowing the lead, because scheduled follow-ups on that channel no longer call your middleware. To lift a permanent block, contact Apten support. If a condition might clear on its own, return a temporary block instead.
A permanent block is the default so existing integrations keep their current behavior. Return "blockType": "temporary" for conditions you expect to clear on their own — for example a pending consent lookup, a per-day contact cap, or an upstream data source that is briefly unavailable.
This applies to the first outreach as well. If the first text, email, or call to a new lead is blocked, the lead’s follow-up sequence still starts: on its normal schedule for a temporary block, or on the next step that uses a different channel for a permanent one.
Voice calls are checked again immediately before dialing. If that check blocks a first-contact or follow-up call, Apten does not place the call. Temporary blocks leave voice eligible for its next normal check; permanent blocks skip voice and continue on any other configured channels. No CALL event is created for a call that was blocked before dialing; the COMPLIANCE_BLOCKED event records the decision. Transfer calls are voice sends, including transfers set up from a text conversation. Apten calls the lead first, so the check uses the voice channel. A permanent voice block stops future transfer calls to that lead as well as regular calls.

Verifying the signature

Apten signs the request body with the same HMAC-SHA256 scheme used for outbound webhooks. Verify in your middleware by recomputing the HMAC using the shared signing secret and comparing it to the X-Signature-SHA256 header.
Every request also carries an X-Apten-Signature header in the form sha256=<hex>. It is the same HMAC value as X-Signature-SHA256 with a scheme prefix. Verify against X-Signature-SHA256 (raw hex) — that is the canonical header for this endpoint.
Always use a constant-time comparison (crypto.timingSafeEqual, hmac.compare_digest, etc.) — never ==. Guard against missing or wrong-length signatures before the comparison; both timingSafeEqual and compare_digest raise when their inputs aren’t both present and of the same length.
Always sign and verify the raw request body bytes, exactly as they arrived on the wire. Re-serializing a parsed JSON object can change whitespace and key ordering and break the signature.

Provider behavior

Apten DNC and external HTTP ordering

Apten-managed DNC runs first on every outbound SMS and voice send (phone-keyed list via the Do Not Contact API). It does not apply to email. If External compliance API is enabled and the channel is in your channels set, Apten then POSTs to your middleware. A DNC block returns before that HTTP call. Provider errors on the HTTP leg follow your Failure Mode; a definitive DNC block is never overridden by fail-open.

Per-channel decisions

Each channel is checked independently. If a lead is blocked on sms but allowed on email, only the SMS send is suppressed. For the first-message Text + Email outreach pattern, a block on one channel does not prevent the other from sending.

No caching

Every send triggers a fresh check against your middleware (the one exception: scheduled follow-ups on a channel with a permanent block are skipped without a check). Apten does not cache responses, because follow-up cadences typically space outbound attempts hours or days apart — a useful cache TTL would expire before the next send anyway. Size your middleware capacity for your peak send volume.

More than one check per send

A single send can reach your middleware more than once, because Apten checks again at each stage before the message or call goes out. A scheduled text is usually checked twice. A call can be checked up to three times: when it is scheduled, when it is queued, and right before dialing. A block at any of these stages stops the send. Two things follow from this:
  • Don’t count check requests as sends. Use leadId and channel to see that requests belong to the same send; triggeredBy shows which stage made each one.
  • Give the same answer for the same lead and channel unless something has actually changed. If your middleware applies per-day contact caps, count the texts and calls that actually went out, not check requests.

Audit log

Every check — allowed or blocked — is written to Apten’s internal audit table including the request, response, source, channel, and timestamp. This is the system of record for SOC 2 evidence. Blocked checks also appear as COMPLIANCE_BLOCKED events on GET /leads/{leadId}/events; allowed checks are audit-only. Contact Apten support if you need a full audit export (including allowed checks) for a specific time range.

Failure modes at a glance

Best practices

  • Always start in fail-open while bringing your middleware online; flip to fail-closed once you’ve watched real traffic and tuned your latency.
  • Keep middleware p99 latency well under your configured timeout. A 1500ms timeout with a 1400ms p99 will produce sporadic fail-mode activations.
  • Rotate the signing secret quarterly from the Settings UI. Use View saved to retrieve the current value before rotation; then Generate, save, and deploy the new value to your middleware.
  • Log the X-Apten-Timestamp header and reject requests older than a few minutes to protect against replay if your endpoint is ever publicly reachable.