ecomone developers
Open Ecomone
Docs / API reference / Orders

Orders

Orders of the shop, including computed VAT/fee/profit fields and marketing attribution.

List orders#

GET/api/public/v1/ordersorders:read

List orders, newest first. Returns orders of the shop sorted by created_at descending, enriched with computed financial fields and attribution (missing UTM/Meta fields are back-filled from the storefront session). Each order also carries updated_at, normalized line_items and shipping_address_normalized for fulfillment integrations.

Query parameters

limitinteger

Page size. Clamped to 1..200. Non-numeric values fall back to the default. Default: 50.

cursorstring (ISO 8601 timestamp)

Value of next_cursor from the previous page. Returns items with created_at strictly before this timestamp.

statusstring

Exact match on status.

fulfillment_statusstring

Exact match on fulfillment_status.

order_numberinteger

Exact order number. Ignored unless it consists of digits only.

emailstring

Exact match on customer_email (the value is lower-cased before matching).

sincestring (ISO 8601)

created_at >= since.

untilstring (ISO 8601)

created_at <= until.

updated_sincestring (ISO 8601 timestamp)

Only orders whose updated_at is at or after this time. Must contain date and time, e.g. 2026-11-13T08:00:00Z; anything else returns 400. Results are still sorted and paginated by created_at, not by updated_at.

shop_iduuid

Only for OAuth tokens that cover several shops: the shop to query. Must be one of the token's shops (else 403 forbidden). Required when the token covers more than one shop (else 400 shop_required). Optional for API keys (a key belongs to exactly one shop; any other value returns 403).

Response fields

dataarray

Orders (fields below plus computed financial fields).

pagination.limitinteger

Effective page size.

pagination.has_moreboolean

Whether another page exists.

pagination.next_cursorstring|null

created_at of the last order when has_more, else null.

data[].iduuid

Order id.

data[].order_numberinteger

Sequential, human-readable order number (per shop).

data[].statusstring

Payment/lifecycle status. Not validated by the API; values seen in code: pending, paid, shipped, delivered, refunded, partially_refunded, canceled (some code also uses fulfilled).

data[].fulfillment_statusstring|null

Shipping status: unfulfilled, processing, partial, shipped, fulfilled or delivered (the values PATCH accepts). Orders changed by other tools in the past may hold other values.

data[].currencystring

ISO currency code of the order.

data[].shipping_centsinteger|null

Shipping charged, in minor units.

data[].total_centsinteger|null

Order total (gross, incl. tax and shipping), in minor units.

data[].itemsarray (raw JSON)

Line items as stored on the order. Common keys include id/product_id, title, price_cents/unit_price_cents, qty/quantity, variant_label, sku, personalization, personalization_surcharge_cents.

data[].customer_emailstring|null

Customer e-mail.

data[].customer_namestring|null

Customer full name.

data[].customer_phonestring|null

Customer phone.

data[].shipping_addressobject|null (raw JSON)

Shipping address as stored (keys seen: name, first_name, last_name, address1/line1, address2/line2, zip/postal_code, city, state/province, country, company, phone).

data[].billing_addressobject|null (raw JSON)

Billing address as stored (same shape as shipping_address).

data[].shipping_rateobject|null (raw JSON)

Selected shipping rate as stored.

data[].tracking_numberstring|null

Carrier tracking number.

data[].tracking_carrierstring|null

Carrier name/code.

data[].tracking_urlstring|null

Tracking link.

data[].payment_methodstring|null

Payment method (e.g. card). Used to estimate the transaction fee.

data[].paid_attimestamp|null

When payment succeeded.

data[].shipped_attimestamp|null

When the order was marked shipped/fulfilled.

data[].delivered_attimestamp|null

When the order was marked delivered.

data[].canceled_attimestamp|null

When the order was canceled.

data[].refunded_attimestamp|null

When the order was refunded.

data[].is_testboolean

Test order (e.g. Stripe test mode).

data[].created_attimestamp

Creation time; also the pagination key.

data[].updated_attimestamp|null

Time of the last change to the order. Any change to the order moves it, also changes that are not visible in this API. Orders last changed before 13 November 2026 carry their shipping, payment or creation time instead. Null only if the server has no change tracking.

data[].session_tokenstring|null

Storefront analytics session id that led to the order.

data[].utm_sourcestring|null

Attribution. If empty on the order, back-filled from the matching storefront session.

data[].utm_mediumstring|null

Attribution (back-filled from session if empty).

data[].utm_campaignstring|null

Attribution (back-filled from session if empty).

data[].utm_contentstring|null

Attribution (back-filled from session if empty).

data[].utm_termstring|null

Attribution (back-filled from session if empty).

data[].utm_idstring|null

Attribution (back-filled from session if empty).

data[].fb_campaign_idstring|null

Meta campaign id (back-filled from session if empty).

data[].fb_adset_idstring|null

Meta ad set id (back-filled from session if empty).

data[].fb_ad_idstring|null

Meta ad id (back-filled from session if empty).

data[].fb_placementstring|null

Meta placement (back-filled from session if empty).

data[].click_idstring|null

Click id (fbclid/gclid/ttclid value) (back-filled from session if empty).

data[].click_id_typestring|null

Which click id: fbclid, gclid or ttclid (back-filled from session if empty).

data[].gross_centsinteger

Computed: equals total_cents (0 if null).

data[].net_centsinteger

Computed: gross without VAT, using the VAT rate of the SHOP's country (legal_country → address_country → backup_region → CH), not the order's market.

data[].tax_centsinteger

Computed: gross_cents - net_cents.

data[].tax_rate_pctnumber

VAT rate used (from a fixed country table: CH/LI 8.1, DE 19, AT 20, ...; unknown countries 0).

