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

# Going Live

> Claim a sandbox into a real Zinc account without breaking the agent that built it, then swap in a live key.

Going live is two separate things, and it helps to keep them apart:

1. **Claiming** — a human adopts the sandbox into their Zinc account. The agent's key survives.
2. **Switching to live** — the account owner mints a `zn_live_` key and funds a wallet.

You can do the first without the second. Claiming preserves work; it doesn't spend money or enable real orders.

## Claiming

The mint response included a `claim_url`. Give it to the human you work for:

> "I've built and tested the ordering flow against a Zinc sandbox. To adopt it into your account, sign in here: `https://app.zinc.com/claim/...`"

When they sign in there, the sandbox folds into their Zinc account:

|                     | Result                                                 |
| ------------------- | ------------------------------------------------------ |
| Sandbox orders      | Repointed to their account — the test history survives |
| The agent's API key | **Reassigned, not revoked**                            |

<Info>
  Not revoking the key is the entire point. An agent that's been running against a sandbox for a week doesn't need redeploying, reconfiguring, or a secret rotation to keep working.
</Info>

Claiming is always a merge into the signed-in account — signing in creates the account if it didn't exist, so there's always something to merge into.

<Warning>
  The claim token is **single-use** and lives only in that URL. Only its hash is stored, so the URL can't be reproduced — if it's lost, mint a new sandbox and hand over the new one.
</Warning>

### Knowing when it happened

An agent that hands off a URL can't see what the human did next. Poll for it:

```bash theme={null}
curl https://api.zinc.com/sandbox/status \
  -H "Authorization: Bearer $ZINC_KEY"
```

| `claimed` | Meaning                                                                      |
| --------- | ---------------------------------------------------------------------------- |
| `false`   | Still provisional — nobody has claimed it. Keep waiting, or re-send the URL. |
| `true`    | Claimed. `claimed_by_email` names the account it now belongs to.             |

Every response carries a plain-language `hint`, so an agent can act on the answer without special-casing each shape.

## Switching to live

<Warning>
  **A claimed key is still a sandbox key.** It reaches sandbox data only, claimed or not. Claiming moves ownership; it does not grant the ability to spend.
</Warning>

To place real orders, the account owner:

<Steps>
  <Step title="Funds a wallet" stepNumber={1}>
    Deposit a balance in the [dashboard](https://app.zinc.com). Each order draws its cost plus the account's order fee. See [Wallet](/docs/v2/wallet) for the fee schedule, or [Stripe Connect](/docs/v2/connect) and [MPP](/docs/v2/mpp) for the other payment rails.
  </Step>

  <Step title="Mints a live key" stepNumber={2}>
    A `zn_live_` key, from the same dashboard.
  </Step>

  <Step title="Hands it to the agent" stepNumber={3}>
    The API surface is identical. Change the key, keep the code.
  </Step>
</Steps>

## What changes when you switch

The request and response shapes don't change. The environment around them does:

|                         | Sandbox                     | Live                                                 |
| ----------------------- | --------------------------- | ---------------------------------------------------- |
| Money                   | Nothing is charged          | Every order draws from a wallet                      |
| Balance checks          | Skipped                     | Enforced — an underfunded order is rejected          |
| URL reachability        | Skipped                     | Enforced                                             |
| Address verification    | Skipped                     | Enforced against external validation                 |
| Retailer URL validation | Skipped                     | Enforced                                             |
| Timing                  | Compressed — minutes        | Real — orders take 5–10 minutes, delivery takes days |
| Failures                | Only the ones you asked for | Whatever the retailer does                           |

<Warning>
  Because the sandbox skips those validations, your first live order can fail in ways no test did — a rejected address, an unreachable URL, a real out-of-stock. Handle `order_failed` and the synchronous rejections before you switch, not after.
</Warning>

## Before your first live order

* **Handle both failure timings.** Some errors come back from `POST /orders`; others arrive minutes later as `order_failed`. See [Error Handling](/docs/v2/api-reference/introduction/error-handling).
* **Set `max_price` to cover the real total.** Item plus tax plus shipping — a ceiling that only covers the item price trips `max_price_exceeded` on live orders that would have passed in the sandbox.
* **Re-register webhooks.** Test-mode webhook config is separate from live; a live key won't inherit it.
* **Send an idempotency key.** On live orders, a retry without one is a second order. See [Idempotency](/docs/v2/api-reference/introduction/idempotency).
* **Start small.** One cheap real order end to end before you turn on volume.

## Reference

<CardGroup cols={2}>
  <Card title="Claim a Sandbox" icon="code" href="/docs/v2/api-reference/sandbox/claim-sandbox">
    `POST /sandbox/claim` — request and response by field.
  </Card>

  <Card title="Get Sandbox Status" icon="code" href="/docs/v2/api-reference/sandbox/get-sandbox-status">
    `GET /sandbox/status` — every response shape.
  </Card>
</CardGroup>
