Environments
Sandbox and production base URLs.
Moon runs two environments. Sandbox is where you build and test; production is where real cards spend real money. They run the same API: the same endpoints, the same request and response shapes, the same validation rules, the same error bodies and the same rate limits.
| Environment | Base URL | What it is for |
|---|---|---|
| Production | https://api.themooncard.com | Live cards and real funds. |
Only the host and the key change between them.
Getting a key for each
Create keys in your Moon dashboard, choosing Sandbox or production at creation time. The key value is shown once. If your dashboard does not offer API keys yet, write to our team.
A key belongs to one environment: a Sandbox key does not authenticate against the production host, and the reverse is also true — both fail with 401 UNAUTHORIZED. Keep the two in separate secrets, and never point a production key at Sandbox or a Sandbox key at production. See Authentication.
What is separate
The two environments share nothing. An id created in Sandbox does not resolve in production, so plan for your own systems to carry the environment alongside every Moon id you store.
Register a separate webhook URL for Sandbox, with its own signing secret — one URL per organization per environment. See Webhooks.
What Sandbox simulates
One endpoint group exists only in Sandbox:
| Purpose | V1 | V2 |
|---|---|---|
| Simulate a card transaction | POST /v1/api-gateway/card/{card_ | POST /v2/api-gateway/simulate/cards/{card_ |
A simulated card transaction runs through the same processing path as a real one: it moves the same ledger balances, applies the same fees and spending controls, and delivers the same webhooks to your Sandbox endpoint. See Simulating card transactions.
Called against production, both return:
JSON
HTTP/1.1 403 Forbidden
{
"message": "This endpoint is only available in non-production environments",
"code": "DEV_ONLY_ENDPOINT"
}Balances in Sandbox
Loading a card draws the prepaid balance for the amount and its fee, and a card with no balance declines with INSUFFICIENT_. See Adding a balance.
Everything outside the simulate endpoints behaves the same way in both environments, including authentication, pagination, validation, error codes, webhook signing and rotation, and rate limits.
Where the two differ
Beyond the host and the key, these are the differences to code around:
| Sandbox | Production | |
|---|---|---|
| Simulation endpoints | Available | 403 DEV_ |
| Minimum first load on a new card | 1 USD | 5 USD |
| Rate limits | 100 requests per 60-second window, per endpoint, per calling IP address | Same |
See Errors.
Going live
- Drive the full lifecycle in Sandbox: fund the prepaid balance, issue and load a card, then simulate an authorization, a reversal, a clearing and a refund. Confirm your webhook receiver verifies signatures — see Verifying webhook signatures.
- Create a production key, register your production webhook URL, and store its signing secret.
- Point your production configuration at
https://api.themooncard.comand re-run your smoke tests. Expect403DEV_from anything that still calls a simulate endpoint.ONLY_ ENDPOINT
Last updated August 17, 2026