Skip to content

Bookings

Create, list, and manage bookings. This is the core of AvailEngine.

Public Booking

POST /v1/bookings/

Create a booking from a public booking widget. Requires an API key with write scope (rate-limited to 60 RPM by default). Use an avail_test_ key for development.

Request body:

json
{
  "business_id": "uuid",
  "booking_date": "2026-05-15",
  "start_time": "14:00",
  "capacity": 1,
  "first_name": "Jane",
  "last_name": "Doe",
  "email": "jane@example.com",
  "phone": "+301234567890",
  "customer_notes": "Prefers window seat"
}
FieldTypeRequiredDescription
business_idUUIDYesTarget business
booking_datedateYesYYYY-MM-DD
start_timetimeYesHH:MM (24h)
capacityintNoParty size (1–50), default 1
first_namestringYesCustomer first name (1–100 chars)
last_namestringYesCustomer last name (1–100 chars)
emailemailYesValid email address
phonestringYes7–20 chars. Returning customers matched by phone.
customer_notesstringNoMax 1000 chars

Without deposit:

json
{
  "booking": {
    "id": "uuid",
    "status": "confirmed",
    "confirmation_code": "AV-ABC123",
    "booking_date": "2026-05-15",
    "start_time": "14:00:00",
    "end_time": "15:00:00",
    "capacity": 1,
    "resource_id": "uuid"
  }
}

With deposit (charge):

json
{
  "booking": {
    "id": "uuid",
    "status": "pending",
    "confirmation_code": "AV-ABC123",
    "booking_date": "2026-05-15",
    "start_time": "14:00:00",
    "end_time": "15:00:00",
    "capacity": 1
  },
  "stripe_client_secret": "pi_xxx_secret_yyy",
  "deposit_type": "charge"
}

With authorization hold:

json
{
  "booking": {
    "id": "uuid",
    "status": "pending",
    "confirmation_code": "AV-ABC123",
    "booking_date": "2026-05-15",
    "start_time": "14:00:00",
    "end_time": "15:00:00",
    "capacity": 1
  },
  "stripe_client_secret": "pi_xxx_secret_yyy",
  "deposit_type": "authorization_hold"
}

Deposit types:

  • charge — Customer pays now. Refunded if they cancel within policy.
  • authorization_hold — Amount blocked on card, captured only on no-show. Premium plans only.

Staff Bookings

Dashboards use these endpoints. All require authentication.

POST /v1/manage/bookings/staff

Create a booking from the dashboard. No deposit, instantly confirmed, source set to staff.

bash
curl -X POST https://api.availengine.com/v1/manage/bookings/staff \
  -H "Authorization: Bearer avail_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "date": "2026-05-15",
    "time": "14:00",
    "capacity": 2,
    "first_name": "Jane",
    "last_name": "Doe",
    "phone": "+301234567890",
    "email": "jane@example.com",
    "notes": "Walk-in, prefers Maria"
  }'
FieldTypeRequiredDescription
datedateYesBooking date
timetimeYesStart time (HH:MM)
capacityintNoParty size (1–50), default 1
first_namestringYes1–100 chars
last_namestringYes1–100 chars
phonestringYes7–20 chars
emailstringNoUp to 254 chars, not validated as email
notesstringNoStaff notes (max 1000 chars)

Auto-assigns a free resource. Returns 409 if none available.

POST /v1/manage/bookings/staff-deposit

Create a booking with a Stripe payment link. Sends the customer a payment email via Brevo.

bash
curl -X POST https://api.availengine.com/v1/manage/bookings/staff-deposit \
  -H "Authorization: Bearer avail_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "date": "2026-05-15",
    "time": "14:00",
    "capacity": 1,
    "first_name": "Jane",
    "last_name": "Doe",
    "phone": "+301234567890",
    "email": "jane@example.com",
    "notes": "Phone booking, needs to prepay"
  }'
FieldTypeRequiredDescription
datedateYesBooking date
timetimeYesStart time (HH:MM)
capacityintNoParty size (1–50), default 1
first_namestringYes1–100 chars
last_namestringYes1–100 chars
phonestringYes7–20 chars
emailemailYesMust be valid — payment link is sent here
notesstringNoStaff notes (max 1000 chars)

