Table Rush
Prijava Započni besplatno

Za programere · plan Premium

API i webhookovi

Povežite web stranicu, CRM, blagajnu ili automatizacije s Table Rushom: čitajte i upisujte rezervacije API ključem, a svaku novu, izmijenjenu ili otkazanu rezervaciju primite kao potpisanu obavijest na svoju adresu.

Autentikacija

Ključ stvara vlasnik u aplikaciji: Postavke → API i webhookovi → Novi ključ. Ključ (tr_ + 40 znakova) prikazuje se samo jednom; u bazi čuvamo samo njegov otisak (SHA-256). Ključ je „samo čitanje" ili „čitanje i pisanje". Opozvani ključ prestaje raditi odmah.

Base URL:  https://flfjwaukkpgxywtoudge.supabase.co/functions/v1/api
Header:    Authorization: Bearer tr_0123456789abcdef0123456789abcdef01234567

Ključ ne stavljajte u kod koji se izvršava u pregledniku posjetitelja — pozivajte API sa svog poslužitelja.

Rezervacije

Polja u odgovoru: id, name, phone, email, date (YYYY-MM-DD), time (HH:MM), guests, status (pending · confirmed · declined · cancelled), source, note, arrival (arrived · noshow · null), event_id, language, cancelled_by, created_at, updated_at.

GET/v1/reservations

Parametri: from, to (zadano danas → +30 dana, najviše 62 dana), status, limit (do 500, zadano 100), offset.

curl -H "Authorization: Bearer $TR_KEY" \
  "$BASE/v1/reservations?from=2026-10-01&to=2026-10-07&status=confirmed"

{ "data": [ { "id": "…", "name": "Ana Horvat", "date": "2026-10-03", "time": "20:00", "guests": 4, "status": "confirmed", … } ],
  "limit": 100, "offset": 0 }

GET/v1/reservations/{id}

Jedna rezervacija. Rezervacija drugog restorana uvijek vraća 404.

POST/v1/reservations

Treba ključ s pravom pisanja. Obavezno: name, phone, date, time, guests (1–99). Neobavezno: email, note, status (pending ili confirmed, zadano pending), language (hr/en/de/it). Izvor rezervacije je api.

curl -X POST -H "Authorization: Bearer $TR_KEY" -H "Content-Type: application/json" \
  -d '{"name":"Ana Horvat","phone":"+385 91 234 5678","email":"ana@example.com","date":"2026-10-03","time":"20:00","guests":4}' \
  "$BASE/v1/reservations"          # → 201 + rezervacija

PATCH/v1/reservations/{id}

Mijenjati se smiju (status može biti pending, confirmed, declined ili cancelled — pending ponovno otvara rezervaciju): status, arrival, note, date, time, guests, name, phone, email. Sva ostala polja (npr. kartica ili ulaznice) odbijaju se s UNKNOWN_FIELD. Rezervacija čija kartica ili ulaznice još nisu plaćene ne može se potvrditi (409).

curl -X PATCH -H "Authorization: Bearer $TR_KEY" -H "Content-Type: application/json" \
  -d '{"status":"confirmed","note":"stol uz prozor"}' "$BASE/v1/reservations/$ID"

Događanja

GET/v1/events

Nadolazeća događanja: id, title, description, date, time, seats, seats_sold, price_eur, status.

Greške i ograničenja

HTTPcodeZnačenje
400VALIDATION · UNKNOWN_FIELDNeispravno ili nedopušteno polje; message kaže koje.
401UNAUTHORIZEDNema ključa, ključ ne postoji ili je opozvan.
403SCOPE · PLAN_REQUIRED · READ_ONLYKljuč samo za čitanje; restoran nije na planu Premium; račun je samo za čitanje (tada rade samo zahtjevi za čitanje).
404NOT_FOUNDNema takve rezervacije u vašem restoranu.
409CARD_PENDING · TICKET_PENDING · EVENT_BOOKING · …Pravilo u bazi odbilo je promjenu. Rezervaciji za događanje API ne mijenja datum, vrijeme ni broj gostiju.
429RATE_LIMITViše od 120 zahtjeva u minuti po ključu.
500INTERNALGreška na našoj strani; pokušajte ponovno.
503UNAVAILABLEBrojač zahtjeva trenutačno ne odgovara; pokušajte za nekoliko sekundi.
{ "error": { "code": "VALIDATION", "message": "guests must be 1–99" } }

Webhookovi

Dodaju se u Postavke → API i webhookovi (do 5 adresa, samo https://, bez IP adresa i lokalnih imena). Uz svaku adresu dobivate tajni ključ (whsec_…) koji se prikazuje samo jednom. Događaji: reservation.created, reservation.updated, reservation.cancelled (i ping kad pošaljete test).

POST https://vasa-stranica.hr/table-rush
Content-Type: application/json
X-TableRush-Event: reservation.created
X-TableRush-Delivery: 5b1f…            (isti id kao "id" u tijelu — koristite ga za odbacivanje duplikata)
X-TableRush-Signature: t=1790000000,v1=9f2c…

{ "id": "5b1f…", "type": "reservation.created", "created_at": "2026-10-01T18:02:11Z",
  "data": { "id": "…", "name": "Ana Horvat", "date": "2026-10-03", "time": "20:00", "guests": 4, "status": "pending", … } }

Provjera potpisa

Potpis je HMAC-SHA256 tajnog ključa nad <t>.<sirovo tijelo zahtjeva>, zapisan heksadecimalno. Odbacite zahtjev ako potpis ne odgovara ili je t stariji od 5 minuta.

Node.js

import crypto from 'node:crypto';
function verify(rawBody, header, secret) {
  const m = /^t=(\d+),v1=([0-9a-f]{64})$/.exec(header || ''); if (!m) return false;
  if (Math.abs(Date.now() / 1000 - Number(m[1])) > 300) return false;
  const expected = crypto.createHmac('sha256', secret).update(`${m[1]}.${rawBody}`).digest('hex');
  return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(m[2]));
}

PHP

function tr_verify(string $raw, string $header, string $secret): bool {
  if (!preg_match('/^t=(\d+),v1=([0-9a-f]{64})$/', $header, $m)) return false;
  if (abs(time() - (int)$m[1]) > 300) return false;
  return hash_equals(hash_hmac('sha256', $m[1] . '.' . $raw, $secret), $m[2]);
}

Python

import hmac, hashlib, re, time
def verify(raw: bytes, header: str, secret: str) -> bool:
    m = re.fullmatch(r"t=(\d+),v1=([0-9a-f]{64})", header or "")
    if not m or abs(time.time() - int(m[1])) > 300: return False
    exp = hmac.new(secret.encode(), f"{m[1]}.".encode() + raw, hashlib.sha256).hexdigest()
    return hmac.compare_digest(exp, m[2])

Pitanja o integraciji: podrska@table-rush.com. API je dio plana Premium.