{"openapi":"3.1.0","info":{"title":"Scanimart Connect API","version":"2026-10-01","description":"Connect a POS system to Scanimart stores: receive online orders, accept or reject them, follow delivery, sync inventory, and book every Scanimart sale. Guides and webhook reference: https://developers.scanimart.com"},"paths":{"/v1/connections/claim":{"post":{"operationId":"claimConnection","description":"The store owner generates a code in the Scanimart retailer app (Settings → POS software → Connect your POS) and enters it in your POS. Exchange it here for access to that store. Codes expire after 15 minutes and work once. Claiming a store you are already connected to returns the existing link. Needs a company-wide key: the store joins your whole company.","summary":"Connect a store with its one-time code","parameters":[{"in":"header","name":"Idempotency-Key","schema":{"type":"string"},"description":"Any unique string (a UUID is ideal). Retrying with the same key returns the first result instead of acting twice. Kept for 24 hours."}],"tags":["Stores"],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClaimInputRequest"}},"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/ClaimInputRequest"}},"multipart/form-data":{"schema":{"$ref":"#/components/schemas/ClaimInputRequest"}}},"required":true},"security":[{"ApiKey":[]}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StoreLink"}}},"description":""},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StoreLink"}}},"description":""},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":""},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"`key_scope_insufficient`: the key is store-scoped. Only a company-wide key can claim connection codes. Nothing was done. The Idempotency-Key, if you sent one, was not used up: retry it with a company-wide key."}}}},"/v1/events":{"get":{"operationId":"listEvents","description":"Order events at your connected stores, oldest first -- the same bodies webhooks carry. Use it to recover anything your endpoint missed. Covers the last 30 days.","summary":"List events","parameters":[{"in":"query","name":"cursor","schema":{"type":"string"},"description":"Opaque cursor from a previous page's `next_cursor`."},{"in":"query","name":"limit","schema":{"type":"integer"},"description":"Page size, 1–100. Default 50."},{"in":"query","name":"since","schema":{"type":"string"},"description":"ISO 8601."},{"in":"query","name":"store_id","schema":{"type":"integer"}},{"in":"query","name":"type","schema":{"type":"string","enum":["delivery.courier_assigned","delivery.courier_booked","delivery.failed","delivery.rider_changed","order.accepted","order.cancelled","order.delivered","order.fulfilment_changed","order.out_for_delivery","order.packed","order.payment_failed","order.payment_recovered","order.picking_started","order.placed","sale.completed","sale.exit_verified"]}}],"tags":["Sales and events"],"security":[{"ApiKey":[]}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EventList"}}},"description":""}}}},"/v1/ping":{"get":{"operationId":"ping","description":"Returns the company and key you are authenticated as. The first call to make.","summary":"Check your key","tags":["Account"],"security":[{"ApiKey":[]}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ping"}}},"description":""}}}},"/v1/sandbox/instore-sales":{"post":{"operationId":"simulateInstoreSale","description":"Requires a company-wide test key.","summary":"Simulate an in-store Scan & Go sale","tags":["Sandbox"],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SandboxOrderInputRequest"}},"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/SandboxOrderInputRequest"}},"multipart/form-data":{"schema":{"$ref":"#/components/schemas/SandboxOrderInputRequest"}}}},"security":[{"ApiKey":[]}],"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SandboxOrderCreated"}}},"description":""}}}},"/v1/sandbox/orders":{"post":{"operationId":"simulateOrder","description":"Creates a paid delivery order at your test store and sends `order.placed`. Requires a company-wide test key. Sandbox only.","summary":"Simulate a paid online order","tags":["Sandbox"],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SandboxOrderInputRequest"}},"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/SandboxOrderInputRequest"}},"multipart/form-data":{"schema":{"$ref":"#/components/schemas/SandboxOrderInputRequest"}}}},"security":[{"ApiKey":[]}],"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SandboxOrderCreated"}}},"description":""}}}},"/v1/sandbox/orders/{order_id}/advance":{"post":{"operationId":"simulateOrderProgress","description":"Play the store, rider or customer: ACCEPTED (from the retailer app), PACKED, OUT_FOR_DELIVERY, DELIVERED, or CANCELLED (by the customer). Requires a company-wide test key.","summary":"Move a test order on","parameters":[{"in":"path","name":"order_id","schema":{"type":"string"},"required":true}],"tags":["Sandbox"],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SandboxAdvanceInputRequest"}},"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/SandboxAdvanceInputRequest"}},"multipart/form-data":{"schema":{"$ref":"#/components/schemas/SandboxAdvanceInputRequest"}}},"required":true},"security":[{"ApiKey":[]}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SandboxAdvanced"}}},"description":""}}}},"/v1/sandbox/reset":{"post":{"operationId":"resetSandbox","description":"Deletes the test store's orders and restores every product to 50 units. Requires a company-wide test key.","summary":"Reset the test store","tags":["Sandbox"],"security":[{"ApiKey":[]}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SandboxReset"}}},"description":""}}}},"/v1/stores":{"get":{"operationId":"listStores","description":"Only stores with an active connection to the POS company authenticated by your API key, in that key's live or test mode. A store-scoped key returns only its own connected store. Unconnected stores, revoked connections and other POS companies' stores are never listed.","summary":"List connected stores","tags":["Stores"],"security":[{"ApiKey":[]}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StoreList"}}},"description":""}}}},"/v1/stores/{store_id}":{"get":{"operationId":"getStore","summary":"Get a connected store","parameters":[{"in":"path","name":"store_id","schema":{"type":"integer"},"required":true}],"tags":["Stores"],"security":[{"ApiKey":[]}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Store"}}},"description":""},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":""}}}},"/v1/stores/{store_id}/disconnect":{"post":{"operationId":"disconnectStore","description":"Stops all events for the store and revokes your access to it. The store can reconnect with a new code.","summary":"Disconnect a store","parameters":[{"in":"path","name":"store_id","schema":{"type":"integer"},"required":true}],"tags":["Stores"],"security":[{"ApiKey":[]}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StoreLink"}}},"description":""}}}},"/v1/stores/{store_id}/inventory":{"get":{"operationId":"listInventory","description":"Stock as Scanimart sees it, with units reserved for paid online orders.","summary":"List stock","parameters":[{"in":"query","name":"barcode","schema":{"type":"string"}},{"in":"query","name":"cursor","schema":{"type":"string"},"description":"Opaque cursor from a previous page's `next_cursor`."},{"in":"query","name":"limit","schema":{"type":"integer"},"description":"Page size, 1–100. Default 50."},{"in":"path","name":"store_id","schema":{"type":"integer"},"required":true}],"tags":["Inventory"],"security":[{"ApiKey":[]}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InventoryList"}}},"description":""}}},"put":{"operationId":"pushInventory","description":"Set the shelf count for up to 1,000 barcodes. Your POS owns the count; Scanimart subtracts the units in its own sales that you had not booked by `as_of` (see `adjusted_for_unbooked_sales`), so a count taken before you booked a Scanimart sale never puts sold stock back on the shelf.\n\nUp to 200 items are applied immediately (200). Larger pushes are queued (202): poll `GET …/inventory/syncs/{id}`. Unknown barcodes need `name`; rows that fail are listed in `errors` and the rest still apply.","summary":"Push stock counts","parameters":[{"in":"header","name":"Idempotency-Key","schema":{"type":"string"},"description":"Any unique string (a UUID is ideal). Retrying with the same key returns the first result instead of acting twice. Kept for 24 hours."},{"in":"path","name":"store_id","schema":{"type":"integer"},"required":true}],"tags":["Inventory"],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InventoryPushInputRequest"}},"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/InventoryPushInputRequest"}},"multipart/form-data":{"schema":{"$ref":"#/components/schemas/InventoryPushInputRequest"}}},"required":true},"security":[{"ApiKey":[]}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InventorySync"}}},"description":""},"202":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InventorySync"}}},"description":""},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":""}}}},"/v1/stores/{store_id}/inventory/adjustments":{"post":{"operationId":"adjustInventory","description":"Move stock by a delta per barcode -- a counter sale (−2), a delivery received (+24). Never takes stock below zero. Send an `Idempotency-Key`: an adjustment applied twice is a wrong shelf count.","summary":"Adjust stock","parameters":[{"in":"header","name":"Idempotency-Key","schema":{"type":"string"},"description":"Any unique string (a UUID is ideal). Retrying with the same key returns the first result instead of acting twice. Kept for 24 hours."},{"in":"path","name":"store_id","schema":{"type":"integer"},"required":true}],"tags":["Inventory"],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdjustmentsInputRequest"}},"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/AdjustmentsInputRequest"}},"multipart/form-data":{"schema":{"$ref":"#/components/schemas/AdjustmentsInputRequest"}}},"required":true},"security":[{"ApiKey":[]}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InventorySync"}}},"description":""},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":""}}}},"/v1/stores/{store_id}/inventory/syncs":{"get":{"operationId":"listInventorySyncs","summary":"List recent stock pushes","parameters":[{"in":"query","name":"limit","schema":{"type":"integer"},"description":"Page size, 1–100. Default 50."},{"in":"path","name":"store_id","schema":{"type":"integer"},"required":true}],"tags":["Inventory"],"security":[{"ApiKey":[]}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InventorySyncList"}}},"description":""}}}},"/v1/stores/{store_id}/inventory/syncs/{run_id}":{"get":{"operationId":"getInventorySync","summary":"Get a stock push","parameters":[{"in":"path","name":"run_id","schema":{"type":"string","format":"uuid"},"required":true},{"in":"path","name":"store_id","schema":{"type":"integer"},"required":true}],"tags":["Inventory"],"security":[{"ApiKey":[]}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InventorySync"}}},"description":""},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":""}}}},"/v1/stores/{store_id}/orders":{"get":{"operationId":"listOrders","description":"Newest first. Use `updated_since` to catch up on anything a missed webhook would have told you.","summary":"List orders","parameters":[{"in":"query","name":"cursor","schema":{"type":"string"},"description":"Opaque cursor from a previous page's `next_cursor`."},{"in":"query","name":"limit","schema":{"type":"integer"},"description":"Page size, 1–100. Default 50."},{"in":"query","name":"status","schema":{"type":"string","enum":["ACCEPTED","CANCELLED","COMPLETED","DELIVERED","OUT_FOR_DELIVERY","PACKED","PAYMENT_FAILED","PENDING"]}},{"in":"path","name":"store_id","schema":{"type":"integer"},"required":true},{"in":"query","name":"type","schema":{"type":"string","enum":["delivery","instore"]},"description":"Default: delivery."},{"in":"query","name":"updated_since","schema":{"type":"string"},"description":"ISO 8601. Orders with any event since then."}],"tags":["Orders"],"security":[{"ApiKey":[]}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrderList"}}},"description":""}}}},"/v1/stores/{store_id}/orders/{order_id}":{"get":{"operationId":"getOrder","summary":"Get an order","parameters":[{"in":"path","name":"order_id","schema":{"type":"string"},"required":true},{"in":"path","name":"store_id","schema":{"type":"integer"},"required":true}],"tags":["Orders"],"security":[{"ApiKey":[]}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Order"}}},"description":""},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":""}}}},"/v1/stores/{store_id}/orders/{order_id}/accept":{"post":{"operationId":"acceptOrder","description":"Accept a PENDING delivery order and choose who delivers it. The store's retailer app can accept too: whichever acts first wins, and the other gets `order_not_in_required_state`.","summary":"Accept an order","parameters":[{"in":"header","name":"Idempotency-Key","schema":{"type":"string"},"description":"Any unique string (a UUID is ideal). Retrying with the same key returns the first result instead of acting twice. Kept for 24 hours."},{"in":"path","name":"order_id","schema":{"type":"string"},"required":true},{"in":"path","name":"store_id","schema":{"type":"integer"},"required":true}],"tags":["Orders"],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AcceptInputRequest"}},"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/AcceptInputRequest"}},"multipart/form-data":{"schema":{"$ref":"#/components/schemas/AcceptInputRequest"}}}},"security":[{"ApiKey":[]}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Order"}}},"description":""},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":""},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":""}}}},"/v1/stores/{store_id}/orders/{order_id}/courier/retry":{"post":{"operationId":"retryCourier","description":"After `delivery.failed` (no courier available), ask Scanimart to try again.","summary":"Retry booking a courier","parameters":[{"in":"path","name":"order_id","schema":{"type":"string"},"required":true},{"in":"path","name":"store_id","schema":{"type":"integer"},"required":true}],"tags":["Orders"],"security":[{"ApiKey":[]}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Order"}}},"description":""},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":""}}}},"/v1/stores/{store_id}/orders/{order_id}/delivery-method":{"post":{"operationId":"changeDeliveryMethod","description":"Hand a Scanimart-courier order back to the store's own riders -- e.g. no courier could be booked. Any booked courier is cancelled. Only before the order is out for delivery.","summary":"Switch to store delivery","parameters":[{"in":"header","name":"Idempotency-Key","schema":{"type":"string"},"description":"Any unique string (a UUID is ideal). Retrying with the same key returns the first result instead of acting twice. Kept for 24 hours."},{"in":"path","name":"order_id","schema":{"type":"string"},"required":true},{"in":"path","name":"store_id","schema":{"type":"integer"},"required":true}],"tags":["Orders"],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeliveryMethodInputRequest"}},"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/DeliveryMethodInputRequest"}},"multipart/form-data":{"schema":{"$ref":"#/components/schemas/DeliveryMethodInputRequest"}}},"required":true},"security":[{"ApiKey":[]}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Order"}}},"description":""},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":""}}}},"/v1/stores/{store_id}/orders/{order_id}/delivery-options":{"get":{"operationId":"getDeliveryOptions","description":"What the store may choose when accepting, with the commission each costs the store.","summary":"Delivery options for an order","parameters":[{"in":"path","name":"order_id","schema":{"type":"string"},"required":true},{"in":"path","name":"store_id","schema":{"type":"integer"},"required":true}],"tags":["Orders"],"security":[{"ApiKey":[]}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeliveryOptionList"}}},"description":""}}}},"/v1/stores/{store_id}/orders/{order_id}/reject":{"post":{"operationId":"rejectOrder","description":"Reject a PENDING delivery order. The customer is refunded and the reserved stock released.","summary":"Reject an order","parameters":[{"in":"header","name":"Idempotency-Key","schema":{"type":"string"},"description":"Any unique string (a UUID is ideal). Retrying with the same key returns the first result instead of acting twice. Kept for 24 hours."},{"in":"path","name":"order_id","schema":{"type":"string"},"required":true},{"in":"path","name":"store_id","schema":{"type":"integer"},"required":true}],"tags":["Orders"],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RejectInputRequest"}},"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/RejectInputRequest"}},"multipart/form-data":{"schema":{"$ref":"#/components/schemas/RejectInputRequest"}}}},"security":[{"ApiKey":[]}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Order"}}},"description":""},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":""},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":""}}}},"/v1/stores/{store_id}/sales":{"get":{"operationId":"listSales","description":"Every Scanimart sale at the store -- delivered online orders and paid in-store Scan & Go -- oldest first, for booking into your POS. The same sales arrive as `sale.completed` webhooks; this is the pull fallback. Covers the last 30 days.","summary":"List completed sales","parameters":[{"in":"query","name":"cursor","schema":{"type":"string"},"description":"Opaque cursor from a previous page's `next_cursor`."},{"in":"query","name":"limit","schema":{"type":"integer"},"description":"Page size, 1–100. Default 50."},{"in":"query","name":"since","schema":{"type":"string"},"description":"ISO 8601."},{"in":"path","name":"store_id","schema":{"type":"integer"},"required":true}],"tags":["Sales and events"],"security":[{"ApiKey":[]}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaleList"}}},"description":""}}}},"/v1/stores/{store_id}/sales/ack":{"post":{"operationId":"acknowledgeSales","description":"For integrations that pull sales instead of receiving webhooks: tell Scanimart which sales you have booked, so stock you push afterwards is not adjusted for them. A 2xx to a `sale.completed` webhook does this automatically.","summary":"Acknowledge booked sales","parameters":[{"in":"header","name":"Idempotency-Key","schema":{"type":"string"},"description":"Any unique string (a UUID is ideal). Retrying with the same key returns the first result instead of acting twice. Kept for 24 hours."},{"in":"path","name":"store_id","schema":{"type":"integer"},"required":true}],"tags":["Sales and events"],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaleAckInputRequest"}},"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/SaleAckInputRequest"}},"multipart/form-data":{"schema":{"$ref":"#/components/schemas/SaleAckInputRequest"}}},"required":true},"security":[{"ApiKey":[]}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaleAck"}}},"description":""}}}},"/v1/webhook-deliveries/{delivery_id}/retry":{"post":{"operationId":"retryWebhookDelivery","description":"Re-sends a failed or given-up delivery straight away.","summary":"Retry a delivery now","parameters":[{"in":"path","name":"delivery_id","schema":{"type":"integer"},"required":true}],"tags":["Webhook endpoints"],"security":[{"ApiKey":[]}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookDelivery"}}},"description":""},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"`key_scope_insufficient`: the key is store-scoped. Only a company-wide key can manage webhook endpoints. Nothing was done."}}}},"/v1/webhook-endpoints":{"get":{"operationId":"listWebhookEndpoints","summary":"List webhook endpoints","tags":["Webhook endpoints"],"security":[{"ApiKey":[]}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEndpointList"}}},"description":""},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"`key_scope_insufficient`: the key is store-scoped. Only a company-wide key can manage webhook endpoints. Nothing was done."}}},"post":{"operationId":"createWebhookEndpoint","description":"The response includes the signing `secret`, shown only now and when rolled.","summary":"Add a webhook endpoint","parameters":[{"in":"header","name":"Idempotency-Key","schema":{"type":"string"},"description":"Any unique string (a UUID is ideal). Retrying with the same key returns the first result instead of acting twice. Kept for 24 hours."}],"tags":["Webhook endpoints"],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEndpointInputRequest"}},"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/WebhookEndpointInputRequest"}},"multipart/form-data":{"schema":{"$ref":"#/components/schemas/WebhookEndpointInputRequest"}}},"required":true},"security":[{"ApiKey":[]}],"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEndpoint"}}},"description":""},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":""},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"`key_scope_insufficient`: the key is store-scoped. Only a company-wide key can manage webhook endpoints. Nothing was done. The Idempotency-Key, if you sent one, was not used up: retry it with a company-wide key."}}}},"/v1/webhook-endpoints/{endpoint_id}":{"get":{"operationId":"getWebhookEndpoint","description":"Looks up one of the caller's endpoints. Holds no handlers itself: the\nsub-resource views (roll-secret, test, deliveries) inherit only this, never\nthe detail view's GET/PATCH/DELETE -- otherwise DELETE .../test would\ndelete the endpoint.","summary":"Get a webhook endpoint","parameters":[{"in":"path","name":"endpoint_id","schema":{"type":"string","format":"uuid"},"required":true}],"tags":["Webhook endpoints"],"security":[{"ApiKey":[]}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEndpoint"}}},"description":""},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"`key_scope_insufficient`: the key is store-scoped. Only a company-wide key can manage webhook endpoints. Nothing was done."}}},"patch":{"operationId":"updateWebhookEndpoint","description":"Setting `status` to ACTIVE re-enables an endpoint that was switched off after repeated failures.","summary":"Update a webhook endpoint","parameters":[{"in":"path","name":"endpoint_id","schema":{"type":"string","format":"uuid"},"required":true}],"tags":["Webhook endpoints"],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PatchedWebhookEndpointPatchRequest"}},"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/PatchedWebhookEndpointPatchRequest"}},"multipart/form-data":{"schema":{"$ref":"#/components/schemas/PatchedWebhookEndpointPatchRequest"}}}},"security":[{"ApiKey":[]}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEndpoint"}}},"description":""},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"`key_scope_insufficient`: the key is store-scoped. Only a company-wide key can manage webhook endpoints. Nothing was done."}}},"delete":{"operationId":"deleteWebhookEndpoint","description":"Looks up one of the caller's endpoints. Holds no handlers itself: the\nsub-resource views (roll-secret, test, deliveries) inherit only this, never\nthe detail view's GET/PATCH/DELETE -- otherwise DELETE .../test would\ndelete the endpoint.","summary":"Delete a webhook endpoint","parameters":[{"in":"path","name":"endpoint_id","schema":{"type":"string","format":"uuid"},"required":true}],"tags":["Webhook endpoints"],"security":[{"ApiKey":[]}],"responses":{"204":{"description":"No response body"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"`key_scope_insufficient`: the key is store-scoped. Only a company-wide key can manage webhook endpoints. Nothing was done."}}}},"/v1/webhook-endpoints/{endpoint_id}/deliveries":{"get":{"operationId":"listWebhookDeliveries","description":"Looks up one of the caller's endpoints. Holds no handlers itself: the\nsub-resource views (roll-secret, test, deliveries) inherit only this, never\nthe detail view's GET/PATCH/DELETE -- otherwise DELETE .../test would\ndelete the endpoint.","summary":"List deliveries to an endpoint","parameters":[{"in":"query","name":"cursor","schema":{"type":"string"},"description":"Opaque cursor from a previous page's `next_cursor`."},{"in":"path","name":"endpoint_id","schema":{"type":"string","format":"uuid"},"required":true},{"in":"query","name":"limit","schema":{"type":"integer"},"description":"Page size, 1–100. Default 50."},{"in":"query","name":"status","schema":{"type":"string","enum":["DEAD","PENDING","SUCCEEDED"]}}],"tags":["Webhook endpoints"],"security":[{"ApiKey":[]}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookDeliveryList"}}},"description":""},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"`key_scope_insufficient`: the key is store-scoped. Only a company-wide key can manage webhook endpoints. Nothing was done."}}}},"/v1/webhook-endpoints/{endpoint_id}/roll-secret":{"post":{"operationId":"rollWebhookSecret","description":"The old secret stops working immediately. Update your receiver before calling this.","summary":"Roll the signing secret","parameters":[{"in":"path","name":"endpoint_id","schema":{"type":"string","format":"uuid"},"required":true}],"tags":["Webhook endpoints"],"security":[{"ApiKey":[]}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEndpoint"}}},"description":""},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"`key_scope_insufficient`: the key is store-scoped. Only a company-wide key can manage webhook endpoints. Nothing was done."}}}},"/v1/webhook-endpoints/{endpoint_id}/test":{"post":{"operationId":"sendTestEvent","description":"Sends one event to this endpoint now and reports how it answered. With `bad_signature: true` the signature is deliberately wrong -- a correct receiver answers 4xx (this is on the go-live checklist).","summary":"Send a test event","parameters":[{"in":"path","name":"endpoint_id","schema":{"type":"string","format":"uuid"},"required":true}],"tags":["Webhook endpoints"],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestEventInputRequest"}},"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/TestEventInputRequest"}},"multipart/form-data":{"schema":{"$ref":"#/components/schemas/TestEventInputRequest"}}}},"security":[{"ApiKey":[]}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookDelivery"}}},"description":""},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"`key_scope_insufficient`: the key is store-scoped. Only a company-wide key can manage webhook endpoints. Nothing was done."}}}}},"components":{"schemas":{"AcceptInputRequest":{"type":"object","properties":{"fulfilment_mode":{"allOf":[{"$ref":"#/components/schemas/FulfilmentModeEnum"}],"description":"Defaults to STORE_STAFF.\n\n* `STORE_STAFF` - STORE_STAFF\n* `SCANIMART_COURIER` - SCANIMART_COURIER"},"external_id":{"type":"string","minLength":1,"description":"Your bill or order number; echoed in every later event.","maxLength":120}}},"AcceptedViaEnum":{"enum":["APP","POS"],"type":"string","description":"* `APP` - APP\n* `POS` - POS"},"AdjustmentInputRequest":{"type":"object","properties":{"barcode":{"type":"string","minLength":1,"maxLength":225},"delta":{"type":"integer","description":"Units to add (positive) or remove (negative)."},"reason":{"allOf":[{"$ref":"#/components/schemas/ReasonEnum"}],"default":"other"},"reference":{"type":"string","minLength":1,"description":"Your bill or GRN number.","maxLength":120}},"required":["barcode","delta"]},"AdjustmentsInputRequest":{"type":"object","properties":{"adjustments":{"type":"array","items":{"$ref":"#/components/schemas/AdjustmentInputRequest"}}},"required":["adjustments"]},"ClaimInputRequest":{"type":"object","properties":{"code":{"type":"string","minLength":1,"description":"The 8-character code the store generated in the Scanimart retailer app, e.g. `K7Q2-M9XP`."}},"required":["code"]},"ConnectModeEnum":{"enum":["live","test"],"type":"string","description":"* `live` - live\n* `test` - test"},"Courier":{"type":"object","properties":{"provider":{"type":["string","null"],"description":"e.g. porter."},"status":{"$ref":"#/components/schemas/CourierStatusEnum"},"tracking_url":{"type":["string","null"],"format":"uri"},"rider_name":{"type":["string","null"]},"rider_phone":{"type":["string","null"]},"vehicle":{"type":["string","null"]},"eta_minutes":{"type":["integer","null"]}},"required":["provider","status"]},"CourierStatusEnum":{"enum":["NOT_REQUESTED","REQUESTED","BOOKED","ASSIGNED","PICKED_UP","DELIVERED","CANCELLED","FAILED"],"type":"string","description":"* `NOT_REQUESTED` - NOT_REQUESTED\n* `REQUESTED` - REQUESTED\n* `BOOKED` - BOOKED\n* `ASSIGNED` - ASSIGNED\n* `PICKED_UP` - PICKED_UP\n* `DELIVERED` - DELIVERED\n* `CANCELLED` - CANCELLED\n* `FAILED` - FAILED"},"DeliveryMethodInputFulfilmentModeEnum":{"enum":["STORE_STAFF"],"type":"string","description":"* `STORE_STAFF` - STORE_STAFF"},"DeliveryMethodInputRequest":{"type":"object","properties":{"fulfilment_mode":{"$ref":"#/components/schemas/DeliveryMethodInputFulfilmentModeEnum"}},"required":["fulfilment_mode"]},"DeliveryOption":{"type":"object","properties":{"mode":{"$ref":"#/components/schemas/FulfilmentModeEnum"},"available":{"type":"boolean"},"reason":{"type":["string","null"]},"commission_percent":{"type":["string","null"],"format":"decimal","pattern":"^-?\\d{0,3}(?:\\.\\d{0,2})?$"},"commission_amount":{"type":["string","null"],"format":"decimal","pattern":"^-?\\d{0,8}(?:\\.\\d{0,2})?$"},"eta_minutes":{"type":["integer","null"]}},"required":["available","commission_amount","commission_percent","eta_minutes","mode","reason"]},"DeliveryOptionList":{"type":"object","properties":{"object":{"type":"string","default":"list"},"data":{"type":"array","items":{"$ref":"#/components/schemas/DeliveryOption"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"],"description":"Pass as `cursor` to get the next page."}},"required":["data","has_more","next_cursor"]},"Error":{"type":"object","properties":{"error":{"$ref":"#/components/schemas/ErrorDetail"}},"required":["error"]},"ErrorDetail":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable reason, e.g. `order_not_found`."},"message":{"type":"string","description":"Human-readable explanation. May change; do not parse."},"details":{"description":"Per-field problems, for `invalid_request`."}},"required":["code","message"]},"Event":{"type":"object","properties":{"id":{"type":"string","description":"Unique; dedupe on it. Deliveries are at-least-once."},"object":{"type":"string","default":"event"},"type":{"$ref":"#/components/schemas/EventTypeEnum"},"api_version":{"type":"string"},"mode":{"$ref":"#/components/schemas/ConnectModeEnum"},"created_at":{"type":"string","format":"date-time"},"store_id":{"type":["integer","null"]},"data":{"description":"`order`, `actor`, and per type `previous_status`, `reason`, `channel`, `sale`."}},"required":["api_version","created_at","data","id","mode","store_id","type"]},"EventList":{"type":"object","properties":{"object":{"type":"string","default":"list"},"data":{"type":"array","items":{"$ref":"#/components/schemas/Event"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"],"description":"Pass as `cursor` to get the next page."}},"required":["data","has_more","next_cursor"]},"EventTypeEnum":{"enum":["order.placed","order.accepted","order.cancelled","order.payment_failed","order.payment_recovered","order.picking_started","order.packed","order.out_for_delivery","order.delivered","sale.completed","sale.exit_verified","order.fulfilment_changed","delivery.courier_booked","delivery.courier_assigned","delivery.rider_changed","delivery.failed","store.connected","store.disconnected","ping"],"type":"string","description":"* `order.placed` - order.placed\n* `order.accepted` - order.accepted\n* `order.cancelled` - order.cancelled\n* `order.payment_failed` - order.payment_failed\n* `order.payment_recovered` - order.payment_recovered\n* `order.picking_started` - order.picking_started\n* `order.packed` - order.packed\n* `order.out_for_delivery` - order.out_for_delivery\n* `order.delivered` - order.delivered\n* `sale.completed` - sale.completed\n* `sale.exit_verified` - sale.exit_verified\n* `order.fulfilment_changed` - order.fulfilment_changed\n* `delivery.courier_booked` - delivery.courier_booked\n* `delivery.courier_assigned` - delivery.courier_assigned\n* `delivery.rider_changed` - delivery.rider_changed\n* `delivery.failed` - delivery.failed\n* `store.connected` - store.connected\n* `store.disconnected` - store.disconnected\n* `ping` - ping"},"FulfilmentModeEnum":{"enum":["STORE_STAFF","SCANIMART_COURIER"],"type":"string","description":"* `STORE_STAFF` - STORE_STAFF\n* `SCANIMART_COURIER` - SCANIMART_COURIER"},"InventoryItem":{"type":"object","properties":{"object":{"type":"string","default":"inventory_item"},"barcode":{"type":["string","null"]},"name":{"type":["string","null"]},"stock":{"type":"integer","description":"Units on the shelf."},"reserved":{"type":"integer","description":"Units held for paid online orders not yet accepted."},"available":{"type":"integer","description":"stock − reserved: what can still be sold."},"mrp":{"type":["string","null"],"format":"decimal","pattern":"^-?\\d{0,8}(?:\\.\\d{0,2})?$"},"price":{"type":["string","null"],"format":"decimal","pattern":"^-?\\d{0,8}(?:\\.\\d{0,2})?$","description":"The store's selling price."},"expiry_date":{"type":["string","null"],"format":"date"},"low_stock_threshold":{"type":"integer"},"source":{"oneOf":[{"$ref":"#/components/schemas/InventoryItemSourceEnum"},{"$ref":"#/components/schemas/NullEnum"}]},"external_id":{"type":["string","null"]}},"required":["available","barcode","expiry_date","external_id","low_stock_threshold","mrp","name","price","reserved","source","stock"]},"InventoryItemSourceEnum":{"enum":["catalog","store_item"],"type":"string","description":"* `catalog` - catalog\n* `store_item` - store_item"},"InventoryList":{"type":"object","properties":{"object":{"type":"string","default":"list"},"data":{"type":"array","items":{"$ref":"#/components/schemas/InventoryItem"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"],"description":"Pass as `cursor` to get the next page."}},"required":["data","has_more","next_cursor"]},"InventoryPushInputRequest":{"type":"object","properties":{"as_of":{"type":"string","format":"date-time","description":"When your POS took this count. Always send it: Scanimart sales you had not booked by then are subtracted. Defaults to now."},"items":{"type":"array","items":{"$ref":"#/components/schemas/InventoryRowInputRequest"}}},"required":["items"]},"InventoryRowInputRequest":{"type":"object","properties":{"barcode":{"type":"string","minLength":1,"maxLength":225},"stock":{"type":"integer","minimum":0,"description":"Units on the shelf according to your POS, at `as_of`."},"name":{"type":"string","minLength":1,"description":"Required the first time Scanimart sees this barcode.","maxLength":225},"mrp":{"type":"string","format":"decimal","pattern":"^-?\\d{0,8}(?:\\.\\d{0,2})?$"},"price":{"type":"string","format":"decimal","pattern":"^-?\\d{0,8}(?:\\.\\d{0,2})?$","description":"The store's selling price."},"expiry_date":{"type":"string","format":"date"},"low_stock_threshold":{"type":"integer","minimum":0},"brand":{"type":"string","maxLength":150},"category":{"type":"string","maxLength":225},"subcategory":{"type":"string","maxLength":225},"weight":{"type":"string","maxLength":20},"description":{"type":"string"},"external_id":{"type":"string","minLength":1,"description":"Your SKU; echoed on order lines.","maxLength":120}},"required":["barcode","stock"]},"InventorySync":{"type":"object","properties":{"object":{"type":"string","default":"inventory_sync"},"id":{"type":"string","format":"uuid"},"kind":{"$ref":"#/components/schemas/KindEnum"},"status":{"$ref":"#/components/schemas/InventorySyncStatusEnum"},"store_id":{"type":"integer"},"as_of":{"type":["string","null"],"format":"date-time"},"received":{"type":"integer"},"created":{"type":"integer"},"updated":{"type":"integer"},"unchanged":{"type":"integer"},"error_count":{"type":"integer"},"errors":{"type":"array","items":{"type":"object","additionalProperties":{}},"description":"First 100 rejected rows: barcode, code, message."},"adjusted_for_unbooked_sales":{"type":"object","additionalProperties":{"type":"integer"},"description":"Units subtracted per barcode for Scanimart sales you had not booked by `as_of`."},"created_at":{"type":"string","format":"date-time"},"finished_at":{"type":["string","null"],"format":"date-time"}},"required":["adjusted_for_unbooked_sales","as_of","created","created_at","error_count","errors","finished_at","id","kind","received","status","store_id","unchanged","updated"]},"InventorySyncList":{"type":"object","properties":{"object":{"type":"string","default":"list"},"data":{"type":"array","items":{"$ref":"#/components/schemas/InventorySync"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"],"description":"Pass as `cursor` to get the next page."}},"required":["data","has_more","next_cursor"]},"InventorySyncStatusEnum":{"enum":["queued","running","completed","failed"],"type":"string","description":"* `queued` - queued\n* `running` - running\n* `completed` - completed\n* `failed` - failed"},"KindEnum":{"enum":["inventory_push","inventory_adjust"],"type":"string","description":"* `inventory_push` - inventory_push\n* `inventory_adjust` - inventory_adjust"},"NullEnum":{"type":"null"},"Order":{"type":"object","properties":{"object":{"type":"string","default":"order"},"id":{"type":"string","description":"Scanimart order id, e.g. ORDER-1A2B3C4D5E."},"external_id":{"type":["string","null"],"description":"Your id for this order, if you sent one when accepting."},"store_id":{"type":"integer"},"type":{"$ref":"#/components/schemas/OrderTypeEnum"},"status":{"$ref":"#/components/schemas/OrderStatusEnum"},"payment":{"$ref":"#/components/schemas/Payment"},"total_amount":{"type":"string","format":"decimal","pattern":"^-?\\d{0,8}(?:\\.\\d{0,2})?$"},"delivery_fee":{"type":["string","null"],"format":"decimal","pattern":"^-?\\d{0,8}(?:\\.\\d{0,2})?$"},"fulfilment_mode":{"oneOf":[{"$ref":"#/components/schemas/FulfilmentModeEnum"},{"$ref":"#/components/schemas/NullEnum"}]},"accepted_via":{"oneOf":[{"$ref":"#/components/schemas/AcceptedViaEnum"},{"$ref":"#/components/schemas/NullEnum"}]},"placed_at":{"type":["string","null"],"format":"date-time"},"lines":{"type":"array","items":{"$ref":"#/components/schemas/OrderLine"}},"courier":{"oneOf":[{"$ref":"#/components/schemas/Courier"},{"type":"null"}],"description":"The Scanimart courier, for SCANIMART_COURIER orders."}},"required":["accepted_via","courier","delivery_fee","external_id","fulfilment_mode","id","lines","payment","placed_at","status","store_id","total_amount","type"]},"OrderLine":{"type":"object","properties":{"barcode":{"type":["string","null"]},"name":{"type":["string","null"]},"quantity":{"type":"integer"},"free_quantity":{"type":["integer","null"],"description":"Units of `quantity` given free by a buy-X-get-Y offer."},"unit_price":{"type":["string","null"],"format":"decimal","pattern":"^-?\\d{0,8}(?:\\.\\d{0,2})?$","description":"Per paid unit, tax-inclusive."},"mrp":{"type":["string","null"],"format":"decimal","pattern":"^-?\\d{0,8}(?:\\.\\d{0,2})?$"},"line_total":{"type":"string","format":"decimal","pattern":"^-?\\d{0,8}(?:\\.\\d{0,2})?$"},"source":{"oneOf":[{"$ref":"#/components/schemas/OrderLineSourceEnum"},{"$ref":"#/components/schemas/NullEnum"}]},"external_id":{"type":["string","null"],"description":"Your id for this item, if you sent one."}},"required":["barcode","external_id","free_quantity","line_total","mrp","name","quantity","source","unit_price"]},"OrderLineSourceEnum":{"enum":["catalog","store_item","misc"],"type":"string","description":"* `catalog` - catalog\n* `store_item` - store_item\n* `misc` - misc"},"OrderList":{"type":"object","properties":{"object":{"type":"string","default":"list"},"data":{"type":"array","items":{"$ref":"#/components/schemas/Order"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"],"description":"Pass as `cursor` to get the next page."}},"required":["data","has_more","next_cursor"]},"OrderStatusEnum":{"enum":["PENDING","ACCEPTED","PACKED","OUT_FOR_DELIVERY","DELIVERED","CANCELLED","COMPLETED","PAYMENT_FAILED"],"type":"string","description":"* `PENDING` - PENDING\n* `ACCEPTED` - ACCEPTED\n* `PACKED` - PACKED\n* `OUT_FOR_DELIVERY` - OUT_FOR_DELIVERY\n* `DELIVERED` - DELIVERED\n* `CANCELLED` - CANCELLED\n* `COMPLETED` - COMPLETED\n* `PAYMENT_FAILED` - PAYMENT_FAILED"},"OrderTypeEnum":{"enum":["delivery","instore"],"type":"string","description":"* `delivery` - delivery\n* `instore` - instore"},"PatchedWebhookEndpointPatchRequest":{"type":"object","properties":{"url":{"type":"string","format":"uri","minLength":1,"maxLength":500},"description":{"type":"string","maxLength":200},"events":{"type":"array","items":{"$ref":"#/components/schemas/EventTypeEnum"}},"status":{"$ref":"#/components/schemas/WebhookEndpointStatusEnum"}}},"Payment":{"type":"object","properties":{"status":{"type":"string"},"paid":{"type":"boolean"},"method":{"type":["string","null"]}},"required":["method","paid","status"]},"Ping":{"type":"object","properties":{"object":{"type":"string","default":"ping"},"mode":{"$ref":"#/components/schemas/ConnectModeEnum"},"company":{"$ref":"#/components/schemas/PingCompany"},"key":{"$ref":"#/components/schemas/PingKey"}},"required":["company","key","mode"]},"PingCompany":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"status":{"$ref":"#/components/schemas/PingCompanyStatusEnum"}},"required":["id","name","status"]},"PingCompanyStatusEnum":{"enum":["PENDING_REVIEW","ACTIVE","SUSPENDED","REJECTED"],"type":"string","description":"* `PENDING_REVIEW` - PENDING_REVIEW\n* `ACTIVE` - ACTIVE\n* `SUSPENDED` - SUSPENDED\n* `REJECTED` - REJECTED"},"PingKey":{"type":"object","properties":{"prefix":{"type":"string"},"scope":{"$ref":"#/components/schemas/ScopeEnum"},"store_id":{"type":["integer","null"]}},"required":["prefix","scope","store_id"]},"ReasonEnum":{"enum":["sale","return","received","damaged","correction","other"],"type":"string","description":"* `sale` - sale\n* `return` - return\n* `received` - received\n* `damaged` - damaged\n* `correction` - correction\n* `other` - other"},"RejectInputRequest":{"type":"object","properties":{"reason":{"type":"string","minLength":1,"maxLength":200}}},"Sale":{"type":"object","properties":{"object":{"type":"string","default":"sale"},"id":{"type":"string","description":"The Scanimart order id this sale came from."},"event_id":{"type":"string","description":"The sale.completed event id; use it to acknowledge."},"external_id":{"type":["string","null"]},"store_id":{"type":"integer"},"channel":{"$ref":"#/components/schemas/SalesChannelEnum"},"sold_at":{"type":"string","format":"date-time"},"total_amount":{"type":"string","format":"decimal","pattern":"^-?\\d{0,8}(?:\\.\\d{0,2})?$"},"delivery_fee":{"type":["string","null"],"format":"decimal","pattern":"^-?\\d{0,8}(?:\\.\\d{0,2})?$"},"payment":{"$ref":"#/components/schemas/Payment"},"lines":{"type":"array","items":{"$ref":"#/components/schemas/OrderLine"}}},"required":["channel","delivery_fee","event_id","external_id","id","lines","payment","sold_at","store_id","total_amount"]},"SaleAck":{"type":"object","properties":{"object":{"type":"string","default":"sale_ack"},"acknowledged":{"type":"array","items":{"type":"string"},"description":"The event ids now booked."},"unknown":{"type":"array","items":{"type":"string"},"description":"Ids that are not sale.completed events at this store since it connected you. Nothing was done with them."}},"required":["acknowledged","unknown"]},"SaleAckInputRequest":{"type":"object","properties":{"event_ids":{"type":"array","items":{"type":"string","minLength":1,"maxLength":40},"description":"`event_id`s from GET …/sales that you have booked.","maxItems":500}},"required":["event_ids"]},"SaleList":{"type":"object","properties":{"object":{"type":"string","default":"list"},"data":{"type":"array","items":{"$ref":"#/components/schemas/Sale"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"],"description":"Pass as `cursor` to get the next page."}},"required":["data","has_more","next_cursor"]},"SalesChannelEnum":{"enum":["SCANIMART_ONLINE","SCANIMART_INSTORE"],"type":"string","description":"* `SCANIMART_ONLINE` - SCANIMART_ONLINE\n* `SCANIMART_INSTORE` - SCANIMART_INSTORE"},"SandboxAdvanceInputRequest":{"type":"object","properties":{"to":{"$ref":"#/components/schemas/ToEnum"}},"required":["to"]},"SandboxAdvanced":{"type":"object","properties":{"order_id":{"type":"string"},"status":{"type":"string"}},"required":["order_id","status"]},"SandboxLineInputRequest":{"type":"object","properties":{"barcode":{"type":"string","minLength":1,"maxLength":225},"quantity":{"type":"integer","minimum":1,"default":1}},"required":["barcode"]},"SandboxOrderCreated":{"type":"object","properties":{"order_id":{"type":"string"},"store_id":{"type":"integer","description":"Your test store."}},"required":["order_id"]},"SandboxOrderInputRequest":{"type":"object","properties":{"lines":{"type":"array","items":{"$ref":"#/components/schemas/SandboxLineInputRequest"},"description":"Defaults to one each of two stocked products."}}},"SandboxReset":{"type":"object","properties":{"deleted_orders":{"type":"integer"}},"required":["deleted_orders"]},"ScopeEnum":{"enum":["company","store"],"type":"string","description":"* `company` - company\n* `store` - store"},"Store":{"type":"object","properties":{"object":{"type":"string","default":"store"},"id":{"type":"integer"},"name":{"type":"string"},"status":{"type":"string","description":"open, closed or renovation."},"active":{"type":"boolean"},"services":{"type":"string","description":"offline_only or offline_online."},"gstin":{"type":["string","null"]},"address":{"type":"string"},"area":{"type":["string","null"]},"city":{"type":["string","null"]},"latitude":{"type":["number","null"],"format":"double"},"longitude":{"type":["number","null"],"format":"double"},"connected_at":{"type":"string","format":"date-time","description":"When the store connected you. On list and get."}},"required":["active","address","area","city","gstin","id","latitude","longitude","name","services","status"]},"StoreLink":{"type":"object","properties":{"object":{"type":"string","default":"store_link"},"id":{"type":"string","format":"uuid"},"store":{"$ref":"#/components/schemas/Store"},"connected_at":{"type":"string","format":"date-time"}},"required":["connected_at","id","store"]},"StoreList":{"type":"object","properties":{"object":{"type":"string","default":"list"},"data":{"type":"array","items":{"$ref":"#/components/schemas/Store"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"],"description":"Pass as `cursor` to get the next page."}},"required":["data","has_more","next_cursor"]},"TestEventInputRequest":{"type":"object","properties":{"type":{"allOf":[{"$ref":"#/components/schemas/EventTypeEnum"}],"default":"ping"},"bad_signature":{"type":"boolean","default":false,"description":"Send with a deliberately wrong signature. Your endpoint should answer 4xx."}}},"ToEnum":{"enum":["ACCEPTED","PACKED","OUT_FOR_DELIVERY","DELIVERED","CANCELLED"],"type":"string","description":"* `ACCEPTED` - ACCEPTED\n* `PACKED` - PACKED\n* `OUT_FOR_DELIVERY` - OUT_FOR_DELIVERY\n* `DELIVERED` - DELIVERED\n* `CANCELLED` - CANCELLED"},"WebhookDelivery":{"type":"object","properties":{"object":{"type":"string","default":"webhook_delivery"},"id":{"type":"integer"},"event_id":{"type":"string"},"event_type":{"type":"string"},"status":{"$ref":"#/components/schemas/WebhookDeliveryStatusEnum"},"attempts":{"type":"integer"},"next_attempt_at":{"type":["string","null"],"format":"date-time"},"last_status_code":{"type":["integer","null"]},"last_error":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"succeeded_at":{"type":["string","null"],"format":"date-time"}},"required":["attempts","created_at","event_id","event_type","id","last_error","last_status_code","next_attempt_at","status","succeeded_at"]},"WebhookDeliveryList":{"type":"object","properties":{"object":{"type":"string","default":"list"},"data":{"type":"array","items":{"$ref":"#/components/schemas/WebhookDelivery"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"],"description":"Pass as `cursor` to get the next page."}},"required":["data","has_more","next_cursor"]},"WebhookDeliveryStatusEnum":{"enum":["PENDING","SUCCEEDED","DEAD"],"type":"string","description":"* `PENDING` - PENDING\n* `SUCCEEDED` - SUCCEEDED\n* `DEAD` - DEAD"},"WebhookEndpoint":{"type":"object","properties":{"object":{"type":"string","default":"webhook_endpoint"},"id":{"type":"string","format":"uuid"},"mode":{"allOf":[{"$ref":"#/components/schemas/ConnectModeEnum"}],"description":"Which environment's events it receives.\n\n* `live` - live\n* `test` - test"},"url":{"type":"string","format":"uri"},"description":{"type":"string"},"events":{"type":"array","items":{"type":"string"},"description":"Empty means every event."},"status":{"$ref":"#/components/schemas/WebhookEndpointStatusEnum"},"disabled_reason":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"secret":{"type":"string","description":"Signing secret. Returned only on create and roll."}},"required":["created_at","description","disabled_reason","events","id","mode","status","url"]},"WebhookEndpointInputRequest":{"type":"object","properties":{"url":{"type":"string","format":"uri","minLength":1,"maxLength":500},"description":{"type":"string","maxLength":200},"events":{"type":"array","items":{"$ref":"#/components/schemas/EventTypeEnum"}}},"required":["url"]},"WebhookEndpointList":{"type":"object","properties":{"object":{"type":"string","default":"list"},"data":{"type":"array","items":{"$ref":"#/components/schemas/WebhookEndpoint"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"],"description":"Pass as `cursor` to get the next page."}},"required":["data","has_more","next_cursor"]},"WebhookEndpointStatusEnum":{"enum":["ACTIVE","DISABLED"],"type":"string","description":"* `ACTIVE` - ACTIVE\n* `DISABLED` - DISABLED"}},"securitySchemes":{"ApiKey":{"type":"http","scheme":"bearer","description":"Your secret key: `sk_live_…` on api.scanimart.com, `sk_test_…` on the sandbox."}}},"servers":[{"url":"https://api.scanimart.com","description":"Live"},{"url":"https://sandbox.api.scanimart.com","description":"Sandbox (test keys)"}],"webhooks":{"order.placed":{"post":{"description":"A customer paid for a delivery order at the store. Accept or reject it (POST …/accept or …/reject) before the reservation expires (15 minutes).\n\nSent as a JSON `POST` to your endpoint with headers `Scanimart-Event-Id`, `Scanimart-Event-Type`, `Scanimart-Mode` and `Scanimart-Signature: t=<unix>,v1=<hex>` -- HMAC-SHA256 of `\"<t>.<raw body>\"` with your endpoint's signing secret. Verify it, reject anything older than 5 minutes, and dedupe on `id`: delivery is at-least-once. Answer any 2xx within 10 seconds; anything else is retried with backoff for about 3 days.","summary":"order.placed","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Event"}}},"required":true},"responses":{"200":{"description":"No response body"}}}},"order.accepted":{"post":{"description":"The order was accepted -- by you, or in the Scanimart retailer app (`data.order.accepted_via`). `data.order.fulfilment_mode` says who delivers.\n\nSent as a JSON `POST` to your endpoint with headers `Scanimart-Event-Id`, `Scanimart-Event-Type`, `Scanimart-Mode` and `Scanimart-Signature: t=<unix>,v1=<hex>` -- HMAC-SHA256 of `\"<t>.<raw body>\"` with your endpoint's signing secret. Verify it, reject anything older than 5 minutes, and dedupe on `id`: delivery is at-least-once. Answer any 2xx within 10 seconds; anything else is retried with backoff for about 3 days.","summary":"order.accepted","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Event"}}},"required":true},"responses":{"200":{"description":"No response body"}}}},"order.cancelled":{"post":{"description":"The order was rejected by the store, cancelled by the customer, or cancelled by Scanimart. `data.actor.kind` and `data.reason` say which.\n\nSent as a JSON `POST` to your endpoint with headers `Scanimart-Event-Id`, `Scanimart-Event-Type`, `Scanimart-Mode` and `Scanimart-Signature: t=<unix>,v1=<hex>` -- HMAC-SHA256 of `\"<t>.<raw body>\"` with your endpoint's signing secret. Verify it, reject anything older than 5 minutes, and dedupe on `id`: delivery is at-least-once. Answer any 2xx within 10 seconds; anything else is retried with backoff for about 3 days.","summary":"order.cancelled","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Event"}}},"required":true},"responses":{"200":{"description":"No response body"}}}},"order.payment_failed":{"post":{"description":"A pending online checkout timed out unpaid. Do not fulfil or book it as a sale. This is not a general notification for unsuccessful in-store payment attempts.\n\nSent as a JSON `POST` to your endpoint with headers `Scanimart-Event-Id`, `Scanimart-Event-Type`, `Scanimart-Mode` and `Scanimart-Signature: t=<unix>,v1=<hex>` -- HMAC-SHA256 of `\"<t>.<raw body>\"` with your endpoint's signing secret. Verify it, reject anything older than 5 minutes, and dedupe on `id`: delivery is at-least-once. Answer any 2xx within 10 seconds; anything else is retried with backoff for about 3 days.","summary":"order.payment_failed","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Event"}}},"required":true},"responses":{"200":{"description":"No response body"}}}},"order.payment_recovered":{"post":{"description":"A payment arrived after the timeout; the order is PENDING again and an `order.placed` follows.\n\nSent as a JSON `POST` to your endpoint with headers `Scanimart-Event-Id`, `Scanimart-Event-Type`, `Scanimart-Mode` and `Scanimart-Signature: t=<unix>,v1=<hex>` -- HMAC-SHA256 of `\"<t>.<raw body>\"` with your endpoint's signing secret. Verify it, reject anything older than 5 minutes, and dedupe on `id`: delivery is at-least-once. Answer any 2xx within 10 seconds; anything else is retried with backoff for about 3 days.","summary":"order.payment_recovered","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Event"}}},"required":true},"responses":{"200":{"description":"No response body"}}}},"order.picking_started":{"post":{"description":"Staff started picking the order in the Scanimart Staff app. The customer can no longer cancel. Informational for the POS; picking is not a public API action.\n\nSent as a JSON `POST` to your endpoint with headers `Scanimart-Event-Id`, `Scanimart-Event-Type`, `Scanimart-Mode` and `Scanimart-Signature: t=<unix>,v1=<hex>` -- HMAC-SHA256 of `\"<t>.<raw body>\"` with your endpoint's signing secret. Verify it, reject anything older than 5 minutes, and dedupe on `id`: delivery is at-least-once. Answer any 2xx within 10 seconds; anything else is retried with backoff for about 3 days.","summary":"order.picking_started","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Event"}}},"required":true},"responses":{"200":{"description":"No response body"}}}},"order.packed":{"post":{"description":"Staff packed the order in the Scanimart Staff app and it is ready for the rider. Informational for the POS; packing is not a public API action.\n\nSent as a JSON `POST` to your endpoint with headers `Scanimart-Event-Id`, `Scanimart-Event-Type`, `Scanimart-Mode` and `Scanimart-Signature: t=<unix>,v1=<hex>` -- HMAC-SHA256 of `\"<t>.<raw body>\"` with your endpoint's signing secret. Verify it, reject anything older than 5 minutes, and dedupe on `id`: delivery is at-least-once. Answer any 2xx within 10 seconds; anything else is retried with backoff for about 3 days.","summary":"order.packed","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Event"}}},"required":true},"responses":{"200":{"description":"No response body"}}}},"order.out_for_delivery":{"post":{"description":"A rider has the order.\n\nSent as a JSON `POST` to your endpoint with headers `Scanimart-Event-Id`, `Scanimart-Event-Type`, `Scanimart-Mode` and `Scanimart-Signature: t=<unix>,v1=<hex>` -- HMAC-SHA256 of `\"<t>.<raw body>\"` with your endpoint's signing secret. Verify it, reject anything older than 5 minutes, and dedupe on `id`: delivery is at-least-once. Answer any 2xx within 10 seconds; anything else is retried with backoff for about 3 days.","summary":"order.out_for_delivery","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Event"}}},"required":true},"responses":{"200":{"description":"No response body"}}}},"order.delivered":{"post":{"description":"The customer received the order. A `sale.completed` follows.\n\nSent as a JSON `POST` to your endpoint with headers `Scanimart-Event-Id`, `Scanimart-Event-Type`, `Scanimart-Mode` and `Scanimart-Signature: t=<unix>,v1=<hex>` -- HMAC-SHA256 of `\"<t>.<raw body>\"` with your endpoint's signing secret. Verify it, reject anything older than 5 minutes, and dedupe on `id`: delivery is at-least-once. Answer any 2xx within 10 seconds; anything else is retried with backoff for about 3 days.","summary":"order.delivered","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Event"}}},"required":true},"responses":{"200":{"description":"No response body"}}}},"sale.completed":{"post":{"description":"A finished Scanimart sale to book into your POS -- a delivered online order (`channel: SCANIMART_ONLINE`) or a paid in-store Scan & Go basket (`SCANIMART_INSTORE`). `data.sale` has every line. Answer 2xx only once it is booked: that is how Scanimart knows your stock count already includes it.\n\nSent as a JSON `POST` to your endpoint with headers `Scanimart-Event-Id`, `Scanimart-Event-Type`, `Scanimart-Mode` and `Scanimart-Signature: t=<unix>,v1=<hex>` -- HMAC-SHA256 of `\"<t>.<raw body>\"` with your endpoint's signing secret. Verify it, reject anything older than 5 minutes, and dedupe on `id`: delivery is at-least-once. Answer any 2xx within 10 seconds; anything else is retried with backoff for about 3 days.","summary":"sale.completed","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Event"}}},"required":true},"responses":{"200":{"description":"No response body"}}}},"sale.exit_verified":{"post":{"description":"An in-store customer's basket was checked at the exit. Informational.\n\nSent as a JSON `POST` to your endpoint with headers `Scanimart-Event-Id`, `Scanimart-Event-Type`, `Scanimart-Mode` and `Scanimart-Signature: t=<unix>,v1=<hex>` -- HMAC-SHA256 of `\"<t>.<raw body>\"` with your endpoint's signing secret. Verify it, reject anything older than 5 minutes, and dedupe on `id`: delivery is at-least-once. Answer any 2xx within 10 seconds; anything else is retried with backoff for about 3 days.","summary":"sale.exit_verified","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Event"}}},"required":true},"responses":{"200":{"description":"No response body"}}}},"order.fulfilment_changed":{"post":{"description":"A Scanimart-courier order was handed back to the store's own riders.\n\nSent as a JSON `POST` to your endpoint with headers `Scanimart-Event-Id`, `Scanimart-Event-Type`, `Scanimart-Mode` and `Scanimart-Signature: t=<unix>,v1=<hex>` -- HMAC-SHA256 of `\"<t>.<raw body>\"` with your endpoint's signing secret. Verify it, reject anything older than 5 minutes, and dedupe on `id`: delivery is at-least-once. Answer any 2xx within 10 seconds; anything else is retried with backoff for about 3 days.","summary":"order.fulfilment_changed","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Event"}}},"required":true},"responses":{"200":{"description":"No response body"}}}},"delivery.courier_booked":{"post":{"description":"Scanimart booked a courier for the order (`data.courier`: provider, tracking link). Hand the bag to that courier.\n\nSent as a JSON `POST` to your endpoint with headers `Scanimart-Event-Id`, `Scanimart-Event-Type`, `Scanimart-Mode` and `Scanimart-Signature: t=<unix>,v1=<hex>` -- HMAC-SHA256 of `\"<t>.<raw body>\"` with your endpoint's signing secret. Verify it, reject anything older than 5 minutes, and dedupe on `id`: delivery is at-least-once. Answer any 2xx within 10 seconds; anything else is retried with backoff for about 3 days.","summary":"delivery.courier_booked","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Event"}}},"required":true},"responses":{"200":{"description":"No response body"}}}},"delivery.courier_assigned":{"post":{"description":"The courier assigned a rider (`data.courier.rider_name`, `rider_phone`).\n\nSent as a JSON `POST` to your endpoint with headers `Scanimart-Event-Id`, `Scanimart-Event-Type`, `Scanimart-Mode` and `Scanimart-Signature: t=<unix>,v1=<hex>` -- HMAC-SHA256 of `\"<t>.<raw body>\"` with your endpoint's signing secret. Verify it, reject anything older than 5 minutes, and dedupe on `id`: delivery is at-least-once. Answer any 2xx within 10 seconds; anything else is retried with backoff for about 3 days.","summary":"delivery.courier_assigned","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Event"}}},"required":true},"responses":{"200":{"description":"No response body"}}}},"delivery.rider_changed":{"post":{"description":"The courier replaced the rider. Hand the bag to the new one.\n\nSent as a JSON `POST` to your endpoint with headers `Scanimart-Event-Id`, `Scanimart-Event-Type`, `Scanimart-Mode` and `Scanimart-Signature: t=<unix>,v1=<hex>` -- HMAC-SHA256 of `\"<t>.<raw body>\"` with your endpoint's signing secret. Verify it, reject anything older than 5 minutes, and dedupe on `id`: delivery is at-least-once. Answer any 2xx within 10 seconds; anything else is retried with backoff for about 3 days.","summary":"delivery.rider_changed","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Event"}}},"required":true},"responses":{"200":{"description":"No response body"}}}},"delivery.failed":{"post":{"description":"No courier could be booked, or the courier gave up. Retry (POST …/courier/retry) or switch to store delivery (POST …/delivery-method).\n\nSent as a JSON `POST` to your endpoint with headers `Scanimart-Event-Id`, `Scanimart-Event-Type`, `Scanimart-Mode` and `Scanimart-Signature: t=<unix>,v1=<hex>` -- HMAC-SHA256 of `\"<t>.<raw body>\"` with your endpoint's signing secret. Verify it, reject anything older than 5 minutes, and dedupe on `id`: delivery is at-least-once. Answer any 2xx within 10 seconds; anything else is retried with backoff for about 3 days.","summary":"delivery.failed","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Event"}}},"required":true},"responses":{"200":{"description":"No response body"}}}},"store.connected":{"post":{"description":"A store connected to your company with a one-time code.\n\nSent as a JSON `POST` to your endpoint with headers `Scanimart-Event-Id`, `Scanimart-Event-Type`, `Scanimart-Mode` and `Scanimart-Signature: t=<unix>,v1=<hex>` -- HMAC-SHA256 of `\"<t>.<raw body>\"` with your endpoint's signing secret. Verify it, reject anything older than 5 minutes, and dedupe on `id`: delivery is at-least-once. Answer any 2xx within 10 seconds; anything else is retried with backoff for about 3 days.","summary":"store.connected","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Event"}}},"required":true},"responses":{"200":{"description":"No response body"}}}},"store.disconnected":{"post":{"description":"A store disconnected you, or you disconnected it. Events for it stop.\n\nSent as a JSON `POST` to your endpoint with headers `Scanimart-Event-Id`, `Scanimart-Event-Type`, `Scanimart-Mode` and `Scanimart-Signature: t=<unix>,v1=<hex>` -- HMAC-SHA256 of `\"<t>.<raw body>\"` with your endpoint's signing secret. Verify it, reject anything older than 5 minutes, and dedupe on `id`: delivery is at-least-once. Answer any 2xx within 10 seconds; anything else is retried with backoff for about 3 days.","summary":"store.disconnected","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Event"}}},"required":true},"responses":{"200":{"description":"No response body"}}}},"ping":{"post":{"description":"Sent by \"Send a test event\". Proves your endpoint is reachable.\n\nSent as a JSON `POST` to your endpoint with headers `Scanimart-Event-Id`, `Scanimart-Event-Type`, `Scanimart-Mode` and `Scanimart-Signature: t=<unix>,v1=<hex>` -- HMAC-SHA256 of `\"<t>.<raw body>\"` with your endpoint's signing secret. Verify it, reject anything older than 5 minutes, and dedupe on `id`: delivery is at-least-once. Answer any 2xx within 10 seconds; anything else is retried with backoff for about 3 days.","summary":"ping","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Event"}}},"required":true},"responses":{"200":{"description":"No response body"}}}}}}