Documentation topics
Developer docs

Event history

The dashboard's Events and Deliveries pages show stored events, each delivery's status, and individual attempts' HTTP status and timing. Use them to investigate a failing receiver and request manual redelivery.

History remains readable while an agent is paused, has an authentication error, or is disconnected. Reading history does not poll WhatsApp, send a webhook, or create deliveries for events that never had one.

History routes

These routes use the API base URL https://api.unpoll.cc and require a Firebase ID token from dashboard sign-in. Agent API keys cannot call them. Resources are workspace-scoped; unknown and foreign IDs return the same 404 not_found.

MethodRoutePurpose
GET/v1/agents/{id}/eventsStored events with their linked delivery, if any.
GET/v1/agents/{id}/deliveriesDelivery status and metadata.
GET/v1/deliveries/{id}Delivery detail and a paginated attempt history.
POST/v1/deliveries/{id}/retrySchedule manual redelivery of an existing terminal delivery.

They use the shared JSON error shape.

Reading events and attempts

Event and delivery lists accept limit (1–50, default 25) and after (the previous page's opaque next_cursor). Reuse the same filters on subsequent pages; a null next cursor means no further matching rows.

  • Events can be filtered by type (message.received or message.status) and provider occurrence time: inclusive RFC 3339 from, exclusive to.
  • Deliveries can be filtered by status: pending, processing, succeeded, or failed.
  • Delivery detail accepts limit and attempts_after, using next_attempts_cursor to read older attempts.

Lists are ordered by storage time and ID, not the provider's occurrence time. Refresh the first page for new activity; pagination is not a snapshot of an entire live stream.

An event's history payload is the stored provider message or status object, not the signed webhook envelope. Payloads over 16,384 UTF-8 bytes in their database JSON text representation are omitted from this monitoring view: payload is null and payload_omitted is true. The event is still listed, and the original data and frozen webhook body are unchanged. This API has no full-payload download endpoint.

An event's delivery is null if no enabled endpoint existed when it was ingested. Such events cannot be redelivered. Updates before an agent's activation cutoff are not stored at all and therefore never appear in history.

Attempts show lifetime attempt numbers, start time, nullable duration, nullable HTTP status, and a sanitized error code. Missing result fields or lease_expired do not prove that your receiver never saw the request; an acknowledgement may have been lost.

Manual redelivery semantics

Use Deliveries in the dashboard for manual redelivery. For direct authenticated use of POST /v1/deliveries/{id}/retry:

  • Send an empty body, no query parameters, and exactly one Idempotency-Key containing a non-nil, 36-character hyphenated UUID.
  • Generate a new random UUID for each intended redelivery. Reuse that same key after a timeout or uncertain response; do not assume an interrupted request rolled back.
  • A new accepted request returns 202 with delivery_id, redelivery_id, and replayed: false. Repeating the same delivery/key pair returns 200, the original receipt, and replayed: true, without rescheduling.
  • A new request requires a succeeded or failed delivery and an enabled endpoint. Pending or processing deliveries return 409 not_terminal; a disabled endpoint returns 409 endpoint_disabled.

The receipt means scheduling was accepted, not that the receiver acknowledged a delivery. Check delivery detail for current status.

Manual redelivery starts a fresh bounded retry cycle but preserves the event ID, delivery ID, exact frozen body bytes, and all prior attempt history. It does not repoll WhatsApp. Receivers must continue deduplicating: delivery is still at least once.

Retention

Events, deliveries, attempts, and redelivery audit history are kept for 7 days after the delivery's last activity, then deleted by the retention sweep. A retry, completion, or manual redelivery restarts that activity period. Events with no delivery are retained for 7 days after ingestion.

Once deleted, history is not available and the delivery cannot be redelivered. Store the events your application needs independently; the dashboard is not a permanent archive. The provider's separate 30-day media lifetime does not extend Unpoll's event retention.