> ## Documentation Index
> Fetch the complete documentation index at: https://documentation.oryxa.in/llms.txt
> Use this file to discover all available pages before exploring further.

# Create, Retrieve, and Track Orders with the Synq OMS

> Learn how to create, retrieve, and track orders using the Synq Order Management System, including the full order lifecycle and idempotency best practices.

The Synq Order Management System (OMS) gives you a reliable pipeline for every order your business processes. When you create an order, Synq reserves inventory, validates your payment details, confirms the order, and emits downstream events — all without you having to coordinate those steps yourself. You interact with a clean REST API; Synq handles the processing and status updates asynchronously.

## Order lifecycle

Every order moves through a well-defined set of statuses. Understanding these helps you build accurate UI states and support flows.

| Status                | Meaning                                       |
| --------------------- | --------------------------------------------- |
| `pending_payment`     | Order created; awaiting payment authorization |
| `payment_authorized`  | Payment hold confirmed with the provider      |
| `confirmed`           | Order confirmed and ready for fulfillment     |
| `processing`          | Fulfillment is actively in progress           |
| `partially_fulfilled` | Some line items have shipped                  |
| `fulfilled`           | All line items have shipped                   |
| `delivered`           | Carrier confirmed delivery                    |
| `completed`           | Order closed successfully                     |
| `return_requested`    | A return has been initiated for this order    |
| `partially_returned`  | Some line items have been returned            |
| `returned`            | All line items have been returned             |
| `refunded`            | Order has been fully refunded                 |
| `partially_refunded`  | Order has been partially refunded             |
| `cancelled`           | Order cancelled (terminal)                    |
| `failed`              | Order processing failed (terminal)            |

<Note>
  Status transitions are enforced by Synq's order state machine. You cannot skip states or move backwards — for example, a `confirmed` order can only move to `processing` or `cancelled`.
</Note>

## Required headers

Every request to the Synq API requires three headers for tenant isolation and authentication.

| Header          | Description                            |
| --------------- | -------------------------------------- |
| `Authorization` | `Bearer <your_api_token>`              |
| `X-Tenant-ID`   | Your Synq tenant identifier            |
| `X-Org-ID`      | The organization scope for the request |

***

## Create an order

<Steps>
  ### Build your request body

  Construct a JSON payload with your line items, payment details, and a unique idempotency key.

  <Note>
    Always generate a fresh `idempotency_key` for every order attempt. Synq uses this key to deduplicate requests — submitting the same key twice returns the result of the original request instead of creating a duplicate order. A UUID v4 per attempt works well.
  </Note>

  <Warning>
    `payment_provider` and `payment_reference` are both required. If either is missing, the request is rejected with `400 Bad Request`. Capture your payment intent or charge reference from your payment provider (e.g. Stripe `pi_...` or `ch_...`) before calling this endpoint.
  </Warning>

  ```json Request body theme={null}
  {
    "idempotency_key": "01942c3e-7b1a-7f3d-a1c2-4d5e6f708a9b",
    "payment_provider": "stripe",
    "payment_reference": "pi_3OqXyZLkdIwHu7ix0AbCdEfG",
    "channel": "web-storefront",
    "currency": "USD",
    "customer_id": "cus_a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "items": [
      {
        "variant_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
        "location_id": "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d",
        "product_title": "Synq Running Shoe",
        "variant_title": "Size 10 / Black",
        "sku": "SRS-10-BLK",
        "unit_price": 129.99,
        "quantity": 2
      },
      {
        "variant_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
        "location_id": "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d",
        "product_title": "Synq Running Socks",
        "variant_title": "L / White",
        "sku": "SRS-SOCK-L-WHT",
        "unit_price": 14.99,
        "quantity": 3
      }
    ]
  }
  ```

  ### Submit the request

  ```bash theme={null}
  curl -X POST https://api.synq.io/api/v1/oms/orders \
    -H "Authorization: Bearer $SYNQ_API_TOKEN" \
    -H "X-Tenant-ID: $SYNQ_TENANT_ID" \
    -H "X-Org-ID: $SYNQ_ORG_ID" \
    -H "Content-Type: application/json" \
    -d @order.json
  ```

  ### Handle the response

  A successful `200 OK` means the order has been accepted and is now being processed. The response contains a submission acknowledgement. Poll `GET /api/v1/oms/orders/{orderID}` to track status, or listen for `order.confirmed` events via your webhook endpoint.

  ```json Response theme={null}
  {
    "order_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
    "status": "pending_payment"
  }
  ```

  <Tip>
    Store the returned `order_id` alongside your internal order record. Use it to poll for status updates or reference the order in support lookups.
  </Tip>
