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

# Admin Booking Creation

Create bookings and orders directly from the admin API using the `orders/from-config` endpoint. This bypasses the public checkout flow and is designed for back-office operations.

For the public checkout flow, see [Order & Checkout Flow](/developers/guides/customer/checkout). For general conventions, see [JSON-API Conventions](/developers/guides/json-api-conventions).

***

## Prerequisites

* A valid Bearer token with admin access — see [Authentication](/developers/guides/authentication)
* Organization context (`?o={organization_id}`)
* At least one resource and service configured in the organization

***

## Recommended Flow (Admin UI Forms)

For Admin UI integrations, prefer the dynamic form flow over manually assembling all custom-field and participant payloads.

### Step A - Build a Dynamic Checkout Form

```http theme={null}
POST /api/v1/ui/admin/checkout-form?o={org_id}

{
  "booking_config": {
    "order_customer_id": null,
    "bookings": [
      {
        "customer_id": null,
        "service_id": { "{service_uuid}": 1 },
        "resource_id": "{resource_uuid}",
        "start_date": "2026-04-15T09:00:00+02:00",
        "end_date": "2026-04-15T10:00:00+02:00"
      },
      {
        "customer_id": "{optional_existing_customer_uuid}",
        "service_id": { "{service_uuid}": 1 },
        "resource_id": "{resource_uuid}",
        "start_date": "2026-04-15T10:00:00+02:00",
        "end_date": "2026-04-15T11:00:00+02:00"
      }
    ]
  }
}
```

This returns a form object (`components`, `validations`, `default`) that includes:

* customer group (`customer-group`)
* customer custom fields
* order custom fields
* per-booking personalization groups (booking custom fields, host, participants)

### Step B - Apply Submitted Form Data

```http theme={null}
POST /api/v1/ui/admin/checkout-form/apply?o={org_id}

{
  "form_data": {
    "customer": {
      "email": "newcustomer@example.com",
      "given_name": "Test",
      "family_name": "Customer"
    },
    "bookings_data": {
      "b_205": {
        "service_custom_fields": {
          "{custom_field_uuid}": "Wheelchair access"
        },
        "participants": [
          {
            "email": "participant@example.com",
            "given_name": "Alex",
            "family_name": "Example"
          }
        ]
      }
    }
  },
  "booking_config": {
    "bookings": [
      {
        "_booking_id": 205,
        "resource_id": "{resource_uuid}",
        "service_id": { "{service_uuid}": 1 },
        "start_date": "2026-04-15T09:00:00+02:00",
        "end_date": "2026-04-15T10:00:00+02:00"
      }
    ]
  }
}
```

The response is an enriched config that is directly compatible with `POST /api/v1/orders/from-config`.

### Step C - Create the Order

Use the enriched payload from Step B as input for `POST /api/v1/orders/from-config`.

### Standalone Forms for Existing Records

You can also fetch standalone admin UI forms for existing records, such as customer, order, and booking edit forms.

The payload structure and persistence rules for those admin UI form endpoints are documented in [Admin UI Forms](/developers/guides/internal/admin-ui-forms), not in this booking-creation guide.

***

## When to Use

| Scenario                                        | Use                                                     |
| ----------------------------------------------- | ------------------------------------------------------- |
| Customer books through the website              | [Public Checkout](/developers/guides/customer/checkout) |
| Admin creates a booking on behalf of a customer | **This guide**                                          |
| Bulk/batch booking creation                     | **This guide**                                          |
| Booking without availability check (override)   | **This guide**                                          |

***

## Step 1 — Pre-Calculate Pricing (Optional)

Request path documentation:

* `paths/admin/orders.yaml` for `POST /api/v1/orders/calculate`

Before creating the order, preview the pricing and resolve available booking quota grants:

```http theme={null}
POST /api/v1/orders/calculate?o={org_id}

{
  "order_customer_id": "{customer_uuid}",
  "bookings": [
    {
      "booking_ref": "bk-1",
      "resource_id": "{resource_uuid}",
      "service_id": { "{service_uuid}": 1 },
      "start_date": "2026-04-15T09:00:00+02:00",
      "end_date": "2026-04-15T10:00:00+02:00"
    }
  ],
  "voucher_code": "SUMMER20",
  "booking_code": "PASS123"
}
```

Returns calculated totals, taxes, and per-booking pricing without persisting anything.

Each booking in the response also includes a `booking_quota_grants` array with all eligible grants,
their applicability, projected usage, and which one is preselected. This allows the UI to display
a grant selection dropdown directly from the calculate response — no separate endpoint call needed.

When the user selects a different grant, re-call calculate with `booking_quota_grant_id` set on
the booking. Set `prevent_applying_default_quota: true` to deselect all grants.

***

## Step 2 — Create the Order

Request path documentation:

* `paths/admin/orders.yaml` for `POST /api/v1/orders/from-config`

```http theme={null}
POST /api/v1/orders/from-config?o={org_id}

{
  "order_customer_id": "{customer_uuid}",
  "bookings": [
    {
      "resource_id": "{resource_uuid}",
      "service_id": { "{service_uuid}": 1 },
      "start_date": "2026-04-15T09:00:00+02:00",
      "end_date": "2026-04-15T10:00:00+02:00",
      "quantity": 1,
      "description": "Team meeting",
      "booking_add_ons": [
        { "add_on_id": "{add_on_uuid}", "quantity": 2 }
      ]
    }
  ],
  "notify_customer": true,
  "complete_order": true,
  "check_availability": true,
  "timezone": "Europe/Berlin"
}
```

