Документация за разработчици

TapTime REST API

Четете и променяйте резервациите на маси и часовете, четете поръчки и карти за лоялност, извличайте подредения поток от събития и получавайте подписани уебхукове — от собствената си CRM, POS система, хранилище за данни или платформа за автоматизация. Тази страница е пълният справочник; защо бихте го използвали, обяснява ръководството за проследяване на конверсиите.

Базов URL адресhttps://api.tapti.me AuthBearer token ФорматJSON Защо да го използвате

Всяко заявка изисква API ключ на компанията (Интеграции → Уебхукове и API в панела), изпратен като Authorization: Bearer tt_live_…. Отговорите и грешките са в формат JSON.

Потвърдени резервации, променени след дадена дата
curl "https://api.tapti.me/v1/company/reservations?status=confirmed&updatedSince=2026-09-01T00:00:00Z" \
  -H "Authorization: Bearer tt_live_…"

Удостоверяване на автентичността

Всяко заявка съдържа API ключ на компанията като токен от типа „bearer“. Създайте такъв от панела — Интеграции → Уебхукове и API → REST API ключове — където той се показва еднократно и се съхранява само от страна на сървъра като хеш SHA-256; изгубен ключ се отменя и заменя, но не се възстановява. Една компания може да притежава до 10 активни ключа.

  • Ключовете само за четене могат да извикват всяка GET крайна точка, както и да абонират и отписват уебхукове — абонаментът не изпраща нищо, което ключът и без това не може да прочете.
  • Ключовете за четене и запис могат също да променят статуса на резервация с POST; ключ само за четене получава 403 Forbidden по тези маршрути.
  • Ключът принадлежи на една компания — всеки списък и заявка вече са ограничени до нея, няма параметър companyId.

Ограничения на скоростта

50 заявки на минута за ключ, в плъзгащ се прозорец, общо за всички крайни точки. При превишаване се връща 429 Too Many Requests; изчакайте и опитайте отново, вместо да проверявате по-често — или абонирайте уебхук и спрете да проверявате.

Крайни точки

GET /v1/company Само за четене или за четене и запис

Вижте текущата компания

На коя компания принадлежи ключът и какво може да прави самият ключ.

GET /v1/company/reservations Само за четене или за четене и запис

Списък с резервациите

Резервации на маси за компанията, подредени по дата на създаване — или, когато е зададено updatedSince, подредени по дата на последно обновяване.

ПараметърTypeЗначение
status string Разделени със запетая: в очакване, потвърдено, присъствал, завършено, не се е явил, отменено. „отменено“ съвпада и с двете причини за отмяна.
branchId integer Ограничете се до един клон.
from ISO 8601 datetime Само резервации, започващи на или след този час (UTC, ако не е посочено отклонение).
to ISO 8601 datetime Само резервации, започващи преди този час.
updatedSince ISO 8601 datetime Само резервациите, променени след този момент; превключва сортирането на updatedAt по възходящ ред за синхронизиране.
limit integer Размер на страницата: 1–100. По подразбиране: 50.
page integer Номерация на страниците, започваща от 1. По подразбиране – 1.
GET /v1/company/appointments Само за четене или за четене и запис

Списък със срещите

Същата структура и филтри като при резервациите, за модула „Назначения“.

ПараметърTypeЗначение
status string Разделени със запетая: в очакване, потвърдено, завършено, несе явил, отменено.
branchId integer Ограничи до един клон.
from ISO 8601 datetime Само резервации, започващи на или след тази дата.
to ISO 8601 datetime Само резервации, които започват преди този час.
updatedSince ISO 8601 datetime Само резервациите, променени след този момент; сортирани по updatedAt в възходящ ред.
limit integer Размер на страницата: 1–100. По подразбиране: 50.
page integer Номерация на страниците, започваща от 1. По подразбиране – 1.
GET /v1/company/reservations/{id} Само за четене или за четене и запис

Направете резервация

Едно условие: да се запази същият формат, в който го предават уебхуковете, заедно с указанието за източника. 404, когато идентификаторът не принадлежи на компанията, свързана с ключа.

GET /v1/company/appointments/{id} Само за четене или за четене и запис

Запишете час

Една среща – същата форма и правила като при търсене на резервация.

POST /v1/company/reservations/{id}/status Само за четене и запис

