Get an Order

This endpoint returns all the information for an order: its items, the customer, the originating channel, and the HATEOAS links with the actions available for its current state. This page also covers two related endpoints for a specific order: its valid state transitions and its financial profit breakdown.

Use it when you need to:

  • Display an order's detail in your application.
  • Sync information to external systems.
  • Verify which actions are available before executing a transition (accept, prepare, cancel).
  • Calculate an order's real profit after shipping, commission, cost of goods, and packaging.

Endpoint

Retrieves an order by its ID

orderIdstringrequired

Order ID (24-character MongoDB ObjectId).

200
{
  "data": {
    "_id": "65f3a1b2c4d5e6f7a8b9c0d1",
    "externalId": "FEN-10042",
    "handle": "fen-10042",
    "locationId": "65f2a0b1c4d5e6f7a8b9c0aa",
    "origin": "manual",
    "channelId": "manual",
    "orderStatus": "accepted",
    "paymentStatus": "paid",
    "currency": "MXN",
    "totalAmount": 1986.26,
    "subtotal": 1798.50,
    "tax": 287.76,
    "orderCreated": "2026-04-11T14:23:11.000Z",
    "items": [
      {
        "sku": "CAM-ROJO-M",
        "title": "Camisa Roja Talla M",
        "quantity": 2,
        "totalAmount": 998.00
      },
      {
        "sku": "PAN-AZUL-32",
        "title": "Pantalón Azul 32",
        "quantity": 1,
        "totalAmount": 799.50
      }
    ],
    "customerInfo": { "name": "María González" },
    "customerId": "65f3a1b2c4d5e6f7a8b9c0d2",
    "_links": {
      "prepare": "/orders/65f3a1b2c4d5e6f7a8b9c0d1/prepare",
      "cancel": "/orders/65f3a1b2c4d5e6f7a8b9c0d1/cancel"
    }
  }
}
404
{
  "error": {
    "code": "orders:not_found",
    "message": "Order not found"
  }
}

Required permission: orders:read

Path parameters

ParameterTypeDescription
orderIdstringOrder ObjectId (24 hex characters). Obtained when creating an order or from the list.

The _links object (inside data, not as a sibling of the order) indicates which actions are available based on the current state. The possible actions are accept, reject, cancel, prepare, fulfill, and returns — the links engine only exposes the ones valid for the order's current state according to the state machine. You don't have to hardcode that logic in your client.

If an action doesn't appear in _links, it isn't valid in the current state; see State Transitions for the complete state machine.

Examples

curl https://api.fenicia.io/orders/65f3a1b2c4d5e6f7a8b9c0d1 \
  -H "Authorization: Bearer fkapi_your_api_key"

Errors

CodeStatusDescription
orders:not_found404No order exists with that ID in your tenant.
auth:invalid_token401The API key is invalid or has been revoked.
auth:permission_denied403The API key doesn't have the orders:read permission.

See the full error catalog for the rest of the possible codes.

Tenant isolation

You can only retrieve orders from your own tenant. Attempting to access an order from another tenant returns 404, never cross-tenant information.


Valid transitions for an order

Returns the states the order can transition to from its current state

orderIdstringrequired

Order ID.

200
{
  "data": {
    "currentStatus": "accepted",
    "validTransitions": ["processing", "preparing", "cancelled"]
  }
}

Required permission: orders:read

Response shape not verified field by field

The status values in the example (accepted → processing, preparing, cancelled) are real and come directly from the state machine (ORDER_STATE_MACHINE, see State Transitions). The exact key names in the response object (currentStatus, validTransitions) were not verified line by line against the source code — confirm them against the real response before depending on their exact shape.

No status returned by this endpoint can differ from the 23 real states of the state machine; states such as on_hold do not exist and will never appear in the response.


Order financial breakdown

Calculates the order's net profit: revenue minus real shipping cost, commission, cost of goods sold (COGS), and packaging

orderIdstringrequired

Order ID.

200
{
  "data": {
    "orderId": "65f3a1b2c4d5e6f7a8b9c0d1",
    "currency": "MXN",
    "revenue": 1986.26,
    "subtotal": 1798.50,
    "shippingCharged": 150.00,
    "costs": {
      "shipping": 187.40,
      "commission": 99.31,
      "cogs": 850.00,
      "packaging": 25.00,
      "otherFees": 0
    },
    "taxWithheld": 0,
    "netProfit": 824.55,
    "marginPercent": 41.51,
    "flags": {
      "cogsComplete": true,
      "currencyMixed": false,
      "packagingPending": false
    }
  }
}

Required permission: orders:read

This endpoint answers the question "how much did this order actually earn?" by subtracting the real shipping cost, the channel commission, the cost of goods sold (COGS), and packaging from the revenue (revenue) — unlike shippingCharged, which is what was charged to the customer for shipping, costs.shipping is what shipping actually cost.

FieldDescription
revenueTotal order revenue.
subtotalSubtotal before taxes.
shippingChargedShipping amount charged to the customer.
costs.shippingReal shipping cost (fee paid to the carrier).
costs.commissionSales channel commission.
costs.cogsCost of goods sold.
costs.packagingPackaging cost.
costs.otherFeesOther fees or charges.
taxWithheldTaxes withheld.
netProfitNet profit (revenue minus all costs).
marginPercentProfit margin as a percentage.
flags.cogsCompletefalse if any order line lacks a cost snapshot — in that case the breakdown doesn't invent a cost, it flags it as incomplete.
flags.currencyMixedtrue if the order mixes different currencies across its components.
flags.packagingPendingtrue if the packaging cost hasn't been recorded yet.

No invented costs

When a line's cost snapshot is missing, the breakdown flags flags.cogsComplete: false instead of estimating or inventing a cost. A netProfit calculated with cogsComplete: false is partial: treat it as a minimum, not as final profit.

Errors

CodeStatusDescription
orders:not_found404No order exists with that ID in your tenant.
auth:invalid_token401The API key is invalid or has been revoked.
auth:permission_denied403The API key doesn't have the orders:read permission.

See the full error catalog for the rest of the possible codes.

Next steps