> ## Documentation Index
> Fetch the complete documentation index at: https://docs.impellabs.tech/llms.txt
> Use this file to discover all available pages before exploring further.

# Bookings

> Read free times, make bookings and manage the services people can book.

Bookings go into the calendar of ImpelLabs, so a booking works without any other calendar. You can read free times,
book a time by hand, move or cancel a booking, and define the services that customers book. A service can have its
own public booking page.

A call uses the token of a member. What the member sees depends on the role.

* An owner or an admin sees every booking.
* Other members see their own bookings, the bookings of their people, and the bookings of the conversations they see.
* Only an owner or an admin can create, change or archive a service. Other members get a `403` with
  `Owners and admins change what customers can book.`

Times are stored in UTC. Send every time with its offset, like `2026-11-03T09:00:00+04:00`. A time without an offset
returns `400`.

## Read free times

```bash theme={null}
curl "https://api.impellabs.tech/api/v1/booking/slots?service_id=SERVICE_ID&from=2026-11-03T00:00:00%2B04:00&to=2026-11-10T00:00:00%2B04:00&zone=Asia/Dubai" \
  -H "Authorization: Bearer imp_..."
```

The query takes these keys. Each key is optional.

| Key | Meaning |
| - | - |
| `from`, `to` | The period. The default is the next 7 days. |
| `service_id` | A service. Its duration, notice and hosts apply. |
| `host` | A member id. |
| `department` | A department id. |
| `app` | An app name. |
| `duration` | Minutes, as a whole number. |
| `zone` | The time zone of the customer. |

The reply has `slots`, `app`, `duration_minutes` and `zone`. Each slot has `start`, `end`, `host` (`id` and `name`),
`host_time` and `customer_time`.

## Make a booking

```bash theme={null}
curl -X POST https://api.impellabs.tech/api/v1/booking/bookings \
  -H "Authorization: Bearer imp_..." \
  -H "Content-Type: application/json" \
  -d '{
    "starts_at": "2026-11-03T10:00:00+04:00",
    "service_id": "SERVICE_ID",
    "customer_name": "Sam",
    "customer_email": "sam@example.test",
    "key": "order-1042"
  }'
```

The reply is the booking, with status `201`.

```json theme={null}
{
  "id": "…",
  "ref": "booking:…",
  "starts_at": "2026-11-03T06:00:00+00:00",
  "ends_at": "2026-11-03T06:30:00+00:00",
  "status": "booked",
  "title": "Intro call",
  "location": "",
  "host": {"id": "…", "name": "Alex"},
  "service": {"id": "…", "name": "Intro call"},
  "created_via": "team",
  "customer": {"name": "Sam", "phone": "", "email": "sam@example.test"},
  "notes": "",
  "contact_id": null,
  "case_id": null,
  "created_by": {"type": "member", "id": "…"},
  "archived": false,
  "created_at": "…",
  "updated_at": "…"
}
```

The request takes `starts_at` (required), `host_id`, `service_id`, `duration_minutes`, `title`, `location`, `notes`,
`customer_name`, `customer_phone`, `customer_email`, `contact_id`, `case_id` and `key`. With no `host_id`, a service
that belongs to the business has no host and any other booking is hosted by the caller. The booking goes through the
same checks as a booking by an agent. When the time is not free, the call returns `400` with a `detail` sentence.
Send the same `key` again to book once: a retry makes the same booking.

| Task | Call |
| - | - |
| List bookings. Keys: `from`, `to`, `host` (an id or `me`), `status` (one or a list with commas), `case`, `contact`, `service`. | `GET /api/v1/booking/bookings` |
| Read one booking. | `GET /api/v1/booking/bookings/{booking_id}` |
| Move, cancel or edit a booking. | `PATCH /api/v1/booking/bookings/{booking_id}` |

The list is `{"bookings": [...]}`, ordered by start time. A booking that ended more than an hour ago is left out
unless you send `from`. A new `starts_at` in a `PATCH` moves the booking and checks the time again. `status` takes
`booked`, `done`, `cancelled` or `no_show`. A change to `cancelled` tells the host. `PATCH` also takes `title`,
`location`, `notes`, `customer_name`, `customer_phone`, `customer_email` and `archived: true`.

