Orders API
Read orders, change their status and receive every new order as it happens. Built for call centers, carriers, ERPs and COD platforms.
Authentication
Create a credential in the store dashboard, under Settings, Integrations and API. Each credential has a token and a secret and only sees the store that created it. Send both on every request, in one of these ways:
X-Api-Token: 50c6...-2175 X-Api-Secret: secret_ae4e...
Authorization: Basic base64(token:secret)
Older keys starting with pd_live_ still work with Authorization: Bearer pd_live_....
Base URL: https://www.shopqila.com/api/v1. JSON responses, amounts as decimal strings ("129.90") next to the currency. Limit of 600 requests per minute per credential. Errors come as {"error": "...", "field": "..."}.
Endpoints
| GET | /store | Store name, country, currency and language. Handy to test the credential. |
| GET | /orders | List sorted by order number. Filters: status, created_from and created_to (order date, like 2026-10-18, in the store time zone), updated_since (ISO 8601, by last change), after (order number), limit (up to 250). The response has next for pagination. |
| GET | /orders/{number} | One order. |
| PATCH | /orders/{number} | Changes status, tracking, note and tags. Cancelling or returning puts the stock back. |
Status: pending, confirmed, shipped, delivered, cancelled, returned.
curl -X PATCH https://www.shopqila.com/api/v1/orders/1042 \
-H "X-Api-Token: YOUR_TOKEN" -H "X-Api-Secret: YOUR_SECRET" -H "Content-Type: application/json" \
-d '{"status": "shipped", "tracking": {"code": "PL123456", "carrier": "InPost", "url": "https://inpost.pl/sledzenie?n=PL123456"}}'
Order
{
"id": "6f1c...", "number": 1042, "name": "#1042", "status": "pending",
"payment_method": "cod", "payment_status": "pending", "currency": "PLN",
"subtotal": "218.00", "discount": "21.80", "shipping": "0.00", "total": "196.20", "shipping_method": "",
"customer": {"name": "Anna Kowalska", "phone": "+48600123456", "email": ""},
"address": {"country": "PL", "state": "MZ", "state_name": "Mazowieckie", "city": "Warszawa",
"zip": "00-001", "street": "ul. Marszałkowska", "number": "10", "complement": "m. 4",
"neighborhood": "", "reference": ""},
"extra_fields": {}, "items": [{"sku": "SER-30", "title": "Serum", "variant": "30 ml",
"quantity": 2, "price": "109.00", "discount": "21.80", "product_id": "...", "variant_id": "..."}],
"tracking": {"code": "", "carrier": "", "url": ""}, "language": "pl", "channel": "meta", "campaign": "...",
"note": "", "tags": [], "created_at": "2026-10-18T14:02:11Z", "updated_at": "2026-10-18T14:02:11Z",
"shipped_at": null, "delivered_at": null
}
Example with made-up data.
Webhooks and postback
Add the URL (https) in the same place as the credential. Webhook events: order.created and order.updated. Each delivery is a POST with {"event", "source", "sent_at", "order"}; source tells whether the change came from the store, the dashboard or the api. Reply 2xx within 10 seconds; otherwise we retry after 5 and after 30 seconds.
The postback is one per store, fires on order.created, and uses the method you choose: POST and PUT send the same JSON body; GET sends only event, order_id, number, status, payment_method, payment_status, total and currency as query parameters, with no customer data.
Check the signature with the secret (whsec_...). For GET, the signed content is the query string.
X-Shopqila-Event: order.created X-Shopqila-Timestamp: 1760796131 X-Shopqila-Signature: sha256=HMAC_SHA256(secret, timestamp + "." + body) X-Shopqila-Delivery: 9f2c41d0a7b3e8c15d6f0a2b X-Shopqila-Store: store id (the same as GET /store)
The same headers also go out with the X-Paydrop- prefix, for integrations built before the name change.
# Python
import hashlib, hmac
expected = hmac.new(secret.encode(), f"{timestamp}.".encode() + body, hashlib.sha256).hexdigest()
ok = hmac.compare_digest("sha256=" + expected, signature)
// Node
const expected = crypto.createHmac("sha256", secret).update(timestamp + "." + body).digest("hex");
const ok = crypto.timingSafeEqual(Buffer.from("sha256=" + expected), Buffer.from(signature));
Reject deliveries whose timestamp is more than 5 minutes off. A retry repeats the same X-Shopqila-Delivery: store it and ignore what you already got. Each credential and webhook belongs to one store; if you serve several stores, use X-Shopqila-Store and each store's secret.