SALAF EMSDevelopers
salafems.com

Orders

Orders with their totals, status and payment state. Compact by default; expand items and the customer when you need them.

Paste a key and every snippet on this page switches from the placeholder to your key — and the Try it panel under each endpoint is ready to send. It is stored in this browser only and goes nowhere except, if you press Send, straight to the API host you pick there.

List orders

GET/ext/v1/ordersorders:read

Compact by default. Add ?expand=customer,items for the full object. updated_after is the sync filter — it catches orders placed before your last poll but changed since.

Query parameters

NameTypeDescription
limitnumberdefault 25max 100Page size.
starting_afterstringReturn the page AFTER this object id (the previous page's next_cursor).
ending_beforestringReturn the page BEFORE this object id.
sortstringdefault -created_atNewest first by default. Only created_at is sortable — a cursor over a mutable key (like updated_at) cannot page reliably. Use updated_after to sync changes.created_at-created_at
store_idstringRestrict to one store. Required breadth control for company-scoped keys; on a store-scoped key it must match the key's own store.
statusstringFilter to one of the values below.pendingfollow_upconfirmedprocessingready_to_shipin_transitdeliveredreturnedfailed_deliverycancelledholdspam
payment_statusstringFilter to one of the values below.unpaidpartially_paidpaidrefunded
fulfillment_statusstringFilter to one of the values below.unfulfilledpartially_fulfilledfulfilledreturned
channelstringSales channel SLUG (the stable per-store key), not its id.
created_afterdate-timeISO-8601 timestamp. Inclusive lower bound.
created_beforedate-timeISO-8601 timestamp. Exclusive upper bound.
updated_afterdate-timeOnly orders changed since this instant. THE sync filter: an order placed last month and confirmed this morning is exactly the row a created_after poll would miss.
searchstringMatch on order number, customer name or customer phone.
expandstring[]Include related objects. Allowed: customer, items. Comma-separated, one level. Omitted by default so a sync walking pages stays cheap.

Request

export SALAF_API_KEY="salaf_sk_YOUR_API_KEY"

curl -sS "https://api.salafems.com/ext/v1/orders?limit=25&updated_after=2026-08-01T00%3A00%3A00Z&expand=customer%2Citems" \
  -H "Authorization: Bearer $SALAF_API_KEY"
Try itruns from your browser
GEThttps://api.salafems.com/ext/v1/orders?channel=facebook

Stored in this browser only and never sent anywhere except to the API host you picked above — these pages are static files with no server behind them.

Query parameters

Blank fields are left out of the request.

Paste a key above to enable Send.

Responses

  • 200A cursor page of orders.
  • 401Missing/invalid API key, revoked or expired key, plan without API access, or a dead store.
  • 403The key's scopes do not cover this endpoint.
  • 422Validation failed — error.fields maps each offending field to its messages.
  • 429Rate limit exceeded for this key. Honor Retry-After and the X-RateLimit-* headers.

Every failure uses the one error envelope — Errors lists each code and what to do with it.

Example 200 response
{
  "data": [
    {
      "id": "5f7d2f60-0d1c-4b3a-9a68-6f4d21f6a001",
      "store_id": "5f7d2f60-0d1c-4b3a-9a68-6f4d21f6a001",
      "number": "ORD-20260811-1042",
      "source": "api",
      "channel": {
        "id": "5f7d2f60-0d1c-4b3a-9a68-6f4d21f6a001",
        "name": "Facebook",
        "slug": "facebook",
        "type": "facebook"
      },
      "customer_id": "5f7d2f60-0d1c-4b3a-9a68-6f4d21f6a001",
      "location_id": null,
      "status": "pending",
      "payment_status": "unpaid",
      "fulfillment_status": "unfulfilled",
      "subtotal": "1250.00",
      "discount_amount": "1250.00",
      "shipping_charge": "1250.00",
      "tax_amount": "1250.00",
      "total_amount": "1250.00",
      "paid_amount": "1250.00",
      "due_amount": "1250.00",
      "refunded_amount": "1250.00",
      "shipping_address": null,
      "coupon": null,
      "custom_fields": null,
      "note": null,
      "delivered_at": "2026-08-11T10:00:00.000Z",
      "created_at": "2026-08-11T10:00:00.000Z",
      "updated_at": "2026-08-11T10:00:00.000Z"
    }
  ],
  "meta": {
    "has_more": true,
    "next_cursor": "5f7d2f60-0d1c-4b3a-9a68-6f4d21f6a001"
  }
}

Create an order

POST/ext/v1/ordersorders:write

Runs the SAME order-creation core as the dashboard and storefront: availability-checked stock reservation, coupon engine, totals math and plan-quota metering are all inherited, never re-implemented. Lines reference variants by id or SKU; the customer is an existing id or a find-or-create by phone. Price overrides are honored — this is a trusted-merchant surface. Company-scoped keys must send store_id.

Headers

NameTypeDescription
Idempotency-KeyrequiredstringREQUIRED. A unique value per logical request (a UUID is ideal); reuse it verbatim when retrying. A retry replays the original response with Idempotent-Replayed: true instead of running twice.

Body parameters

NameTypeDescription
store_iduuidTarget store. REQUIRED with a company-scoped key; with a store-scoped key it may only repeat the key's own store.
channelstringA sales-channel SLUG for attribution. Defaults to the store's manual channel (Decision Q11 — tagging is optional, never forced).
location_iduuidLocation (warehouse) to allocate stock from. Defaults to the company's default location — the admin-desk rule.
customer_iduuidAn existing customer. Provide this OR customer.
customerCreateOrderCustomerDtoFind-or-create by phone. Provide this OR customer_id.
itemsrequiredCreateOrderLineDto[]
shipping_addressobjectFree-form shipping address object, stored verbatim.
shipping_chargenumberDelivery charge as YOUR system computed it (trusted surface). A free-shipping coupon still zeroes it. Default 0.
tax_amountnumber
coupon_codestringPriced and redeemed by the same engine as every other surface; an unusable code fails the order rather than mispricing it.
notestring
paymentCreateOrderPaymentDtoAn upfront settled payment (like the admin desk's "paid amount"). Omit for an unpaid order; record later payments via POST /v1/orders/{id}/payments.

customer fields

NameTypeDescription
phonerequiredstringBangladeshi mobile, any accepted spelling — stored canonical. THE find-or-create match key.
full_namestringRequired when the phone matches no existing customer (a new record needs a name); ignored when one exists — a sale never silently renames a customer.
emailstring

items[] fields

NameTypeDescription
variant_iduuidThe variant to sell. Provide this OR sku.
skustringResolve the variant by SKU instead of id.
quantityrequirednumber
unit_pricenumberOverride the regular unit price (trusted surface). Omitted = the variant's current catalog price — the admin-desk rule, verbatim.
discount_pricenumberOverride the discounted unit price. Only honored when it is a REAL discount (above 0, below the regular price) — same rule as the desk.

payment fields

NameTypeDescription
payment_method_iduuidOne of the store's payment methods (must be active).
amountrequirednumber
transaction_idstring

Request

export SALAF_API_KEY="salaf_sk_YOUR_API_KEY"

curl -sS -X POST "https://api.salafems.com/ext/v1/orders" \
  -H "Authorization: Bearer $SALAF_API_KEY" \
  -H "Idempotency-Key: e7a1…-your-uuid" \
  -H "Content-Type: application/json" \
  -d '{
  "channel": "facebook",
  "customer": {
    "phone": "01712345678",
    "full_name": "Rafiqul Islam"
  },
  "items": [
    {
      "sku": "TSHIRT-RED-M",
      "quantity": 2
    }
  ],
  "shipping_charge": 120,
  "note": "Deliver after 6pm."
}'
Try itruns from your browser
POSThttps://api.salafems.com/ext/v1/orders

Stored in this browser only and never sent anywhere except to the API host you picked above — these pages are static files with no server behind them.

Valid JSON
Idempotency-Keyrequired
generating…

A new value is generated whenever you edit this request, and kept while you do not — so sending twice without changing anything is a real retry and comes back Idempotent-Replayed: true instead of writing again.

Paste a key above to enable Send.

Responses

  • 201The created order, in the same shape as GET /v1/orders/{id} with customer and items expanded.
  • 401Missing/invalid API key, revoked or expired key, plan without API access, or a dead store.
  • 403Missing scope, or the plan order quota is exhausted (plan_limit_reached).
  • 409A request with this idempotency key is still in flight (IDEMPOTENCY_IN_FLIGHT).
  • 422Validation failed — error.fields maps each offending field to its messages.
  • 429Rate limit exceeded for this key. Honor Retry-After and the X-RateLimit-* headers.

Every failure uses the one error envelope — Errors lists each code and what to do with it.

Example 200 response
{
  "id": "5f7d2f60-0d1c-4b3a-9a68-6f4d21f6a001",
  "store_id": "5f7d2f60-0d1c-4b3a-9a68-6f4d21f6a001",
  "number": "ORD-20260811-1042",
  "source": "api",
  "channel": {
    "id": "5f7d2f60-0d1c-4b3a-9a68-6f4d21f6a001",
    "name": "Facebook",
    "slug": "facebook",
    "type": "facebook"
  },
  "customer_id": "5f7d2f60-0d1c-4b3a-9a68-6f4d21f6a001",
  "location_id": null,
  "status": "pending",
  "payment_status": "unpaid",
  "fulfillment_status": "unfulfilled",
  "subtotal": "1250.00",
  "discount_amount": "1250.00",
  "shipping_charge": "1250.00",
  "tax_amount": "1250.00",
  "total_amount": "1250.00",
  "paid_amount": "1250.00",
  "due_amount": "1250.00",
  "refunded_amount": "1250.00",
  "shipping_address": null,
  "coupon": null,
  "custom_fields": null,
  "note": null,
  "delivered_at": "2026-08-11T10:00:00.000Z",
  "created_at": "2026-08-11T10:00:00.000Z",
  "updated_at": "2026-08-11T10:00:00.000Z",
  "items": [
    {
      "id": "5f7d2f60-0d1c-4b3a-9a68-6f4d21f6a001",
      "product_id": "5f7d2f60-0d1c-4b3a-9a68-6f4d21f6a001",
      "variant_id": "5f7d2f60-0d1c-4b3a-9a68-6f4d21f6a001",
      "product_name": "Classic Cotton T-Shirt",
      "variant_name": "Red / M",
      "sku": "TSHIRT-RED-M",
      "quantity": 2,
      "unit_price": "1250.00",
      "discount_price": "1250.00",
      "subtotal": "1250.00"
    }
  ],
  "customer": {
    "id": "5f7d2f60-0d1c-4b3a-9a68-6f4d21f6a001",
    "full_name": "Rafiqul Islam",
    "email": null,
    "phone": "01712345678",
    "type": "manual",
    "status": "active"
  }
}

Get an order by id

GET/ext/v1/orders/{id}orders:read

Add ?expand=customer,items for the related objects.

Path parameters

NameTypeDescription
idrequireduuidThe order id.

Query parameters

NameTypeDescription
expandstring[]
store_idstringRestrict the lookup to one store (company-scoped keys).

Request

export SALAF_API_KEY="salaf_sk_YOUR_API_KEY"

curl -sS "https://api.salafems.com/ext/v1/orders/REPLACE_WITH_ID?expand=customer%2Citems" \
  -H "Authorization: Bearer $SALAF_API_KEY"
Try itruns from your browser
GEThttps://api.salafems.com/ext/v1/orders/5f7d2f60-0d1c-4b3a-9a68-6f4d21f6a001

Stored in this browser only and never sent anywhere except to the API host you picked above — these pages are static files with no server behind them.

Path parameters

Query parameters

Blank fields are left out of the request.

Paste a key above to enable Send.

Responses

  • 200The order.
  • 401Missing/invalid API key, revoked or expired key, plan without API access, or a dead store.
  • 403The key's scopes do not cover this endpoint.
  • 404Order not found.
  • 422Validation failed — error.fields maps each offending field to its messages.
  • 429Rate limit exceeded for this key. Honor Retry-After and the X-RateLimit-* headers.

Every failure uses the one error envelope — Errors lists each code and what to do with it.

Example 200 response
{
  "id": "5f7d2f60-0d1c-4b3a-9a68-6f4d21f6a001",
  "store_id": "5f7d2f60-0d1c-4b3a-9a68-6f4d21f6a001",
  "number": "ORD-20260811-1042",
  "source": "api",
  "channel": {
    "id": "5f7d2f60-0d1c-4b3a-9a68-6f4d21f6a001",
    "name": "Facebook",
    "slug": "facebook",
    "type": "facebook"
  },
  "customer_id": "5f7d2f60-0d1c-4b3a-9a68-6f4d21f6a001",
  "location_id": null,
  "status": "pending",
  "payment_status": "unpaid",
  "fulfillment_status": "unfulfilled",
  "subtotal": "1250.00",
  "discount_amount": "1250.00",
  "shipping_charge": "1250.00",
  "tax_amount": "1250.00",
  "total_amount": "1250.00",
  "paid_amount": "1250.00",
  "due_amount": "1250.00",
  "refunded_amount": "1250.00",
  "shipping_address": null,
  "coupon": null,
  "custom_fields": null,
  "note": null,
  "delivered_at": "2026-08-11T10:00:00.000Z",
  "created_at": "2026-08-11T10:00:00.000Z",
  "updated_at": "2026-08-11T10:00:00.000Z",
  "items": [
    {
      "id": "5f7d2f60-0d1c-4b3a-9a68-6f4d21f6a001",
      "product_id": "5f7d2f60-0d1c-4b3a-9a68-6f4d21f6a001",
      "variant_id": "5f7d2f60-0d1c-4b3a-9a68-6f4d21f6a001",
      "product_name": "Classic Cotton T-Shirt",
      "variant_name": "Red / M",
      "sku": "TSHIRT-RED-M",
      "quantity": 2,
      "unit_price": "1250.00",
      "discount_price": "1250.00",
      "subtotal": "1250.00"
    }
  ],
  "customer": {
    "id": "5f7d2f60-0d1c-4b3a-9a68-6f4d21f6a001",
    "full_name": "Rafiqul Islam",
    "email": null,
    "phone": "01712345678",
    "type": "manual",
    "status": "active"
  }
}

Cancel an order

POST/ext/v1/orders/{id}/cancelorders:write

Sugar for the cancelled transition: same map, same stock unwind (release an open reservation, reverse a committed sale).

Path parameters

NameTypeDescription
idrequireduuidThe order id.

Headers

NameTypeDescription
Idempotency-KeystringOptional, but honored: send it to make retries of this request safe.

Body parameters

NameTypeDescription
store_iduuidTarget store. REQUIRED with a company-scoped key; with a store-scoped key it may only repeat the key's own store.
notestringRecorded on the order's timeline.

Request

export SALAF_API_KEY="salaf_sk_YOUR_API_KEY"

curl -sS -X POST "https://api.salafems.com/ext/v1/orders/REPLACE_WITH_ID/cancel" \
  -H "Authorization: Bearer $SALAF_API_KEY" \
  -H "Idempotency-Key: e7a1…-your-uuid" \
  -H "Content-Type: application/json" \
  -d '{
  "note": "Customer changed their mind."
}'
Try itruns from your browser
POSThttps://api.salafems.com/ext/v1/orders/5f7d2f60-0d1c-4b3a-9a68-6f4d21f6a001/cancel

