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

# Execute Booking

> Create a booking with automatic voucher delivery

# Execute Booking

<Note>
  This endpoint creates a real booking and sends a voucher email within 30 seconds. **99% success rate** with live inventory sync.
</Note>

## Use This Endpoint When

<CardGroup cols={2}>
  <Card title="User confirms selection" icon="check">
    * "Book this one"
    * "Reserve for tomorrow"
    * "I want the spa package"
  </Card>

  <Card title="After recommendation" icon="arrow-right">
    * User selected from `/recommend` results
    * User chose from `/inventory` listings
  </Card>
</CardGroup>

## Request

<ParamField body="activity_id" type="string" required>
  Activity ID from `/recommend` or `/inventory` response
</ParamField>

<ParamField body="user_email" type="string" required>
  Email address for voucher delivery
</ParamField>

<ParamField body="user_name" type="string" required>
  Guest name for the voucher
</ParamField>

<ParamField body="booking_date" type="string" required>
  ISO 8601 date format (e.g., `2025-12-15`)
</ParamField>

<ParamField body="num_adults" type="number" required>
  Number of adults (1-20)
</ParamField>

<ParamField body="num_children" type="number" default="0">
  Number of children
</ParamField>

<ParamField body="context_log_id" type="string">
  **Recommended**: Pass the `log_id` from `/recommend` response for conversion tracking and feedback loop
</ParamField>

<ParamField body="special_requests" type="string">
  Any special requests or notes
</ParamField>

<ParamField body="webhook_url" type="string">
  Optional URL to receive booking status callbacks
</ParamField>

## Response

<ResponseField name="success" type="boolean">
  Whether the booking was created successfully
</ResponseField>

<ResponseField name="data" type="object">
  <Expandable title="Properties">
    <ResponseField name="booking_id" type="string">
      Unique booking identifier
    </ResponseField>

    <ResponseField name="status" type="string">
      One of: `confirmed`, `pending`, `processing`
    </ResponseField>

    <ResponseField name="voucher" type="object">
      Voucher information

      <Expandable title="Properties">
        <ResponseField name="code" type="string">
          Unique voucher code
        </ResponseField>

        <ResponseField name="qr_url" type="string">
          URL to QR code image
        </ResponseField>

        <ResponseField name="valid_until" type="string">
          Voucher expiration date
        </ResponseField>
      </Expandable>
    </ResponseField>

    <ResponseField name="activity" type="object">
      Booked activity details

      <Expandable title="Properties">
        <ResponseField name="id" type="string">
          Activity ID
        </ResponseField>

        <ResponseField name="title" type="string">
          Activity title
        </ResponseField>

        <ResponseField name="location" type="string">
          Venue address
        </ResponseField>

        <ResponseField name="check_in_instructions" type="string">
          How to use the voucher at venue
        </ResponseField>
      </Expandable>
    </ResponseField>

    <ResponseField name="pricing" type="object">
      Pricing breakdown

      <Expandable title="Properties">
        <ResponseField name="unit_price" type="number">
          Price per person
        </ResponseField>

        <ResponseField name="total_guests" type="number">
          Total guests (adults + children)
        </ResponseField>

        <ResponseField name="subtotal" type="number">
          Subtotal before discounts
        </ResponseField>

        <ResponseField name="discount" type="number">
          Applied discount amount
        </ResponseField>

        <ResponseField name="total" type="number">
          Final total
        </ResponseField>

        <ResponseField name="currency" type="string">
          Currency code
        </ResponseField>
      </Expandable>
    </ResponseField>

    <ResponseField name="email_sent" type="boolean">
      Whether voucher email was sent
    </ResponseField>

    <ResponseField name="email_sent_at" type="string">
      Timestamp of email delivery
    </ResponseField>
  </Expandable>
</ResponseField>

## Examples

### Basic Booking

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.privetag.com/api/b2a/execute_booking \
    -H "x-api-key: pk_a1b2c3..." \
    -H "Content-Type: application/json" \
    -d '{
      "activity_id": "act_abc123",
      "user_email": "guest@example.com",
      "user_name": "John Doe",
      "booking_date": "2025-12-15",
      "num_adults": 2,
      "context_log_id": "ctx_xyz789"
    }'
  ```

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

  response = requests.post(
      "https://api.privetag.com/api/b2a/execute_booking",
      headers={
          "x-api-key": "pk_a1b2c3...",
          "Content-Type": "application/json"
      },
      json={
          "activity_id": "act_abc123",
          "user_email": "guest@example.com",
          "user_name": "John Doe",
          "booking_date": "2025-12-15",
          "num_adults": 2,
          "context_log_id": "ctx_xyz789"
      }
  )

  booking = response.json()
  print(f"Booking confirmed: {booking['data']['booking_id']}")
  print(f"Voucher code: {booking['data']['voucher']['code']}")
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch('https://api.privetag.com/api/b2a/execute_booking', {
    method: 'POST',
    headers: {
      'x-api-key': 'pk_a1b2c3...',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      activity_id: 'act_abc123',
      user_email: 'guest@example.com',
      user_name: 'John Doe',
      booking_date: '2025-12-15',
      num_adults: 2,
      context_log_id: 'ctx_xyz789'
    })
  });

  const booking = await response.json();
  console.log(`Booking confirmed: ${booking.data.booking_id}`);
  ```
