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

# Sandbox testing

> Create isolated orders and move them through deterministic scenarios.

The sandbox uses the V2 contract. Its base URL is `https://sandbox.api.bahnexpress.fi`.

<Note>
  Sandbox credentials, orders, files, webhook endpoints, signing secrets, events, and tracking snapshots stay separate from production data.
</Note>

Sandbox orders never enter production operations. Uploaded sandbox files expire after 30 days.

## Prepare the environment

Create a sandbox credential and webhook endpoint on the Customer API page in the Bahn portal.

Sandbox address responses use the structured address fields that you send. Include `country_code` in each address.

An ordering channel can use any supported test business ID. The sandbox creates an isolated customer when no test customer matches.

The supported country codes are `FI`, `DK`, `DE`, and `PL`.

## Apply a scenario

Create a normal order, then call `POST /v2/test/orders/{order_id}/advance`.

The call needs the `test:write` scope and an idempotency key. The optional `occurred_at` field makes the test time deterministic.

The response contains the current order. It does not replace webhook delivery.

## Test the main order flow

Apply these scenarios in order for a standard transport flow:

| Step | Scenario                     | Result to verify                                           |
| ---- | ---------------------------- | ---------------------------------------------------------- |
| 1    | `pickup_readiness_confirmed` | Pickup readiness becomes `confirmed`.                      |
| 2    | `pickup_approach_started`    | Tracking becomes active and progress becomes `on_the_way`. |
| 3    | `pickup_nearby`              | Pickup progress becomes `nearby`.                          |
| 4    | `pickup_completed`           | The order enters transit.                                  |
| 5    | `delivery_eta_changed`       | A delivery ETA becomes available.                          |
| 6    | `files_published`            | Sample order files become available.                       |
| 7    | `tracking_available`         | A driver position becomes available.                       |
| 8    | `delivery_completed`         | The order becomes delivered.                               |

Read the related resource and verify the signed webhook after each scenario.

## Test optional states

| Scenario               | Required state                       | Result                                   |
| ---------------------- | ------------------------------------ | ---------------------------------------- |
| `inspection_completed` | Full inspection and completed pickup | The inspection report becomes available. |
| `tracking_unavailable` | Completed pickup                     | The position becomes unavailable.        |
| `tracking_paused`      | Completed pickup                     | A ferry phase pauses live tracking.      |
| `cancelled`            | The order is not cancelled           | The order becomes `cancelled`.           |

Create the order with `inspection: full` before you test `inspection_completed`.

Use one of the named scenarios. A request fails when the scenario does not match the current order state.

## Move from sandbox to production

Sandbox prices, times, files, and positions are test data. They do not predict a production result.

Use `/v2/test` routes only with the sandbox base URL.

Sandbox webhooks use the normal event and signature formats. Test every event type through your sandbox endpoint before production use.
