VetoVetoDocs
Hosted REST API

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).

authorized request
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 formModeCreates / reads
veto_test_…testtest-mode merchants, policies, products
veto_live_…livelive-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 403 LIVE_KEY_REQUIRED.
  • A route that demands a test key rejects a live key with 403 TEST_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.

ScopeGrants
merchants:read / merchants:writeRead / mutate merchants + receiving.
products:read / products:writeRead / mutate catalog.
policy:read / policy:writeRead / create policy versions.
orders:readRead the orders activity feed.
reputation:readRead reputation scores.
ingest:writePost gate outcomes to /v1/ingest/*.
keys:read / keys:writeManage API keys.
webhooks:read / webhooks:writeManage webhook endpoints.
threat:readRead 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

StatusReason codeCause
401UNAUTHENTICATEDNo Authorization / X-Veto-Api-Key header.
401INVALID_API_KEYUnknown or revoked key.
403INSUFFICIENT_SCOPEKey lacks a required scope.
403LIVE_KEY_REQUIREDLive-only route called with a test key.
403TEST_MODE_RAIL_FORBIDDENTest-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…"
200
{
  "project": { "id": "proj_01J…", "name": "Acme" },
  "org": { "id": "org_01J…", "name": "Acme Corp", "slug": "acme" },
  "livemode": false,
  "scopes": ["merchants:read", "merchants:write", "products:read", "…"]
}