data[].transaction_fee_centsinteger

Computed: ESTIMATED payment fee from the payment method (order endpoints never use booked Stripe fees).

data[].platform_fee_centsinteger

Computed: Ecomone platform fee incl. VAT (same value as platform_fee_gross_cents).

data[].platform_fee_net_centsinteger

Computed platform fee excl. VAT.

data[].platform_fee_vat_centsinteger

Computed VAT on the platform fee.

data[].platform_fee_vat_rate_pctnumber

VAT rate applied to the platform fee.

data[].platform_fee_gross_centsinteger

Computed platform fee incl. VAT.

data[].profit_centsinteger

net_cents - transaction_fee_cents - platform_fee_cents (no COGS, no shipping cost).

data[].refunded_centsinteger

Sum of succeeded refunds.

data[].refund_countinteger

Number of succeeded refunds.

data[].is_fully_refundedboolean

refunded_cents >= gross_cents and gross_cents > 0.

data[].is_partially_refundedboolean

0 < refunded_cents < gross_cents.

data[].net_profit_centsinteger

profit_cents - refunded_cents.

data[].refundsarray

Refunds with status succeeded or pending: [{id, amount_cents, reason, status, created_at}].

data[].line_itemsarray

Line items in a stable format: id, product_id, variant_id, title, variant_title, sku, quantity, unit_price_cents, total_cents, requires_shipping. Bundle lines with several variants are split into one line per unit; these carry bundle_line_id (the original line) and the variant’s own sku.

data[].line_items[].idstring

Line id stored with the order; otherwise <order id>:<position> (position starts at 0).

data[].line_items[].product_idstring|null

Product id.

data[].line_items[].variant_idstring|null

Variant id or key stored with the line. For older orders it is looked up in the shop's current product by the selected options, or derived from the selected option values. Null for products without variants.

data[].line_items[].titlestring|null

Product title at the time of purchase.

data[].line_items[].variant_titlestring|null

Variant label, e.g. M / White; built from the selected option values if no label was stored.

data[].line_items[].skustring|null

SKU stored with the line; otherwise the SKU of the matching variant or product in the current catalog.

data[].line_items[].quantityinteger

Quantity (1 if not stored).

data[].line_items[].unit_price_centsinteger

Unit price as charged, in minor units.

data[].line_items[].total_centsinteger

unit_price_cents × quantity plus personalization surcharges.

data[].line_items[].requires_shippingboolean

Whether the line must be shipped; false for digital products.

data[].shipping_address_normalizedobject

The shipping address in one fixed shape, built from shipping_address. Each value is a trimmed string or null.

data[].shipping_address_normalized.namestring|null

Recipient name; falls back to the customer name.

data[].shipping_address_normalized.companystring|null

Company.

data[].shipping_address_normalized.line1string|null

Street and number.

data[].shipping_address_normalized.line2string|null

Additional address line.

data[].shipping_address_normalized.postal_codestring|null

Postal code.

data[].shipping_address_normalized.citystring|null

City.

data[].shipping_address_normalized.statestring|null

State or province.

data[].shipping_address_normalized.countrystring|null

Two-letter country code in upper case; null if the stored value is not a two-letter code.

data[].shipping_address_normalized.phonestring|null

Phone; falls back to the customer phone.

data[].is_canceledboolean

true when the order was cancelled (canceled_at is set). A paid order cancelled with a full refund has status: "refunded" — use this flag instead of checking the status.

Errors

400bad_request

updated_since is not a timestamp with date and time.

401unauthorized

Any endpoint. Response carries header WWW-Authenticate: Bearer resource_metadata="<origin>/.well-known/oauth-protected-resource".

403forbidden

Scope check per endpoint (and per body field on PATCH /orders/:id).

403forbidden

shop_id query parameter names a shop outside the credential's reach.

400shop_required

Multi-shop OAuth token without shop_id.

404not_found

Any endpoint when the resolved shop has active=false.

429rate_limited

Any endpoint. Header Retry-After (seconds until the next minute bucket).

500server_error

Any unexpected database error.

503unavailable

updated_since was sent while the server has no change tracking. Without updated_since the list still works (with updated_at: null).

Try itNot authorized
Request
curl "https://api.ecomone.shop/api/public/v1/orders?limit=10" \
  -H "X-Api-Key: $ECOMONE_API_KEY" \
  -H "X-Api-Secret: $ECOMONE_API_SECRET"
