---
title: "Ingest an event"
method: POST
path: "/events"
tags: ["Events"]
---

# Ingest an event

`POST /events`

Send a custom event to Privy. Use events to trigger **Flows** and other
automations from activity in your own systems (a completed purchase, a
finished quiz, a loyalty milestone, etc.).

Identify the contact with **exactly one** of `email`, `phone`, or `privy_id`.
If the contact doesn't exist yet, Privy creates one (by email or phone);
`privy_id` must reference an existing contact.

## Response status

Unlike most endpoints, a successful ingest returns **`200 OK`** with a
`status` field rather than `201`. A payload that fails validation returns
**`400 Bad Request`** with a top-level `errors` array — a different shape
from the standard `error` envelope used for auth and rate-limit errors.

## Idempotency

Set the `Idempotency-Key` header (or an `idempotency_key` body field; the
header wins if both are present) to safely retry. The first request ingests
the event; a retry with the same key returns the original response with
`idempotent_replay: true` instead of ingesting a duplicate. Only accepted
events are replayed — a rejected payload re-validates on retry.

## Limits

The request body must not exceed **256 KB**; larger bodies return `413`.

**Required scope:** `events_write`

## Headers

- `Idempotency-Key` string

## Request body

- IngestEventRequest — An event to ingest. You must identify the contact with **exactly one** of `email`, `phone`, or `privy_id`, and provide an `event_type`. Everything else is optional. Unknown top-level keys are ignored — put your own data under `event_data`.
  - `email` string, email — The contact's email address. Provide exactly one of `email`, `phone`, or `privy_id` to identify the contact.
  - `phone` string — The contact's phone number in E.164 format (`+` followed by country code and number). Provide exactly one of `email`, `phone`, or `privy_id`.
  - `privy_id` string — The contact's Privy customer ID (the `id` returned by the Contacts API, prefixed with `cus_`). Provide exactly one of `email`, `phone`, or `privy_id`.
  - `event_type` string, required — A name for the event. Up to 128 characters; letters, numbers, hyphens, and underscores only. Choose a stable, descriptive name — you'll use it to trigger Flows (e.g. `purchase_completed`, `quiz_finished`).
  - `event_time` string, date-time — ISO 8601 date-time the event occurred. Must be UTC — end the timestamp with `Z` (or a zero offset). Optional; defaults to the time Privy received the event.
  - `event_data` object — Arbitrary key-value data describing the event. Values may be strings, numbers, booleans, `null`, objects, or arrays. Objects and arrays may be nested up to 10 levels deep. Stored and made available to downstream automations verbatim.
  - `idempotency_key` string — Optional key to safely retry a request without creating a duplicate event. Prefer the `Idempotency-Key` header; if both are sent, the header wins. See the endpoint description for replay semantics.

## Response `200`

The event was accepted, or replayed from a prior request with the same
idempotency key.

- EventAccepted — The event was accepted (or replayed from a prior identical request).
  - `event_id` string — Privy's identifier for the stored event.
  - `status` 'accepted'
  - `idempotent_replay` boolean — Present and `true` only when this response was served from a prior request with the same idempotency key, rather than ingesting a new event.

## Other responses

- `400` — The payload failed validation and was not ingested. Problems are listed in the top-level `errors` array (not the standard `error` envelope).
- `401` — Missing or invalid bearer token.
- `403` — Token lacks the required scope for this endpoint.
- `413` — The request body exceeds the maximum allowed size.
- `429` — Rate limit exceeded. Retry after the specified time.

---

[API](https://skmtc.dev/privy/apis/privy-api.md) · [All operations](https://skmtc.dev/privy/apis/privy-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/privy/privy-api/revisions/5378aff56b9a/schema)