Stored in this browser only and never sent anywhere except to the API host you picked above — these pages are static files with no server behind them.

Path parameters

Valid JSON
Idempotency-Keyoptional
generating…

A new value is generated whenever you edit this request, and kept while you do not — so sending twice without changing anything is a real retry and comes back Idempotent-Replayed: true instead of writing again.

Paste a key above to enable Send.

Responses

  • 200The cancelled order (customer and items expanded).
  • 400The order cannot be cancelled from its current status (INVALID_STATUS_TRANSITION).
  • 401Missing/invalid API key, revoked or expired key, plan without API access, or a dead store.
  • 403The key's scopes do not cover this endpoint.
  • 404Order not found.
  • 422Validation failed — error.fields maps each offending field to its messages.
  • 429Rate limit exceeded for this key. Honor Retry-After and the X-RateLimit-* headers.

Every failure uses the one error envelope — Errors lists each code and what to do with it.

Example 200 response
{
  "id": "5f7d2f60-0d1c-4b3a-9a68-6f4d21f6a001",
  "store_id": "5f7d2f60-0d1c-4b3a-9a68-6f4d21f6a001",
  "number": "ORD-20260811-1042",
  "source": "api",
  "channel": {
    "id": "5f7d2f60-0d1c-4b3a-9a68-6f4d21f6a001",
    "name": "Facebook",
    "slug": "facebook",
    "type": "facebook"
  },
  "customer_id": "5f7d2f60-0d1c-4b3a-9a68-6f4d21f6a001",
  "location_id": null,
  "status": "pending",
  "payment_status": "unpaid",
  "fulfillment_status": "unfulfilled",
  "subtotal": "1250.00",
  "discount_amount": "1250.00",
  "shipping_charge": "1250.00",
  "tax_amount": "1250.00",
  "total_amount": "1250.00",
  "paid_amount": "1250.00",
  "due_amount": "1250.00",
  "refunded_amount": "1250.00",
  "shipping_address": null,
  "coupon": null,
  "custom_fields": null,
  "note": null,
  "delivered_at": "2026-08-11T10:00:00.000Z",
  "created_at": "2026-08-11T10:00:00.000Z",
  "updated_at": "2026-08-11T10:00:00.000Z",
  "items": [
    {
      "id": "5f7d2f60-0d1c-4b3a-9a68-6f4d21f6a001",
      "product_id": "5f7d2f60-0d1c-4b3a-9a68-6f4d21f6a001",
      "variant_id": "5f7d2f60-0d1c-4b3a-9a68-6f4d21f6a001",
      "product_name": "Classic Cotton T-Shirt",
      "variant_name": "Red / M",
      "sku": "TSHIRT-RED-M",
      "quantity": 2,
      "unit_price": "1250.00",
      "discount_price": "1250.00",
      "subtotal": "1250.00"
    }
  ],
  "customer": {
    "id": "5f7d2f60-0d1c-4b3a-9a68-6f4d21f6a001",
    "full_name": "Rafiqul Islam",
    "email": null,
    "phone": "01712345678",
    "type": "manual",
    "status": "active"
  }
}

