v1

latestOpenAPI 3.1.02026-07-2671538.5 KB
Orders

Order placed

Send an order to Privy when a customer completes a purchase.

Privy uses order_id to decide whether to create or update the order. The first request for an order_id creates the order and returns 201 Created. Later requests with the same order_id update it and return 200 OK. When updating an order, send its latest data. If you leave out an optional field, Privy keeps its existing value.

Privy links the order to a contact using email. If you do not send an email address, it uses phone instead. If no matching contact exists, Privy creates one.

accepts_email_marketing can subscribe the contact to email but cannot unsubscribe an existing contact. accepts_sms_marketing records an SMS opt-in only for newly created contacts and requires phone. It does not change the SMS consent of an existing contact.

To associate the order with a specific Custom Integration, include the optional X-Privy-Integration-Token header. See the header description below for setup instructions and fallback behavior.

Required scope: orders_write

post/orders/placed

Headers

X-Privy-Integration-Tokenstring

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.

Request body

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

emailstring email

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

phonestring

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

customer_idstring

Your external identifier for the customer.

subtotalnumber

Order subtotal before tax, shipping, and discounts.

totalnumber required

Order grand total. Required.

currencystring required

ISO 4217 three-letter currency code. Required.

total_itemsinteger

Total number of items in the order.

financial_status'authorized' | 'expired' | 'paid' | 'partially_paid' | 'partially_refunded' | 'pending' | 'refunded' | 'voided'

Payment status of the order.

fulfillment_status'fulfilled' | 'in_progress' | 'on_hold' | 'open' | 'partially_fulfilled' | 'pending' | 'pending_fulfillment' | 'request_declined' | 'restocked' | 'scheduled' | 'unfulfilled'

The order's overall fulfillment state (mirrors Shopify's OrderDisplayFulfillmentStatus). Stored on the order but does not affect delivery-based flow triggers — use shipment_status for that.

shipment_status'attempted_delivery' | 'carrier_picked_up' | 'confirmed' | 'delayed' | 'delivered' | 'failure' | 'in_transit' | 'label_printed' | 'label_purchased' | 'out_for_delivery' | 'picked_up' | 'ready_for_pickup'

Carrier delivery status of the shipment (mirrors Shopify's FulfillmentEventStatus). Setting this to delivered triggers any "Order Received" flows for the customer.

accepts_email_marketingboolean

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

accepts_sms_marketingboolean

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.

order_datestring 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).

initial_syncboolean

Set to true for bulk historical imports. Suppresses real-time side effects (Flows and other automations, and campaign-revenue attribution) while still recording the order, associating the contact, and updating the contact's order_count, first_order_at, and last_order_at values.

Example request

{
  "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",
  "shipment_status": "delivered",
  "line_items": [
    {
      "product_id": 1001,
      "variant_id": 1002,
      "sku": "SKU-1",
      "title": "Sample Product",
      "quantity": 2,
      "price": 45
    }
  ],
  "billing_address": {
    "first_name": "Jane",
    "last_name": "Shopper",
    "name": "Jane Shopper",
    "address1": "123 Main St",
    "address2": "Apt 101",
    "city": "Boston",
    "state_code": "MA",
    "country_code": "US",
    "postal_code": "02118"
  },
  "shipping_address": {
    "first_name": "Jane",
    "last_name": "Shopper",
    "name": "Jane Shopper",
    "address1": "123 Main St",
    "address2": "Apt 101",
    "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"
}

Response

Existing order updated.

Example response

{
  "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",
    "shipment_status": "in_transit",
    "customer_id": "ext-42",
    "subtotal": 90,
    "discounts": [
      {
        "code": "SAVE10",
        "amount": 10
      }
    ],
    "tax_lines": [
      {
        "title": "VAT",
        "amount": 5
      }
    ],
    "total_items": 2,
    "line_items": [
      {
        "product_id": 1001,
        "variant_id": 1002,
        "sku": "SKU-1",
        "title": "Sample Product",
        "quantity": 2,
        "price": 45
      }
    ],
    "billing_address": {
      "first_name": "Jane",
      "last_name": "Shopper",
      "name": "Jane Shopper",
      "address1": "123 Main St",
      "address2": "Apt 101",
      "city": "Boston",
      "state_code": "MA",
      "country_code": "US",
      "postal_code": "02118"
    },
    "shipping_address": {
      "first_name": "Jane",
      "last_name": "Shopper",
      "name": "Jane Shopper",
      "address1": "123 Main St",
      "address2": "Apt 101",
      "city": "Boston",
      "state_code": "MA",
      "country_code": "US",
      "postal_code": "02118"
    },
    "accepts_email_marketing": true,
    "accepts_sms_marketing": true,
    "integration": {
      "store_name": "My Store",
      "store_url": "https://mystore.example.com"
    },
    "created_at": "2026-06-01T12:00:05Z",
    "updated_at": "2026-06-01T12:00:05Z"
  }
}