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

# Testing and environments

> Build against a sandbox environment, then switch to production by changing the base URL and the key.

VEXiON cards gives you two environments: **production**, where your real customers and balances live, and a **sandbox**, where you build and test. They expose the same endpoints and return the same responses. The sandbox receives each release before production, so it can be briefly ahead; the [Changelog](https://vexioncards.mintlify.site/api-reference/changelog.md) says when a change reaches production. The two have separate databases, so nothing you do in the sandbox reaches a real customer.

Moving from one to the other means changing two values: the base URL and the API key.

| Environment | Base URL | Key prefix |
| - | - | - |
| Production | `https://api.vexioncards.one` | `vxn_sk_` |
| Sandbox | `https://migration.api.vexioncards.one` | `vxn_test_sk_` |

The API Reference playground carries both: pick the environment from the server dropdown above any endpoint.

```mermaid theme={null}
%%{init: {'theme':'base','themeVariables':{'primaryColor':'#E5F6FF','primaryBorderColor':'#36C6FA','primaryTextColor':'#0B3A4A','lineColor':'#2BA8D9','secondaryColor':'#F4FCFF','tertiaryColor':'#FFFFFF','fontFamily':'Manrope, ui-sans-serif, system-ui, sans-serif'}}}%%
flowchart LR
    subgraph Sandbox["Sandbox"]
        direction TB
        SK["Key<br/>vxn_test_sk_..."] --> SU["Base URL<br/>migration.api.vexioncards.one"]
        SU --> SD[("Sandbox data<br/>cards · customers · balances")]
        SD --> SE["Sandbox effects<br/>emails · wallet passes · webhooks"]
    end

    subgraph Production["Production"]
        direction TB
        PK["Key<br/>vxn_sk_..."] --> PU["Base URL<br/>api.vexioncards.one"]
        PU --> PD[("Production data<br/>cards · customers · balances")]
        PD --> PE["Real effects<br/>emails · wallet passes · webhooks"]
    end

    SK -. rejected .-x PU
    PK -. rejected .-x SU

    linkStyle 6,7 stroke:#94A3B8,color:#94A3B8
```

A sandbox key only ever resolves inside the sandbox lane. There is no path from a vxn\_test\_sk\_ key to production data, and no path from a vxn\_sk\_ key to sandbox data.

> [card] Sandbox
>
> Key prefix `vxn_test_sk_`. Requests only ever reach sandbox data, no
> matter which endpoint you call.

> [card] Production
>
> Key prefix `vxn_sk_`. Requests only ever reach production data, no
> matter which endpoint you call.

## The two environments

| | Production | Sandbox |
| - | - | - |
| Purpose | Your live business | Building and testing an integration |
| Data | Your real cards, customers and balances | Throwaway data you create |
| Key format | `vxn_sk_...` | `vxn_test_sk_...` |
| Endpoints, responses, errors, webhooks | The same | The same, and briefly ahead after a release |

Because the key prefix differs, you can tell at a glance which environment a key belongs to, including in your own configuration and logs. A key is only ever valid in the environment that issued it.

## Getting sandbox access

Sandbox access is provisioned per partner. Contact us and we will create a sandbox organization for you and issue a `vxn_test_sk_` key. The key is what grants access; without one the sandbox host will not authenticate you. Dashboard keys (`vxn_sk_`) are production keys and do not work in the sandbox.

Your production keys stay where they are, at **Dashboard → Settings → Developer**.

## Working in the sandbox

The sandbox works like production, which is the point: what you see while building is what you get in production. Effects are real within the sandbox, so a stamp award moves a sandbox balance, a delivery sends the email, and a pass pushes to a wallet.

That makes a few habits worth adopting from the start.

**1. Send side effects to yourself**

When you exercise a flow that emails, texts or pushes a pass, use your own
address, phone or device as the recipient. You see exactly what a customer
would receive.

**2. Tag the data your tests create**

Pass a recognizable `external_id` (for example `qa-run-4821-cus-1`) on the
customers and transactions your tests create, so you can find them later and
so a re-run never double-creates.

**3. Scope each key to what it needs**

Give a key only the scopes it uses. Each endpoint page in the API reference
names the scope it needs. This is good practice in both environments.

**4. Point webhooks at an endpoint you control**

Register a [webhook endpoint](https://vexioncards.mintlify.site/api-reference/webhooks.md) on a tunnel or a test
receiver, verify the signature, and watch real events arrive. Delivery,
signing and retries behave the same in both environments.

## Idempotency

Every mutating call accepts an `Idempotency-Key`. Reusing the same key on a retry returns the original result instead of performing the operation twice, so a network retry of a stamp award never awards twice. Wire it in from the start and it protects you in both environments. See [Idempotency](https://vexioncards.mintlify.site/api-reference/idempotency.md).

## Going live

**1. Swap the base URL**

Point your client at the production base URL.

**2. Swap the key**

Replace your `vxn_test_sk_` key with a production `vxn_sk_` key from the
dashboard.

**3. Re-create what production needs**

Sandbox data stays in the sandbox. Create your production cards and webhook
endpoints the same way your integration created them in the sandbox. Set up
locations in the dashboard.

Request shapes, responses and webhook payloads are the same, because you built against the same API the whole time.

> [!WARNING]
>
> Treat a production `vxn_sk_` key as live access from its first request. Store
> keys in a secret manager, never in client-side code or source control.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.