> ## 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.

# Event history

> List event metadata and retrieve available exact webhook payload bytes for an team or project.

The Platform API records a bounded history of team and project events.
Use it to inspect what happened before checking the related webhook deliveries.
History, webhooks, event streams, `polymorfa listen`, and the MCP event tools
contain only the event types documented in the [webhook reference](/api/webhooks),
plus test events you create.

Team events include customer lifecycle and campaign lifecycle activity:

```http theme={null}
GET /platform/events
GET /platform/events/{eventId}
```

Project events cover activity owned by one project:

```http theme={null}
GET /platform/projects/{projectId}/events
GET /platform/projects/{projectId}/events/{eventId}
```

All four routes require `events:read`. Project credentials can access only the
project routes for their bound project. Team credentials use the
team routes directly and can select a project through the project
route prefix.

## List events

List routes return newest events first. Filter by exact event `type`, `since`,
or exclusive `until`. A page contains at most 100 items and includes an opaque
`nextCursor` when more items remain.

Do not modify or decode a cursor. A cursor is bound to its owner and filters.
Send it with `limit` only; changing the filters returns `invalid_cursor`.

List results never contain payload bytes. Each event reports:

* its team and optional project owner;
* event type, source, environment, and creation time;
* `payloadAvailability`;
* `replayableUntil` when a retained payload remains replayable; and
* `metadataExpiresAt` for the event record itself.

These timestamps are authoritative. Do not assume a fixed retention duration.

## Retrieve payload bytes

Retrieve metadata without content by default. Add `includePayload=true` to ask
for the exact native webhook body:

```bash theme={null}
curl "https://api.polymorfa.com/platform/projects/$PROJECT_ID/events/$EVENT_ID?includePayload=true" \
  -H "Authorization: Bearer $POLYMORFA_KEY"
```

When available and still authorized, `payload` contains base64-encoded bytes
with `encoding: "base64"` and `contentType: "application/json"`. Decode those
bytes without parsing and reserializing them when you need the original body.

A null payload is not reconstructed from metadata. Check
`payloadAvailability` and `replayableUntil` on every response. Disabling the
content-retention grant for the exact source session makes its retained content
unavailable immediately, even if its metadata remains visible.

Event metadata never includes signing secrets, authorization headers, cookies,
raw network errors, or webhook response bodies.

## Replay an event

Replay creates a new logical delivery for one existing event and one webhook:

```http theme={null}
POST /platform/events/{eventId}/replays
POST /platform/projects/{projectId}/events/{eventId}/replays
```

Send `webhookId` in the JSON body and an `Idempotency-Key` header. The route
requires `events:replay`; it does not use the delivery-retry permission. The
event and webhook must have the same owner, and the server rechecks payload
availability in the mutation transaction.

The response immediately identifies the original event, the new delivery, the
asynchronous operation, and the idempotency receipt. It does not wait for the
network attempt to finish. If the exact body is unavailable or past
`replayableUntil`, the request returns `payload_not_replayable` without
creating a delivery.

Replay preserves the original event and every existing delivery. Use delivery
retry when you need another attempt on an existing logical delivery.
