API pentru dezvoltatori
API-ul deschis Vitrina: meniu, comenzi, rezervări, oaspeți și vânzări pentru POS-ul, ecranul din bucătărie, CRM-ul sau contabilitatea ta. REST și JSON, chei cu permisiuni, webhookuri semnate.
Ce poți face
- Meniu: categorii, preparate, prețuri și disponibilitate pe locații, plus produsele epuizate: scoți un preparat de la vânzare sau îl readuci
- Editarea meniului: categorii și preparate, denumiri și descrieri în limbile oaspeților, prețuri, porții, modificatori, ordine și vizibilitate
- Comenzi: listă cu filtre, produse și sume, stările din bucătărie și de predare (acceptată, în preparare, gata, predată)
- Comenzi noi din call center, de la un chioșc sau de pe alt site, cu aceleași prețuri și reguli de livrare ca pe site-ul tău; POS-ul și bucătăria le văd imediat, iar oaspetele plătește la primire
- Livrare: cine duce comanda (doar prenumele curierului), când a ridicat-o și când a livrat-o: în comandă și ca eveniment
- Plățile și rambursările fiecărei comenzi pentru reconciliere, doar citire
- Rezervări: listă, rezervare nouă și schimbarea stării (confirmare, refuz, oaspetele a venit sau nu a venit)
- Oaspeți: profiluri și date de contact, doar cu o permisiune separată
- Punctele de fidelitate ale oaspeților: le adaugi sau le scazi cu un motiv, cu o permisiune separată; soldul nu ajunge pe minus, iar fiecare operațiune intră în jurnal
- Vânzări pe zile pentru contabilitate: comenzi, încasări, reduceri, rambursări și bacșișuri, pe metode de plată și canale
- Locații: adrese, contacte și program
- Evenimente (comandă nouă, schimbare de stare, plată, anulare, rambursare, livrare, rezervare nouă, produse epuizate și modificări de meniu) prin webhook pe serverul tău
API-ul nu încasează plăți, nu face rambursări și nu anulează comenzi: banii oaspeților îi mișcă doar localul însuși. De aceea, comenzile din API oaspetele le plătește la primire.
Acces și permisiuni
Cheia o creează proprietarul localului în panoul de administrare, în secțiunea „API și webhookuri”: dă un nume integrării și alege permisiunile și locațiile. Cheia se afișează o singură dată (în baza de date rămâne doar amprenta ei) și poate fi revocată oricând. Numele, telefoanele și adresele oaspeților integrarea le vede doar cu permisiunea customers:read.
Permisiunile cheii
locations:read- Locații: adrese, contacte și program
menu:read- Meniu, prețuri și disponibilitatea preparatelor
menu:write- Produse epuizate: scoți un preparat de la vânzare sau îl readuci
menu:manage- Editarea meniului: categorii, preparate, prețuri, porții și ordine
orders:read- Comenzi: listă și detalii, fără datele de contact ale oaspetelui
orders:write- Stările din bucătărie și de predare
orders:create- Comenzi noi cu plata la primire
payments:read- Plățile și rambursările comenzilor, doar citire
reservations:read- Rezervări: listă și detalii
reservations:write- Rezervare nouă și schimbarea stării ei
customers:read- Numele, telefonul, e-mailul și adresa oaspetelui în comenzi, rezervări și lista de oaspeți
loyalty:write- Adăugarea și scăderea punctelor de fidelitate ale oaspetelui, doar împreună cu accesul la oaspeți
reports:read- Vânzări pe zile pentru contabilitate
Prima cerere
API-ul rulează pe serverul localului: fiecare client Vitrina are propriul server și propriul domeniu. Cheia se trimite în antetul Authorization: Bearer vit_live_…, iar răspunsul e JSON mereu în același plic: date, câmpuri tehnice și o eroare cu cod și mesaj în limba cererii.
curl https://api.example.com/api/open/v1/ping \
-H "Authorization: Bearer vit_live_…"{
"data": {
"ok": true,
"brand": "my-bistro",
"apiVersion": "2026-10-13",
"serverTime": "2026-10-13T09:30:00.000Z",
"clientName": "POS integration",
"scopes": ["menu:read", "orders:read", "orders:write"],
"cafeIds": []
},
"meta": null,
"error": null
}Webhookuri
Adresele pentru evenimente le adaugă proprietarul în aceeași secțiune a panoului și alege pentru fiecare ce evenimente primește. Fiecare cerere e semnată: antetul Vitrina-Signature conține momentul trimiterii și un HMAC-SHA256 al momentului și al corpului cererii, calculat cu secretul adresei. Numele și datele de contact ale oaspeților ajung în evenimente doar pe adresele cu opțiunea „Trimite datele de contact ale oaspetelui” bifată.
Evenimente
order.created- Comandă nouă
order.status_changed- S-a schimbat starea comenzii
order.paid- Comandă plătită
order.cancelled- Comandă anulată
order.refunded- Oaspetelui i s-au returnat banii sau punctele
order.delivery_updated- Un curier a fost alocat sau retras, comanda a fost ridicată sau livrată
reservation.created- Rezervare nouă
reservation.status_changed- S-a schimbat starea rezervării
menu.availability_changed- Un preparat a fost scos de la vânzare sau readus
menu.changed- S-a schimbat meniul: categorii, preparate, prețuri sau ordine
import { createHmac, timingSafeEqual } from 'node:crypto'
const TOLERANCE_SECONDS = 300
export function isFromVitrina(rawBody, header, secret) {
const parts = header.split(',').map((part) => part.trim().split('='))
const t = parts.find(([name]) => name === 't')?.[1] ?? ''
const age = Math.abs(Date.now() / 1000 - Number(t))
if (!/^\d+$/.test(t) || age > TOLERANCE_SECONDS) return false
const hmac = createHmac('sha256', secret).update(`${t}.${rawBody}`)
const want = Buffer.from(hmac.digest('hex'))
return parts
.filter(([name]) => name === 'v1')
.map(([, value]) => Buffer.from(value ?? ''))
.some((got) => got.length === want.length && timingSafeEqual(got, want))
}Semnătura se calculează din corpul brut al cererii, înainte de parsarea JSON. Respinge semnăturile mai vechi de 5 min; o livrare repetată a aceluiași eveniment are același Vitrina-Event-Id; după el elimini duplicatele.
Limite și fiabilitate
- 600 de cereri pe minut pentru fiecare cheie, în vârf până la 60 deodată; peste limită primești răspunsul 429 și antetul
Retry-After - Antetul
Idempotency-Keyla POST, PUT și PATCH: o repetare cu aceeași cheie în 24 h întoarce primul răspuns în loc să creeze un duplicat; pentru comenzi noi și puncte de fidelitate este obligatoriu - Listele vin pe pagini: limit până la 200 și offset, iar răspunsul conține numărul total
- Dacă serverul tău nu răspunde în 10 s, retrimitem evenimentul cu pauze tot mai lungi: 8 încercări în aproape două zile
- O adresă care nu a acceptat 20 de livrări la rând se dezactivează singură; jurnalul livrărilor se păstrează 30 de zile, iar orice eveniment din el poate fi retrimis
Versiuni
Versiunea e în adresă: /api/open/v1. Schimbările incompatibile apar doar ca versiune nouă lângă cea veche, iar cea veche răspunde cât timp e folosită. Data reviziei interfeței e în câmpul apiVersion al fiecărui eveniment, acum 2026-10-13.
Descriere completă
Toate cererile, răspunsurile și codurile de eroare sunt în specificația OpenAPI de pe serverul localului: pagina /api/open/v1/docs și fișierul /api/open/v1/openapi.json pentru generatoarele de clienți.
Pentru integratori
Construiești o integrare pentru mai multe localuri, de exemplu POS, serviciu de livrare sau contabilitate? Scrie-ne: îți dăm acces de test și te ajutăm cu prima conectare.
Cât costă
API-ul și webhookurile sunt incluse în pachetele „Complet” și „Lanț”. Pentru „Start” și „Restaurant”, la cerere.