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.