Authentication
Every tenant-facing endpoint — wallets, assets, tokenization, receipts, AMM and IMM swaps, journal, the mobile-facing /u/* routes — authenticates with your own API Key and API Secret. This is also true of most of what looks like an "admin" route: IMM/Treasury configuration (rates, vault, rebalance, corridors) and Token Factory (create/mint/burn your own tokens) key everything by tenant, so your own API Key/Secret works there too, automatically scoped to your own data — you never see or affect another tenant's rates, vault, corridors, or tokens.
A small remaining set of routes are genuinely platform-wide, not tenant-owned data — creating/managing other tenants, AMM pool creation/funding, asset registration, and the bridge — and stay Service-Token-only regardless. Each of those is marked 🔒 in its own reference page.
Booking an IMC mint (IMC & Airtime →) is the mirror image: those two routes accept only your API Key/Secret — a service token or a dashboard session gets 403 and is pointed at the operator's own POST /admin/imc/airtime-topup, and every request must carry the gateway receipt number for the airtime being booked.
Getting Your API Key and Secret
API keys are managed through the Admin Dashboard. Contact your platform administrator to create a tenant and receive your credentials.
The secret is shown once
apiSecret is only returned at creation (or regeneration) time — write it down immediately. It's never stored in recoverable form; if you lose it, the only option is to regenerate a new pair (which invalidates the old one).
Making Authenticated Calls
curl "http://localhost:8100/api/v1/wallets/balance?externalUserId=123" \
-H "X-API-Key: YOUR_API_KEY" \
-H "X-API-Secret: YOUR_API_SECRET"Never commit a real key/secret to docs, code, or version control
Treat apiSecret like a password — the format above (40-char key, 64-char secret, both hex) is real, but the values are placeholders on purpose. Generate your own via the Admin Dashboard, and if one is ever exposed by mistake, regenerate immediately — the old pair stops working the instant a new one is issued.
Configure your own key/secret in the panel at the top of this page (or any API reference page) and every <CurlBlock> on this site renders your real, copy-pasteable command instead of a placeholder.
How It Works
- Engine receives the
X-API-Keyheader - Looks up the tenant by API key in MongoDB
- Computes SHA-256 of the provided
X-API-Secret - Compares against the stored hash using constant-time comparison (prevents timing attacks)
- Valid → the tenant is set in request context, every operation below is automatically scoped to it — you never need to pass
tenantSlugyourself - Invalid →
401 Unauthorized
Format: API Key is a 40-character random hex string (public, used for lookup); API Secret is a 64-character random hex string (private, never stored in plaintext — only its hash).
Tenant Scoping
Comet Engine is multi-tenant — every wallet, asset, and journal entry is scoped to a tenant. Authenticating with your API Key/Secret resolves and scopes every call to your tenant automatically; you never pass tenantSlug yourself. (The default tenant on a fresh install is "comet", auto-seeded at boot — only relevant if you're calling admin routes with a service token, which do require it explicitly.)
Admin Routes and Service Tokens
A small number of platform-operator routes — creating/managing tenants, AMM pool creation/funding, asset registration, the bridge — are intentionally not reachable with a tenant's own API Key/Secret, by design: these are privileged, platform-wide operations that touch shared state every tenant's traffic depends on, not something an individual tenant's own credentials should be able to do. They require a Service Token (X-Service-Token header, matched against the engine's SERVICE_TOKENS allowlist) instead — confirmed directly: a regular tenant's API Key/Secret gets a real 401 on these routes, on purpose.
IMM/Treasury admin config and Token Factory are not in this list — see above.
curl -X POST http://localhost:8100/api/v1/admin/imm/rates \
-H "X-Service-Token: YOUR_SERVICE_TOKEN" \
-H "Content-Type: application/json" \
-d '{"base": "USDT", "quote": "IMC", "rate": 1.05}'Every admin-tier <CurlBlock> on this site is marked 🔒 and always renders with X-Service-Token, regardless of the panel's global setting above — so a copied command for one of those never silently fails auth by using the wrong credential type. Service tokens are configured via the SERVICE_TOKENS env var (comma-separated) — see Configuration.