List an order's payments

GET/ext/v1/orders/{id}/paymentspayments:read

Every settled, pending and refunded row against the order, oldest first. Refunds are negative amounts with status refunded.

Path parameters

NameTypeDescription
idrequireduuidThe order id.

Query parameters

NameTypeDescription
store_iduuidRestrict the lookup to one store. Breadth control for company-scoped keys; on a store-scoped key it must match the key's own store.

Request

export SALAF_API_KEY="salaf_sk_YOUR_API_KEY"

curl -sS "https://api.salafems.com/ext/v1/orders/REPLACE_WITH_ID/payments" \
  -H "Authorization: Bearer $SALAF_API_KEY"
Try itruns from your browser
GEThttps://api.salafems.com/ext/v1/orders/5f7d2f60-0d1c-4b3a-9a68-6f4d21f6a001/payments

Stored in this browser only and never sent anywhere except to the API host you picked above — these pages are static files with no server behind them.

Path parameters

Query parameters

Blank fields are left out of the request.

Paste a key above to enable Send.

Responses

  • 200The order's payment rows.
  • 401Missing/invalid API key, revoked or expired key, plan without API access, or a dead store.
  • 403The key's scopes do not cover this endpoint.
  • 404Order not found.
  • 422Validation failed — error.fields maps each offending field to its messages.
  • 429Rate limit exceeded for this key. Honor Retry-After and the X-RateLimit-* headers.