200Response
{
  "data": [
    {
      "id": "9f1c2b7e-4a55-4d1f-9b62-1c0a3f6d8e21",
      "order_number": 1042,
      "status": "paid",
      "fulfillment_status": "unfulfilled",
      "currency": "CHF",
      "shipping_cents": 690,
      "total_cents": 8590,
      "items": [
        {
          "id": "3b8b1f0a-1d2c-4f34-8a7c-6e2f9b4d5c11",
          "title": "Linen Shirt White",
          "price_cents": 3950,
          "qty": 2,
          "variant_label": "M / White",
          "sku": "LS-W-M",
          "variants": {
            "Size": "M",
            "Color": "White"
          }
        }
      ],
      "customer_email": "jane.doe@example.com",
      "customer_name": "Jane Doe",
      "customer_phone": "+41 79 000 00 00",
      "shipping_address": {
        "name": "Jane Doe",
        "address1": "Example Street 1",
        "zip": "8000",
        "city": "Zurich",
        "country": "CH"
      },
      "billing_address": null,
      "shipping_rate": {
        "name": "Standard",
        "price_cents": 690
      },
      "tracking_number": null,
      "tracking_carrier": null,
      "tracking_url": null,
      "payment_method": "card",
      "paid_at": "2026-08-28T09:14:22.000Z",
      "shipped_at": null,
      "delivered_at": null,
      "canceled_at": null,
      "refunded_at": null,
      "is_test": false,
      "created_at": "2026-08-28T09:13:58.000Z",
      "updated_at": "2026-08-28T09:14:25.000Z",
      "session_token": "a1b2c3d4-0000-4000-8000-00000000abcd",
      "utm_source": "facebook",
      "utm_medium": "paid",
      "utm_campaign": "summer",
      "utm_content": null,
      "utm_term": null,
      "utm_id": null,
      "fb_campaign_id": "120000000000001",
      "fb_adset_id": "120000000000002",
      "fb_ad_id": "120000000000003",
      "fb_placement": "Instagram_Feed",
      "click_id": "IwAR0exampleclickid",
      "click_id_type": "fbclid",
      "gross_cents": 8590,
      "net_cents": 7946,
      "tax_cents": 644,
      "tax_rate_pct": 8.1,
      "transaction_fee_cents": 279,
      "platform_fee_cents": 287,
      "platform_fee_net_cents": 266,
      "platform_fee_vat_cents": 21,
      "platform_fee_vat_rate_pct": 8.1,
      "platform_fee_gross_cents": 287,
      "profit_cents": 7380,
      "refunded_cents": 0,
      "refund_count": 0,
      "is_fully_refunded": false,
      "is_partially_refunded": false,
      "net_profit_cents": 7380,
      "refunds": [],
      "line_items": [
        {
          "id": "9f1c2b7e-4a55-4d1f-9b62-1c0a3f6d8e21:0",
          "product_id": "3b8b1f0a-1d2c-4f34-8a7c-6e2f9b4d5c11",
          "variant_id": "v1",
          "title": "Linen Shirt White",
          "variant_title": "M / White",
          "sku": "LS-W-M",
          "quantity": 2,
          "unit_price_cents": 3950,
          "total_cents": 7900,
          "requires_shipping": true
        }
      ],
      "shipping_address_normalized": {
        "name": "Jane Doe",
        "company": null,
        "line1": "Example Street 1",
        "line2": null,
        "postal_code": "8000",
        "city": "Zurich",
        "state": null,
        "country": "CH",
        "phone": "+41 79 000 00 00"
      }
    }
  ],
  "pagination": {
    "limit": 50,
    "has_more": true,
    "next_cursor": "2026-08-28T09:13:58.000Z"
  }
}

Retrieve an order#

GET/api/public/v1/orders/{id}orders:read

Retrieve one order. Looks up an order by UUID or by order number (digits only). Includes internal_note, updated_at, normalized line_items and shipping_address_normalized.

Path parameters

iduuid | integerrequired

Order UUID or numeric order number.

Query parameters

shop_iduuid

Only for OAuth tokens that cover several shops: the shop to query. Must be one of the token's shops (else 403 forbidden). Required when the token covers more than one shop (else 400 shop_required). Optional for API keys (a key belongs to exactly one shop; any other value returns 403).

Response fields

data.iduuid

Order id.

data.order_numberinteger

Sequential, human-readable order number (per shop).

data.statusstring

Payment/lifecycle status. Not validated by the API; values seen in code: pending, paid, shipped, delivered, refunded, partially_refunded, canceled (some code also uses fulfilled).

data.fulfillment_statusstring|null

Shipping status: unfulfilled, processing, partial, shipped, fulfilled or delivered (the values PATCH accepts). Orders changed by other tools in the past may hold other values.

data.currencystring

ISO currency code of the order.

data.shipping_centsinteger|null

Shipping charged, in minor units.

data.total_centsinteger|null

Order total (gross, incl. tax and shipping), in minor units.

data.itemsarray (raw JSON)

Line items as stored on the order. Common keys include id/product_id, title, price_cents/unit_price_cents, qty/quantity, variant_label, sku, personalization, personalization_surcharge_cents.

data.customer_emailstring|null

Customer e-mail.

data.customer_namestring|null

Customer full name.

data.customer_phonestring|null

Customer phone.

data.shipping_addressobject|null (raw JSON)

Shipping address as stored (keys seen: name, first_name, last_name, address1/line1, address2/line2, zip/postal_code, city, state/province, country, company, phone).

data.billing_addressobject|null (raw JSON)

Billing address as stored (same shape as shipping_address).

data.shipping_rateobject|null (raw JSON)

Selected shipping rate as stored.

data.tracking_numberstring|null

Carrier tracking number.

data.tracking_carrierstring|null

Carrier name/code.

data.tracking_urlstring|null

Tracking link.

data.payment_methodstring|null

Payment method (e.g. card). Used to estimate the transaction fee.

data.paid_attimestamp|null

When payment succeeded.

data.shipped_attimestamp|null

When the order was marked shipped/fulfilled.

data.delivered_attimestamp|null

When the order was marked delivered.

data.canceled_attimestamp|null

When the order was canceled.

data.refunded_attimestamp|null

When the order was refunded.

data.is_testboolean

Test order (e.g. Stripe test mode).

data.created_attimestamp

Creation time; also the pagination key.

data.updated_attimestamp|null

Time of the last change to the order. Any change to the order moves it, also changes that are not visible in this API. Orders last changed before 13 November 2026 carry their shipping, payment or creation time instead. Null only if the server has no change tracking.

data.session_tokenstring|null

Storefront analytics session id that led to the order.

data.utm_sourcestring|null

Attribution. If empty on the order, back-filled from the matching storefront session.

data.utm_mediumstring|null

Attribution (back-filled from session if empty).

data.utm_campaignstring|null

Attribution (back-filled from session if empty).

data.utm_contentstring|null

Attribution (back-filled from session if empty).

