Authentication
The two headers that authenticate every request, and the three request tiers.
The API uses two headers. There's no OAuth, no token exchange, and no partner-signed JWT — your backend holds one API key and identifies users by the same id you already use for them. The only signature anywhere in the flow is the user's one-time SIWS at onboarding.
X-Titan-Key
every request
Authenticates your integration (your tenant). Keep it server-side; never ship it to a browser.
X-Titan-User
every user-scoped request
Your stable id for the end-user — the same value you onboarded as sub. Titan maps it to that user's manager.
Every header originates on your backend. Nothing goes from the end-user's browser directly to Titan.
X-Titan-Key
Your partner API key. Never expose to browsers.
X-Titan-User
Your stable id for the user the request acts on. Required on user-scoped routes.
Content-Type
application/json on POST/PATCH.
X-Idempotency-Key
Optional on selected POSTs. A stable, unique-per-operation string. See Idempotency.
X-Request-Id
Optional. If set, Titan keeps it in logs and echoes it back as x-request-id. Otherwise one is generated.
Request tiers
Public
none
GET /health
Partner-only
X-Titan-Key
POST /partner/onboard, GET /partners/me/* (reporting)
User-scoped
X-Titan-Key + X-Titan-User
Everything that acts on a specific user — balances, orders, withdrawals, GET /me.
User consent
A user's external wallet is bound to their manager by a SIWS signature collected once at POST /partner/onboard. After that, you act on their behalf within the on-chain policy by sending X-Titan-User — no further per-request user signature. The policy pins the manager to order-execution swaps — DCA cycles and trigger fills — plus withdrawals only to that user's own external wallet, so neither you nor Titan can move funds anywhere else.
Auth errors
These apply to every authenticated endpoint:
HTTP
error.code
When
401
INVALID_API_KEY
Missing or unknown X-Titan-Key.
401
KEY_REVOKED
Your key was revoked.
401
ENV_MISMATCH
Key issued for a different environment.
401
UNAUTHORIZED
On a user-scoped route: X-Titan-User is missing, or the supplied id was never onboarded. Call POST /partner/onboard for that user first.
403
PRODUCT_DISABLED
The product is disabled on your key.
403
PRODUCT_EXPIRED
Your product grant has expired.
403
TENANT_SUSPENDED
Your tenant is suspended (recoverable; contact Titan).
403
TENANT_DELETED
Your tenant is deleted.
403
TENANT_NOT_PROVISIONED
Key valid, but no tenant row yet — onboarding step missing on Titan's side.
Verify your plumbing
GET /me resolves the identity for the current request and is the quickest smoke test that X-Titan-Key + X-Titan-User map to the user you expect:
sessionId is always empty for partner integrations — ignore it. Rely on userId / walletAddress, and treat both as opaque strings (the field names are stable; their format may change).
Related pages
Onboarding (SIWS) — how the
X-Titan-User→ manager mapping gets createdEndpoints — the tier each route belongs to
Error Codes — the complete error catalog
Last updated