Every failure uses the one error envelope — Errors lists each code and what to do with it.

Example 200 response
{
  "data": [
    {
      "id": "5f7d2f60-0d1c-4b3a-9a68-6f4d21f6a001",
      "store_id": "5f7d2f60-0d1c-4b3a-9a68-6f4d21f6a001",
      "order_id": "5f7d2f60-0d1c-4b3a-9a68-6f4d21f6a001",
      "amount": "1250.00",
      "status": "paid",
      "transaction_id": "TRX9F3K2",
      "payment_method": {
        "id": "5f7d2f60-0d1c-4b3a-9a68-6f4d21f6a001",
        "name": "bKash",
        "type": "mobile_banking"
      },
      "paid_at": "2026-08-11T10:00:00.000Z",
      "created_at": "2026-08-11T10:00:00.000Z"
    }
  ]
}

Record a payment against an order

POST/ext/v1/orders/{id}/paymentspayments:write

The staff path verbatim: the amount is capped at the order's NET due (refunds counted), the paid/due rollup recomputes under a row lock, and the paid-in-full events fire exactly once. A provider transaction id is unique per store — recording the same TrxID twice is a 409.

Path parameters

NameTypeDescription
idrequireduuidThe order id.

Headers

NameTypeDescription
Idempotency-KeyrequiredstringREQUIRED. A unique value per logical request (a UUID is ideal); reuse it verbatim when retrying. A retry replays the original response with Idempotent-Replayed: true instead of running twice.

