Partner API

MODR Open API (v1)

Public REST API for partners: menu, Orderhanterare, open checks and closed sales per outlet. Authenticate with outlet API keys — not device JWTs or staff PINs.

Download OpenAPI specification:Download

E-mail: hello@modr.se

Base URL: https://api.modr.se/v1

Getting started

  1. Create a test key in Backoffice → Integrations → Open API (plaintext shown once).
  2. Call GET /version without a key to verify the base URL.
  3. Call GET /products with Authorization: Bearer modr_test_…

Read more about integrations →

API key

All protected calls require a valid outlet key. Send either:

Authorization: Bearer modr_live_…

or

Authorization: Bearer modr_test_…

Alternative header:X-Api-Key: modr_test_…

Invalid or revoked keys return 401. Keys are stored hashed; prefix and last4 are shown in Backoffice.

Environments

Always call MODR Open API on api.modr.se. Live and test share the same host — the key prefix selects the environment. Use modr_test_ keys against a test outlet while developing.

  • https://api.modr.se/v1 — canonical base URL
  • https://modr.se/api/v1 — same API via modr.se
  • modr_test_ — sandbox / lower rate limit
  • modr_live_ — production

Rate limits

Fixed window per minute per key. Exceeding the limit returns 429 with Retry-After.

  • modr_test_ — 60 req/min (default)
  • modr_live_ — 120 req/min (default)

Response headers: X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset

Idempotency-Key

POST and PUT accept an optional Idempotency-Key (8–128 characters). The same key and body replay the original response. The same key with a different body returns 409.

Idempotency-Key: 8f3c2a91-partner-order-14

Correlation-Id

Optionally send X-Correlation-Id. The same value is returned and included in error payloads — use it when contacting support.

Endpoints

All paths are relative to the base URL above. POST /orders puts a waiting order in Orderhanterare. POST /checks creates an open POS check. GET /sales is cursor-paginated — pass nextCursor as cursor.

GET/versionpublic

API version (no key)

curl -sS "https://api.modr.se/v1/version"
GET/environment

Key environment and outlet binding

curl -sS "https://api.modr.se/v1/environment" \
  -H "Authorization: Bearer modr_test_…"
GET/products

Published menu / catalog with modifiers

curl -sS "https://api.modr.se/v1/products" \
  -H "Authorization: Bearer modr_test_…"
GET/tables

Tables and any open check

curl -sS "https://api.modr.se/v1/tables" \
  -H "Authorization: Bearer modr_test_…"
GET/checks

List open POS checks

curl -sS "https://api.modr.se/v1/checks?limit=50" \
  -H "Authorization: Bearer modr_test_…"
POST/checks

Create open POS check (no payment)

curl -sS -X POST "https://api.modr.se/v1/checks" \
  -H "Authorization: Bearer modr_test_…" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"name":"Online 1","tableId":"<tableId>","lines":[{"productId":"<id>","qty":1}]}'
GET/checks/{id}

Get one open check

curl -sS "https://api.modr.se/v1/checks/<checkId>" \
  -H "Authorization: Bearer modr_test_…"
POST/checks/{id}/items

Add items to an open check

curl -sS -X POST "https://api.modr.se/v1/checks/<checkId>/items" \
  -H "Authorization: Bearer modr_test_…" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"lines":[{"productId":"<id>","qty":1}]}'
PUT/checks/{id}/table

Attach check to a table

curl -sS -X PUT "https://api.modr.se/v1/checks/<checkId>/table" \
  -H "Authorization: Bearer modr_test_…" \
  -H "Content-Type: application/json" \
  -d '{"tableId":"<tableId>"}'
POST/orders

Create Orderhanterare waiting-queue order

curl -sS -X POST "https://api.modr.se/v1/orders" \
  -H "Authorization: Bearer modr_test_…" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"name":"Wolt 14","orderType":"Takeaway","lines":[{"productId":"<id>","qty":1}]}'
GET/orders

List Orderhanterare queue orders

curl -sS "https://api.modr.se/v1/orders?queue=waiting" \
  -H "Authorization: Bearer modr_test_…"
GET/sales

Closed sales with lines, VAT and payments

curl -sS "https://api.modr.se/v1/sales?limit=50" \
  -H "Authorization: Bearer modr_test_…"
GET/sales/{id}

Get one closed sale

curl -sS "https://api.modr.se/v1/sales/<saleId>" \
  -H "Authorization: Bearer modr_test_…"

Webhooks

Configure a public HTTPS URL and events in Backoffice. The first attempt is synchronous. Failed deliveries retry with backoff, up to 8 attempts. sale.created includes lines, VAT and payments.

  • check.created
  • check.updated
  • order.created
  • sale.created

Signature

Headers: X-Modr-Timestamp, X-Modr-Signature, X-Modr-Event

HMAC-SHA256 hex of{timestamp}.{rawBody} using the webhook secret.

# verify (pseudo)
expected = hmac_sha256(secret, timestamp + "." + rawBody)
assert expected == X-Modr-Signature

Errors

JSON errors use a consistent shape:

{
  "code": "unauthorized",
  "message": "Missing API key …",
  "correlationId": "…"
}

Out of scope for v1

Pay/terminal, refunds, cash, Z/X/fiscal, staff PIN, device link and manager override are not part of Open API v1.