data.utm_termstring|null

Attribution (back-filled from session if empty).

data.utm_idstring|null

Attribution (back-filled from session if empty).

data.fb_campaign_idstring|null

Meta campaign id (back-filled from session if empty).

data.fb_adset_idstring|null

Meta ad set id (back-filled from session if empty).

data.fb_ad_idstring|null

Meta ad id (back-filled from session if empty).

data.fb_placementstring|null

Meta placement (back-filled from session if empty).

data.click_idstring|null

Click id (fbclid/gclid/ttclid value) (back-filled from session if empty).

data.click_id_typestring|null

Which click id: fbclid, gclid or ttclid (back-filled from session if empty).

data.internal_notestring|null

Merchant-internal note (detail and PATCH responses only, not in the list).

data.gross_centsinteger

Computed: equals total_cents (0 if null).

data.net_centsinteger

Computed: gross without VAT, using the VAT rate of the SHOP's country (legal_country → address_country → backup_region → CH), not the order's market.

data.tax_centsinteger

Computed: gross_cents - net_cents.

data.tax_rate_pctnumber

VAT rate used (from a fixed country table: CH/LI 8.1, DE 19, AT 20, ...; unknown countries 0).

data.transaction_fee_centsinteger

Computed: ESTIMATED payment fee from the payment method (order endpoints never use booked Stripe fees).

data.platform_fee_centsinteger

Computed: Ecomone platform fee incl. VAT (same value as platform_fee_gross_cents).

data.platform_fee_net_centsinteger

Computed platform fee excl. VAT.

data.platform_fee_vat_centsinteger

Computed VAT on the platform fee.

data.platform_fee_vat_rate_pctnumber

VAT rate applied to the platform fee.

data.platform_fee_gross_centsinteger

Computed platform fee incl. VAT.

data.profit_centsinteger

net_cents - transaction_fee_cents - platform_fee_cents (no COGS, no shipping cost).

data.refunded_centsinteger

Sum of succeeded refunds.

data.refund_countinteger

Number of succeeded refunds.

data.is_fully_refundedboolean

refunded_cents >= gross_cents and gross_cents > 0.

data.is_partially_refundedboolean

0 < refunded_cents < gross_cents.

data.net_profit_centsinteger

profit_cents - refunded_cents.

data.refundsarray

Refunds with status succeeded or pending: [{id, amount_cents, reason, status, created_at}].

data.line_itemsarray

Line items in a stable format: id, product_id, variant_id, title, variant_title, sku, quantity, unit_price_cents, total_cents, requires_shipping. Bundle lines with several variants are split into one line per unit; these carry bundle_line_id (the original line) and the variant’s own sku.

data.line_items[].idstring

Line id stored with the order; otherwise <order id>:<position> (position starts at 0).

data.line_items[].product_idstring|null

Product id.

data.line_items[].variant_idstring|null

Variant id or key stored with the line. For older orders it is looked up in the shop's current product by the selected options, or derived from the selected option values. Null for products without variants.

data.line_items[].titlestring|null

Product title at the time of purchase.

data.line_items[].variant_titlestring|null

Variant label, e.g. M / White; built from the selected option values if no label was stored.

data.line_items[].skustring|null

SKU stored with the line; otherwise the SKU of the matching variant or product in the current catalog.

data.line_items[].quantityinteger

Quantity (1 if not stored).

data.line_items[].unit_price_centsinteger

Unit price as charged, in minor units.

data.line_items[].total_centsinteger

unit_price_cents × quantity plus personalization surcharges.

data.line_items[].requires_shippingboolean

Whether the line must be shipped; false for digital products.

data.shipping_address_normalizedobject

The shipping address in one fixed shape, built from shipping_address. Each value is a trimmed string or null.

data.shipping_address_normalized.namestring|null

Recipient name; falls back to the customer name.

data.shipping_address_normalized.companystring|null

Company.

data.shipping_address_normalized.line1string|null

Street and number.

data.shipping_address_normalized.line2string|null

Additional address line.

data.shipping_address_normalized.postal_codestring|null

Postal code.

data.shipping_address_normalized.citystring|null

City.

data.shipping_address_normalized.statestring|null

State or province.

data.shipping_address_normalized.countrystring|null

Two-letter country code in upper case; null if the stored value is not a two-letter code.

data.shipping_address_normalized.phonestring|null

Phone; falls back to the customer phone.

data.is_canceledboolean

true when the order was cancelled (canceled_at is set). A paid order cancelled with a full refund has status: "refunded" — use this flag instead of checking the status.

Errors

400bad_request

Detail endpoints and PATCH.

404not_found

Detail endpoints.

401unauthorized

Any endpoint. Response carries header WWW-Authenticate: Bearer resource_metadata="<origin>/.well-known/oauth-protected-resource".

403forbidden

Scope check per endpoint (and per body field on PATCH /orders/:id).

403forbidden

shop_id query parameter names a shop outside the credential's reach.

400shop_required

Multi-shop OAuth token without shop_id.

404not_found

Any endpoint when the resolved shop has active=false.

429rate_limited

Any endpoint. Header Retry-After (seconds until the next minute bucket).

500server_error

Any endpoint.

Try itNot authorized
Request
curl "https://api.ecomone.shop/api/public/v1/orders/9f1c2b7e-4a55-4d1f-9b62-1c0a3f6d8e21" \
  -H "X-Api-Key: $ECOMONE_API_KEY" \
  -H "X-Api-Secret: $ECOMONE_API_SECRET"
