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

# Create Booking

> Creates a new booking in the LatePoint system with automatic availability validation.

## Description

This endpoint allows you to create a new booking in your LatePoint system. It includes automatic availability validation, creation of new customers if necessary, and application of configured business rules.

## Authentication

<ParamField header="X-API-Key" type="string" required>
  Your LatePoint API key. You can get it from the admin panel.
</ParamField>

## Request Body

### Required Fields

<ParamField body="service_id" type="integer" required>
  ID of the service to book
</ParamField>

<ParamField body="agent_id" type="integer|string" required>
  ID of the agent who will provide the service. Use "any" or "-1" for automatic agent assignment based on availability
</ParamField>

<ParamField body="start_date" type="string" required>
  Booking date (format: YYYY-MM-DD)
</ParamField>

<ParamField body="start_time" type="string" required>
  Start time (format: HH:MM in 24-hour format)
</ParamField>

### Customer Information

<ParamField body="customer_id" type="integer">
  ID of an existing customer. If provided, new customer fields are ignored
</ParamField>

<ParamField body="customer.first_name" type="string">
  Customer first name (required if customer\_id is not provided)
</ParamField>

<ParamField body="customer.last_name" type="string">
  Customer last name (required if customer\_id is not provided)
</ParamField>

<ParamField body="customer.email" type="string">
  Customer email (required if customer\_id is not provided)
</ParamField>

<ParamField body="customer.phone" type="string">
  Customer phone
</ParamField>

### Optional Fields

<ParamField body="location_id" type="integer">
  Location ID (uses default location if not specified)
</ParamField>

<ParamField body="duration" type="integer">
  Custom duration in minutes (uses service default duration)
</ParamField>

<ParamField body="price" type="string">
  Custom price (uses service default price)
</ParamField>

<ParamField body="status" type="string" default="pending">
  Initial booking status

  **Possible values:**

  * `pending` - Pending
  * `approved` - Approved
  * `cancelled` - Cancelled
</ParamField>

<ParamField body="notes" type="string">
  Additional notes for the booking
</ParamField>

<ParamField body="send_confirmation" type="boolean" default="true">
  Whether to send confirmation email to customer
</ParamField>

## Respuesta

### Success Response (201 Created)

<ResponseField name="status" type="string">
  Response status ("success")
</ResponseField>

<ResponseField name="data" type="object">
  Created booking object

  <Expandable title="Created Booking Structure">
    <ResponseField name="id" type="integer">
      Unique ID of the created booking
    </ResponseField>

    <ResponseField name="booking_code" type="string">
      Unique code generated for the booking
    </ResponseField>

    <ResponseField name="status" type="string">
      Booking status
    </ResponseField>

    <ResponseField name="start_date" type="string">
      Start date (YYYY-MM-DD)
    </ResponseField>

    <ResponseField name="start_time" type="string">
      Start time (HH:MM)
    </ResponseField>

    <ResponseField name="end_time" type="string">
      Calculated end time (HH:MM)
    </ResponseField>

    <ResponseField name="duration" type="integer">
      Duration in minutes
    </ResponseField>

    <ResponseField name="price" type="string">
      Total booking price
    </ResponseField>

    <ResponseField name="customer" type="object">
      Customer information (created or existing)
    </ResponseField>

    <ResponseField name="agent" type="object">
      Agent information
    </ResponseField>

    <ResponseField name="service" type="object">
      Service information
    </ResponseField>

    <ResponseField name="location" type="object">
      Location information
    </ResponseField>

    <ResponseField name="created_at" type="string">
      Creation date and time (ISO 8601)
    </ResponseField>
  </Expandable>
</ResponseField>

## Examples

