# Complete a booking without live supply

Canonical human page: https://aune.ai/docs/sandbox
Canonical machine page: https://aune.ai/ai/sandbox-quickstart.md

The sandbox exercises the same public request shapes and booking truth semantics as `/v1`, while using synthetic data and fixed future dates. It never contacts a provider.

## Facts

- **Base path:** /sandbox/v1
- **Version:** aune_sandbox_v1
- **Clock:** 2099-01-15T08:00:00.000Z
- **Verticals:** vvs, electrician, moving, cleaning
- **State isolation:** X-Aune-Client-Id
- **PII:** Synthetic values only

## Fastest complete run

The CLI reads capabilities, searches seeded availability, accepts the exact returned terms, confirms one option, and prints the full booking truth.

### From a source checkout

```bash
npm run build:aune-cli
node packages/cli/dist/aune.js sandbox-book --vertical moving --postcode 11122 --destination-postcode 41256
```

## Search without personal data

Search sends postcodes and job facts only. For moving, both origin and destination postcodes are mandatory.

### Sandbox option search

```bash
curl -X POST "https://aune-homepage-chat.vercel.app/sandbox/v1/booking-options" \
  -H "Content-Type: application/json" \
  -H "X-Aune-Client-Id: quickstart" \
  --data '{
    "vertical_id": "moving",
    "job_type_id": "moving_home",
    "description": "Synthetic move for sandbox verification",
    "location": {"country_code": "SE", "postcode": "11122"},
    "destination_location": {"country_code": "SE", "postcode": "41256"},
    "timing": {"preferred_time_text": "next available time"}
  }'
```

## Failure injection

Set `X-Aune-Sandbox-Scenario` on each request. Sandbox bookings and synthetic slot occupancy are isolated by `X-Aune-Client-Id`, so independent agents cannot consume each other's fixture capacity. Reuse one client ID to test conflicts and lifecycle ownership; use a unique client ID for an independent run.

- `happy_path`: deterministic option and confirmation.
- `no_options`: valid search with provider-follow-up guidance.
- `stale_option`: confirmation requires a fresh search.
- `slot_conflict`: the selected slot is taken concurrently.
- `dependency_timeout`: retryable dependency failure.
- `webhook_500`: booking stays confirmed while webhook delivery retries separately.

## Lifecycle proof

- Confirm only after explicit synthetic consent and exact terms acceptance.
- Read the booking by ID and verify redacted status.
- Cancel only after fresh explicit user confirmation.
- Reschedule only to a newly searched option for the booking's current provider and reaccept its exact terms version. Change provider by cancelling and confirming a new booking.
- Repeat the same write with the same idempotency key and verify the same booking truth is returned.
