Skip to content
Help

Authentication

Create scoped API keys, send them with each request, check what a key can do, and revoke or rotate them.

Public API2 min read

#Creating a key

Settings → Developers → Create key in the dashboard. You need the restaurant:write permission, which owners and admins have.

A key is defined by:

  • Name: a label for you, so you know what to revoke later.
  • Scopes: exactly what the key may do. Pick the minimum.
  • Branches: leave every branch unchecked for restaurant-wide access, or check specific branches to limit the key to them.
  • Expires in: pick a window, or never. A key with an expiry stops working on its own, which suits a contractor or a short-lived integration.

When you create the key, Restro shows the token once:

text
rk_a1b2c3d4e5f60718_Zm9vYmFyYmF6cXV4Y29ycmVjdGhvcnNlYmF0dGVyeQ

Copy it at that point. Restro stores only a SHA-256 hash of the secret, so the token cannot be shown again. If you lose it, create a new key.

#Using a key

Send it as a bearer token:

bash
curl https://api.tryrestro.com/v1/me \
  -H "Authorization: Bearer rk_a1b2c3d4e5f60718_..."

If your HTTP client cannot set a bearer token, send it in the X-API-Key header instead:

bash
curl https://api.tryrestro.com/v1/me \
  -H "X-API-Key: rk_a1b2c3d4e5f60718_..."

Both are equivalent. Never put a key in a URL, in client-side code, or in a mobile app. It is a server-side credential.

#Scopes

ScopeGrants
orders:readList and fetch orders
orders:update-statusAdvance or cancel an order
menu:readList categories and items
menu:writeUpdate item publication, availability, and branch prices
customers:readList and fetch customers
inventory:readList and fetch stock
inventory:writeRecord stock movements

Scopes use the same permission vocabulary as staff roles in the dashboard, so a scope means the same thing in both places.

Calling an endpoint without its scope returns 403:

json
{ "error": "Missing required scope: menu:write", "code": "forbidden" }

#Checking a key

GET /v1/me tells you what the key can do without changing anything. It needs no particular scope, so it is a good first call from a new integration.

json
{
  "key": {
    "id": "cmd8x2k9p0001abcdefghijkl",
    "name": "Accounting sync",
    "prefix": "a1b2c3d4e5f60718",
    "scopes": ["orders:read", "customers:read"],
    "branchIds": []
  },
  "restaurant": {
    "id": "cmd8w1j8o0000abcdefghijkl",
    "name": "Sage & Salt",
    "subdomain": "sageandsalt"
  }
}

An empty branchIds means the key is not branch-restricted.

#Branch scoping

A branch-scoped key sees only those branches. Orders elsewhere return 404 rather than 403, so the key cannot confirm that the order exists.

Requesting a branch outside the key's scope via ?branchId= returns 403.

#Revoking

Settings → Developers. Revoke stops the key working immediately and keeps it in the list for the record. Delete removes it entirely.

Revoke rather than delete when you may need to trace an integration later, since activity log entries still point at the key by name.

Revoked and expired keys return 401:

json
{ "error": "API key is revoked or expired", "code": "key_inactive" }

#Rotating a key

There is no in-place rotation. Create the new key, deploy it, confirm traffic has moved by watching last used on both keys, then revoke the old one. This sequence has no window in which nothing works.

Did this page miss something? Tell us.

Back to top