Body parameters

NameTypeDescription
store_iduuidTarget store. REQUIRED with a company-scoped key; with a store-scoped key it may only repeat the key's own store.
amountrequirednumber
payment_method_iduuidOne of the store's payment methods (must be active).
transaction_idstringProvider transaction id. Unique per store — recording the same TrxID twice is a 409.

Request

export SALAF_API_KEY="salaf_sk_YOUR_API_KEY"

curl -sS -X POST "https://api.salafems.com/ext/v1/orders/REPLACE_WITH_ID/payments" \
  -H "Authorization: Bearer $SALAF_API_KEY" \
  -H "Idempotency-Key: e7a1…-your-uuid" \
  -H "Content-Type: application/json" \
  -d '{
  "amount": 500,
  "transaction_id": "TRX9F3K2"
}'
Try itruns from your browser
POSThttps://api.salafems.com/ext/v1/orders/5f7d2f60-0d1c-4b3a-9a68-6f4d21f6a001/payments

Stored in this browser only and never sent anywhere except to the API host you picked above — these pages are static files with no server behind them.

Path parameters

Valid JSON
Idempotency-Keyrequired
generating…

A new value is generated whenever you edit this request, and kept while you do not — so sending twice without changing anything is a real retry and comes back Idempotent-Replayed: true instead of writing again.