200Response
{
  "data": {
    "id": "9f1c2b7e-4a55-4d1f-9b62-1c0a3f6d8e21",
    "order_number": 1042,
    "status": "paid",
    "fulfillment_status": "unfulfilled",
    "currency": "CHF",
    "shipping_cents": 690,
    "total_cents": 8590,
    "items": [
      {
        "id": "3b8b1f0a-1d2c-4f34-8a7c-6e2f9b4d5c11",
        "title": "Linen Shirt White",
        "price_cents": 3950,
        "qty": 2,
        "variant_label": "M / White",
        "sku": "LS-W-M",
        "variants": {
          "Size": "M",
          "Color": "White"
        }
      }
    ],
    "customer_email": "jane.doe@example.com",
    "customer_name": "Jane Doe",
    "customer_phone": "+41 79 000 00 00",
    "shipping_address": {
      "name": "Jane Doe",
      "address1": "Example Street 1",
      "zip": "8000",
      "city": "Zurich",
      "country": "CH"
    },
    "billing_address": null,
    "shipping_rate": {
      "name": "Standard",
      "price_cents": 690
    },
    "tracking_number": null,
    "tracking_carrier": null,
    "tracking_url": null,
    "payment_method": "card",
    "paid_at": "2026-08-28T09:14:22.000Z",
    "shipped_at": null,
    "delivered_at": null,
    "canceled_at": null,
    "refunded_at": null,
    "is_test": false,
    "created_at": "2026-08-28T09:13:58.000Z",
    "updated_at": "2026-08-28T09:14:25.000Z",
    "session_token": "a1b2c3d4-0000-4000-8000-00000000abcd",
    "utm_source": "facebook",
    "utm_medium": "paid",
    "utm_campaign": "summer",
    "utm_content": null,
    "utm_term": null,
    "utm_id": null,
    "fb_campaign_id": "120000000000001",
    "fb_adset_id": "120000000000002",
    "fb_ad_id": "120000000000003",
    "fb_placement": "Instagram_Feed",
    "click_id": "IwAR0exampleclickid",
    "click_id_type": "fbclid",
    "internal_note": null,
    "gross_cents": 8590,
    "net_cents": 7946,
    "tax_cents": 644,
    "tax_rate_pct": 8.1,
    "transaction_fee_cents": 279,
    "platform_fee_cents": 287,
    "platform_fee_net_cents": 266,
    "platform_fee_vat_cents": 21,
    "platform_fee_vat_rate_pct": 8.1,
    "platform_fee_gross_cents": 287,
    "profit_cents": 7380,
    "refunded_cents": 0,
    "refund_count": 0,
    "is_fully_refunded": false,
    "is_partially_refunded": false,
    "net_profit_cents": 7380,
    "refunds": [],
    "line_items": [
      {
        "id": "9f1c2b7e-4a55-4d1f-9b62-1c0a3f6d8e21:0",
        "product_id": "3b8b1f0a-1d2c-4f34-8a7c-6e2f9b4d5c11",
        "variant_id": "v1",
        "title": "Linen Shirt White",
        "variant_title": "M / White",
        "sku": "LS-W-M",
        "quantity": 2,
        "unit_price_cents": 3950,
        "total_cents": 7900,
        "requires_shipping": true
      }
    ],
    "shipping_address_normalized": {
      "name": "Jane Doe",
      "company": null,
      "line1": "Example Street 1",
      "line2": null,
      "postal_code": "8000",
      "city": "Zurich",
      "state": null,
      "country": "CH",
      "phone": "+41 79 000 00 00"
    }
  }
}

Update an order#

PATCH/api/public/v1/orders/{id}orders:fulfillment | orders:notes | orders:cancel (per field)Live effect

Update fulfillment and tracking, the internal note, or cancel the order. Send only the fields you want to change. The body is validated strictly: an unknown field, a wrong type or a value outside the allowed list returns 400 and nothing is changed. Each field group needs its own scope; all scope checks run before anything is written, so a 403 means nothing was changed. Fields from several groups can be combined; a cancellation runs first, then the other fields are saved. Returns the updated order in the same shape as GET /orders/{id}. Changes apply to the live shop immediately.

⚡

Changes apply immediately. The customer gets the shipping e-mail when the status becomes shipped or fulfilled, and a tracking update when you later send a new tracking number (unless notify_customer is false). action: "cancel" refunds the payment and e-mails the customer.

Path parameters

iduuid | integerrequired

Order UUID or numeric order number.

Query parameters

shop_iduuid

Only for OAuth tokens that cover several shops: the shop to query. Must be one of the token's shops (else 403 forbidden). Required when the token covers more than one shop (else 400 shop_required). Optional for API keys (a key belongs to exactly one shop; any other value returns 403).

Body parameters

fulfillment_statusstring orders:fulfillment

New fulfillment status. With shipped or fulfilled, shipped_at is set to now if it is still empty. A change to shipped sends the order.shipped webhook, a change to fulfilled the order.fulfilled webhook.

unfulfilledprocessingpartialshippedfulfilleddelivered
tracking_numberstring|null orders:fulfillment

Tracking number, max 200 characters; null clears it.

tracking_carrierstring|null orders:fulfillment

Carrier, max 200 characters; null clears it.

tracking_urlstring|null orders:fulfillment

Tracking link, max 2048 characters; null clears it. Not validated as a URL.

notify_customerboolean orders:fulfillment / orders:cancel

Default true. Send false to suppress customer e-mails. The shipping e-mail is sent when the status changes to shipped or fulfilled. If the order is already shipped and you send a new tracking number, the customer gets a tracking update e-mail (once per tracking number). Default: true.

internal_notestring|null orders:notes

Replaces the internal note, max 8000 characters; null clears it. Never shown to the customer.

action"cancel" orders:cancel

