Public API

Sidebar: Settings → API Documentation

The public API lets your own systems create leads, drive your CRM and read or write bookings. Everything it does is scoped to one organization.

The full, always-current reference — every endpoint, every field, an example payload, the status codes and a request console that sends real calls with one of your keys — lives inside the dashboard. This page explains how it fits together.

Authentication and scope

Requests carry an API key from Settings → API Keys. The organization is read from the key itself: a key can never read or change another organization’s data, and there is no organization parameter to get wrong.

Keys are shown once. FlyB stores an encrypted fingerprint and cannot recover a key — only replace it. Revoking a key stops every integration using it immediately.

What the API covers

Discovery

List funnels and stages returns every CRM funnel with its stages in board order. Start here to collect the identifiers the other endpoints expect.

Contacts

EndpointNotes
Retrieve a contactBy ID
Create a contactA matching phone or e-mail merges into the existing record instead of duplicating it, and the response reports merged: true along with any field conflicts. Send stage_id to place the contact in the CRM in the same call
Update a contactOnly the fields you send; anything omitted keeps its stored value
Delete a contactPermanent, along with its CRM positions and history

A contact also carries its lead owner and its lead score, both read-only: the owner is decided by your capture rules and CRM automations (and only an admin may hand a lead over), and the score is awarded by your scoring rules, which record why alongside every point. They are published because “who owns this lead and how hot is it” is exactly what an agent deciding who to contact next is asking — but a number an integration could simply write would make the history a fiction.

CRM

Add or move to a stage places a contact in a stage — moving it if it is already in that funnel, keeping its history, or entering the funnel otherwise. Stage automations (auto-tags, auto-qualify) run as usual.

Qualify a contact, Mark as won and Mark as lost close or flag the position. Marking as lost accepts one of the predefined loss-reason codes, or your own short text — the predefined codes group better in reports.

Calendars and bookings

EndpointNotes
List calendarsEvery calendar with its custom questions, weekly availability rules, vacation periods, minimum notice (min_notice_hours) and public link
List days with availabilityDays with at least one free time. Booked times, times held for a guest whose payment is clearing, Google Calendar conflicts, vacations and the calendar’s minimum notice are already excluded
List times of a dayEach with the slot_id the booking endpoint expects back
List days and timesBoth of the above in one round trip — meant for agents that want the whole picture at once
Book an appointmentName the time with slot_id or starts_at; name the guest with contact_id or with a contact object. send_confirmation_email: false books silently — no confirmation e-mail, and no WhatsApp confirmation either when the calendar sends one. whatsapp_opt_in records the guest’s consent to WhatsApp messages: false sends them nothing on WhatsApp, true records that they agreed; omitted, the calendar’s WhatsApp messages go out as they always did
List bookingsFilter by guest, calendar and date range
Retrieve a bookingWith the Meet link and the guest’s self-service reschedule URL
Cancel a bookingBy ID, or found from the guest’s e-mail or phone

Two behaviours are worth knowing:

  • show_all bypasses the calendar’s slot presentation rule and returns every free time. It defaults to false, so by default the API offers exactly what the public page offers. Booking itself never applies the rule — a hidden slot is a real opening.
  • Time zones. Every response carries a timezone, and starts_at / ends_at are absolute instants. Send a timezone parameter to read and render dates on another clock; omit it to speak the calendar’s own.
  • Paid calendars. On a calendar that charges for bookings, a booking made through the API is confirmed without the online payment — the integration is your own. Charge the guest your own way, or send them the booking page instead.

Phone numbers

phone is accepted with or without the dial code. These two bodies create the same contact, and both come back with country_code filled:

{ "name": "Ana", "phone": "5511987654321" }
{ "name": "Ana", "phone": "11987654321" }

A number sent without a dial code is read against your organization’s country (Settings → Organization). A number that already carries one is recognised and not given a second copy — which is what lets you point an integration at the API without normalising its output first. Symbols and spaces are ignored, a leading + is honoured, and a number belonging to another country is recognised from its own dial code.

Send country_code when you know it — a number that could be read either way is then read the way you meant. It is never required.

The same reading is applied to the guest’s phone when booking, and to the booking page’s ?phone=, so a number reaches the same contact however it arrived.

Errors

Errors name the field that failed, because the callers of this API are often AI agents and a vague message costs a round trip:

querystring.days: Expected number, received nan

Two conflict responses carry extra information rather than just failing:

  • 409 on booking — the time is gone; the response includes that day’s remaining free times.
  • 409 on cancelling — more than one upcoming booking matched; the response includes the candidates, so you can send a booking_id, narrow the search, or cancel them all.

Other statuses: 400 validation, 401 missing or invalid key, 403 plan contact limit reached (creating a contact directly — booking never returns it, the guest’s contact is always created), 404 not found in this organization, 409 no open position in the funnel, 500 retryable.

The request console

Each endpoint page has a Try it panel that sends a real request using a key you pick. The request runs on FlyB’s servers, so the key’s secret never has to be typed into the page — and it hits the real endpoint, scoped to your organization. Records really are created, changed or deleted. Destructive calls require an explicit confirmation first.

Every page also gives you a ready-to-paste cURL.

Fair use

The API is provided for integrating your own systems. Automated harvesting, load that threatens platform stability, and use as a way around plan limits are prohibited — see the Acceptable Use Policy. FlyB may apply rate limits.