Paste a key above to enable Send.

Responses

  • 201The updated order (customer and items expanded).
  • 401Missing/invalid API key, revoked or expired key, plan without API access, or a dead store.
  • 403The key's scopes do not cover this endpoint.
  • 404Order not found.
  • 409Duplicate transaction id, or an idempotency key still in flight.
  • 422Validation failed — error.fields maps each offending field to its messages.
  • 429Rate limit exceeded for this key. Honor Retry-After and the X-RateLimit-* headers.

Every failure uses the one error envelope — Errors lists each code and what to do with it.

Example 200 response
{
  "id": "5f7d2f60-0d1c-4b3a-9a68-6f4d21f6a001",
  "store_id": "5f7d2f60-0d1c-4b3a-9a68-6f4d21f6a001",
  "number": "ORD-20260811-1042",
  "source": "api",
  "channel": {
    "id": "5f7d2f60-0d1c-4b3a-9a68-6f4d21f6a001",
    "name": "Facebook",
    "slug": "facebook",
    "type": "facebook"
  },
  "customer_id": "5f7d2f60-0d1c-4b3a-9a68-6f4d21f6a001",
  "location_id": null,
  "status": "pending",
  "payment_status": "unpaid",
  "fulfillment_status": "unfulfilled",
  "subtotal": "1250.00",
  "discount_amount": "1250.00",
  "shipping_charge": "1250.00",
  "tax_amount": "1250.00",
  "total_amount": "1250.00",
  "paid_amount": "1250.00",
  "due_amount": "1250.00",
  "refunded_amount": "1250.00",
  "shipping_address": null,
  "coupon": null,
  "custom_fields": null,
  "note": null,
  "delivered_at": "2026-08-11T10:00:00.000Z",
  "created_at": "2026-08-11T10:00:00.000Z",
  "updated_at": "2026-08-11T10:00:00.000Z",
  "items": [
    {
      "id": "5f7d2f60-0d1c-4b3a-9a68-6f4d21f6a001",
      "product_id": "5f7d2f60-0d1c-4b3a-9a68-6f4d21f6a001",
      "variant_id": "5f7d2f60-0d1c-4b3a-9a68-6f4d21f6a001",
      "product_name": "Classic Cotton T-Shirt",
      "variant_name": "Red / M",
      "sku": "TSHIRT-RED-M",
      "quantity": 2,
      "unit_price": "1250.00",
      "discount_price": "1250.00",
      "subtotal": "1250.00"
    }
  ],
  "customer": {
    "id": "5f7d2f60-0d1c-4b3a-9a68-6f4d21f6a001",
    "full_name": "Rafiqul Islam",
    "email": null,
    "phone": "01712345678",
    "type": "manual",
    "status": "active"
  }
}

Change an order status

PATCH/ext/v1/orders/{id}/statusorders:write

Validated against the SAME strict transition map staff use — an illegal move is refused with INVALID_STATUS_TRANSITION. Stock side effects (commit on delivery, release/reverse on cancel/return) are the staff path's, inherited.