"cancel" (or status: "canceled") cancels the order: the payment is refunded, the customer is e-mailed (unless notify_customer is false) and the order.cancelled webhook is sent. Cancellation cannot be combined with fulfillment fields in the same request.

status"canceled" orders:cancel

Alias for action: "cancel".

Response fields

data.iduuid

Order id.

data.order_numberinteger

Sequential, human-readable order number (per shop).

data.statusstring

Payment/lifecycle status. Not validated by the API; values seen in code: pending, paid, shipped, delivered, refunded, partially_refunded, canceled (some code also uses fulfilled).

data.fulfillment_statusstring|null

Shipping status: unfulfilled, processing, partial, shipped, fulfilled or delivered (the values PATCH accepts). Orders changed by other tools in the past may hold other values.

data.currencystring

ISO currency code of the order.

data.shipping_centsinteger|null

Shipping charged, in minor units.

data.total_centsinteger|null

Order total (gross, incl. tax and shipping), in minor units.

data.itemsarray (raw JSON)

Line items as stored on the order. Common keys include id/product_id, title, price_cents/unit_price_cents, qty/quantity, variant_label, sku, personalization, personalization_surcharge_cents.

data.customer_emailstring|null

Customer e-mail.

data.customer_namestring|null

Customer full name.

data.customer_phonestring|null

Customer phone.

data.shipping_addressobject|null (raw JSON)

Shipping address as stored (keys seen: name, first_name, last_name, address1/line1, address2/line2, zip/postal_code, city, state/province, country, company, phone).

data.billing_addressobject|null (raw JSON)

Billing address as stored (same shape as shipping_address).

data.shipping_rateobject|null (raw JSON)

Selected shipping rate as stored.

data.tracking_numberstring|null

Carrier tracking number.

data.tracking_carrierstring|null

Carrier name/code.

data.tracking_urlstring|null

Tracking link.

data.payment_methodstring|null

Payment method (e.g. card). Used to estimate the transaction fee.

data.paid_attimestamp|null

When payment succeeded.

data.shipped_attimestamp|null

When the order was marked shipped/fulfilled.

data.delivered_attimestamp|null

When the order was marked delivered.

data.canceled_attimestamp|null

When the order was canceled.

data.refunded_attimestamp|null

When the order was refunded.

data.is_testboolean

Test order (e.g. Stripe test mode).

data.created_attimestamp

Creation time; also the pagination key.

data.updated_attimestamp|null

Time of the last change to the order. Any change to the order moves it, also changes that are not visible in this API. Orders last changed before 13 November 2026 carry their shipping, payment or creation time instead. Null only if the server has no change tracking.

data.session_tokenstring|null

Storefront analytics session id that led to the order.

data.utm_sourcestring|null

Attribution. If empty on the order, back-filled from the matching storefront session.

data.utm_mediumstring|null

Attribution (back-filled from session if empty).

data.utm_campaignstring|null

Attribution (back-filled from session if empty).

data.utm_contentstring|null

Attribution (back-filled from session if empty).

data.utm_termstring|null

Attribution (back-filled from session if empty).

data.utm_idstring|null

Attribution (back-filled from session if empty).

data.fb_campaign_idstring|null

Meta campaign id (back-filled from session if empty).

data.fb_adset_idstring|null

Meta ad set id (back-filled from session if empty).

data.fb_ad_idstring|null

Meta ad id (back-filled from session if empty).

data.fb_placementstring|null

Meta placement (back-filled from session if empty).

data.click_idstring|null

Click id (fbclid/gclid/ttclid value) (back-filled from session if empty).

data.click_id_typestring|null

Which click id: fbclid, gclid or ttclid (back-filled from session if empty).

data.internal_notestring|null

Merchant-internal note (detail and PATCH responses only, not in the list).

data.gross_centsinteger

Computed: equals total_cents (0 if null).

data.net_centsinteger

Computed: gross without VAT, using the VAT rate of the SHOP's country (legal_country → address_country → backup_region → CH), not the order's market.

data.tax_centsinteger

Computed: gross_cents - net_cents.

data.tax_rate_pctnumber

VAT rate used (from a fixed country table: CH/LI 8.1, DE 19, AT 20, ...; unknown countries 0).

data.transaction_fee_centsinteger

Computed: ESTIMATED payment fee from the payment method (order endpoints never use booked Stripe fees).

data.platform_fee_centsinteger

Computed: Ecomone platform fee incl. VAT (same value as platform_fee_gross_cents).

data.platform_fee_net_centsinteger

Computed platform fee excl. VAT.

data.platform_fee_vat_centsinteger

Computed VAT on the platform fee.

data.platform_fee_vat_rate_pctnumber

VAT rate applied to the platform fee.

data.platform_fee_gross_centsinteger

Computed platform fee incl. VAT.

data.profit_centsinteger

net_cents - transaction_fee_cents - platform_fee_cents (no COGS, no shipping cost).

data.refunded_centsinteger

Sum of succeeded refunds. Exception: after a cancellation in this request it is the amount refunded by this cancellation (0 if nothing was refunded or the order was already cancelled).

data.refund_countinteger

Number of succeeded refunds.

data.is_fully_refundedboolean

refunded_cents >= gross_cents and gross_cents > 0.

data.is_partially_refundedboolean

0 < refunded_cents < gross_cents.

data.net_profit_centsinteger

profit_cents - refunded_cents.

data.refundsarray

Refunds with status succeeded or pending: [{id, amount_cents, reason, status, created_at}].

data.line_itemsarray

Line items in a stable format: id, product_id, variant_id, title, variant_title, sku, quantity, unit_price_cents, total_cents, requires_shipping. Bundle lines with several variants are split into one line per unit; these carry bundle_line_id (the original line) and the variant’s own sku.

data.line_items[].idstring

