Skip to content

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. Over-limit requests get 429 with X-RateLimit-* headers and a Retry-After (seconds). Successful responses carry no rate-limit headers.

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.
403Key is the wrong type for this endpoint (company vs venue), or lacks the required read/write scope.
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://www.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.