### Create Booking with Existing Customer

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST "http://latepoint-dev.local/wp-json/latepoint-api/v1/bookings" \
    -H "X-API-Key: lp_n1k6BVf3h7JRyjXkWMSoXi0BBZYRaOLL4QohDPQJ" \
    -H "Content-Type: application/json" \
    -d '{
      "service_id": 2,
      "agent_id": 1,
      "customer_id": 2,
      "start_date": "2025-09-01",
      "start_time": "14:30",
      "status": "approved",
      "notes": "Consulta de seguimiento"
    }'
  ```

  ```javascript JavaScript theme={null}
  const bookingData = {
    service_id: 7,
    agent_id: 3,
    customer_id: 45,
    start_date: '2024-01-20',
    start_time: '14:30',
    status: 'approved',
    notes: 'Consulta de seguimiento'
  };

  const response = await fetch('https://your-site.com/wp-json/latepoint-api/v1/bookings', {
    method: 'POST',
    headers: {
      'X-API-Key': 'lp_live_1234567890abcdef',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(bookingData)
  });

  const result = await response.json();
  console.log(result);
  ```

  ```python Python theme={null}
  import requests
  import json

  booking_data = {
      'service_id': 7,
      'agent_id': 3,
      'customer_id': 45,
      'start_date': '2024-01-20',
      'start_time': '14:30',
      'status': 'approved',
      'notes': 'Consulta de seguimiento'
  }

  response = requests.post(
      'http://latepoint-dev.local/wp-json/latepoint-api/v1/bookings',
      headers={
          'X-API-Key': 'lp_n1k6BVf3h7JRyjXkWMSoXi0BBZYRaOLL4QohDPQJ',
          'Content-Type': 'application/json'
      },
      data=json.dumps(booking_data)
  )

  result = response.json()
  print(result)
  ```

  ```php PHP theme={null}
  <?php
  $booking_data = [
      'service_id' => 7,
      'agent_id' => 3,
      'customer_id' => 45,
      'start_date' => '2024-01-20',
      'start_time' => '14:30',
      'status' => 'approved',
      'notes' => 'Consulta de seguimiento'
  ];

  $curl = curl_init();

  curl_setopt_array($curl, [
      CURLOPT_URL => 'http://latepoint-dev.local/wp-json/latepoint-api/v1/bookings',
      CURLOPT_RETURNTRANSFER => true,
      CURLOPT_POST => true,
      CURLOPT_POSTFIELDS => json_encode($booking_data),
      CURLOPT_HTTPHEADER => [
          'X-API-Key: lp_n1k6BVf3h7JRyjXkWMSoXi0BBZYRaOLL4QohDPQJ',
          'Content-Type: application/json'
      ]
  ]);

  $response = curl_exec($curl);
  $result = json_decode($response, true);

  curl_close($curl);
  print_r($result);
  ?>
  ```
</CodeGroup>

### Create Booking with New Customer

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST "http://latepoint-dev.local/wp-json/latepoint-api/v1/bookings" \
    -H "X-API-Key: lp_n1k6BVf3h7JRyjXkWMSoXi0BBZYRaOLL4QohDPQJ" \
    -H "Content-Type: application/json" \
    -d '{
      "service_id": 2,
      "agent_id": 1,
      "start_date": "2025-09-01",
      "start_time": "16:00",
      "customer": {
        "first_name": "Ana",
        "last_name": "López",
        "email": "ana.lopez@email.com",
        "phone": "+52 555 987 6543"
      },
      "status": "pending",
      "send_confirmation": true
    }'
  ```

  ```javascript JavaScript theme={null}
  const bookingData = {
    service_id: 7,
    agent_id: 3,
    start_date: '2024-01-20',
    start_time: '16:00',
    customer: {
      first_name: 'Ana',
      last_name: 'López',
      email: 'ana.lopez@email.com',
      phone: '+52 555 987 6543'
    },
    status: 'pending',
    send_confirmation: true
  };

  const response = await fetch('https://your-site.com/wp-json/latepoint-api/v1/bookings', {
    method: 'POST',
    headers: {
      'X-API-Key': 'lp_live_1234567890abcdef',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(bookingData)
  });

  const result = await response.json();
  ```

  ```python Python theme={null}
  import requests
  import json

  booking_data = {
      'service_id': 7,
      'agent_id': 3,
      'start_date': '2024-01-20',
      'start_time': '16:00',
      'customer': {
          'first_name': 'Ana',
          'last_name': 'López',
          'email': 'ana.lopez@email.com',
          'phone': '+52 555 987 6543'
      },
      'status': 'pending',
      'send_confirmation': True
  }

  response = requests.post(
      'https://your-site.com/wp-json/latepoint-api/v1/bookings',
      headers={
          'X-API-Key': 'lp_live_1234567890abcdef',
          'Content-Type': 'application/json'
      },
      data=json.dumps(booking_data)
  )

  result = response.json()
  ```
</CodeGroup>

## Example Response

### Successfully Created Booking

```json theme={null}
{
  "status": "success",
  "data": {
    "id": 156,
    "booking_code": "LP-2024-002",
    "status": "approved",
    "start_date": "2024-01-20",
    "start_time": "14:30",
    "end_time": "15:30",
    "duration": 60,
    "price": "75.00",
    "customer": {
      "id": 45,
      "first_name": "Juan",
      "last_name": "Pérez",
      "email": "juan.perez@email.com",
      "phone": "+52 555 123 4567"
    },
    "agent": {
      "id": 3,
      "display_name": "Dr. María García",
      "email": "maria.garcia@clinica.com"
    },
    "service": {
      "id": 7,
      "name": "Consulta General",
      "duration": 60,
      "price": "75.00"
    },
    "location": {
      "id": 1,
      "name": "Clínica Principal",
      "address": "Av. Reforma 123, CDMX"
    },
    "notes": "Consulta de seguimiento",
    "created_at": "2024-01-15T10:30:00Z"
  }
}
```

## Error Codes

<ResponseExample>
  ```json Error 400 - Invalid Data theme={null}
  {
    "status": "error",
    "error": {
      "code": "invalid_request",
      "message": "Invalid input data",
      "details": {
        "service_id": "The specified service does not exist",
        "start_time": "Invalid time format, use HH:MM",
        "customer.email": "Invalid email"
      }
    }
  }
  ```

  ```json Error 409 - Time Conflict theme={null}
  {
    "status": "error",
    "error": {
      "code": "time_slot_unavailable",
      "message": "The requested time slot is not available",
      "details": {
        "requested_time": "2024-01-20 14:30",
        "agent_id": 3,
        "conflicting_booking_id": 145,
        "available_slots": [
          "2024-01-20 15:30",
          "2024-01-20 16:30"
        ]
      }
    }
  }
  ```

  ```json Error 422 - Validation Failed theme={null}
  {
    "status": "error",
    "error": {
      "code": "validation_failed",
      "message": "The provided data failed validation",
      "details": {
        "start_date": "Date cannot be in the past",
        "agent_id": "Agent is not available on this date",
        "customer.phone": "Invalid phone format"
      }
    }
  }
  ```

  ```json Error 403 - Insufficient Permissions theme={null}
  {
    "status": "error",
    "error": {
      "code": "forbidden",
      "message": "You do not have permission to create bookings"
    }
  }
  ```
</ResponseExample>

## Validations

### Automatic Validations

The system performs the following validations automatically:

1. **Agent Availability**: Verifies that the agent is available at the requested time
2. **Working Hours**: Validates that the time is within the agent's working hours
3. **Service Duration**: Verifies there is enough time to complete the service
4. **Valid Dates**: Does not allow bookings on past dates
5. **Unique Email**: If creating a new customer, verifies the email is not already in use

### Business Rules

<Note>
  **Existing vs New Customer**: If you provide `customer_id`, all `customer` fields are ignored. If you don't provide `customer_id`, the `first_name`, `last_name` and `email` fields are required.
</Note>

<Warning>
  **Availability Check**: Always verify availability using the `/availability` endpoint before creating a booking to avoid conflicts.
</Warning>

<Tip>
  **Booking Codes**: Booking codes are automatically generated following the pattern `LP-YYYY-NNN` where YYYY is the year and NNN is a sequential number.
</Tip>

## Recommended Flow

### 1. Check Availability

```javascript theme={null}
// First check availability
const availabilityResponse = await fetch(
`/wp-json/latepoint-api/v1/availability?service_id=7&agent_id=3&date=2024-01-20&duration=60`
);
const availability = await availabilityResponse.json();

if (availability.data.available_slots.includes('14:30')) {
  // Proceed with booking creation
}
```

### 2. Create the Booking

```javascript theme={null}
// Create the booking if available
const bookingResponse = await fetch('/wp-json/latepoint-api/v1/bookings', {
  method: 'POST',
  headers: {
    'X-API-Key': 'tu_api_key',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify(bookingData)
});
```

### 3. Handle the Response

```javascript theme={null}
if (bookingResponse.ok) {
  const result = await bookingResponse.json();
  console.log('Booking created:', result.data.booking_code);
} else {
  const error = await bookingResponse.json();
  console.error('Error:', error.error.message);
}
```

## Common Use Cases

### 1. Quick Booking (Existing Customer)

```javascript theme={null}
// For customers already in the system
const quickBooking = {
  service_id: 7,
  agent_id: 3,
  customer_id: 45,
  start_date: '2024-01-20',
  start_time: '14:30',
  status: 'approved'
};
```

### 2. First Booking (New Customer)

```javascript theme={null}
// For new customers
const newCustomerBooking = {
  service_id: 7,
  agent_id: 3,
  start_date: '2024-01-20',
  start_time: '14:30',
  customer: {
    first_name: 'Ana',
    last_name: 'López',
    email: 'ana.lopez@email.com',
    phone: '+52 555 987 6543'
  },
  send_confirmation: true
};
```

### 3. Booking with Custom Configuration

````javascript theme={null}
// With custom duration and price
const customBooking = {
  service_id: 7,
  agent_id: 3,
  customer_id: 45,
  start_date: '2024-01-20',
  start_time: '14:30',
  duration: 90, // 90 minutes instead of default 60
  price: '100.00', // Custom price
  notes: 'Extended session with complete evaluation'
};```
````