Line id stored with the order; otherwise <order id>:<position> (position starts at 0).

data.line_items[].product_idstring|null

Product id.

data.line_items[].variant_idstring|null

Variant id or key stored with the line. For older orders it is looked up in the shop's current product by the selected options, or derived from the selected option values. Null for products without variants.

data.line_items[].titlestring|null

Product title at the time of purchase.

data.line_items[].variant_titlestring|null

Variant label, e.g. M / White; built from the selected option values if no label was stored.

data.line_items[].skustring|null

SKU stored with the line; otherwise the SKU of the matching variant or product in the current catalog.

data.line_items[].quantityinteger

Quantity (1 if not stored).

data.line_items[].unit_price_centsinteger

Unit price as charged, in minor units.

data.line_items[].total_centsinteger

unit_price_cents × quantity plus personalization surcharges.

data.line_items[].requires_shippingboolean

Whether the line must be shipped; false for digital products.

data.shipping_address_normalizedobject

The shipping address in one fixed shape, built from shipping_address. Each value is a trimmed string or null.

data.shipping_address_normalized.namestring|null

Recipient name; falls back to the customer name.

data.shipping_address_normalized.companystring|null

Company.

data.shipping_address_normalized.line1string|null

Street and number.

data.shipping_address_normalized.line2string|null

Additional address line.

data.shipping_address_normalized.postal_codestring|null

Postal code.

data.shipping_address_normalized.citystring|null

City.

data.shipping_address_normalized.statestring|null

State or province.

data.shipping_address_normalized.countrystring|null

Two-letter country code in upper case; null if the stored value is not a two-letter code.

data.shipping_address_normalized.phonestring|null

Phone; falls back to the customer phone.

Errors

400bad_request

Invalid id ("id muss eine UUID oder eine Bestellnummer sein"); invalid body ("Ungültige Bestellfelder: <fields>": not a JSON object, unknown field, wrong type, value not allowed or too long); or nothing to change ("Keine gültigen/erlaubten Felder", e.g. only notify_customer).

403forbidden

A sent field needs orders:fulfillment, orders:notes or orders:cancel and the credential lacks it.

403forbidden

Cancellation with an API key whose creator is unknown.

404not_found

No order with this id or number in the shop.

502refund_failed

Cancellation of a paid order whose refund failed or whose shop has no connected payment account. Nothing else was changed; the order can be cancelled again later.

401unauthorized

Any endpoint. Response carries header WWW-Authenticate: Bearer resource_metadata="<origin>/.well-known/oauth-protected-resource".

403forbidden

shop_id query parameter names a shop outside the credential's reach.

400shop_required

Multi-shop OAuth token without shop_id.

404not_found

Any endpoint when the resolved shop has active=false.

429rate_limited

Any endpoint. Header Retry-After (seconds until the next minute bucket).

403forbidden

Fulfillment or cancellation.

409conflict

PATCH with action: "cancel" or fulfillment fields.

Try itNot authorized
Request
curl -X PATCH "https://api.ecomone.shop/api/public/v1/orders/9f1c2b7e-4a55-4d1f-9b62-1c0a3f6d8e21" \
  -H "X-Api-Key: $ECOMONE_API_KEY" \
  -H "X-Api-Secret: $ECOMONE_API_SECRET" \
  -H "Content-Type: application/json" \
  -d '{
  "fulfillment_status": "shipped",
  "tracking_number": "99.00.123456.78901234",
  "tracking_carrier": "Swiss Post",
  "tracking_url": "https://service.post.ch/track?formattedParcelCodes=99.00.123456.78901234",
  "notify_customer": true
}'
200Response
{
  "data": {
    "id": "9f1c2b7e-4a55-4d1f-9b62-1c0a3f6d8e21",
    "order_number": 1042,
    "status": "paid",
    "fulfillment_status": "shipped",
    "currency": "CHF",
    "shipping_cents": 690,
    "total_cents": 8590,
    "items": [
      {
        "id": "3b8b1f0a-1d2c-4f34-8a7c-6e2f9b4d5c11",
        "title": "Linen Shirt White",
        "price_cents": 3950,
        "qty": 2,
        "variant_label": "M / White",
        "sku": "LS-W-M",
        "variants": {
          "Size": "M",
          "Color": "White"
        }
      }
    ],
    "customer_email": "jane.doe@example.com",
    "customer_name": "Jane Doe",
    "customer_phone": "+41 79 000 00 00",
    "shipping_address": {
      "name": "Jane Doe",
      "address1": "Example Street 1",
      "zip": "8000",
      "city": "Zurich",
      "country": "CH"
    },
    "billing_address": null,
    "shipping_rate": {
      "name": "Standard",
      "price_cents": 690
    },
    "tracking_number": "99.00.123456.78901234",
    "tracking_carrier": "Swiss Post",
    "tracking_url": "https://service.post.ch/track?formattedParcelCodes=99.00.123456.78901234",
    "payment_method": "card",
    "paid_at": "2026-08-28T09:14:22.000Z",
    "shipped_at": "2026-08-30T07:45:10.000Z",
    "delivered_at": null,
    "canceled_at": null,
    "refunded_at": null,
    "is_test": false,
    "created_at": "2026-08-28T09:13:58.000Z",
    "updated_at": "2026-08-30T07:45:10.000Z",
    "session_token": "a1b2c3d4-0000-4000-8000-00000000abcd",
    "utm_source": "facebook",
    "utm_medium": "paid",
    "utm_campaign": "summer",
    "utm_content": null,
    "utm_term": null,
    "utm_id": null,
    "fb_campaign_id": "120000000000001",
    "fb_adset_id": "120000000000002",
    "fb_ad_id": "120000000000003",
    "fb_placement": "Instagram_Feed",
    "click_id": "IwAR0exampleclickid",
    "click_id_type": "fbclid",
    "internal_note": null,
    "gross_cents": 8590,
    "net_cents": 7946,
    "tax_cents": 644,
    "tax_rate_pct": 8.1,
    "transaction_fee_cents": 279,
    "platform_fee_cents": 287,
    "platform_fee_net_cents": 266,
    "platform_fee_vat_cents": 21,
    "platform_fee_vat_rate_pct": 8.1,
    "platform_fee_gross_cents": 287,
    "profit_cents": 7380,
    "refunded_cents": 0,
    "refund_count": 0,
    "is_fully_refunded": false,
    "is_partially_refunded": false,
    "net_profit_cents": 7380,
    "refunds": [],
    "line_items": [
      {
        "id": "9f1c2b7e-4a55-4d1f-9b62-1c0a3f6d8e21:0",
        "product_id": "3b8b1f0a-1d2c-4f34-8a7c-6e2f9b4d5c11",
        "variant_id": "v1",
        "title": "Linen Shirt White",
        "variant_title": "M / White",
        "sku": "LS-W-M",
        "quantity": 2,
        "unit_price_cents": 3950,
        "total_cents": 7900,
        "requires_shipping": true
      }
    ],
    "shipping_address_normalized": {
      "name": "Jane Doe",
      "company": null,
      "line1": "Example Street 1",
      "line2": null,
      "postal_code": "8000",
      "city": "Zurich",
      "state": null,
      "country": "CH",
      "phone": "+41 79 000 00 00"
    }
  }
}