Промяна на статуса на резервацията

Потвърждаване, запазване на място, завършване, отбелязване на неявяване, отмяна или повторно отваряне — задейства същите уебхукове и конверсии, както при промяна на таблото. Текст на JSON: {"status": "..."}.

ПараметърTypeЗначение
status string, required Едно от следните: в очакване, потвърдено, с резервирано място, завършено, не се е явил, отменено (приемат се също „canceled“ и „canceled_by_venue“).
POST /v1/company/appointments/{id}/status Само за четене и запис

Промяна на статуса на среща

Същото като крайната точка за резервация, но без състоянието „на място“.

ПараметърTypeЗначение
status string, required Едно от следните: в процес, потвърдено, завършено, не се е явил, отменено (приемат се също „canceled“ и „canceled_by_venue“).
GET /v1/company/events Само за четене или за четене и запис

Извличане на данни от лентата със събития

Всяко събитие за резервация, поръчка и лоялност, като най-старите са първи — същият поток, от който се изпращат уебхуковете. Подайте последния видян курсор като after, за да получите само новото, и type, за да получите само някои видове.

ПараметърTypeЗначение
after integer cursor Курсорът от последното събитие, което сте обработили. Пропуснете, за да започнете от началото.
type string Типове или групи събития, разделени със запетая: booking.confirmed,order.placed или order, loyalty.*. Пропуснете за всички събития.
limit integer Размер на страницата, 1–100. По подразбиране: 50.
GET /v1/company/orders Само за четене или за четене и запис

Списък с поръчките

Поръчките на гостите на маса, за вкъщи и с доставка, както и всяка продажба, маркирана на касата, като най-старите са първи — или, когато е зададено paidSince, в реда на плащане. Поръчка, която още чака предплащане, не се включва.

ПараметърTypeЗначение
status string Разделени със запетая: open, paid.
source string customer (направена от госта) или staff (маркирана от персонала).
fulfilment string Разделени със запетая: dine_in, takeaway, delivery.
branchId integer Само за един клон.
from ISO 8601 datetime Само поръчки, създадени в този момент или след него.
to ISO 8601 datetime Само поръчки, създадени преди този момент.
paidSince ISO 8601 datetime Само поръчки, платени след този момент; сортира по paidAt във възходящ ред — за синхронизиране на продажбите.
limit integer Размер на страницата: 1–100. По подразбиране: 50.
page integer Номерация на страниците, започваща от 1. По подразбиране – 1.
GET /v1/company/orders/{id} Само за четене или за четене и запис

Вижте поръчка

Една поръчка с артикулите, сумите и атрибуцията ѝ — във формата, в който я носят уебхуковете за поръчки.

GET /v1/company/loyalty/programs Само за четене или за четене и запис

Списък с програмите за лоялност

Всяка програма с карти с печати: име, статус, необходими печати, наградата и къде важи.

GET /v1/company/loyalty/cards Само за четене или за четене и запис

Списък с картите за лоялност

Картите на членовете във формата на обекта за лоялност. Когато член запълни карта, тя става completed и до нея се появява нова активна; customer.id е членът.

ПараметърTypeЗначение
programId integer Само за една програма.
customerId integer Само за един член.
status string Разделени със запетая: active, completed.
updatedSince ISO 8601 datetime Само карти, получили печат или запълнени след този момент; сортира по updatedAt във възходящ ред.
limit integer Размер на страницата: 1–100. По подразбиране: 50.
page integer Номерация на страниците, започваща от 1. По подразбиране – 1.
GET /v1/company/loyalty/rewards Само за четене или за четене и запис

Списък с наградите за лоялност

Наградите, спечелени със запълнена карта, с кода им, срока на валидност и дали са осребрени.

ПараметърTypeЗначение
programId integer Само за една програма.
customerId integer Само за един член.
status string Разделени със запетая: issued, redeemed, expired.
from ISO 8601 datetime Само награди, издадени в този момент или след него.
to ISO 8601 datetime Само награди, издадени преди този момент.
limit integer Размер на страницата: 1–100. По подразбиране: 50.
page integer Номерация на страниците, започваща от 1. По подразбиране – 1.
GET /v1/company/webhooks Само за четене или за четене и запис

Списък с абонаментите за уебхукове

