Skip to main content
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.

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, 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

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.