</Steps>

### Request fields

<ParamField body="idempotency_key" type="string" required>
  A unique key scoped to this order attempt. Synq uses this to prevent duplicate order creation — submitting the same key twice returns the original result. Generate a new UUID v4 for each distinct order attempt.
</ParamField>

<ParamField body="payment_provider" type="string" required>
  The payment provider used for this order. For example: `"stripe"`, `"adyen"`, `"braintree"`.
</ParamField>

<ParamField body="payment_reference" type="string" required>
  The transaction or payment intent ID from your payment provider. For Stripe this is typically a `pi_...` or `ch_...` value.
</ParamField>

<ParamField body="items" type="array" required>
  One or more line items in the order. At least one item is required.

  <ParamField body="items[].product_title" type="string" required>
    Human-readable product name recorded on the order line.
  </ParamField>

  <ParamField body="items[].quantity" type="integer" required>
    Number of units. Must be greater than zero.
  </ParamField>

  <ParamField body="items[].unit_price" type="number" required>
    Price per unit in the order currency. Cannot be negative.
  </ParamField>

  <ParamField body="items[].variant_id" type="string (UUID)">
    The Synq variant UUID. Required for inventory-backed items. When provided, `location_id` is also required.
  </ParamField>

  <ParamField body="items[].location_id" type="string (UUID)">
    The fulfillment location UUID from which inventory will be reserved. Required when `variant_id` is set.
  </ParamField>

  <ParamField body="items[].sku" type="string">
    Optional SKU recorded on the line item for reference.
  </ParamField>

  <ParamField body="items[].variant_title" type="string">
    Optional human-readable variant label (e.g. `"Size 10 / Black"`).
  </ParamField>

  <ParamField body="items[].requires_shipping" type="boolean">
    Whether this line item requires physical shipment. Defaults to `true` when omitted.
  </ParamField>
</ParamField>

<ParamField body="currency" type="string">
  ISO 4217 currency code. Defaults to `"USD"` when omitted.
</ParamField>

<ParamField body="customer_id" type="string (UUID)">
  The Synq customer UUID to associate with this order.
</ParamField>

<ParamField body="channel" type="string">
  The sales channel identifier (e.g. `"web-storefront"`, `"mobile-app"`, `"pos-terminal"`).
</ParamField>

<ParamField body="source_platform" type="string">
  Optional label for the originating platform used for analytics and channel sync.
</ParamField>

***

## List orders

Use `GET /api/v1/oms/orders` to retrieve a paginated list of orders scoped to the authenticated organization.

```bash theme={null}
curl -X GET "https://api.synq.io/api/v1/oms/orders?limit=20&offset=0" \
  -H "Authorization: Bearer $SYNQ_API_TOKEN" \
  -H "X-Tenant-ID: $SYNQ_TENANT_ID" \
  -H "X-Org-ID: $SYNQ_ORG_ID"
```

**Query parameters**

<ParamField query="limit" type="integer">
  Number of orders to return per page. Defaults to `50`; maximum is `100`.
</ParamField>

<ParamField query="offset" type="integer">
  Number of records to skip for pagination. Defaults to `0`.
</ParamField>

