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

# Sandbox

> A real workspace with real endpoints, kept off every public surface.

A sandbox workspace is not a mock server. It is a real Maat tenancy — same endpoints,
same schemas, same validation, real create-then-read loops — with one property: nothing
in it can reach the public. Push a property and it is really created; block four nights
and a real calendar really holds them; read your blocks back and you see exactly what
we hold.

That realism is the point. The integration you prove in the sandbox is the integration
that will run in production, byte for byte — including the failure paths. A `409`
conflict, a `validation_failed` naming the field you got wrong, a photo URL we refuse:
all of it behaves in the sandbox exactly as this documentation says.

## The environment is not a parameter

Every API key is issued for exactly one workspace, and that workspace is either a
sandbox or a production tenancy. Your token carries the environment it was issued for,
we compare it against the workspace on **every request**, and a disagreement in either
direction is refused with `workspace_scope_mismatch`.

There is no header, no query parameter and no request field that switches environments.
To move from sandbox to production you exchange a production key — your code otherwise
does not change.

## What is isolated

Everything a sandbox workspace contains is excluded from every public surface:

* sandbox properties never appear in search, on the map, or in the guest feed;
* a sandbox listing has no public listing page;
* no notification of any kind is sent for sandbox activity;
* a sandbox booking can never end in a real charge — sandbox workspaces do not reach a
  payment provider at all, and anything that would lead to a charge is refused with a
  real error rather than faked.

The exclusion is unconditional. There is no way — for you or for us — to ask a public
surface to include sandbox rows.

## Treat sandbox content as disposable

The platform is designed to reset sandbox **content** on a nightly schedule: properties,
calendars and blocks can be wiped. What always survives a reset is what your integration
depends on — the workspace itself, your API key, and your webhook registration. Build
your sandbox setup as something you can re-run (the property and block contracts are
idempotent by construction, so re-pushing your catalogue is one loop), and never treat
sandbox data as durable.

## What the sandbox cannot prove yet

One loop is not exercisable end-to-end today: a sandbox **booking**. Because a sandbox
workspace cannot reach a payment provider, no guest can complete a booking in it, which
means a `booking.confirmed` webhook cannot be triggered by a real sandbox stay. Webhook
registration, the signed challenge and signature verification are all real in the
sandbox — the delivery you verify against is the challenge. This limitation is stated
here rather than papered over; see the [changelog](/guides/changelog) for when it
changes.

## Getting a sandbox key

Sandbox keys are issued by your Maat contact, like production keys, and behind the same
gate: your organization's data-sharing agreement must be recorded first. There is no
self-serve signup today.
