Linkit

Orders

Unified order management — create, track, update status, and export orders

Orders

Orders are ingested from any source — manual entry, integrations, or API calls. Each order tracks customer info, line items, totals, status, and fulfillment data.

Read responses (GET /api/v1/orders, GET /api/v1/orders/{id}) always use a single contract: an envelope with spec_version 2026-04-01, event metadata, and a normalized order object (UnifiedOrderPayload). Vendor-native capture may still be stored server-side for ingestion; it is not returned in JSON.


UnifiedOrderPayload (order field)

This is the normalized order inside every read envelope. Field names mirror outbound webhooks.

FieldTypeDescription
idstringOrder record id
organization_idstringTenant id
source_referencestringHuman or upstream reference
source_transaction_idstringIdempotency / upstream transaction key
source_timestampstringProvider timestamp (RFC3339), when known
destination_idstringBranch / store id in Linkit
destination_referencestringExternal branch or vendor reference
order_statusstringWorkflow status
fulfillment_statusstringFulfillment pipeline
payment_statusstringPayment pipeline
fulfillment_methodstringe.g. delivery, pickup, shipping
payment_methodstringTender / channel
currencystringISO 4217
total_amountnumberGrand total
discounts_amountnumberDiscounts
vat_amountnumberVAT
customer_name / customer_phone / customer_emailstringBuyer
receiver_name / receiver_phonestringRecipient when different
skusstring[]Sku codes when normalized
productsarrayLine items (normalized JSON)
shipping_addressobjectStructured address when present
order_codestringDisplay code
order_typestringOrder classification
transport_typestringLogistics / handoff hint
commentstringNotes
promised_forstringScheduled / promise time (RFC3339)
is_preorderbooleanPreorder flag
delivery_fee / service_fee / subtotalnumberFee breakdown
store_namestringResolved store label
dispatch_routingobjectDispatch metadata when present
shipping_fulfillmentobjectCarrier / fulfillment metadata when present
created_at / updated_atstringLinkit record times (RFC3339)

organization_app_id and catalog app_slug live on the parent envelope (see below), not on orderorders.source in storage is the install id (organization_apps row).

Order Statuses

StatusDescription
pendingReceived, not yet processed
confirmedAccepted by the merchant
preparingBeing prepared
readyReady for pickup or delivery
shippedIn transit
deliveredSuccessfully delivered
cancelledCancelled before fulfillment
returnedReturned after delivery

Payment Statuses

StatusDescription
pendingAwaiting payment
paidPayment received
refundedFull refund issued
partially_refundedPartial refund issued
failedPayment failed

List Orders

GET /api/v1/orders

Every call uses the same authenticated tenant context as the rest of the API: a valid bearer token plus the organization resolved from that token (or an X-Organization-ID override when your account is allowed to access that organization). No additional scopes apply beyond your existing membership and API key rules.

Query Parameters

ParameterTypeDefaultDescription
pageinteger1Page number
limitinteger20Items per page (max 100)
statusstring-Filter by order status
payment_statusstring-Filter by payment status
fulfillment_statusstring-Filter by fulfillment status
sourcestring-Filter by source platform
searchstring-Search in customer name, email, external ID
fromstring-Lower bound on created (RFC 3339), e.g. 2026-04-21T00:00:00Z
tostring-Upper bound on created (RFC 3339); omit for “until now”
sortstring-createdSort field

High-frequency polling (rolling window)

For terminals or integrations that poll every minute or so, narrow what you ask for: keep sort=-created, leave filters empty except pagination, and pass a from timestamp within roughly the last six hours (RFC 3339). Optional to should not be earlier than from. Under those conditions the service may answer directly from a tenant-isolated materialized view that is kept in lockstep whenever orders are created, updated, or removed for that organization—including when marketplace “orders” integrations promote rows from their intake feed into the unified order ledger.

When that path applies, the JSON body is still the same orders.listed list envelope as the database-backed path; only latency and backend routing differ.

Example Request

curl -X GET "https://linkit.works/api/v1/orders?status=delivered&source=salla&limit=50" \
  -H "Authorization: Bearer your_token_here"
const response = await fetch(
  'https://linkit.works/api/v1/orders?status=delivered&source=salla&limit=50',
  { headers: { 'Authorization': 'Bearer your_token_here' } }
);
const body = await response.json();
// body.event_type === "orders.listed"; body.orders[].event_type === "order.snapshot"
import requests

response = requests.get(
    'https://linkit.works/api/v1/orders',
    params={'status': 'delivered', 'source': 'salla', 'limit': 50},
    headers={'Authorization': 'Bearer your_token_here'}
)
body = response.json()

Response

