API

Connect your own systems — accounting, BI, payroll — with keys and webhooks.

Nantli has an API so your own systems can read and write your property's data: your accounting software can read the day's sales, your payroll system can read the team and their schedules, your BI can pull reports. All with keys you create and revoke from this page.

Keys and permissions

Every key has a name and a list of permissions. Give each system its own key with the least it needs: the accounting system gets read-only orders and reports; the payroll one gets team and schedules.

Select New key, name it, pick permissions and select Create. The full key (nk_live_…) is shown exactly once — store it in your system right then. If it gets lost, revoke it and create another; Nantli cannot recover it.

Write permissions only work while your property has the matching product live: orders and catalog ride on the point of sale, team and schedules on Team, reports on the POS.

Using the API

Every request carries the key in the Authorization header:

curl https://app.nantli.ai/api/v1/me \
  -H "Authorization: Bearer nk_live_…"

/me tells you which property the key belongs to, with its timezone, currency and language — use it so you never hardcode any of the three. The main resources:

  • GET /api/v1/orders — orders, with ?updated_after= to sync only what changed.
  • GET /api/v1/orders/{id} — one order with items, payments and refunds.
  • POST /api/v1/orders — creates an order; prices always come from your catalog.
  • POST /api/v1/orders/{id}/payments — registers a payment.
  • GET /api/v1/catalog/products — your menu with prices.
  • GET /api/v1/reports/sales?from=&to= — aggregated sales, in your property's timezone.
  • GET /api/v1/staff, GET /api/v1/schedules/entries, GET /api/v1/absences — team and schedules.

Large lists paginate with next_cursor; pass it back as ?cursor=. POSTs that move money require an Idempotency-Key header: retrying with the same key never duplicates the operation.

Errors arrive as { "error": { "code", "message", "request_id" } } with stable codes (invalid_api_key, insufficient_scope, validation_failed…). Usage is limited per key; on rate_limited, wait and retry.

Webhooks

Instead of polling every minute, your system can be told: register a destination with New destination, pick the events (order paid, employee updated, shift changed…) and Nantli will make a signed POST to your URL whenever they happen.

Every delivery is signed with the Standard Webhooks scheme: verify the signature with the destination's secret (visible via Show secret) and drop duplicates by the webhook-id header — deliveries are at least once. If your destination fails, Nantli retries with growing waits for up to a day; if it keeps failing, the destination pauses itself and you can re-enable it right here.

Good practices

  • One key per system, with the least permissions. Revoking one never touches the rest.
  • Store the key as a secret in your system — never in code or a shared sheet.
  • Sync with updated_after + next_cursor instead of downloading everything each time.
  • The Last used column tells you whether a key is still alive; revoke the ones that aren't.