Response:

json
{
  "booking": { "id": "uuid", "status": "pending", ... },
  "checkout_url": "https://checkout.stripe.com/...",
  "expires_at": "2026-05-15T16:00:00Z"
}

The checkout link expires in 2 hours. If unpaid, the booking is auto-cancelled.

Listing Bookings

GET /v1/manage/bookings

List bookings for the current business. Cursor-paginated.

ParamTypeDescription
res_datedateFilter by booking date (alias: booking_date)
statusstringFilter by status
codestringSearch by confirmation code (case-insensitive partial match)
latestboolMost recent first (by created_at)
limitintPage size (default 50, max 200)
cursorstringPagination cursor

Response includes joined data:

json
{
  "items": [
    {
      "id": "uuid",
      "customer": {
        "id": "uuid",
        "first_name": "Jane",
        "last_name": "Doe",
        "phone": "+301234567890",
        "email": "jane@example.com"
      },
      "resource": {
        "name": "Maria",
        "capacity_max": 1,
        "section": "Main Floor"
      },
      "deposit": {
        "status": "held",
        "amount_cents": 2000
      },
      "booking_date": "2026-05-15",
      "start_time": "14:00",
      "end_time": "15:00",
      "status": "confirmed",
      "confirmation_code": "AV-ABC123",
      "capacity": 2,
      "source": "online",
      "customer_notes": null,
      "staff_notes": null,
      "created_at": "2026-05-14T10:30:00Z"
    }
  ],
  "next_cursor": null,
  "has_more": false
}

Updating a Booking

PATCH /v1/manage/bookings/{booking_id}

Update status, resource, or capacity. Only allowed transitions are enforced.

FieldTypeDescription
statusstringNew status (see transitions below)
resource_idUUIDMove booking to a different resource
capacityintChange party size (1–50)

Status transitions:

pending    → confirmed, cancelled
confirmed  → checked_in, cancelled, no_show
checked_in → completed, no_show
completed  → (terminal)
cancelled  → (terminal)
no_show    → (terminal)

Invalid transitions return 409 Conflict.

PATCH /v1/manage/bookings/{booking_id}/notes

Save internal staff notes. Separate from status updates so notes don't get overwritten.

bash
curl -X PATCH https://api.availengine.com/v1/manage/bookings/{booking_id}/notes \
  -H "Authorization: Bearer avail_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"staff_notes": "Allergic to latex — use nitrile gloves"}'
FieldTypeRequiredDescription
staff_notesstringYesMax 2000 chars

Resource Reassignment

GET /v1/manage/bookings/{booking_id}/available-resources

When moving a booking, see which other resources are free during its time slot.

bash
curl https://api.availengine.com/v1/manage/bookings/{booking_id}/available-resources \
  -H "Authorization: Bearer avail_live_YOUR_KEY"

Returns all active resources with sufficient capacity that have no conflicting bookings in the same time window. Excludes the booking's current resource.

No-Show Handling

POST /v1/manage/bookings/{booking_id}/no-show

Mark booking as no-show. If the business uses authorization holds, the hold is captured (charged).

bash
curl -X POST https://api.availengine.com/v1/manage/bookings/{booking_id}/no-show \
  -H "Authorization: Bearer avail_live_YOUR_KEY"

Preconditions:

  • Booking status must not be cancelled, completed, or no_show
  • A deposit must exist with status held

Response:

json
{ "detail": "No-show recorded. EUR 20 hold captured." }

POST /v1/manage/bookings/{booking_id}/release-hold

Release an authorization hold without charging. The customer is billed manually instead.

bash
curl -X POST https://api.availengine.com/v1/manage/bookings/{booking_id}/release-hold \
  -H "Authorization: Bearer avail_live_YOUR_KEY"
json
{ "detail": "Hold released. Deduct EUR 20 from the customer's bill manually." }

Precondition: deposit must exist with status held.

This is useful when a business wants to handle the charge at the POS rather than through the booking system.

Confirmation Codes

Every booking gets a unique 8-character alphanumeric confirmation code (e.g. AV-ABC123). These are generated with retry logic to handle collisions. The code is shown in confirmation emails and can be searched in the dashboard.

Released under the MIT License.