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

# API Changelog

> Updates, additions, and breaking changes to the Privy API.

<Warning>
  This page tracks user-facing changes to the Privy API. Dates reflect the day a change went live in production. For migration help, email [support@privy.com](mailto:support@privy.com).
</Warning>

## 2026-07-03

### Added `POST /v1/events` endpoint (closed beta)

You can send custom events to Privy through the API with the `POST /v1/events` endpoint. Accepted events can trigger **Flows** and other automations, keyed on the `event_type` you send. A successful `200` response means the event was accepted for processing — it does not guarantee a specific automation ran.

The custom events API is in **closed beta**. If you're interested in trying it, reach out to [support@privy.com](mailto:support@privy.com).

***

## 2026-06-22

### Added `POST /v1/orders/placed` endpoint

You can create and update orders through the API with the `POST /v1/orders/placed` endpoint, available under the `orders_write` OAuth scope.

The endpoint is an **idempotent upsert** keyed on `order_id`: the first call for a given `order_id` creates the order and returns `201 Created`, while subsequent calls with the same `order_id` update the existing order and return `200 OK`. Send the full current state of the order on every call — omitted optional fields keep their previously stored values.

* **Required fields:** `order_id`, `total`, `currency`, `order_date`, plus at least one of `email` or `phone`.
* **Customer linkage.** When an `email` or `phone` is provided, Privy finds or creates the matching contact. `accepts_email_marketing` drives email subscribe-on-create semantics, and `accepts_sms_marketing` records an SMS opt-in on newly created contacts (requires `phone`).
* **Historical imports.** Pass `initial_sync: true` to load past orders without triggering real-time side effects such as flows, automations, and campaign-revenue attribution. Customer order stats are still updated so segmentation and winback stay accurate.

### Tie orders to a Custom Integration with `X-Privy-Integration-Token`

`POST /v1/orders/placed` accepts an optional `X-Privy-Integration-Token` header that attributes the order to a specific Custom Integration. Generate the token when you create a Custom Integration in **Settings → Integrations Hub**, and retrieve it later with the **Reveal** action.

* When the header is present, it must match an active Custom Integration for your business.
* When the header is omitted and exactly one Custom Integration exists, the order is automatically tied to it.
* Otherwise, the order is created with no integration attribution.

The header is sent **in addition to** your standard `Authorization: Bearer` OAuth token, which still authenticates the request.

***

## 2026-05-22

### Welcome SMS for API-created SMS subscribers

When you set `sms_consent` to `subscribed` via `POST /v1/contacts` or `PATCH /v1/contacts/{id}`, Privy now automatically sends a TCPA-required welcome SMS to the contact. This only fires when the contact actually transitions to a confirmed opt-in state — contacts that are already subscribed are not messaged again.

To suppress the welcome SMS (for example, when you already collected consent outside of Privy), pass `send_welcome_sms: false` in the request body. The parameter defaults to `true`.

***

## 2026-05-14

### Contact creation conflict responses now include `id`

`POST /v1/contacts` now returns the `id` of the existing contact in `409 Conflict` responses. This lets API consumers identify and update the existing contact without a separate lookup.

***

## 2026-05-12

### Consent vocabulary and PATCH-based consent management

**Breaking changes:**

* **Response field renames.** Contact responses now return `email_consent` and `sms_consent` instead of `email_permission` and `phone_permission`.
* **Filter parameter renames.** The `GET /v1/contacts` query parameters `email_permission` and `phone_permission` have been renamed to `email_consent` and `sms_consent`.
* **New consent values.** The old `non_subscribed` value has been replaced by `never_subscribed`. New values have been added — see below.

**New features:**

* **Consent management via PATCH.** `PATCH /v1/contacts/{id}` now accepts `email_consent` and `sms_consent` fields. You can combine consent changes with other field updates in a single request.
* **Consent on create.** `POST /v1/contacts` now accepts the full set of writable consent values for `email_consent` and `sms_consent`.
* **Expanded email consent values:**
  * `subscribed` — contact opted into email.
  * `unsubscribed` — contact opted out of email.
  * `never_subscribed` — no opt-in, no opt-out (replaces `non_subscribed`).
  * `suppressed` — merchant-suppressed (writable). Writing any consent value to a merchant-suppressed contact unsuppresses it first.
  * `compliance_suppressed` — system-suppressed (read-only, filterable). Any write to a compliance-suppressed contact returns `422`.
* **Expanded SMS consent values:**
  * `subscribed` — contact has confirmed SMS opt-in.
  * `unsubscribed` — contact opted out of SMS.
  * `never_subscribed` — no opt-in, no opt-out (replaces `non_subscribed`).
  * `single_opt_in` — merchant collected a single opt-in (not yet confirmed). Writable; requires a phone number.
  * `pending` — awaiting confirmation reply (read-only, filterable).

**Deprecations:**

* **`POST /v1/contacts/{id}/unsubscribe` is deprecated.** Use `PATCH /v1/contacts/{id}` with `email_consent: "unsubscribed"` instead. The endpoint continues to work but now returns `Deprecation: true` and `Link` headers.