{
  "spec_version": "2026-04-01",
  "event_type": "orders.listed",
  "occurred_at": "2026-04-21T10:30:00.123456789Z",
  "organization_id": "org_abc123",
  "orders": [
    {
      "spec_version": "2026-04-01",
      "event_id": "snapshot-r1234567890abcdef-1713694200123456789",
      "event_type": "order.snapshot",
      "occurred_at": "2026-04-21T10:30:00.123456789Z",
      "organization_id": "org_abc123",
      "organization_app_id": "org_app_install_row_id",
      "app_slug": "salla-orders",
      "order": {
        "id": "r1234567890abcdef",
        "organization_id": "org_abc123",
        "source_reference": "SALLA-ORD-12345",
        "source_transaction_id": "TXN-001",
        "source_timestamp": "2026-04-21T09:00:00Z",
        "destination_id": "store_iv_1",
        "destination_reference": "REF-001",
        "order_status": "RECEIVED",
        "fulfillment_status": "Full",
        "payment_status": "paid",
        "fulfillment_method": "delivery",
        "payment_method": "card",
        "currency": "SAR",
        "total_amount": 45.65,
        "discounts_amount": 0,
        "vat_amount": 0,
        "customer_name": "Ahmed Hassan",
        "products": [],
        "created_at": "2026-04-21T09:05:00Z",
        "updated_at": "2026-04-21T10:00:00Z"
      }
    }
  ],
  "pagination": {
    "page": 1,
    "per_page": 50,
    "total_items": 5432,
    "total_pages": 109,
    "has_next": true,
    "has_prev": false
  },
  "meta": {}
}

Get Single Order

GET /api/v1/orders/{id}

Uses the same authenticated organization scope as list orders. The body is always one UnifiedOrderEventPayload with event_type order.snapshot (same order object as list rows). Cached hot reads return the same shape.

Example (trimmed)

{
  "spec_version": "2026-04-01",
  "event_id": "snapshot-r1234567890abcdef-1713694200123456789",
  "event_type": "order.snapshot",
  "occurred_at": "2026-04-21T10:30:00.123456789Z",
  "organization_id": "org_abc123",
  "organization_app_id": "org_app_install_row_id",
  "app_slug": "salla-orders",
  "order": {
    "id": "r1234567890abcdef",
    "source_reference": "SALLA-ORD-12345",
    "source_transaction_id": "TXN-001",
    "total_amount": 45.65,
    "currency": "SAR",
    "order_status": "RECEIVED",
    "products": []
  }
}

Create Order

POST /api/v1/orders

Request Body

{
  "source": "manual",
  "customer_name": "Sarah Smith",
  "customer_email": "sarah@example.com",
  "customer_phone": "+966509876543",
  "products": [
    {
      "product_id": "prd_001",
      "name": "Product One",
      "quantity": 2,
      "price": 29.99
    }
  ],
  "subtotal": 59.98,
  "tax": 9.00,
  "delivery_fee": 15.00,
  "total_amount": 83.98,
  "currency": "SAR",
  "status": "pending",
  "payment_status": "pending"
}

Required Fields

FieldTypeConstraints
sourcestringOrigin identifier
productsarrayAt least one line item
total_amountnumber>= 0
currencystringISO 4217 code

Response (201 Created)

{
  "success": true,
  "message": "Order created successfully",
  "timestamp": "2026-04-21T10:30:00Z",
  "data": {
    "id": "r1234567890abcdef",
    "order_number": "ORD-2026-001"
  }
}

Update Order

PUT /api/v1/orders/{id}

Full replacement update. Include all fields you want to keep.


Update Order Status

Partial update for status fields only.

PATCH /api/v1/orders/{id}/status

Request Body

{
  "status": "delivered",
  "payment_status": "paid",
  "fulfillment_status": "fulfilled"
}

All fields are optional — include only the statuses you want to change.

Example

curl -X PATCH "https://linkit.works/api/v1/orders/r1234567890abcdef/status" \
  -H "Authorization: Bearer your_token_here" \
  -H "Content-Type: application/json" \
  -d '{"status": "delivered", "payment_status": "paid"}'

Bulk Operations

Bulk Create

POST /api/v1/orders/bulk

Request body is an array of order objects (same structure as single create). Max 1,000 per request.

Bulk Status Update

PATCH /api/v1/orders/bulk/status
{
  "updates": [
    { "id": "order_001", "status": "delivered", "payment_status": "paid" },
    { "id": "order_002", "status": "cancelled" }
  ]
}

Bulk Delete

DELETE /api/v1/orders/bulk
{
  "ids": ["order_001", "order_002", "order_003"]
}

Response (all bulk operations)

{
  "success": true,
  "data": {
    "succeeded": 98,
    "failed": 2,
    "errors": {
      "order_050": "Order not found",
      "order_075": "Invalid status transition"
    }
  },
  "timestamp": "2024-01-15T10:30:00Z"
}

Error Responses

404 Not Found

{
  "code": 404,
  "error": "Order not found",
  "details": { "id": "nonexistent" }
}

422 Validation Error

{
  "code": 422,
  "error": "Validation failed",
  "details": { "products": "At least one product is required" }
}