Path parameters

NameTypeDescription
idrequireduuidThe order id.

Headers

NameTypeDescription
Idempotency-KeystringOptional, but honored: send it to make retries of this request safe.

Body parameters

NameTypeDescription
store_iduuidTarget store. REQUIRED with a company-scoped key; with a store-scoped key it may only repeat the key's own store.
statusrequiredstringpendingfollow_upconfirmedprocessingready_to_shipin_transitdeliveredreturnedfailed_deliverycancelledholdspam
notestringRecorded on the order's timeline.

Request

export SALAF_API_KEY="salaf_sk_YOUR_API_KEY"

curl -sS -X PATCH "https://api.salafems.com/ext/v1/orders/REPLACE_WITH_ID/status" \
  -H "Authorization: Bearer $SALAF_API_KEY" \
  -H "Idempotency-Key: e7a1…-your-uuid" \
  -H "Content-Type: application/json" \
  -d '{
  "status": "confirmed",
  "note": "Confirmed over the phone."
}'
Try itruns from your browser
PATCHhttps://api.salafems.com/ext/v1/orders/5f7d2f60-0d1c-4b3a-9a68-6f4d21f6a001/status

Stored in this browser only and never sent anywhere except to the API host you picked above — these pages are static files with no server behind them.

Path parameters

Valid JSON
Idempotency-Keyoptional
generating…

A new value is generated whenever you edit this request, and kept while you do not — so sending twice without changing anything is a real retry and comes back Idempotent-Replayed: true instead of writing again.

Paste a key above to enable Send.

Responses

  • 200The updated order (customer and items expanded).
  • 400The transition map forbids this move (INVALID_STATUS_TRANSITION).
  • 401Missing/invalid API key, revoked or expired key, plan without API access, or a dead store.
  • 403The key's scopes do not cover this endpoint.
  • 404Order not found.
  • 422Validation failed — error.fields maps each offending field to its messages.
  • 429Rate limit exceeded for this key. Honor Retry-After and the X-RateLimit-* headers.

Every failure uses the one error envelope — Errors lists each code and what to do with it.

Example 200 response
{
  "id": "5f7d2f60-0d1c-4b3a-9a68-6f4d21f6a001",
  "store_id": "5f7d2f60-0d1c-4b3a-9a68-6f4d21f6a001",
  "number": "ORD-20260811-1042",
  "source": "api",
  "channel": {
    "id": "5f7d2f60-0d1c-4b3a-9a68-6f4d21f6a001",
    "name": "Facebook",
    "slug": "facebook",
    "type": "facebook"
  },
  "customer_id": "5f7d2f60-0d1c-4b3a-9a68-6f4d21f6a001",
  "location_id": null,
  "status": "pending",
  "payment_status": "unpaid",
  "fulfillment_status": "unfulfilled",
  "subtotal": "1250.00",
  "discount_amount": "1250.00",
  "shipping_charge": "1250.00",
  "tax_amount": "1250.00",
  "total_amount": "1250.00",
  "paid_amount": "1250.00",
  "due_amount": "1250.00",
  "refunded_amount": "1250.00",
  "shipping_address": null,
  "coupon": null,
  "custom_fields": null,
  "note": null,
  "delivered_at": "2026-08-11T10:00:00.000Z",
  "created_at": "2026-08-11T10:00:00.000Z",
  "updated_at": "2026-08-11T10:00:00.000Z",
  "items": [
    {
      "id": "5f7d2f60-0d1c-4b3a-9a68-6f4d21f6a001",
      "product_id": "5f7d2f60-0d1c-4b3a-9a68-6f4d21f6a001",
      "variant_id": "5f7d2f60-0d1c-4b3a-9a68-6f4d21f6a001",
      "product_name": "Classic Cotton T-Shirt",
      "variant_name": "Red / M",
      "sku": "TSHIRT-RED-M",
      "quantity": 2,
      "unit_price": "1250.00",
      "discount_price": "1250.00",
      "subtotal": "1250.00"
    }
  ],
  "customer": {
    "id": "5f7d2f60-0d1c-4b3a-9a68-6f4d21f6a001",
    "full_name": "Rafiqul Islam",
    "email": null,
    "phone": "01712345678",
    "type": "manual",
    "status": "active"
  }
}