### Top-Level Fields

| Field                | Type    | Required | Default | Description                                                                                                |
| -------------------- | ------- | -------- | ------- | ---------------------------------------------------------------------------------------------------------- |
| `order_customer_id`  | string  | No       | —       | Customer UUID for the entire order                                                                         |
| `bookings`           | array   | Yes\*    | —       | Array of booking configurations. \*May be empty or omitted when `add_ons` or `booking_passes` are present. |
| `add_ons`            | array   | No       | —       | Standalone add-ons `{ add_on_id, quantity }`, billed on the order invoice                                  |
| `booking_passes`     | array   | No       | —       | Booking passes from bundles `{ booking_bundle_id, quantity }`, billed on the order invoice                 |
| `voucher_code`       | string  | No       | —       | Discount voucher code                                                                                      |
| `notify_customer`    | boolean | No       | `true`  | Send confirmation email to customer                                                                        |
| `complete_order`     | boolean | No       | `true`  | `false` creates a draft order                                                                              |
| `check_availability` | boolean | No       | `true`  | `false` skips availability validation                                                                      |
| `timezone`           | string  | No       | —       | Timezone for date interpretation                                                                           |

### Booking Object Fields

| Field                   | Type         | Required | Description                                                              |
| ----------------------- | ------------ | -------- | ------------------------------------------------------------------------ |
| `resource_id`           | string/array | Yes      | Resource UUID(s). Array for multi-resource bookings.                     |
| `service_id`            | object       | Yes      | Map of `service_uuid → quantity` (e.g. `{"uuid": 1}`)                    |
| `start_date`            | string       | Yes      | Booking start (Atom format)                                              |
| `end_date`              | string       | Yes      | Booking end (Atom format)                                                |
| `customer_id`           | string       | No       | Per-booking customer (overrides `order_customer_id`)                     |
| `quantity`              | integer      | No       | Number of slots/participants                                             |
| `description`           | string       | No       | Internal description                                                     |
| `note`                  | string       | No       | Admin-visible note                                                       |
| `customer_note`         | string       | No       | Customer-visible note                                                    |
| `booking_add_ons`       | array        | No       | Array of `{ add_on_id, quantity }`                                       |
| `sub_bookings`          | array        | No       | Array of `{ service_id, resource_id, quantity }` for linked sub-bookings |
| `service_custom_fields` | object       | No       | Custom field values (UUID → value)                                       |
| `order_custom_fields`   | object       | No       | Order-level custom field values                                          |
| `recurring`             | object       | No       | Recurring rules (frequency, interval, until, count)                      |
| `timeslot_series_id`    | string       | No       | Link to a specific timeslot series                                       |

### Response

Returns a standard JSON-API `orders` resource with the created bookings:

```json theme={null}
{
  "data": {
    "type": "orders",
    "id": "order-uuid",
    "attributes": {
      "status": "completed",
      "manually_created": true,
      "total": 5000,
      "currency": "EUR"
    },
    "relationships": {
      "bookings": {
        "data": [{ "type": "bookings", "id": "b1" }]
      },
      "customer": {
        "data": { "type": "customers", "id": "c1" }
      }
    }
  }
}
```

***

## Multiple Bookings in One Order

Add multiple booking objects to create them in a single order:

```json theme={null}
{
  "order_customer_id": "{customer_uuid}",
  "bookings": [
    {
      "resource_id": "{room_uuid}",
      "service_id": { "{meeting_service}": 1 },
      "start_date": "2026-04-15T09:00:00+02:00",
      "end_date": "2026-04-15T10:00:00+02:00"
    },
    {
      "resource_id": "{desk_uuid}",
      "service_id": { "{desk_service}": 1 },
      "start_date": "2026-04-15T10:00:00+02:00",
      "end_date": "2026-04-15T17:00:00+02:00"
    }
  ]
}
```

***

## Skipping Availability Checks

Set `check_availability: false` to override availability constraints. Use this for:

* Overbooking scenarios
* Creating bookings in the past
* Special arrangements outside normal schedules

> **Warning:** Skipping availability checks can create conflicting bookings. Use with care.

***

## Re-Sending Order Notifications

If the customer didn't receive the confirmation:

```http theme={null}
GET /api/v1/orders/{order_id}/send-notification?o={org_id}
```

Triggers the order confirmation notification to the associated customer.

***

## Common Errors

| Error                         | Cause                               | Solution                                                              |
| ----------------------------- | ----------------------------------- | --------------------------------------------------------------------- |
| `422` — resource\_id required | Missing resource in booking object  | Include `resource_id` for each booking                                |
| `422` — service\_id required  | Missing service mapping             | Provide `service_id` as `{ "uuid": quantity }`                        |
| `422` — slot unavailable      | Time conflict with existing booking | Set `check_availability: false` to override, or pick a different time |
| `422` — customer not found    | Invalid `order_customer_id`         | Verify the customer UUID exists in the organization                   |
| `403` — unauthorized          | Insufficient permissions            | Requires order creation permission for the organization               |