Абонаментите, създадени от този ключ. Уебхуковете, добавени в панела, не се показват тук.

POST /v1/company/webhooks Само за четене или за четене и запис

Абониране на уебхук

Започва изпращането на събития към URL адрес — това извиква приложението на платформата за автоматизация, когато потребител включи тригер. Връща абонамента и неговия таен ключ за подпис — еднократно. JSON тяло: {"url": "…", "events": ["order.placed"]}; приема се и форматът на Zapier {"target_url": "…", "event": "…"}.

ПараметърTypeЗначение
url string, required https адресът, към който да се изпраща (приема се и target_url).
events array of strings, required Типове събития, групи като order.* или loyalty, или * за всичко (за едно се приема и event).
description string Име, показвано в панела. По подразбиране — платформата и името на ключа.
DELETE /v1/company/webhooks/{id} Само за четене или за четене и запис

Отписване на уебхук

Спира изпращането към абонамент, създаден от този ключ. Връща 204. Отмяната на ключа премахва и всичките му абонаменти.

Обектът на резервацията

Резервацията и назначението се представят в един общ формат: вид, идентификационен номер, статус, източник, guestInitiated, startsAt/endsAt/часова зона (собствената зона на клона), валута, компания, клон, гост, приписване, conversionId, createdAt/updatedAt — плюс partySize и таблица за резервацията, услугата и специалиста за срещата. Това е точно това, което предоставя уебхукът, така че получател, който обработва едното, обработва и двете.

Вземи /v1/company/reservations/4821 → данни
{
  "data": {
    "kind": "reservation",
    "id": 4821,
    "status": "confirmed",
    "source": "online",
    "guestInitiated": true,
    "startsAt": "2026-09-12T20:00:00+03:00",
    "endsAt": "2026-09-12T21:30:00+03:00",
    "timezone": "Asia/Baku",
    "currency": "AZN",
    "company": { "id": 12, "name": "Cafe Aroma", "slug": "cafe-aroma", "country": "AZ" },
    "branch": { "id": 3, "name": "Nizami st." },
    "partySize": 4,
    "table": { "id": 9, "label": "T3" },
    "guest": { "name": "Maria K.", "phone": "…", "email": "…" },
    "locale": "en",
    "note": null,
    "conversionId": "tt3f9c…",
    "createdAt": "2026-09-10T08:12:04+00:00",
    "updatedAt": "2026-09-12T20:00:03+00:00",
    "attribution": { "channel": "widget", "utmSource": "instagram", "gclid": null, "fbclid": "IwAR2…" }
  }
}

Обектът на поръчката

Поръчката има един и същ формат, където и да я срещнете — в REST API, в уебхуковете за поръчки и в потока от събития: kind ("order"), id, number (номерът, който персоналът извиква), status (open или paid), source (customer или staff), guestInitiated, fulfilment, table, label, deliveryAddress, note, currency, timezone, company, branch, customer (членът на програмата за лоялност, когато персоналът го е разпознал), items (name, variant, quantity, unitPriceCents, subtotalCents), itemCount, subtotalCents, discountCents, deliveryFeeCents, tipCents, totalCents, valueCents (стойността на поръчката без бакшиша — числото, което отчитат конверсиите), paymentMethod, servedBy, conversionId, createdAt, paidAt и attribution. Сумите винаги са в най-малките единици на валутата.

GET /v1/company/orders/9170 → данни
{
  "data": {
    "kind": "order",
    "id": 9170,
    "number": 42,
    "status": "paid",
    "source": "customer",
    "guestInitiated": true,
    "fulfilment": "takeaway",
    "table": null,
    "label": "Ana",
    "currency": "EUR",
    "branch": { "id": 3, "name": "Vitosha Blvd" },
    "customer": { "id": 311, "name": "Ana", "phone": "…" },
    "items": [
      { "menuItemId": 88, "name": "Flat white", "variant": "Large",
        "quantity": 2, "unitPriceCents": 450, "subtotalCents": 900 }
    ],
    "itemCount": 2,
    "subtotalCents": 900,
    "discountCents": 0,
    "deliveryFeeCents": 0,
    "tipCents": 100,
    "totalCents": 1000,
    "valueCents": 900,
    "paymentMethod": "online",
    "conversionId": "tt81ad…",
    "createdAt": "2026-09-12T12:04:10+03:00",
    "paidAt": "2026-09-12T12:05:02+03:00",
    "attribution": { "channel": "web", "utmSource": "google", "gclid": "Cj0K…" }
  }
}

