> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.truvo.com/llms.txt.

# Sandbox scenarios

Each sandbox key has its own sandbox workspace. The workspace keeps the active scenario, its own clock, and your sandbox records. The paths under `/v1/sandbox/` only work with a sandbox key, and a live key gets `404`.

## Default scenarios

A new workspace has no scenario selected, so each line answers with one quote:

| Line          | Default scenario              |
| ------------- | ----------------------------- |
| Personal auto | `auto-one-driver-one-vehicle` |
| Renters       | `renters-one-offer`           |
| Pet           | `pet-one-dog`                 |

## Select a scenario

```bash
curl -X POST https://api.truvo.com/v1/sandbox/scenarios \
  -H "Authorization: Bearer $TRUVO_API_KEY" \
  -H "Idempotency-Key: select-scenario-01" \
  -H "Content-Type: application/json" \
  -d '{"scenario": "renters-several-offers"}'
```

The scenario applies to each later quote request of its line, until you select another one or reset the workspace. Requests for other lines keep their default.

To use a scenario for one quote request only, send its ID in that request's `scenario` field. The scenario must be for the request's line.

## Check the workspace

```bash
curl https://api.truvo.com/v1/sandbox/workspace \
  -H "Authorization: Bearer $TRUVO_API_KEY"
```

The response gives `active_scenario`, `clock_offset_seconds`, `workspace_time`, `quotes_expired_at`, `reset_count`, and `scenario_catalog_version`. `active_scenario` is `null` until you select a scenario.

## Control time and expiry

Send one control at a time to `POST /v1/sandbox/controls`. Each control requires an `Idempotency-Key`, so a retry never moves the clock twice.

| Control         | Body                                               | Effect                                                                                                                                                                                                                                     |
| --------------- | -------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `advance_time`  | `{"control": "advance_time", "by_seconds": 86400}` | Moves the workspace clock forward. Sandbox quotes expire 30 days after Truvo creates them.                                                                                                                                                 |
| `force_expiry`  | `{"control": "force_expiry"}`                      | Quotes that Truvo created at or before this time read as expired.                                                                                                                                                                          |
| `replay_events` | `{"control": "replay_events", "scenario": "..."}`  | Needs an event scenario, and the catalog has none yet, so this control answers `422` `invalid_input` for every scenario. To see an event, make a real change, such as a quote request or `force_expiry`. See [Webhooks](/guides/webhooks). |

## Reset the workspace

To clear the workspace's records, send `POST /v1/sandbox/reset` with the body `{}` and an `Idempotency-Key`. A reset also puts the controls back to their start values, and every line back on its default scenario.

## About sandbox quotes

* A sandbox quote has the evidence label `mock` and no comparison amount.
* Its coverage conditions include `Sandbox premium. Not a carrier price.`
* A synthetic premium isn't a carrier price, and it isn't a market comparison.

## Scenario IDs

These IDs come from catalog version `2026-09-28`. A mock offer is a synthetic offer, not a market comparison.

### Personal auto

| Scenario                        | Result                                                                    |
| ------------------------------- | ------------------------------------------------------------------------- |
| `auto-one-driver-one-vehicle`   | One driver and one owned vehicle.                                         |
| `auto-several-drivers-vehicles` | Three drivers and two vehicles. One vehicle is owned and one is financed. |
| `auto-financed-vehicle`         | One driver and one financed vehicle.                                      |
| `auto-leased-vehicle`           | One driver and one leased vehicle for business use.                       |
| `auto-several-offers`           | Two mock offers for one owned vehicle.                                    |
| `auto-no-offers`                | The request completes with zero quotes.                                   |
| `auto-partial-result`           | One mock offer and one failed carrier.                                    |
| `auto-decline`                  | The carrier declines. The request completes with zero quotes.             |
| `auto-expiry`                   | The mock offer is already expired.                                        |
| `auto-delay`                    | The mock offer arrives after a fixed delay.                               |
| `auto-unknown-result`           | The carrier's answer is unknown. The API doesn't invent a premium.        |
| `auto-no-answer`                | One mock offer arrives after the collection deadline.                     |
| `auto-duplicate-delivery`       | The same mock offer arrives twice.                                        |

### Renters

| Scenario                     | Result                                                                                                      |
| ---------------------------- | ----------------------------------------------------------------------------------------------------------- |
| `renters-one-offer`          | One mock renters offer. The quote ID and the carrier quote ID are stable.                                   |
| `renters-no-active-product`  | A Florida address, where not every renters carrier quotes. The request still completes with one mock offer. |
| `renters-several-offers`     | Two mock renters offers. Each offer keeps its own quote ID.                                                 |
| `renters-no-offers`          | The request completes with zero quotes.                                                                     |
| `renters-partial-result`     | One mock offer and one failed carrier.                                                                      |
| `renters-decline`            | The carrier declines. The request completes with zero quotes.                                               |
| `renters-expiry`             | The mock offer is already expired. It keeps its quote ID.                                                   |
| `renters-delay`              | The mock offer arrives after a fixed delay.                                                                 |
| `renters-unknown-result`     | The carrier's answer is unknown. The API doesn't invent a premium.                                          |
| `renters-no-answer`          | One mock offer arrives after the collection deadline.                                                       |
| `renters-duplicate-delivery` | The same mock offer arrives twice, with the same quote ID.                                                  |

### Pet

Pet is quote plus a hand-off to the carrier. Pet carriers sell on their own sites, so the customer buys on the carrier's site, and Truvo doesn't learn the result.

Each pet quote returns a `continue_on_carrier_site` action with a `url` to open in a new tab. In the sandbox, the link opens a Truvo sandbox page, never a carrier site. The link works until the quote expires on the workspace clock, and after that it opens a Truvo page that says the quote has expired.

| Scenario                  | Result                                                                                                                                                                            |
| ------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `pet-one-dog`             | One mock pet offer for one dog.                                                                                                                                                   |
| `pet-several-carriers`    | Three mock carriers quote one dog. Each offer keeps its own quote ID.                                                                                                             |
| `pet-two-pets`            | One mock offer for a dog and a cat. The quote has one subject for each pet.                                                                                                       |
| `pet-mixed-breed`         | No carrier breed matches the requested breed. The carrier rates each pet as mixed, and the quote labels this with `breed_rated_as_mixed`.                                         |
| `pet-coverage-adjustment` | The carrier sells a $250 or a $1,000 deductible. It changes any other requested deductible to the next lower value, and the quote labels this with `carrier_coverage_adjustment`. |
| `pet-unsupported-state`   | One carrier doesn't sell in the owner's state and declines. The other carrier quotes.                                                                                             |
| `pet-decline`             | The carrier declines the household. The request completes with zero quotes.                                                                                                       |
| `pet-no-offers`           | No carrier returns an offer. The request completes with zero quotes.                                                                                                              |
| `pet-no-answer`           | One mock pet offer arrives after the collection deadline.                                                                                                                         |

### Purchase

The catalog also has purchase and payment scenarios for auto and renters, for example `auto-pay-in-full` and `renters-monthly`. The API doesn't have the purchase operations yet.