Orders

Report an order placed in your store.

This is an idempotent upsert keyed on order_id: the first call for an order_id creates the order and returns 201 Created; subsequent calls with the same order_id update it and return 200 OK. The order carries the full current state each time — omitted optional fields keep their previously stored value.

The order is associated to a contact by email (or, when no email is sent, by phone), creating the contact if needed.

accepts_email_marketing and accepts_sms_marketing drive the contact's marketing consent — see the field descriptions for the exact semantics.

Optionally send the X-Privy-Integration-Token header to tie the order to a specific Custom Integration (see the header parameter below).

Required scope: orders_write

post/orders/placed

Request

  • Base URL
    https://api.privy.com/v1
  • Auth
    HTTP bearer

Headers

Privy-Account-Idstring

Target a subaccount instead of the main connected account. Pass a subaccount id from get_account's subaccounts list. Only direct subaccounts of the connected account are reachable — omit this for the main account itself.

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, using Shopify's order financial-status vocabulary, which Privy treats as canonical across every source. Privy stores the value and reports it back; no flow or automation is triggered by it.

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

The order's overall fulfillment state — where the order sits in your store's fulfillment process (mirrors Shopify's OrderDisplayFulfillmentStatus). Stored with the order and echoed back, but it drives nothing: delivery-based flow triggers key off shipment_status instead.

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 — where the parcel is (mirrors Shopify's FulfillmentEventStatus). This is the one order status Privy acts on: when a stored order's shipment_status becomes delivered, any "Order Received" flows start for the contact.

Only the change fires the flows. Sending delivered on the call that creates the order counts as a change; repeating it on a later call does not fire them again. initial_sync suppresses this along with the other real-time side effects.

accepts_email_marketingboolean

Whether the buyer opted into email marketing as part of this order.

When true, Privy records email consent for the associated contact — including resubscribing a contact who had previously unsubscribed. Two limits apply: the order must have been placed within the last six months, so a backdated order_date older than that has no consent effect; and a suppressed contact stays suppressed.

When false, nothing is revoked. It never unsubscribes an existing contact and never weakens consent already on record — it only leaves a contact created by this call without email consent. The field has no effect on an order sent with a phone and no email.

accepts_sms_marketingboolean

Whether the buyer opted into SMS marketing as part of this order. Requires phone.

Applies to newly created contacts only: the phone number becomes the contact's, and the opt-in is written to Privy's SMS consent log, which makes the contact textable immediately with no confirmation reply. An existing contact's SMS consent is never changed by this endpoint — use PATCH /v1/contacts/{id} for that.

Because this path bypasses Privy's own opt-in flows, you are responsible for having collected the consent in a TCPA-compliant manner. Unlike the Contacts endpoints, this one sends no welcome text.

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": [
    {
      "sku": "SKU-1",
      "title": "Sample Product",
      "quantity": 2
    }
  ],
  "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",
    "subtotal": 90,
    "discounts": [
      {
        "code": "SAVE10",
        "amount": 10
      }
    ],
    "tax_lines": [
      {
        "title": "VAT",
        "amount": 5
      }
    ],
    "total_items": 2,
    "line_items": [
      {
        "sku": "SKU-1",
        "title": "Sample Product",
        "quantity": 2
      }
    ],
    "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"
  }
}

