Manage destinations
The/v1/destinations API supports list, get, create, patch and delete. Reads require
destinations:read; writes require destinations:write (admin or owner). Credentials go in
headers; auth_type describes the authentication style and does not synthesize an Authorization
header. URLs are readable by organization members: keep secrets in headers, not URL query strings.
/v1/destinations with a unique Idempotency-Key. All responses replace header
values with •••. A PATCH omitting headers preserves credentials; a supplied object replaces the
entire header set, and {} clears it. Sending masked values back is rejected. Unknown fields,
invalid enums and numeric limits produce 422 validation_failed, before database writes. Invalid
compiled modal content returns 400. Bodies over 256 KiB are rejected with 413.
DELETE returns 409 while a current template version references the destination, including a
modal submission webhook configured on a button. Old sent messages and draft/historical versions
are not protected by that check: deleting their destination makes subsequent clicks fail. Historical
interaction logs remain, with the deleted destination ID set to null. To stop dispatch deliberately,
PATCH is_active: false. Existing runtime dispatch already checks active status.
Signed destination tests
POST /v1/destinations/{id}/test accepts { "signing_secret": "YOUR_SHARED_TEST_SECRET" } and an
optional Idempotency-Key. This dispatches one real request using the destination’s method and
stored headers, with a generated lithoblocks.destination_test payload. It does not spend a message
credit or retry automatically. The receiver’s HTTP status and elapsed milliseconds are returned;
its response body is discarded. A completed non-2xx response returns delivered: false with that
status. A transport failure, timeout or blocked redirect returns HTTP 502: delivery is uncertain,
and an idempotency key retains that outcome for reconciliation.
Tests are available only for HTTPS receiver hosts enabled for your environment. IP addresses, alternate ports, URL credentials, and redirects are not allowed. If your receiver is not enabled, contact support. A destination test sends a real request; use an endpoint you control.
The receiver verifies X-Lithoblocks-Signature: v1=<hex> as HMAC-SHA256 over
v1:<X-Lithoblocks-Timestamp>:<raw request body>. Compare signatures in constant time and reject
stale timestamps/reused test IDs. A secret supplied in the request body is never stored or returned;
omit it to sign the test with the destination’s stored signing secret, and if the destination has
none, the test is refused with 409 rather than sent unsigned.
Signing ordinary deliveries
Setsigning_secret on a destination (16–512 characters) and every dispatch to it is signed with
the same scheme — button clicks and modal submissions alike, not just tests:
signing_secret_set: true instead. Omitting the field on a PATCH preserves it; null removes it.
Rotating is a PATCH with the new value, so add the new secret to your receiver as an accepted
alternative before rotating, and drop the old one afterwards.
Verify it over the raw body as received, before any JSON parsing or re-serialisation — the
signature covers the exact bytes sent:
X-Lithoblocks-* name; those are reserved so
a configured header cannot forge or displace a signature. Destinations without a signing secret are
delivered exactly as before, unsigned, authenticated only by whatever headers they carry — so
receivers that need proof of sender should set one.
See Webhook destinations for UI setup and payload variables for action payloads.