Retrieve an order’s customer journey#

GET/api/public/v1/orders/{id}/journeyorders:read

Customer journey of an order (session, attribution, page views). Finds the storefront session that converted into the order (by converted_order_id, else by the order's session_token) and returns session data, Meta attribution (with campaign/ad set/ad names resolved from synced Meta insights when available) and up to 200 page views in chronological order. Requires the plan feature browser_tracking.

Path parameters

iduuid | integerrequired

Order UUID or numeric order number.

Query parameters

shop_iduuid

Only for OAuth tokens that cover several shops: the shop to query. Must be one of the token's shops (else 403 forbidden). Required when the token covers more than one shop (else 400 shop_required). Optional for API keys (a key belongs to exactly one shop; any other value returns 403).

Response fields

data.order_iduuid

Order id.

data.order_numberinteger

Order number.

data.sessionobject|null

null when no session was found. Fields: session_token, started_at, last_seen_at, page_views_count, country, city, region, referrer, landing_path, stage, utm_source, utm_medium, utm_campaign, utm_content, utm_term, utm_id.

data.attributionobject|null

null when no session was found. Fields: fb_campaign_id, fb_adset_id, fb_ad_id, fb_placement, campaign_name, adset_name, ad_name, click_id, click_id_type.

data.page_viewsarray

[{path, viewed_at}] ascending, max 200.

Errors

402feature_not_in_plan

GET /orders/:id/journey (feature browser_tracking) and GET /revenue (feature reports). Checked BEFORE the scope check.

400bad_request

Detail endpoints and PATCH.

404not_found

Detail endpoints.

401unauthorized

Any endpoint. Response carries header WWW-Authenticate: Bearer resource_metadata="<origin>/.well-known/oauth-protected-resource".

403forbidden

Scope check per endpoint (and per body field on PATCH /orders/:id).

403forbidden

shop_id query parameter names a shop outside the credential's reach.

400shop_required

Multi-shop OAuth token without shop_id.

404not_found

Any endpoint when the resolved shop has active=false.

429rate_limited

Any endpoint. Header Retry-After (seconds until the next minute bucket).

500server_error

Any endpoint.

Try itNot authorized
Request
curl "https://api.ecomone.shop/api/public/v1/orders/9f1c2b7e-4a55-4d1f-9b62-1c0a3f6d8e21/journey" \
  -H "X-Api-Key: $ECOMONE_API_KEY" \
  -H "X-Api-Secret: $ECOMONE_API_SECRET"
200Response
{
  "data": {
    "order_id": "9f1c2b7e-4a55-4d1f-9b62-1c0a3f6d8e21",
    "order_number": 1042,
    "session": {
      "session_token": "a1b2c3d4-0000-4000-8000-00000000abcd",
      "started_at": "2026-08-28T09:02:11.000Z",
      "last_seen_at": "2026-08-28T09:14:30.000Z",
      "page_views_count": 5,
      "country": "CH",
      "city": "Zurich",
      "region": "ZH",
      "referrer": "https://l.instagram.com/",
      "landing_path": "/products/linen-shirt-white",
      "stage": "purchase",
      "utm_source": "facebook",
      "utm_medium": "paid",
      "utm_campaign": "summer",
      "utm_content": null,
      "utm_term": null,
      "utm_id": null
    },
    "attribution": {
      "fb_campaign_id": "120000000000001",
      "fb_adset_id": "120000000000002",
      "fb_ad_id": "120000000000003",
      "fb_placement": "Instagram_Feed",
      "campaign_name": "Summer Sale",
      "adset_name": "CH 25-45",
      "ad_name": "Video A",
      "click_id": "IwAR0exampleclickid",
      "click_id_type": "fbclid"
    },
    "page_views": [
      {
        "path": "/products/linen-shirt-white",
        "viewed_at": "2026-08-28T09:02:11.000Z"
      },
      {
        "path": "/checkout",
        "viewed_at": "2026-08-28T09:12:40.000Z"
      }
    ]
  }
}

Authorize requests

Requests go straight from your browser to https://api.ecomone.shop. Your credentials stay in this browser tab and are never sent to this documentation site.