</CodeGroup>

### Family Booking with Children

```json theme={null}
{
  "activity_id": "act_abc123",
  "user_email": "family@example.com",
  "user_name": "Smith Family",
  "booking_date": "2025-12-20",
  "num_adults": 2,
  "num_children": 3,
  "special_requests": "One child is under 3 years old",
  "context_log_id": "ctx_xyz789"
}
```

### With Webhook Callback

```json theme={null}
{
  "activity_id": "act_abc123",
  "user_email": "guest@example.com",
  "user_name": "John Doe",
  "booking_date": "2025-12-15",
  "num_adults": 2,
  "webhook_url": "https://your-server.com/webhooks/privetag"
}
```

## Response Example

```json theme={null}
{
  "success": true,
  "data": {
    "booking_id": "bkg_h7j9k2m4",
    "status": "confirmed",
    "voucher": {
      "code": "PVT-2025-ABC123",
      "qr_url": "https://cdn.privetag.com/vouchers/qr/bkg_h7j9k2m4.png",
      "valid_until": "2025-12-15T23:59:59Z"
    },
    "activity": {
      "id": "act_abc123",
      "title": "Safari World Bangkok",
      "location": "99 Panyaintra Road, Sam Wa Tawan Tok, Bangkok",
      "check_in_instructions": "Show QR code at main entrance ticket counter"
    },
    "pricing": {
      "unit_price": 1500,
      "total_guests": 2,
      "subtotal": 3000,
      "discount": 0,
      "total": 3000,
      "currency": "THB"
    },
    "email_sent": true,
    "email_sent_at": "2025-12-10T14:30:15Z"
  }
}
```

## Booking Flow

```mermaid theme={null}
sequenceDiagram
    participant AI Agent
    participant PriveTag API
    participant User
    participant Venue

    AI Agent->>PriveTag API: POST /execute_booking
    PriveTag API->>PriveTag API: Verify availability
    PriveTag API->>PriveTag API: Create booking
    PriveTag API->>PriveTag API: Generate voucher + QR
    PriveTag API->>User: Send voucher email
    PriveTag API-->>AI Agent: Booking confirmation

    Note over User,Venue: On visit day

    User->>Venue: Present QR code
    Venue->>PriveTag API: Scan QR (verification)
    PriveTag API->>PriveTag API: Record Ground Truth
    PriveTag API-->>Venue: Validate voucher
```

## Ground Truth Feedback Loop

<Info>
  **Why pass `context_log_id`?**

  When a user visits the venue and scans their QR code, we connect:

  1. The original recommendation context
  2. Which activity was booked
  3. Whether they actually visited

  This creates a **feedback loop** that improves future recommendations for similar user profiles.
</Info>

## Webhook Events

If you provide a `webhook_url`, you'll receive callbacks for:

| Event               | Description                       |
| ------------------- | --------------------------------- |
| `booking_confirmed` | Booking successfully created      |
| `voucher_delivered` | Email sent to user                |
| `qr_verified`       | User visited venue (Ground Truth) |
| `booking_cancelled` | Booking was cancelled             |

Webhook payload example:

```json theme={null}
{
  "event": "qr_verified",
  "booking_id": "bkg_h7j9k2m4",
  "activity_id": "act_abc123",
  "verified_at": "2025-12-15T10:30:00Z",
  "context_log_id": "ctx_xyz789"
}
```

## Error Responses

| Code                     | Description                                  |
| ------------------------ | -------------------------------------------- |
| `ACTIVITY_NOT_FOUND`     | Activity ID doesn't exist                    |
| `ACTIVITY_UNAVAILABLE`   | Activity not available on requested date     |
| `INVALID_DATE`           | Booking date is in the past or too far ahead |
| `INVENTORY_EXHAUSTED`    | No more slots available                      |
| `INVALID_EMAIL`          | Email format is invalid                      |
| `BOOKING_LIMIT_EXCEEDED` | Maximum guests per booking exceeded          |

### Error Response Example

```json theme={null}
{
  "success": false,
  "error": "Activity not available",
  "code": "ACTIVITY_UNAVAILABLE",
  "details": "Safari World is closed on Mondays. Available dates: Tue-Sun"
}
```

## Best Practices

<AccordionGroup>
  <Accordion title="Always pass context_log_id">
    This enables the Ground Truth feedback loop, improving recommendations over time.
  </Accordion>

  <Accordion title="Handle webhook callbacks">
    Use webhooks to update your UI in real-time when voucher is delivered or QR is scanned.
  </Accordion>

  <Accordion title="Validate dates client-side">
    Check that booking\_date is not in the past and is within the activity's operating days.
  </Accordion>

  <Accordion title="Confirm with user before booking">
    Bookings are real and charged. Always confirm details with the user before calling this endpoint.
  </Accordion>
</AccordionGroup>

## Next Steps

<CardGroup cols={2}>
  <Card title="Check Inventory" icon="warehouse" href="/api-reference/b2a/inventory">
    View real-time availability before booking
  </Card>

  <Card title="Webhooks" icon="webhook" href="/authentication/webhooks">
    Set up webhook callbacks for booking events
  </Card>
</CardGroup>
