Skip to content

Go to production

The sandbox is testnet-only. Going live means pointing at the production endpoint and having your controls in place before real value moves. Nothing about the API surface changes — the guarantees you built against are the same.

EnvironmentBase URLChains
Sandboxhttps://api.mpc-dev.xkova.com/v1Avalanche Fuji, Base Sepolia, Bitcoin signet
Productionhttps://api.mpc.xkova.com/v1mainnets — available at launch

Switch by changing baseUrl and using mainnet chainIds (Send on EVM). Use a separate API key per environment so a sandbox key can never touch production.

Pick the right tier per vault. The tier is fixed at creation and decides who must authorize a signature. For funds you control, self gives true self-custody; for user wallets, hosted gates each signature on the user’s token. Review How it works.

Set spend controls. Configure per-transaction and per-day limits and your recipient/asset policy on each vault. These are checked before any share participates — a violation is rejected with no partial signature. Start conservative.

Make every send idempotent. Derive idempotencyKey from your own operation ID, persist it before you call, and reuse it on retry. This is your protection against double-spending on a timeout or crash. See Send on EVM.

Use webhooks, and reconcile. Register a webhook and verify every delivery’s signature (Webhooks). Keep a slower getTransaction reconciliation loop as a backstop for missed deliveries. Never assume a POST that returned 202 has settled.

Protect the API seed. It lives in a secrets manager, never in source or logs. Mint one key per service so a leak is contained; revoking a key is immediate and does not touch funds. Rotate by minting, cutting over, then revoking.

Handle errors by code, not message. Branch on the stable code slug and the HTTP status, not on human-readable text (Errors). Treat rate_limited and unavailable as retryable with backoff; treat rejected transactions as terminal and surface the reason.

  • Everything money-moving is asynchronous. Design your flows around states and webhooks, not blocking calls.
  • Rotation is invisible to you. Vault resharing does not change addresses; signing pauses briefly. Don’t hardcode assumptions about instant availability.
  • Retry on the retryable, fail closed on the rest. A refused signature never produces a partial result — there is nothing to clean up, only to surface.
  1. Production API key minted and stored in a secrets manager.
  2. Vaults created at the intended tier; limits and policy configured.
  3. Idempotency keys persisted before each send.
  4. Webhook endpoint verifying signatures, plus a reconciliation loop.
  5. Error handling branches on code; retryable vs terminal separated.
  6. Alerting on failed/rejected transactions and on frozen vaults.