Authentication
API keys, scopes, and test/live mode isolation for the Veto hosted control plane. Send your key as a Bearer token; mode is carried by the key prefix.
Every data-plane route on the hosted control plane is guarded by an API key. Keys are minted by the sign-in flow and revealed exactly once.
Presenting a key
Send the key as a Bearer token. The legacy X-Veto-Api-Key header is also accepted (the
shipped SDK reputation client uses it).
curl https://api.veto-ai.com/v1/merchants \
-H "Authorization: Bearer veto_test_8f2c…"Keys are veto_{live|test}_<hex48>. They are hashed at rest (sha256 + a server-side
pepper) and the plaintext is shown only at creation — store it in a secret manager.
| Key form | Mode | Creates / reads |
|---|---|---|
veto_test_… | test | test-mode merchants, policies, products |
veto_live_… | live | live-mode merchants, policies, products |
Mode isolation
Mode is part of the key — there is no separate environment switch. The two modes are fully isolated:
- A test key that targets a live merchant id gets
404(it doesn't exist for that key). - A route that demands a live key rejects a test key with
403LIVE_KEY_REQUIRED. - A route that demands a test key rejects a live key with
403TEST_MODE_RAIL_FORBIDDEN.
The mock rail is test-only.
The mock receiving rail can never be a live receiving destination. Setting it on a live
merchant fails with RECEIVING_MOCK_IN_LIVE.
Scopes
Each route requires one or more scopes. A freshly bootstrapped key carries the full default scope set, so first-login keys can do everything; you can mint narrower keys later.
| Scope | Grants |
|---|---|
merchants:read / merchants:write | Read / mutate merchants + receiving. |
products:read / products:write | Read / mutate catalog. |
policy:read / policy:write | Read / create policy versions. |
orders:read | Read the orders activity feed. |
reputation:read | Read reputation scores. |
ingest:write | Post gate outcomes to /v1/ingest/*. |
keys:read / keys:write | Manage API keys. |
webhooks:read / webhooks:write | Manage webhook endpoints. |
threat:read | Read threat intelligence. |
A request missing a required scope is rejected with 403 INSUFFICIENT_SCOPE;
the error_human names the missing scope(s).
Auth failure modes
| Status | Reason code | Cause |
|---|---|---|
401 | UNAUTHENTICATED | No Authorization / X-Veto-Api-Key header. |
401 | INVALID_API_KEY | Unknown or revoked key. |
403 | INSUFFICIENT_SCOPE | Key lacks a required scope. |
403 | LIVE_KEY_REQUIRED | Live-only route called with a test key. |
403 | TEST_MODE_RAIL_FORBIDDEN | Test-only route called with a live key. |
The caller identity — GET /v1/me
Resolve who a key belongs to. Requires merchants:read.
curl https://api.veto-ai.com/v1/me -H "Authorization: Bearer veto_test_8f2c…"{
"project": { "id": "proj_01J…", "name": "Acme" },
"org": { "id": "org_01J…", "name": "Acme Corp", "slug": "acme" },
"livemode": false,
"scopes": ["merchants:read", "merchants:write", "products:read", "…"]
}Hosted REST API
The Veto merchant control plane — the hosted REST API behind merchants.veto-ai.com. Provision merchants, manage catalog, policy, and receiving, serve discovery manifests, ingest gate outcomes, and read reputation.
Errors & conventions
The single protocol error shape, status-code semantics, idempotency, ID prefixes, and the money rule shared by every hosted REST endpoint.