Sapa Moto

Sapa Moto Partner API

Price a delivery, create orders, follow the courier and receive signed webhooks — from your own order system.

The Partner API connects your shop, restaurant or warehouse system to Sapa Moto couriers in Almaty. Everything a manager does in the cabinet can be done by your system: price a delivery, create and change orders, cancel them, follow the courier, fetch proof of delivery — and get a signed webhook on every status change.

How it works

  1. Quote — POST /v1/quotes returns the price, its breakdown and the ETA. The price holds for 10 minutes.
  2. Order — POST /v1/orders creates the order (with the quote's price). You get a tracking_url for the recipient and a delivery_code the recipient tells the courier.
  3. Ready — POST /v1/orders/{id}/ready when the order is packed (optional; otherwise the point's assembly norm applies).
  4. Events — webhooks order.status_changed, order.courier_assigned, order.eta_changed, order.delivered…
  5. Proof — GET /v1/orders/{id}/proof: photo, code check, geopoint and time.

Environments and keys

  • https://partner-sandbox.sapamoto.kz/v1 — Sandbox — test keys sk_test_…, virtual courier, no money
  • https://partner.sapamoto.kz/v1 — Production — live keys sk_live_…
SandboxProduction
Keysk_test_…sk_live_…
Availableright after your organization is createdafter the integration checklist and the contract
Couriersa virtual courier, 2–3 minutes per orderreal couriers
Moneynone — never in invoices or reportsinvoices, deposit, cash on delivery
Paths and payloadsidenticalidentical

Create keys in the cabinet, section «Интеграция». A key is shown once; store it in your secret manager. See Authentication.

First order in 5 minutes

You need a test key (sk_test_…). The sandbox accepts addresses with coordinates, so you do not need a pickup point yet.

1. Price the delivery

curl https://partner-sandbox.sapamoto.kz/v1/quotes \
  -H "Authorization: Bearer $SAPA_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "pickup":  {"address": "Алматы, Абая 10", "latitude": 43.2389, "longitude": 76.9286},
    "dropoff": {"address": "Алматы, Жандосова 58", "latitude": 43.214, "longitude": 76.88}
  }'

The answer is 201 with quote_id, price ({"amount": 145000, "currency": "KZT"} — 1 450 ₸ in tiyn), breakdown, eta_minutes and valid_until.

2. Create the order

Pass the quote_id, your own order number as external_id and a fresh Idempotency-Key — so a retry after a timeout never creates a second order.

curl https://partner-sandbox.sapamoto.kz/v1/orders \
  -H "Authorization: Bearer $SAPA_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "external_id": "SHOP-100245",
    "quote_id": "'"$QUOTE_ID"'",
    "pickup":  {"address": "Алматы, Абая 10", "latitude": 43.2389, "longitude": 76.9286},
    "dropoff": {"address": "Алматы, Жандосова 58", "latitude": 43.214, "longitude": 76.88, "apartment": "41"},
    "recipient": {"name": "Мадина", "phone": "+77011234567"},
    "comment": "Позвонить за 10 минут"
  }'

The order starts in created. In the sandbox a virtual courier picks it up within seconds and takes it to delivered in about two minutes.

3. Follow it

curl
curl https://partner-sandbox.sapamoto.kz/v1/orders/SHOP-100245 -H "Authorization: Bearer $SAPA_KEY"

{id} accepts our id or your external_id. Better than polling: add a webhook endpoint in the cabinet (or with POST /v1/webhooks) and receive signed events for every change.

4. Go live

When the sandbox flow works, pass the integration checklist in the cabinet — an order created, a webhook accepted with a valid signature, a retried webhook handled, a cancellation, a failed delivery. Your account manager then enables live keys. Switch the host to partner.sapamoto.kz and the key to sk_live_… — nothing else changes.

Conventions

  • JSON, UTF-8, snake_case. Ignore unknown fields — we add fields within v1.
  • Money — {"amount": <integer tiyn>, "currency": "KZT"}; 1 ₸ = 100 tiyn. Request fields that end in _tiyn are plain integers in tiyn.
  • Time — ISO 8601 with an offset (2026-10-24T15:00:00+05:00); responses are in UTC (Z).
  • Coordinates — WGS-84 decimal degrees.
  • Errors — application/problem+json with a stable code — see Errors.
  • Request id — every response has X-Request-Id; send your own to correlate logs.

These docs are built from the platform's OpenAPI specification. Download OpenAPI