# Booking Create

## Create a Booking

Use this endpoint to create a new booking.\
**To prevent duplicates, you must provide a unique `booking.id` (UUID v4) generated by your client.**\
**You must also provide either an existing `guest.id` or full guest details inside `guest`.**

#### Endpoint

```http
POST /api/v1/client/bookings
```

#### Example `curl`

```bash
curl "/api/v1/client/bookings" \
  -H "accept: application/json" \
  -H "content-type: application/json" \
  -H "origin: https://docs.hostelmate.co" \
  --data-raw '{
    "booking": {
      "id": "e7b7f6bb-6c0c-4e2c-9b3e-9c6f2a1c0a77",
      "dates": [
        { "date": "2025-11-05", "amount": 25000 },
        { "date": "2025-11-06", "amount": 25000 },
        { "date": "2025-11-07", "amount": 25000 }
      ]
    },
    "room": "92b6f8b8-6ea2-4e0e-9b7b-3e2f9b6a7c2d",
    "guest": {
      "id": "f1b2c3d4-5678-49ab-9cde-112233445566",
      "first_name": "John",
      "last_name": "Doe",
      "email": "john@example.com",
      "phone": "+447712345678",
      "country_code": "GB",
      "address": {
        "line1": "Westminster",
        "city": "London",
        "postal_code": "SW1A 1AA",
        "country_code": "GB"
      }
    },
    "notes": "Late arrival around 22:00"
  }'
```

> If `guest.id` is provided, the identity comes from that ID. Other guest fields may update contact details if supported by your account policy. If `guest.id` is **not** provided, `guest.first_name`, `guest.last_name`, and `guest.email` are required.

***

#### Request Payload

**Top-level Fields**

<table><thead><tr><th width="104.3515625">Field</th><th width="92.70703125">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>booking</code></td><td>object</td><td>Booking info including a client-generated unique ID and nightly amounts.</td></tr><tr><td><code>room</code></td><td>string</td><td>The selected room or room type ID (UUID).</td></tr><tr><td><code>guest</code></td><td>object</td><td>Guest reference <em>or</em> full guest details (see “Guest Object”).</td></tr><tr><td><code>notes</code></td><td>string</td><td>Internal notes for the booking (optional).</td></tr></tbody></table>

**Booking Object**

<table><thead><tr><th width="104.3515625">Field</th><th width="92.70703125">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>id</code></td><td>string</td><td><strong>Required.</strong> Client-generated unique booking ID (UUID v4). Used to prevent duplicate processing.</td></tr><tr><td><code>dates</code></td><td>array</td><td>Array of nightly pricing items. The server computes <em>total</em> from the sum of these amounts.</td></tr></tbody></table>

**Dates Item**

<table><thead><tr><th width="104.3515625">Field</th><th width="92.70703125">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>date</code></td><td>string</td><td>Night date (format: YYYY-MM-DD).</td></tr><tr><td><code>amount</code></td><td>integer</td><td>Nightly amount in minor units (e.g., fils/cents).</td></tr></tbody></table>

**Guest Object**

<table><thead><tr><th width="104.3515625">Field</th><th width="92.70703125">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>id</code></td><td>string</td><td>Existing guest ID (UUID). If provided, this identifies the guest.</td></tr><tr><td><code>first_name</code></td><td>string</td><td>Required if <code>id</code> is not provided.</td></tr><tr><td><code>last_name</code></td><td>string</td><td>Required if <code>id</code> is not provided.</td></tr><tr><td><code>email</code></td><td>string</td><td>Required if <code>id</code> is not provided. Must be a valid email.</td></tr><tr><td><code>phone</code></td><td>string</td><td>Optional. E.164 format recommended (e.g., <code>+447...</code>).</td></tr><tr><td><code>country_code</code></td><td>string</td><td>Optional. ISO 3166-1 alpha-2 (e.g., <code>GB</code>).</td></tr><tr><td><code>address</code></td><td>object</td><td>Optional postal address (see below).</td></tr></tbody></table>

**Address Object**

<table><thead><tr><th width="104.3515625">Field</th><th width="92.70703125">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>line1</code></td><td>string</td><td>Street line 1.</td></tr><tr><td><code>city</code></td><td>string</td><td>City.</td></tr><tr><td><code>postal_code</code></td><td>string</td><td>Postal/ZIP code.</td></tr><tr><td><code>country_code</code></td><td>string</td><td>ISO 3166-1 alpha-2 (e.g., <code>GB</code>).</td></tr></tbody></table>

***

#### Response (201 Created)

```json
{
  "bookingId": "e7b7f6bb-6c0c-4e2c-9b3e-9c6f2a1c0a77",
  "status": "confirmed",
  "room": "92b6f8b8-6ea2-4e0e-9b7b-3e2f9b6a7c2d",
  "total": 75000,
  "dates": [
    { "date": "2025-11-05", "amount": 25000 },
    { "date": "2025-11-06", "amount": 25000 },
    { "date": "2025-11-07", "amount": 25000 }
  ],
  "guest": {
    "id": "f1b2c3d4-5678-49ab-9cde-112233445566",
    "first_name": "John",
    "last_name": "Doe",
    "email": "john@example.com"
  },
  "createdAt": "2025-10-02T09:20:17Z"
}
```

***

#### Validation Rules

* `booking.id` is required and must be a UUID v4. Re-using it with a different payload will be rejected.
* Provide **either** `guest.id` **or** (`guest.first_name`, `guest.last_name`, `guest.email`). Not both.
* `dates[]` must contain at least one item; `date` must be valid (YYYY-MM-DD).
* `amount` must be non-negative integer (minor units).
* The server computes `total` as the sum of `dates[].amount`.

***

#### Error Codes

<table><thead><tr><th width="104.3515625">HTTP</th><th width="92.70703125">Code</th><th>Description</th></tr></thead><tbody><tr><td>400</td><td><code>bad_request</code></td><td>Validation failed (e.g., missing required fields, malformed email, invalid dates).</td></tr><tr><td>404</td><td><code>room_not_found</code></td><td>The specified <code>room</code> does not exist.</td></tr><tr><td>409</td><td><code>booking_id_conflict</code></td><td><code>booking.id</code> already used for a different payload.</td></tr><tr><td>409</td><td><code>availability_conflict</code></td><td>The selected room is no longer available for the requested dates.</td></tr><tr><td>422</td><td><code>guest_invalid</code></td><td><code>guest.id</code> not found or guest fields invalid.</td></tr><tr><td>500</td><td><code>server_error</code></td><td>Unexpected error.</td></tr></tbody></table>
