A client asks for "some kind of paper for the treatment." A specialist doesn't check the CRM between clients and is the last to learn about a reschedule. A studio keeps its own records in another system and wants paid visits to land there automatically. Three different requests, three different mechanisms — and each has its own limit, better known in advance.
Where it is in the CRM
- Print templates: Settings → Processes → PDF templates.
- Phone notifications: Settings → Salon → Notifications.
- Webhooks: Settings → Integrations → Webhooks. The item is visible only to companies whose plan includes API access.
Print templates: layout, variables, preview
A template is HTML plus optional CSS plus page parameters: format (A4, A5, Letter), orientation, and margins in millimeters. The editor has three tabs — HTML, CSS, and "Settings". A new template opens with a starter layout: a header with the salon's name and address, a table with the date, client, phone, specialist, and status, a services table, and a total.
Data is filled in through variables in curly braces. The set is fixed: company ({{company.name}}, address, phone, website, logo), appointment ({{appointment.id}}, date, start and end time, status, comment, price, the "Paid" flag, specialist's full name), client (name, phone, email, address), plus {{currency}}, {{document_date}}, and two ready-made tables — {{services_table}} and {{products_table}}. The API reference gives the same list, so nothing has to be guessed.
There can be any number of templates, but only one default per company, and an inactive template cannot be made the default. The "Preview" button opens a finished PDF with test data — that's what you check the layout against.
Now for the limit, and it matters. There is no "print this visit's document" button in the interface. Only the API can generate a PDF for a real appointment — GET /v1/appointments/pdf-templates/{id}/preview/{appointmentId} returns the file. So right now the section is a template editor, not a way to print documents from a client's card.
Push: devices, quiet hours, log
These are personal settings, and they don't require salon-configuration rights: a person connects their own phone, not someone else's. The "Turn on" button subscribes exactly the device you clicked it from. If the browser has blocked notifications, the page says so directly; on iPhone they only work in the app added to the Home Screen — there's a separate hint about that too.
There are three settings: send or don't; "To all devices" or "Phones only" (notifications are visible in the interface anyway when you're at a computer); "Do not disturb from… until…", where an interval that crosses midnight is a normal case, not an input mistake.
The "Send a test" button sends itself a test notification and returns not "success" but the number of devices that accepted it. Zero is the answer to "why isn't it arriving." Below is a log of recent sends with the reason nothing went out: notifications are off, the type is muted, quiet hours, no connected devices, filtered out by the "phones only" setting, sending is not configured. The device list shows when each one last got a notification and why it was disconnected; the token itself is never exposed, only its last eight characters — enough to tell a device apart in support.
Push gets the same events as the bell icon in the CRM: a new online booking, tasks, chats, cashbox and warehouse events, payroll calculations. There is one rule — push never breaks whatever triggered it: a send error is caught and logged, not shown on the administrator's screen. A notification addressed to the whole company never goes to phones at all: waking up at night people the event doesn't concern is worse than staying silent.
Two limits. Turning off individual notification types is only possible through the API — there are no type toggles on the screen, even though the log does show that reason. And the whole subsystem stays silent if Firebase isn't configured in the environment: the section then says outright that push isn't configured here, instead of showing a button that does nothing.
Webhooks: events, signature, retries
A subscription is a name, a receiver URL, and a set of events; clicking a category selects the whole category at once. The list of events is long: leads, clients, appointments, employees, products, payments, chats, invoices, forms, tasks. What actually gets sent are the ones with a listener behind them — appointments (created, updated, cancelled, completed, reminder), clients, leads, employees, products, tasks.
The event body is the same for all of them: event, subscription_id, timestamp, and data. The headers are X-Beesection-Event, X-Beesection-Delivery-Id, and X-Beesection-Signature in the form sha256=…, i.e., HMAC-SHA256 of the request body. You can add your own headers, but not override the system ones. The address is checked for being "internal" before every send: a webhook won't fire to an internal or private address, even if the hostname resolved to a public one at the moment it was saved.
Delivery goes through a queue, not from the request handler: a slow receiver shouldn't hold up saving the appointment. The timeout is set from 5 to 120 seconds (default 30), the number of retries from 0 to 10 (default 3), with growing pauses: a minute, five minutes, a quarter hour, an hour, two hours. Every attempt lands in the delivery log — event, status, attempt number, error; the subscription list shows a running success/failed count next to it.
There's one main limitation, and it breaks expectations: events go only to verified subscriptions, and there's no verification button in the interface. Verification is a separate API call (POST /v1/event-subscriptions/{id}/verify): we send {"type":"url_verification","challenge":"…"} to your URL and wait for the same value back in the response. Until then, "Test ping" will also fail. Second: the subscription secret is generated on creation but is never shown anywhere — not on screen, not in the API response — so right now the only way to verify the signature on your side is to pull the secret from the database.
There's also a second, separate webhook mechanism — for the partner Connect API. It's configured only through that same API, signs the body differently (X-Webhook-Signature is computed from "timestamp + body"), and has its own retries: three attempts with pauses of 60, 300, and 900 seconds. The event ID there stays the same across all attempts — the subscriber uses it to discard duplicates.
What to do
Make one document template and check it with the "Preview" button before you actually need it: the starter layout in the editor already works, and it's faster to tweak than to write from scratch.
Turn push on for yourself and ask specialists to turn it on too — but click "Send a test" first. If it comes back zero, there's no point going further: the log will name the reason right away.
Set up a webhook only when there's genuinely someone on the other end to receive requests, and plan API verification right away — without it, the subscription will look created and active but won't receive a single event.
Comments
No comments yet. Ask your question — we answer within a day.