## Services

A service is something a customer can book: its length, its place, its notice, its hosts and its own page.

```bash theme={null}
curl -X POST https://api.impellabs.tech/api/v1/booking/services \
  -H "Authorization: Bearer imp_..." \
  -H "Content-Type: application/json" \
  -d '{"name": "Intro call", "duration_minutes": 30, "slug": "intro-call"}'
```

| Field | Rule |
| - | - |
| `name` | Required. Up to 160 characters. |
| `description`, `location` | Text. |
| `kind`, `location_type` | One of the choices the call names in its `400` answer. |
| `whose` | `team` or `business`. |
| `duration_minutes` | 5 to 1440. |
| `capacity` | 1 to 1000. |
| `buffer_minutes` | 0 to 480. |
| `advance_days` | 1 to 730. How far ahead a customer can book. |
| `min_notice_minutes` | 0 to 10080. |
| `price_minor` | 0 or more, in the smallest unit of the currency. |
| `is_active` | `true` or `false`. |
| `hosts` | A list of member ids of active members. |
| `options` | Up to 30 options, each `{id?, name, price_minor?, duration_minutes?}`. |
| `slug` | The link of the public page: 3 to 60 small letters, numbers and single hyphens. It is unique on the platform. |

| Task | Call |
| - | - |
| List services. Add `?all=1` to include switched-off ones. The reply has `services` and `currency`. | `GET /api/v1/booking/services` |
| Read, change or archive one. An archive keeps its bookings. | `GET`, `PATCH`, `DELETE /api/v1/booking/services/{service_id}` |
| Read or change `send_confirmations` and `currency`. | `GET`, `PATCH /api/v1/booking/settings` |

`currency` is a three-letter code. `send_confirmations` switches the booking confirmation workflow on or off.

## Hours and time off

| Task | Call |
| - | - |
| Read your own hours and time off. | `GET /api/v1/availability/me` |
| Replace your hours with `hours`, or your upcoming time off with `away`. | `PUT /api/v1/availability/me` |
| Read the people you manage. Owners and admins read everyone. Add `?department=` to narrow it. | `GET /api/v1/availability/members` |

Each time off is `{id?, starts_at, ends_at, reason?, cover_id?}`. The list replaces the current and later ones. A time
off ends after it starts. Empty `hours` means the business hours apply. A member who is not a manager gets `403` on
the members list.

## The public booking page

A service with a `slug` has a public page. It needs no token. The page uses these two calls. You can call them from
your own site.

```bash theme={null}
# The service and its free times. zone, from and days are optional.
curl "https://api.impellabs.tech/api/v1/book/intro-call?zone=Asia/Dubai&days=7"

# Book a time.
curl -X POST https://api.impellabs.tech/api/v1/book/intro-call \
  -H "Content-Type: application/json" \
  -d '{"start": "2026-11-03T10:00:00+04:00", "name": "Sam", "email": "sam@example.test"}'
```

The `GET` reply has `slug`, `name`, `description`, `minutes`, `location_type`, `business`, `zone` and `slots`. Each
slot has `start`, `end`, `host_id` and `time`. Free times start on a quarter hour, and the page looks ahead at most
21 days.

The `POST` takes `start`, `name` and `email` (all required), and `phone`, `host_id`, `zone` and `b`. It returns
`ok` set to `true` and a `booking` object with `starts_at`, `ends_at`, `title` and `location`.

| Status | Meaning |
| - | - |
| `400` | A `problems` object. Each problem is one key and one sentence, such as `name` and `Write your name.` |
| `404` | The page does not exist, or the service is switched off or archived. |
| `409` | `{"detail": "This time was just taken. Choose another."}` |
| `429` | A sender address can book 20 times an hour on one page. |

The person is found or made from the email. The booking goes into the calendar of the business, and the booking
confirmation workflow tells the customer when it is on. A link that came from a broadcast email carries `b`, and the
booking then adds the person to that broadcast campaign.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.