Building in the Sandbox

Build and verify your Partner app in sandbox before you certify its OAuth handshake in production.

📘

Where sandbox fits

Sandbox is where you build. It has its own database and synthetic operators, so nothing you do there touches a real customer. You build and certify almost your entire integration here—every endpoint, every webhook, and the install lifecycle—then complete one final step in production. See Going live for that step.

What you get

CapabilityIn sandbox
Full Partner API surface—every endpoint and scope
An install representing an operator's grant✅ Provisioned by Monta
install.created / install.revoked / install.config.updated webhooks✅ Real deliveries and signatures
403 NEEDS_REAUTH behavior after a scope change
Per-install rate limiting
Synthetic operators, sites, and charge points
The OAuth authorization-code handshake❌ Certified in production; see Going live

Why the handshake is not in sandbox

The consent screen is part of the Monta operator experience: an operator signs in and approves your scopes. Reproducing that outside production would require a second identity provider and a second Hub, and would have you rehearse against endpoints you never ship with—a common source of launch-day invalid_client failures.

Sandbox gives you everything the handshake produces: a live install, credentials, data, and webhooks. Monta certifies the handshake once, with you, against production endpoints scoped to a Monta-owned test operator. In practice, the deferred work is limited to exchanging a code and refreshing a token.

Get set up

Ask Monta for sandbox access and provide:

  • Your app name and the scopes you need
  • Your publicly reachable HTTPS webhook URL
  • The contact address that should receive credentials

Monta registers your app and provisions an install against a synthetic operator. You receive an install.created webhook containing install_id, operator_id, and your sandbox client_id and client_secret. Monta also sends the credentials directly as a fallback.

🚧

Sandbox credentials are sandbox-only

They do not work in production, and Monta issues production credentials separately. See Going live.

Authenticate

Sandbox uses the Partner API's own credential exchange rather than the OAuth handshake:

curl -X POST https://partner-api.sandbox.monta.com/api/v1/auth/token \
  -H "Content-Type: application/json" \
  -d '{"clientId": "<your_sandbox_client_id>", "clientSecret": "<your_sandbox_client_secret>"}'

A successful response contains access and refresh tokens:

{
  "accessToken": "…",
  "refreshToken": "…"
}

Call the API with the access token:

curl https://partner-api.sandbox.monta.com/api/v1/charge-points?perPage=50 \
  -H "Authorization: Bearer <accessToken>"

Refresh the token with POST /api/v1/auth/refresh and your refreshToken.

📘

What changes in production

Only token acquisition changes. In production, you exchange an authorization code at the identity provider's token endpoint rather than calling /api/v1/auth/token. Every API call, payload, scope, and webhook is identical—the API authorizes against the install, not how you authenticated. Keep token acquisition behind one interface in your code so the production switch needs one implementation change.

Build and prove the integration

Work through this list in sandbox so production certification becomes a formality:

  • Exercise the read paths you depend on with realistic pagination.
  • Request the narrowest scopes and confirm that you never call an endpoint outside them.
  • Verify webhooks: read X-Monta-Signature: sha256=<hex>, calculate HMAC-SHA256 over the raw body with your webhook_secret, compare in constant time before parsing, and reject stale delivered_at timestamps.
  • Stop using an install immediately after install.revoked, and ensure nothing retries against it.
  • Re-read configuration after install.config.updated rather than caching it indefinitely.
  • Handle 403 NEEDS_REAUTH separately from other 403 responses: surface it and stop calling the API for that install.
  • Apply backoff for the default limit of 1,000 requests per 60 seconds per install.
  • Implement reconciliation that can recover state from the API without relying on a webhook delivery.
🚧

Webhook delivery is best-effort

Monta does not automatically retry a timeout, non-2xx response, or transport error. Monta can replay deliveries on request. Treat webhooks as an accelerator and the API as your source of truth. Your endpoint must return 2xx within 10 seconds.

Test the lifecycle

Ask Monta to drive these events against your sandbox install:

To testAsk for
First installA fresh install; you receive install.created
UninstallThe install revoked; you receive install.revoked
Configuration changeA config update; you receive install.config.updated
Re-authorizationA scope widening so calls begin returning 403 NEEDS_REAUTH

Each is a one-command operation on Monta's side, so iterate as often as you need.

Endpoints

PurposeSandbox
Partner APIhttps://partner-api.sandbox.monta.com/api/v1
Credential exchangePOST /api/v1/auth/token
RefreshPOST /api/v1/auth/refresh
API referenceSee the API Reference section

When you are ready

Work through the checklist in Going live. Production issues new credentials, and your first production install is against a Monta test operator before any real customer sees your app.


Did this page help you?