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

# Environments and test mode

> Two environments, each with its own host. Build against the sandbox, then point at production to go live.

Maple runs two fully isolated environments, each with its own base URL and its own credentials:

| Environment    | Base URL                           | Credential   |
| -------------- | ---------------------------------- | ------------ |
| **Sandbox**    | `https://api.staging.maple.inc/v1` | `mpk_test_…` |
| **Production** | `https://api.maple.inc/v1`         | `mpk_live_…` |

You develop and test entirely in the **sandbox** — the Maple team provisions it for you and issues your sandbox credentials. When your integration is approved, you point the same code at **production** with your live key. The two environments never share data: a connection, subscription, or order in the sandbox is invisible to production, and the reverse.

<Info>
  The only differences between environments are the **base URL** and the **credential**. Your request and response
  shapes, webhook signing, and the order loop are identical — so going live is a configuration change, not a rewrite.
</Info>

## Why this matters

The sandbox lets you exercise the full order loop against data that can't affect a real merchant or charge a real customer. Once your webhook handler verifies signatures correctly and you've driven orders end to end, switching to production is a base-URL-and-credential swap.

```mermaid theme={null}
flowchart LR
  subgraph Sandbox [Sandbox · api.staging.maple.inc]
    SK[mpk_test_ key] --> SD[(sandbox data)]
  end
  subgraph Production [Production · api.maple.inc]
    LK[mpk_live_ key] --> LD[(live data)]
  end
```

## Telling environments apart in your code

The sandbox and production are **separate deployments on different hosts**, so a request or webhook belongs to whichever environment its host and credential do — you don't infer it from the payload. Where you do want it explicitly:

* `GET /v1/me` returns the credential's `environment` (`test` or `live`).
* The order resource carries `livemode` — `true` in production, `false` in the sandbox.

<Warning>
  Use a separate webhook subscription per environment, and point each at the matching base URL. The delivered event
  doesn't carry an environment field — the endpoint that receives it already tells you which environment it came from.
</Warning>

## A test-first workflow

<Steps>
  <Step title="Build against the sandbox">
    Point your client at `https://api.staging.maple.inc/v1` with your `mpk_test_…` key. Connect to the sandbox
    location Maple grants you, subscribe a webhook, and exercise the full order loop.
  </Step>

  <Step title="Prove your webhook handler">
    `POST /v1/webhook_subscriptions/{id}/test` delivers a signed `webhook.test` event so you can confirm signature
    verification and your `2xx` response before any real order exists.
  </Step>

  <Step title="Get approved and go live">
    Once your integration is approved, Maple issues a `mpk_live_…` key. Switch the base URL to
    `https://api.maple.inc/v1` and the credential to your live key, then re-run your setup — connect the live location,
    subscribe a live webhook. Your code is otherwise unchanged.
  </Step>
</Steps>

## Going-live checklist

* Your client's base URL and credential both point at the same environment.
* Your webhook handler verifies the HMAC signature and rejects bad or stale signatures. See [Webhooks](/developer-api/concepts/webhooks).
* You dedupe deliveries on the envelope `id` (delivery is at-least-once).
* You respond `2xx` quickly and do slower work asynchronously.
* Decision calls are retried safely on transient errors (they're [replay-safe](/developer-api/concepts/idempotency)).
* You store the live signing secret (`mwhsec_…`) securely — it's shown only once.
