Skip to content
Syncore

Orders

Orders from all your channels (Skroutz, Shopflix, eMAG, Trendyol, Temu, TikTok Shop, WooCommerce, Shopify, …) and the ones you create yourself through the API.

Endpoint Ability
GET /orders, GET /orders/{id} orders:read
POST /orders orders:write
PATCH /orders/{id}/status orders:write
POST /orders/{id}/shipment orders:write

List

curl -s "https://app.syncore.gr/api/v1/orders?status=pending&updated_since=2026-10-28T00:00:00Z" \
  -H "Authorization: Bearer $SYNCORE_TOKEN"

Filters: status (pending, processing, shipped, completed, cancelled, refunded), source_channel, search (number / customer), placed_from, placed_to, updated_since (ISO 8601), page, per_page.

To sync, keep the time of your last request and ask for updated_since — or use the order.created / order.updated webhooks.

One order

GET /orders/{id} returns the order with its lines:

{
  "data": {
    "id": 5001,
    "order_number": "SK-240001",
    "external_ref": null,
    "source_channel": "skroutz",
    "status": "processing",
    "payment_status": "succeeded",
    "payment_method": "card",
    "currency": "EUR",
    "subtotal": 39.8,
    "shipping_cost": 3.5,
    "total_amount": 43.3,
    "customer": { "name": "Sample Customer", "email": "customer@example.com", "phone": "2100000000" },
    "shipping_address": { "address": "Street 1", "city": "Athens", "postcode": "10000" },
    "billing_address": null,
    "notes": null,
    "shipment": {
      "courier": null,
      "tracking_number": null,
      "shipped_at": null,
      "push_status": null,
      "push_error": null,
      "pushed_at": null
    },
    "placed_at": "2026-10-29T09:40:00+02:00",
    "created_at": "2026-10-29T09:41:00+02:00",
    "updated_at": "2026-10-29T10:00:00+02:00",
    "items": [
      { "id": 9001, "product_id": 1201, "sku": "ABC-1001", "name": "Sample product", "quantity": 2, "unit_price": 19.9, "total_price": 39.8 }
    ]
  }
}

Create an order from your own store

POST /orders records an order from your own store (source_channel: "api"). It is idempotent on external_ref: sending the same value again returns the existing order with 200 instead of 201.

curl -s -X POST "https://app.syncore.gr/api/v1/orders" \
  -H "Authorization: Bearer $SYNCORE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "external_ref": "SHOP-10045",
    "order_number": "10045",
    "currency": "EUR",
    "shipping_cost": 3.5,
    "payment_method": "cod",
    "customer": { "name": "Sample Customer", "email": "customer@example.com", "phone": "2100000000" },
    "shipping_address": { "address": "Street 1", "city": "Athens", "postcode": "10000" },
    "items": [ { "sku": "ABC-1001", "quantity": 2, "unit_price": 19.9 } ]
  }'

Required: external_ref and items (1–500 lines, each with sku, quantity ≥ 1, unit_price).

Change status

curl -s -X PATCH "https://app.syncore.gr/api/v1/orders/5001/status" \
  -H "Authorization: Bearer $SYNCORE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"status": "processing"}'

Only the next step pending → processing → shipped → completed is allowed, or cancelled from any non-final status. Any other transition answers 422 with errors.status = ["transition_not_allowed"] and allowed (what is allowed now).

Shipment (courier & tracking number)

POST /orders/{id}/shipment marks the order shipped and sends the courier and tracking number (voucher) back to the order's channel — Skroutz, Shopflix, eMAG, Trendyol, Temu or TikTok Shop.

curl -s -X POST "https://app.syncore.gr/api/v1/orders/5001/shipment" \
  -H "Authorization: Bearer $SYNCORE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"courier": "ACS", "tracking_number": "1234567890"}'

Sending to the channel is queued. Progress shows in shipment.push_status:

push_status Meaning
pending Queued
success The channel accepted it
failed Failed — see shipment.push_error
skipped The channel does not need / support tracking details

Repeating with the same details retries only if it has not already succeeded. Every change sends an order.updated webhook.