Skip to content
OpenALaCarte

Reference

Authentication & conventions

Everything that applies to every endpoint: how to authenticate, the limits, and how responses are shaped.

Authentication

Every request carries an Authorization: Bearer header with a key you mint in your dashboard. Keys look like oac_live_…, are scoped to your company, and are shown once at creation — store them securely. A missing, malformed, or revoked key returns 401.

Authorization: Bearer oac_live_3f9a…c1e7

Every read is automatically scoped to your company's restaurants — you can never see another tenant's data, even by guessing an id. Mint or revoke keys in API keys.

Rate limits

60 requests per minute per API key. Every response carries the current budget; over-limit requests get 429 with a Retry-After (seconds).

X-RateLimit-Limit: 60
X-RateLimit-Remaining: 41
X-RateLimit-Reset: 1734556800
Retry-After: 17          # only on 429

Need a higher ceiling for a bulk sync? Talk to us.

Errors

Errors use standard HTTP status codes and a JSON body with a human-readable error.

{ "error": "Restaurant not found" }
StatusMeaning
200 / 201Success. POSTs that create a resource return 201.
400Malformed request — bad JSON or invalid/missing fields.
401Missing, malformed, or revoked API key.
404Resource not found, or not owned by your company.
409Conflict — bookings disabled, or the slot is fully booked.
429Rate limit exceeded. Back off using Retry-After.
5xxTransient server error — retry with backoff.

Pagination

List endpoints are cursor-paginated. Pass limit (default 50, max 100) and follow nextCursor until it's null. Never rely on offsets.

Paging through every booking
let cursor = null;
do {
  const url = new URL("https://openalacarte.com/api/v1/bookings");
  url.searchParams.set("limit", "100");
  if (cursor) url.searchParams.set("cursor", cursor);
  const { data, nextCursor } = await (await fetch(url, {
    headers: { Authorization: `Bearer ${process.env.OAC_API_KEY}` },
  })).json();
  handle(data);
  cursor = nextCursor;
} while (cursor);

Versioning & stability

  • The API is versioned in the URL (/api/v1/…). Breaking changes ship as v2 alongside v1.
  • v1 stays online for at least 12 months after any deprecation notice.
  • Additive changes (new fields, endpoints, webhook events) are not breaking — tolerate unknown fields.
  • All timestamps are ISO-8601 in UTC.

Generate a typed SDK or import into Postman from the OpenAPI 3.0 spec.