One chat in front.
An API behind it.
This page tracks what Tourgram will do and how other systems can talk to it. Nothing here is live yet. Names and numbers are fictional.
Status
Demo = the interactive demo on the main site already shows it. Build = where it sits in the plan. Nothing is built yet.
| Feature | Demo | Build | Needs |
|---|---|---|---|
| Chat assistant on Telegram | Yes | Next | Bot account, privacy policy |
| Chat assistant on WhatsApp | Yes | Later | Verified business, number, approved templates |
| Rates (inventory) | Yes | Next | Data model |
| Contracts: PDF to rates, ask on conflicts | Yes | Next | Storage, reading engine, review step, test set |
| Bookings, quotes, vouchers, LPOs | Yes | Next | PDF templates, numbering |
| Reminders, daily summary, tips | Yes | Next | Scheduler, rule set |
| Mini app (Telegram) | Yes | Later | Sign-in check |
| Payment links, paid by webhook | Yes | Next | Payment provider with connected accounts |
| Reports (Excel) | Yes | Later | Report jobs |
| Live search and booking: hotels, flights, activities, transfers | Yes | Needs partner | Official supplier APIs, guest nationality for hotel prices |
| Concierge: manual requests | Yes | Next | Request queue, supplier replies |
| Channel managers: connect, map rooms and rate plans | Yes | Needs partner | Channel manager API, agreement, code mapping |
| Public API and webhooks | Draft below | Next | Keys, signing, sandbox |
API draft
Base URL https://api.example.com/v1 (placeholder). JSON over HTTPS. Subject to change.
Auth
One secret key per agency, sent as Authorization: Bearer <key>. Keys are stored hashed. Test keys use the sandbox.
Conventions
ISO dates. Money as {"amount":"330.00","currency":"EUR"}. Cursor paging. Idempotency-Key on every write.
Errors
{"error":{"code":"…","message":"…"}} with a stable code. Unclear data is returned as a question, never guessed.
Contracts: PDF in, rates out
| Call | What it does |
|---|---|
POST /contracts | Upload a PDF or sheet. Returns 202 with an id; reading runs in the background. |
GET /contracts/{id} | Status, rates found, and any checks (a question, the options, and the pages they came from). |
POST /contracts/{id}/answers | Answer a check, or send it back to the hotel. |
POST /contracts/{id}/publish | Write the reviewed rates into the inventory. |
curl -X POST https://api.example.com/v1/contracts \
-H "Authorization: Bearer $KEY" -H "Idempotency-Key: 7c1e…" \
-F "file=@HotelRates_2027.pdf"
{ "id": "ctr_8f2k", "status": "reading" }
Inventory, bookings, payments, reports
| Call | What it does |
|---|---|
GET /hotels · GET /rates?hotel=&from=&to= | Read the inventory. Every rate carries its source (contract and page, supplier, or manual). |
PUT /rates/{id} | Change one rate. |
GET /bookings · GET /bookings/{id} | Status, paid and left, supplier confirmation. |
POST /payment-links | Create a link for a deposit or a balance. Pays into the agency's own account. |
POST /reports · GET /reports/{id} | Start a report (sales, by supplier) and fetch the Excel file when ready. The chart image comes with it. |
Live search and requests
| Call | What it does |
|---|---|
POST /searches | Search one category: hotels, flights, activities or transfers. Hotel searches need dates, guests and nationality, because net prices depend on it. |
POST /bookings | Book an offer from a search. Add more items (a transfer, an activity) to the same booking. |
POST /requests | A manual request (concierge). It is sent to the supplier; the price stays open until they answer. |
Channel managers
| Call | What it does |
|---|---|
POST /channels | Connect a channel manager with its agreement (PDF). The agreement is checked: scope, dates, signatures. |
POST /channels/{id}/activate | Activate it once every check is clear. |
GET /channels/{id}/suggestions?hotel= | Rooms and rate plans found for a hotel, with a suggested match to your rates. |
POST /channels/{id}/maps | Confirm the map. After this the hotel is ready to receive rates and availability. |
Webhooks
Signed, retried, one endpoint per agency.
| Event | When |
|---|---|
contract.read | A contract finished reading. |
contract.needs_check | Something is unclear and needs an answer. |
rates.published | Reviewed rates were written to the inventory. |
booking.created · booking.updated · booking.cancelled | A booking changed. |
payment.paid · payment.failed | A payment link result arrived. The booking is matched automatically. |
channel.activated · channel.mapped | A channel manager was activated, or a hotel was mapped and is ready to receive rates. |
POST https://your-system.example/hooks/tourgram
Tourgram-Signature: t=1761325200,v1=5c0b… (HMAC-SHA256 of "t.body")
{ "id": "evt_3q9", "type": "payment.paid",
"data": { "booking": "HP-1042", "amount": { "amount": "782.00", "currency": "EUR" } } }
Reply 2xx to confirm. Failures are retried with growing delays for 24 hours. Handle events by id: you may see one twice.
Integrating a system
Two directions, both through the API above: we send reviewed rates and booking changes, we read what the other system owns. The steps are the same for every system: connect, check the agreement, map the codes, activate. Agencies with their own systems connect with a key and webhooks; larger groups add branches and roles later. To start we need:
- Docs and a sandbox with test credentials.
- Code mapping for hotels, rooms and meal plans, so the same thing has the same id on both sides.
- One source of truth per field. Who wins when both change.
- Sync style: polling, webhooks, or both, and the limits on each.
- A test agency to run the first sync end to end.