# Environments and sandboxes

There is no separate test API. You test in a **sandbox**: a company of its own, linked to yours. Its keys start with
`exa_test_`. Your real company's keys start with `exa_live_`. The API, the SDK and your code are the same in both, so
going live is swapping the key.

## Make a sandbox

An admin opens **Settings → Developer → Sandboxes → New sandbox** and names it (1 to 100 characters). **Open** switches
into it. In the company switcher a sandbox has a **Sandbox** badge.

- A company can have **5 open sandboxes** at once. A sixth is refused with `sandbox_limit_reached`.
- A sandbox cannot have sandboxes of its own.
- The admin who makes it is its admin and can invite others as usual.
- Sandboxes are made on the Developer page only. There is no API call to make one.

In the sandbox, make an app and a key as usual (see [Apps and keys](https://developers.exayard.com/apps-and-keys.md)). An app that belongs to a sandbox
gets `exa_test_` keys.

## How a sandbox differs

- **Plan and billing.** A sandbox follows your company's plan, and your company pays for its usage. It has no billing
  of its own: buying credits or a plan in it is refused with `sandbox_billed_to_parent`. It gets no monthly Free
  usage, plan usage or welcome gift.
- **Messages to people outside it are held.** A bid share email and a signed copy sent to anyone who is not a member
  of the sandbox are not sent, and no texts are sent. They show as "Not sent because this company is a sandbox".
  Invitations to join the sandbox are sent as usual.
- **Webhooks and integrations work normally**, so you can test your receiver end to end.
- **No welcome or product emails** go to a sandbox.

## AI work in a sandbox

Takeoffs and file reads in a sandbox return results copied from our sample project, at no charge. They are marked
`"sample": true` on the takeoff, on each of its pages and in the `assessment.completed` webhook. A takeoff you cancel
in a sandbox carries `"sample": true` too.

Estimates, bids, element search and chat answer with samples too, at no charge. An estimate or bid made in a sandbox
carries `"sample": true`, in the response and on the saved document. Other AI answers come from the call's own answer
format, or read "This is a sample answer from a sandbox company.". Image generation is refused.

## Delete a sandbox

**Delete** on the sandbox's row closes it: every app in it loses access, and its data is erased after the usual purge
window. Calls with its keys then get 401.

## Going live

1. In your real company, make the app and a key the same way. The key starts with `exa_live_`.
2. Swap `EXAYARD_API_KEY` (or whatever holds the key) to the new key.
3. Register your webhook endpoints in the real company too. Each endpoint has its own signing secret.

Your code needs no other change: a key implies its own company.
