List Orders
List a brand's orders from the local synced store, with created_at range, state, billing status, and customer filters.
GET /cdp/commerce/orders — list your brand's orders, scoped to your shop. Orders
are served from the CDP's local synced store (no live Shopify call) and returned in
a normalized, backend-agnostic shape — the raw Shopify payload is never exposed.
Requires the beta:cdp-commerce permission on your brand.
Request
GET /cdp/commerce/orders
Authorization: Bearer vyg_…Query parameters
| Param | Type | Default | Description |
|---|---|---|---|
limit | integer | 25 | Page size, clamped to a maximum of 100. |
offset | integer | 0 | Offset; offset + limit must stay within the 10,000-row window or the request is rejected 400. |
created_at_gte | string | — | Inclusive lower bound on the order's created_at (ISO 8601). |
created_at_lte | string | — | Inclusive upper bound on the order's created_at (ISO 8601). |
state | string | — | Filter by order state: pending, draft, complete, delivered, cancelled. |
billing_status | string | — | Filter by billing status: billable, processing, complete, on_hold. |
customer_email | string | — | Only orders whose contact matches this normalized email. |
customer_phone | string | — | Only orders whose contact matches this phone (normalized to E.164). |
customer_id | string | — | Only orders whose contact matches this Shopify customer id. |
When more than one customer_* filter is supplied, they resolve to a single
customer by precedence (email › Shopify customer id › phone). An identifier that
matches no customer in your brand returns an empty page — never another brand's
orders.
Response 200
{
"list": [
{
"id": "b2c1…",
"external_id": "4501234567890",
"number": "1001",
"state": "complete",
"billing_status": "complete",
"total": "120.00",
"currency_code": "USD",
"customer": { "contact_id": "c9f0…" },
"created_at": "2026-03-02T14:21:00.000Z",
"recovered_at": null
}
],
"totalSize": 1,
"offset": 0,
"pageSize": 25,
"scope": "your-shop.myshopify.com",
"nextCursor": null
}| Field | Type | Description |
|---|---|---|
list | array | The page of normalized orders (summary shape — see Get Order for line items). |
totalSize | integer | Total orders matching the filters. |
offset | integer | Offset this page started at. |
pageSize | integer | Effective page size. |
scope | string | Your brand's connected shop domain. |
nextCursor | string | null | Always null for orders — page with offset. |
Each order's customer.contact_id is the local contacts.id — pass it straight to
Get Customer (GET /cdp/customers/{contact_id}) or
Customer Orders to pull that customer's full record
or history. It resolves with matched_by: "contact_id".
Example
curl -s "https://cdp.vyg.app/cdp/commerce/orders?created_at_gte=2026-01-01&state=complete&limit=25" \
-H "Authorization: Bearer vyg_your_key_here"Errors
| Status | When |
|---|---|
400 | A deep offset past the result window, or an invalid date / state / billing_status value. |
401 | Missing or invalid credential. |
403 | Brand not enrolled in the commerce beta (beta_not_enabled), or no connected Shopify integration (integration_not_connected). |
405 | Non-GET method. |
See Errors for the full envelope and Tenant Isolation & Scope for why cross-brand data is never returned.