Обектът за лоялност

Всяко събитие, карта и награда за лоялност имат един формат: kind ("loyalty"), id (картата), timezone, company, branch (къде се е случило, когато има такъв), program (id, name, stampsRequired, rewardTitle), customer (id, name, phone, locale), card (id, status, stampsCount, stampsRequired, stampsToReward, createdAt), stamp (при печат: source, issuedBy, createdAt) и reward (при награда: code, title, status, expiresAt, redeemedAt, redeemedBy), плюс conversionId — идентификаторът, под който се отчита регистрацията в програмата за лоялност.

GET /v1/company/loyalty/cards → data[0]
{
  "kind": "loyalty",
  "id": 5120,
  "program": { "id": 4, "name": "Coffee card", "stampsRequired": 8, "rewardTitle": "Free coffee" },
  "customer": { "id": 311, "name": "Ana", "phone": "…", "locale": "bg" },
  "card": { "id": 5120, "status": "active", "stampsCount": 5,
            "stampsRequired": 8, "stampsToReward": 3 },
  "branch": { "id": 3, "name": "Vitosha Blvd" },
  "stamp": { "source": "qr_scan", "issuedBy": "Ivan", "createdAt": "…" },
  "reward": null,
  "conversionId": "tt5c02…"
}

Поток от събития

Всеки ред е { id, cursor, type, createdAt, previousStatus, data }. data съдържа обекта под ключа, който посочва префиксът на събитието: data.booking, data.order или data.loyalty. Запазвайте най-високия обработен курсор и го подавайте обратно като after — той никога не пропуска и не повтаря ред, така че е безопасно да продължите след срив. Пренебрегвайте типовете, които не обработвате: може да бъдат добавени нови.

Тип на събитиетоЗначение
booking.requestedГост е заявил резервация, която чака вашето потвърждение.
booking.confirmedРезервацията е потвърдена — направена като потвърдена или потвърдена по-късно от персонала.
booking.cancelledОтменена от госта или от обекта; status показва кое от двете.
booking.no_showГостът не е дошъл.
booking.completedПосещението е приключило.
order.placedПоръчка на гост е стигнала до обекта — от страницата, от QR кода на маса, за вкъщи или с доставка; след плащането, когато обектът взима предплащане.
order.paidПлатена е поръчка, включително продажба, маркирана на касата.
loyalty.member_joinedКлиент е получил първия си печат в програма.
loyalty.stamp_addedКъм карта е добавен печат.
loyalty.reward_issuedКарта е запълнена и наградата ѝ е издадена.
loyalty.reward_redeemedНаграда е предадена на госта.
Бъдете в крак с актуалните новини за събитието
curl "https://api.tapti.me/v1/company/events?after=998&limit=100" \
  -H "Authorization: Bearer tt_live_…"

Уебхукове

Създайте крайна точка в „Интеграции“ → „Уебхукове и API“ — или свържете Zapier, Make, n8n или Pipedream в „Интеграции“ → „Автоматизация“, — за да изпраща TapTime подписано JSON събитие чрез POST в момента, в който се промени резервация, поръчка или карта за лоялност. Събитията се избират за всяка крайна точка поотделно. Една компания може да има общо до 50 уебхука, постбека, чата и връзки за автоматизация.

ЗаглавиеЗначение
TapTime-EventТипът на събитието, например booking.confirmed.
TapTime-Event-IdСтабилен идентификатор на събитието — използвайте го, за да избегнете дублиране при повторен опит за доставка.
TapTime-DeliveryИдентификационен номер на този конкретен опит за доставка.
TapTime-Signaturet=<Unix време>, v1=<шестнадесетичен HMAC-SHA256 на "t.rawBody">, подписан със собствения секретен ключ на крайната точка.
  • Всеки отговор от типа 2xx се счита за успешно предаден; при отговор, различен от 2xx, или при изтичане на времето за изчакване се извършват повторни опити с интервали (1 м, 5 м, 15 м, 1 ч, 3 ч, 6 ч, 12 ч) до 8 пъти — при код 410 повторните опити се прекратяват.
  • Пренасочванията не се проследяват.
  • URL адресът трябва да е HTTPS в производствената среда и не трябва да сочи към частен адрес или адрес за обратна връзка.
  • Доставката се извършва поне веднъж: винаги проверявайте подписа и премахвайте дублираните записи при TapTime-Event-Id.