Changes

    • warning

      added the new forbidden enum value to the / response property for the response status

    • warning

      added the new forbidden enum value to the / response property for the response status

    • warning

      added the new forbidden enum value to the / response property for the response status

    • warning

      added the new forbidden enum value to the / response property for the response status

    • warning

      added the new segment_builder_required enum value to the / response property for the response status

    • warning

      added the new segment_builder_required enum value to the / response property for the response status

    • warning

      added the new segment_builder_required enum value to the / response property for the response status

    • warning

      added the new segment_builder_required enum value to the / response property for the response status

    • breaking

      the // request property type changed from number to string number null

    • breaking

      the // request property type changed from number to string number

    • breaking

      the // request property type changed from number to string number

    • breaking

      the response property // became nullable for the status

    • breaking

      the response property // became nullable for the status

    • breaking

      the response property // became nullable for the status

    • breaking

      the response property // became nullable for the status

    • breaking

      the response property // became nullable for the status

    • breaking

      the response property // became nullable for the status

    • breaking

      the response property // became nullable for the status

    • breaking

      the response property // became nullable for the status

    • breaking

      the response property // became nullable for the status

    • breaking

      the response property // became nullable for the status

    • breaking

      the response property // became nullable for the status

    • breaking

      the response property // became nullable for the status

    • breaking

      the response property // became nullable for the status

    • breaking

      the response property // became nullable for the status

    • breaking

      the response property // became nullable for the status

    • breaking

      the response property // became nullable for the status

    • breaking

      the response property // became nullable for the status

    • breaking

      the response property // became nullable for the status

    • breaking

      the response property /// became nullable for the status

    • breaking

      the response property /// became nullable for the status

    • breaking

      the response property /// became nullable for the status

    • breaking

      the response property /// became nullable for the status

    • breaking

      the response property /// became nullable for the status

    • breaking

      the response property /// became nullable for the status

    • breaking

      the response property /// became nullable for the status

    • breaking

      the response property /// became nullable for the status

    • breaking

      the response property /// became nullable for the status

    • breaking

      the response property /// became nullable for the status

    • breaking

      the response property /// became nullable for the status

    • breaking

      the response property /// became nullable for the status

    • breaking

      the response property // became nullable for the status

    • breaking

      the response property // became nullable for the status

    • breaking

      the response property // became nullable for the status

    • breaking

      the response property // became nullable for the status

    • breaking

      the response property // became nullable for the status

    • breaking

      the response property // became nullable for the status

    • breaking

      the response property // became nullable for the status

    • breaking

      the response property // became nullable for the status

    • breaking

      the response property // became nullable for the status

    • breaking

      the response property // became nullable for the status

    • breaking

      the response property // became nullable for the status

    • breaking

      the response property // became nullable for the status

    • breaking

      the response property // became nullable for the status

    • breaking

      the response property // became nullable for the status

    • breaking

      the response property // became nullable for the status

    • breaking

      the response property // became nullable for the status

    • breaking

      the response property // became nullable for the status

    • breaking

      the response property // became nullable for the status

    • breaking

      the response property /// became nullable for the status

    • breaking

      the response property /// became nullable for the status

    • breaking

      the response property /// became nullable for the status

    • breaking

      the response property /// became nullable for the status

    • breaking

      the / response's property type changed from string to string integer for status

    • breaking

      the / response's property type changed from string to string integer for status

    • breaking

      the /// response's property type changed from number to string number null for status

    • breaking

      the /// response's property type changed from number to string number null for status

    • breaking

      the /// response's property type changed from number to string number for status

    • breaking

      the /// response's property type changed from number to string number for status

    • breaking

      the /// response's property type changed from number to string number for status

    • breaking

      the /// response's property type changed from number to string number for status

    • warning

      added the new api_access_required enum value to the / response property for the response status

    • warning

      added the new api_access_required enum value to the / response property for the response status

    • warning

      added the new api_access_required enum value to the / response property for the response status

    • warning

      added the new api_access_required enum value to the / response property for the response status

    • warning

      added the new contacts_not_ready enum value to the / response property for the response status

    • warning

      added the new contacts_not_ready enum value to the / response property for the response status

    • warning

      added the new contacts_not_ready enum value to the / response property for the response status

    • warning

      added the new contacts_not_ready enum value to the / response property for the response status

    • warning

      added the new no_connected_store enum value to the / response property for the response status

    • warning

      added the new no_connected_store enum value to the / response property for the response status

    • warning

      added the new no_connected_store enum value to the / response property for the response status

    • warning

      added the new no_connected_store enum value to the / response property for the response status

    • warning

      added the new paid_plan_required enum value to the / response property for the response status

    • warning

      added the new paid_plan_required enum value to the / response property for the response status

    • warning

      added the new paid_plan_required enum value to the / response property for the response status

    • warning

      added the new paid_plan_required enum value to the / response property for the response status

    • warning

      added the new store_unavailable enum value to the / response property for the response status

    • warning

      added the new store_unavailable enum value to the / response property for the response status

    • warning

      added the new store_unavailable enum value to the / response property for the response status

    • warning

      added the new store_unavailable enum value to the / response property for the response status

    • info

      added the new optional header request parameter Privy-Account-Id

    • info

      the request property / became nullable

    • info

      the request property / became nullable

    • info

      the request property / became nullable

    • info

      the request property / became nullable

    • info

      the request property / became nullable

    • info

      the request property / became nullable

    • info

      the request property / became nullable

    • info

      the request property / became nullable

    • info

      the request property / became nullable

    • info

      the request property // became nullable

    • info

      the request property // became nullable

    • info

      the request property // became nullable

    • info

      the request property // became nullable

    • info

      the request property // became nullable

    • info

      the request property // became nullable

    • info

      the request property / became nullable

    • info

      the request property / became nullable

    • info

      the request property / became nullable

    • info

      the request property / became nullable

    • info

      the request property / became nullable

    • info

      the request property / became nullable

    • info

      the request property / became nullable

    • info

      the request property / became nullable

    • info

      the request property / became nullable

    • info

      the request property // became nullable

    • info

      the request property // became nullable