```json Response theme={null}
{
  "orders": [
    {
      "id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
      "status": "confirmed",
      "currency": "USD",
      "subtotal": 304.95,
      "discount_total": 0.00,
      "shipping_total": 9.99,
      "tax_total": 24.40,
      "total": 339.34,
      "payment_status": "authorized",
      "payment_provider": "stripe",
      "payment_reference": "pi_3OqXyZLkdIwHu7ix0AbCdEfG",
      "channel": "web-storefront",
      "source_platform": null,
      "idempotency_key": "01942c3e-7b1a-7f3d-a1c2-4d5e6f708a9b",
      "created_at": "2025-06-01T14:22:10Z",
      "updated_at": "2025-06-01T14:22:43Z",
      "tags": []
    }
  ],
  "limit": 20,
  "offset": 0
}
```

***

## Get a single order

Use `GET /api/v1/oms/orders/{orderID}` to retrieve the full detail of one order by its UUID.

```bash theme={null}
curl -X GET "https://api.synq.io/api/v1/oms/orders/f47ac10b-58cc-4372-a567-0e02b2c3d479" \
  -H "Authorization: Bearer $SYNQ_API_TOKEN" \
  -H "X-Tenant-ID: $SYNQ_TENANT_ID" \
  -H "X-Org-ID: $SYNQ_ORG_ID"
```

```json Response theme={null}
{
  "id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
  "status": "fulfilled",
  "currency": "USD",
  "subtotal": 304.95,
  "discount_total": 0.00,
  "shipping_total": 9.99,
  "tax_total": 24.40,
  "total": 339.34,
  "payment_status": "authorized",
  "payment_provider": "stripe",
  "payment_reference": "pi_3OqXyZLkdIwHu7ix0AbCdEfG",
  "channel": "web-storefront",
  "source_platform": null,
  "idempotency_key": "01942c3e-7b1a-7f3d-a1c2-4d5e6f708a9b",
  "created_at": "2025-06-01T14:22:10Z",
  "updated_at": "2025-06-01T15:04:31Z",
  "tags": []
}
```

### Response fields

<ResponseField name="id" type="string">
  The UUID of the order.
</ResponseField>

<ResponseField name="status" type="string">
  Current lifecycle status. See the [order lifecycle](#order-lifecycle) table above.
</ResponseField>

<ResponseField name="currency" type="string">
  ISO 4217 currency code for all monetary values on this order.
</ResponseField>

<ResponseField name="subtotal" type="number">
  Sum of all line item totals before discounts, shipping, and tax.
</ResponseField>

<ResponseField name="discount_total" type="number">
  Total value of discounts applied to the order.
</ResponseField>

<ResponseField name="shipping_total" type="number">
  Total shipping cost applied to the order.
</ResponseField>

<ResponseField name="tax_total" type="number">
  Total tax applied to the order.
</ResponseField>

<ResponseField name="total" type="number">
  Final order total: `subtotal - discount_total + shipping_total + tax_total`.
</ResponseField>

<ResponseField name="payment_status" type="string">
  Payment authorization state, e.g. `"authorized"`.
</ResponseField>

<ResponseField name="payment_provider" type="string">
  The payment provider recorded at order creation.
</ResponseField>

<ResponseField name="payment_reference" type="string">
  The provider transaction ID recorded at order creation.
</ResponseField>

<ResponseField name="channel" type="string">
  The sales channel identifier recorded at order creation.
</ResponseField>

<ResponseField name="source_platform" type="string">
  The originating platform label, if provided at creation. Otherwise `null`.
</ResponseField>

<ResponseField name="idempotency_key" type="string">
  The key you supplied at creation, useful for correlating your internal records.
</ResponseField>

<ResponseField name="created_at" type="string (ISO 8601)">
  UTC timestamp of order creation.
</ResponseField>

<ResponseField name="updated_at" type="string (ISO 8601)">
  UTC timestamp of the most recent status change or update.
</ResponseField>

<ResponseField name="tags" type="array">
  Arbitrary string tags attached to the order.
</ResponseField>