ПУБЛИКАЦИЯ · application/json · booking.confirmed
{
  "id": "evt_9f3c2a7e1b",
  "type": "booking.confirmed",
  "createdAt": "2026-09-12T19:02:11+03:00",
  "test": false,
  "data": { "booking": { "kind": "reservation", "id": 4821, "status": "confirmed", "…": "…" } }
}
Проверка на подписа (Node.js)
const [t, v1] = req.headers["taptime-signature"]
  .split(",").map(part => part.split("=")[1]);
const expected = crypto
  .createHmac("sha256", process.env.TAPTIME_WEBHOOK_SECRET)
  .update(`${t}.${rawBody}`)
  .digest("hex");
const valid = crypto.timingSafeEqual(
  Buffer.from(expected), Buffer.from(v1));

Абонаменти за уебхукове

Платформите за автоматизация включват и изключват тригерите през API, вместо да молят потребителя да постави URL адрес („REST hooks“): изпратете с POST собствения URL адрес на платформата и желаните събития, запазете върнатия id и го изтрийте с DELETE, когато тригерът бъде изключен. Абонаментът е обикновен подписан уебхук — вижда се в панела, отбелязан с ключа, който го е създал.

  • Ключът вижда и премахва само абонаментите, които е създал; отмяната на ключа премахва всички тях.
  • Адресите в hooks.zapier.com, make.com и pipedream.net се разпознават и се показват с името на платформата; всеки друг https адрес е обикновен уебхук.
  • Тайният ключ за подпис се връща еднократно, в отговора на POST заявката; собственикът може да го види отново в панела.
Абонирайте URL адрес за нови поръчки
curl -X POST "https://api.tapti.me/v1/company/webhooks" \
  -H "Authorization: Bearer tt_live_…" -H "Content-Type: application/json" \
  -d '{"url": "https://hooks.zapier.com/hooks/catch/123/abc/", "events": ["order.placed"]}'

Отговори

GET или POST заявка към собствения URL адрес на вашия тракер с попълнени макроси — за платформи, които приемат постбекове чрез параметри в URL адреса, а не JSON уебхукове. За поръчка {value} е стойността на поръчката без бакшиша, а {order_id} — нейният идентификатор.

URL за обратно изпращане с заместващи символи · GET или POST
https://tracker.example/postback
  ?cid={click_id}&event={event}&status={status}
  &payout={value}&cur={currency}

Налични заместващи символи

  • {event}
  • {event_id}
  • {status}
  • {booking_id}
  • {booking_type}
  • {order_id}
  • {customer_id}
  • {conversion_id}
  • {value}
  • {currency}
  • {party_size}
  • {branch_id}
  • {timestamp}
  • {utm_source}
  • {utm_medium}
  • {utm_campaign}
  • {utm_term}
  • {utm_content}
  • {gclid}
  • {fbclid}
  • {msclkid}
  • {ttclid}
  • {click_id}

Грешки

Всяка грешка е JSON: { "error": "<code>", "message": "<human-readable>" }.

StatusгрешкаЗначение
401 unauthorized Липсва заглавката „Authorization“ или ключът е невалиден или е отменен.
403 forbidden Ключ само за четене, наричан „крайна точка за запис“ (промяна на състоянието).
404 not_found Няма резервация с този идентификационен номер, принадлежаща на компанията, издала ключа.
409 conflict Промяната на статуса би довела до двойно резервиране на масата или мястото; нищо не се промени.
422 invalid_status Стойността на полето „Статус“ не е сред допустимите стойности за този тип резервация.
422 invalid_type Параметърът type на потока от събития не посочва нито тип, нито група събития.
422 invalid_url URL адресът на абонамента не е публичен https адрес.
429 rate_limited Повече от 50 заявки за този ключ за една минута. Намалете честотата и опитайте отново.
Имате ли нужда от ключ?

Достъпът до API, уебхуковете и интеграциите с чатове и платформи за автоматизация са включени във всеки модул — без допълнителна такса и без отделен план за разработчици.

Започнете безплатен пробен период