Partner API

MODR Open API (v1)

Public REST API for partners: menu, 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://vbkvldzmjycapdlkoawr.supabase.co/functions/v1/open-api/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

Same Supabase project for live and test. Use modr_test_ keys against a test outlet while developing. A separate sandbox project comes later.

  • 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

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.

GET/versionpublic

API version (no key)

curl -sS "https://vbkvldzmjycapdlkoawr.supabase.co/functions/v1/open-api/v1/version"
GET/environment

Key environment and outlet binding

curl -sS "https://vbkvldzmjycapdlkoawr.supabase.co/functions/v1/open-api/v1/environment" \
  -H "Authorization: Bearer modr_test_…"
GET/products

Published menu / catalog

curl -sS "https://vbkvldzmjycapdlkoawr.supabase.co/functions/v1/open-api/v1/products" \
  -H "Authorization: Bearer modr_test_…"
GET/checks

List open checks

curl -sS "https://vbkvldzmjycapdlkoawr.supabase.co/functions/v1/open-api/v1/checks?limit=50" \
  -H "Authorization: Bearer modr_test_…"
POST/checks

Create open check (no payment)

curl -sS -X POST "https://vbkvldzmjycapdlkoawr.supabase.co/functions/v1/open-api/v1/checks" \
  -H "Authorization: Bearer modr_test_…" \
  -H "Content-Type: application/json" \
  -d '{"name":"Online 1","lines":[{"productId":"<id>","qty":1}]}'
GET/checks/{id}

Get one open check

curl -sS "https://vbkvldzmjycapdlkoawr.supabase.co/functions/v1/open-api/v1/checks/<checkId>" \
  -H "Authorization: Bearer modr_test_…"
GET/sales

Closed sales (closed_checks)

curl -sS "https://vbkvldzmjycapdlkoawr.supabase.co/functions/v1/open-api/v1/sales?limit=50" \
  -H "Authorization: Bearer modr_test_…"

Webhooks

Configure HTTPS URL and events in Backoffice. Deliveries are logged; v1 makes one sync attempt and stores a row for retry.

  • check.created
  • check.updated
  • 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.