Developer docs

Rate limits

No per-key limit is enforced today. Generous numbers to design against anyway, what happens if you vastly exceed them, and how to keep this a non-issue.

There is no enforced per-key rate limit today. Send what your venue's actual guest traffic needs — do not write retry-on-429 handling for a response the API cannot currently return.

That will not stay true forever, and we are not going to pretend otherwise: a limit is coming, sized around the numbers on this page. It will be announced in advance, never switched on silently, and signalled the standard way once it exists — 429 Too Many Requests with a Retry-After header. An API key is the natural bucket for it: you already send one on every call, and each key maps to one venue (or, for a secret key, typically one server integration) — a limit per key is a limit per real caller, not per URL or per IP. (The one exception is BookDinePlay's own platform-scoped secret key, which is deliberately not tied to a single venue and carries every venue's public-page traffic behind one credential — no third-party integration is ever issued one, so it changes nothing below.)

What to design against

These numbers are ours to propose, not yours to guess, so here is the reasoning. A guest's whole session — landing on the page, checking a couple of dates, booking — looks like this:

Moment Calls Why
Page load up to 6, once The six venue reads on Venue — profile, business info, opening hours, menus, resources, floor plan. The stock widget only needs two of them by default (profile, floor plan — Venue → Caching); a custom page showing menus or hours inline uses more, still just once
A two-week date-strip prefetch ~14, in one burst One Availability call per date shown — there is no multi-date shape today, so 14 calls is the honest cost of colouring a strip, not a sign you are doing something wrong
Adjusting party size, date or resource type while booking a handful more, spread out Availability re-runs after each change a guest actually settles on — debounced, not on every keystroke (see below)
Confirming 1–2 One POST …/reservations, plus one POST …/payment-intents when a deposit is collected

Add it up and one guest's session is comfortably under 30 requests, most of them in the first few seconds. A publishable key is shared by every guest on the venue's site at once, so size your ceiling for several guests arriving together, not for one: a dozen guests opening the page at Friday-night kickoff is roughly 12 × (6 page-load + 14 prefetch) ≈ 240 calls inside those first few seconds, before any of their booking flows even start.

Design against 300 requests per key per minute — and let that budget land however guest traffic actually arrives, rather than pacing it evenly across the minute: up to the full 300 may fall within any 10-second window, which comfortably covers the 240-call kickoff above with room to spare. That is one ceiling, not two competing ones — a burst is this same per-minute budget spent quickly, not an allowance stacked on top of it, so 240 calls in the first ten seconds followed by quieter booking-flow traffic for the rest of the minute both draw on the same 300. It covers a busy sports bar with a dozen guests browsing and booking at once on one publishable key; a secret key used by a single server integration will rarely come close. If your integration regularly sits anywhere near this, it is usually a retry loop or opening hours re-fetched on every keystroke rather than genuine guest traffic — the good-behaviour list below fixes both.

If you are already outside this

A client that is genuinely far above these numbers today — not a burst, a sustained pattern, like polling availability once a second all day — gets a human response, not a silent block: we reach out first, to understand what you are building, before anything changes. If you already know you need more than this — you are aggregating several venues behind one key, say, or building something that polls continuously — tell us first at hello@bookdineplay.com rather than find out once a limit exists.

Good client behaviour

Four habits keep any integration well inside the numbers above, limit or not:

  • Debounce availability. Fire on the pause, not on every keystroke or slider tick. 300 ms after a guest stops changing party size, date or resource type is a sound default — long enough to collapse a burst of changes into one call, short enough that the result still feels instant:

    let timer;
    function onFilterChange() {
      clearTimeout(timer);
      timer = setTimeout(fetchAvailability, 300); // ms — collapses a burst of changes into one call
    }
  • Cache the venue reads per page load, not per interaction. Profile, opening hours, menus, resources and the floor plan change only when an operator edits something in the console — read each once when the page opens and reuse it for the rest of the visit, as the stock widget already does (Venue → Caching).

  • Ask for the date a guest is actually looking at, not a wider range "to be safe." A 14-day prefetch for a visible date strip is a legitimate 14 calls; fetching a month nobody will scroll to is not.

  • Back off on 5xx, not on 429 — there is no 429 yet. An exponential backoff with jitter on a 5xx response (ours, not the guest's fault) is the one retry behaviour worth writing today.

Next steps

  • Authentication — the key that identifies each caller.
  • Availability — the endpoint the debounce advice above is mostly about.
  • Errors — every problem the API can return today; 429 is not among them yet.