Skip to main content
Drains forward new project data to your own receiver. Open Project Settings → Drains to inspect destinations, delivery status and errors. The Drains product page explains the data sources, destination settings and signed delivery formats.

Choose the data source

Each drain has one source: Analytics must be enabled before enabling an analytics drain. Logs do not require Analytics. Neither source includes message bodies, contact identities or credentials. Analytics snapshots are prepared hourly for the latest completed UTC hour. Overlapping rolling windows are observations; adding them double-counts activity.

Add a destination

Team owners and admins manage drains. Members see drain metadata with destination URLs and custom-header names hidden. A project supports up to five drains across both sources.
  1. Select Add drain and choose Logs or Analytics.
  2. Select Custom endpoint and enter a name and public HTTPS URL.
  3. Choose JSON or NDJSON. A signing secret is generated; copy it to your receiver before saving. You can replace it, regenerate it or clear it for unsigned delivery.
  4. Add custom headers if your receiver requires them.
  5. Select Add drain.
For Analytics, also choose the number scope and rolling window. Source, number scope, window and encoding are fixed when created; create a new drain to change them. Saved signing secrets and custom-header values are not returned in the configuration view. Native integrations are marked Coming soon.

Accept a delivery

Your receiver gets an HTTPS POST. JSON uses application/json and a {version, deliveryId, records} envelope. NDJSON uses application/x-ndjson and one newline-terminated {version, deliveryId, record} envelope.
  • When a signing secret is configured, verify HMAC-SHA256 over the timestamp, a period and the original request body. Include NDJSON’s trailing newline. Reject stale timestamps and compare in constant time. Unsigned deliveries have no Polymorfa HMAC signature.
  • Deduplicate by Idempotency-Key, which matches deliveryId.
  • Return 2xx after accepting the record durably. Delivery is at least once.
  • Other responses and connection failures use bounded retries, with at most six attempts and no later than 24 hours after queueing.
See delivery envelopes and signature verification for the exact bytes, headers and retry schedule, and analytics snapshot fields for the analytics payload.

Inspect and pause

The destination list shows enabled or paused status, pending and failed counts, and the latest recorded HTTP status or error. Pause stops new queue entries and delivery claims; an in-flight request can finish. Resume continues eligible queued deliveries. Delete removes the drain and its queued deliveries. Disabling Analytics deletes queued analytics snapshots and stops new collection. Re-enabling starts a new consent period. Data already accepted by your receiver follows your own retention policy.

Collect metrics instead

Use the OpenTelemetry setup when your destination expects OTLP metrics. Its Prometheus receiver pulls windowed gauges; a drain pushes Polymorfa’s JSON or NDJSON envelopes. They use different receiver formats.

Device and conversation data

Analytics snapshots include deviceAnalytics and conversationBreakdown for each scoped number and the combined summary. Joint conversation rows retain the completion bucket, calling code, message type, length band, send source, observed customer device-count class, outcome counts and total reply latency. They contain no message content or recipient identities. A drain sends the scoped snapshot. Apply category predicates to its joint rows to build your own filtered views. JSON and NDJSON carry the same data fields.