Skip to main content
POST
/
orders
/
placed
Order placed
curl --request POST \
  --url https://api.privy.com/v1/orders/placed \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '
{
  "order_id": 1001,
  "email": "buyer@example.com",
  "phone": "+12025550123",
  "customer_id": "ext-42",
  "subtotal": 90,
  "discounts": [
    {
      "code": "SAVE10",
      "amount": 10
    }
  ],
  "tax_lines": [
    {
      "title": "VAT",
      "amount": 5
    }
  ],
  "total": 95,
  "currency": "USD",
  "total_items": 2,
  "financial_status": "paid",
  "fulfillment_status": "fulfilled",
  "line_items": [
    {
      "sku": "SKU-1",
      "quantity": 2,
      "price": 45
    }
  ],
  "billing_address": {
    "first_name": "Janet",
    "last_name": "Biller",
    "city": "Boston",
    "state_code": "MA",
    "country_code": "US",
    "postal_code": "02118"
  },
  "shipping_address": {
    "first_name": "Jane",
    "last_name": "Shopper",
    "city": "Boston",
    "state_code": "MA",
    "country_code": "US",
    "postal_code": "02118"
  },
  "accepts_email_marketing": true,
  "accepts_sms_marketing": true,
  "order_date": "2026-06-01T12:00:00Z"
}
'
{
  "data": {
    "order_id": 1001,
    "source": "api",
    "email": "buyer@example.com",
    "phone": "+12025550123",
    "total_amount": "95.00",
    "currency_code": "USD",
    "placed_at": "2026-06-01T12:00:00Z",
    "financial_status": "paid",
    "fulfillment_status": "fulfilled",
    "customer_id": "ext-42",
    "total_items": 2,
    "accepts_email_marketing": true,
    "accepts_sms_marketing": true,
    "created_at": "2026-06-01T12:00:05Z",
    "updated_at": "2026-06-02T09:14:00Z"
  }
}

Authorizations

Authorization
string
header
required

Send either an API token or an OAuth access token as Authorization: Bearer <token>. See the Authentication page for details.

Headers

X-Privy-Integration-Token
string

Optional. The integration token of a Custom Integration, sent in addition to the Authorization: Bearer token, to tie the order to that specific integration. Find it in your Privy dashboard under Settings → Integrations Hub → Connected, or generate a new one in the same Integrations Hub section under Custom Integration.

When omitted and the business has exactly one Custom Integration, the order is auto-tied to it; otherwise no integration is attributed. If the value doesn't match an active Custom Integration for your business, the request returns 422. This token only narrows attribution within the business already established by the bearer token — it is not a standalone credential.

Body

application/json

order_id, total, currency, and order_date are required on every call, plus at least one of email or phone. All other fields are optional; on an update, omitted optional fields keep their previously stored value.

order_id
integer<int64>
required

Your unique identifier for the order. Must be a positive integer (a digits-only string is also accepted). This is the idempotency key: the first call for an order_id creates the order, subsequent calls update it.

Example:

1001

total
number
required

Order grand total. Required.

Example:

95

currency
string
required

ISO 4217 three-letter currency code. Required.

Example:

"USD"

order_date
string<date-time>
required

ISO 8601 date-time the order was placed. Required. Expected to be in UTC (zero offset) — end the timestamp with Z (e.g. 2026-06-01T12:00:00Z).

Example:

"2026-06-01T12:00:00Z"

email
string<email>

Buyer's email. Used to find or create the associated contact. At least one of email or phone is required.

Example:

"buyer@example.com"

phone
string

Buyer's phone number. Loosely formatted input is accepted and normalized to E.164. Required when accepts_sms_marketing is true.

Example:

"+12025550123"

customer_id
string

Your external identifier for the customer.

Example:

"ext-42"

subtotal
number

Order subtotal before tax, shipping, and discounts.

Example:

90

discounts
object[]

Discounts applied to the order.

tax_lines
object[]

Tax lines applied to the order.

total_items
integer

Total number of items in the order.

Example:

2

financial_status
enum<string>

Payment status of the order.

Available options:
authorized,
expired,
paid,
partially_paid,
partially_refunded,
pending,
refunded,
voided
Example:

"paid"

fulfillment_status
enum<string>

Fulfillment status of the order.

Available options:
delivered,
fulfilled,
in_progress,
on_hold,
open,
partially_fulfilled,
pending,
pending_fulfillment,
request_declined,
restocked,
scheduled,
unfulfilled
Example:

"fulfilled"

line_items
object[]

The products purchased.

billing_address
object

A billing or shipping address. Stored and echoed back verbatim. When a new contact is created, its name is taken from the address — shipping first, billing as fallback — using first_name/last_name, or a single name field split on whitespace.

shipping_address
object

A billing or shipping address. Stored and echoed back verbatim. When a new contact is created, its name is taken from the address — shipping first, billing as fallback — using first_name/last_name, or a single name field split on whitespace.

accepts_email_marketing
boolean

Whether the buyer opted into email marketing. Subscribes the contact on signup; never unsubscribes an existing contact.

Example:

true

accepts_sms_marketing
boolean

Whether the buyer opted into SMS marketing. Requires phone. Records an SMS opt-in for newly created contacts only; existing contacts' SMS consent is left untouched.

Example:

true

initial_sync
boolean
default:false

Set to true for bulk historical imports. Suppresses real-time side effects (Flows and other automations, attribution, and order-stat updates) while still recording the order and associating the contact.

Example:

false

Response

Existing order updated.

data
object

An order as persisted. Echoes back the fields you sent (column-backed fields normalized, the rest verbatim). Empty values are omitted from the response.