> ## Documentation Index
> Fetch the complete documentation index at: https://docs.polymorfa.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Drains

> Send project logs or hourly number analytics to your HTTPS endpoint.

Drains forward new project data to your own receiver. Open **Project Settings →
Drains** to inspect destinations, delivery status and errors. The [Drains product
page](https://www.polymorfa.com/drains) explains the data sources, destination settings and signed delivery formats.

## Choose the data source

Each drain has one source:

| Source | Data | Configuration |
| - | - | - |
| Logs | API requests, number updates and webhook deliveries | Ordered sampling rules select which new records are forwarded. |
| Analytics | Per-number message, engagement, call and activity aggregates | Choose all project numbers or one number, with a 1-, 24- or 168-hour rolling window. |

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](/console/log-forwarding#receive-deliveries)
for the exact bytes, headers and retry schedule, and
[analytics snapshot fields](/console/analytics-collectors#send-hourly-json-snapshots)
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](/console/analytics-collectors) 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.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.