Machine-Readable Spec
For coding agents and SDK code-generators, point your tooling at these URLs directly — they are the source of truth, not this page.| Artifact | URL | Purpose |
|---|---|---|
| OpenAPI 3.1 JSON | https://api.glider.fi/v2/openapi.json | Generate SDKs, typed clients, Postman collections |
| LLM-friendly markdown | https://api.glider.fi/v2/llms.txt | Primer for coding agents (Claude, Cursor, etc.) |
| Interactive docs (Scalar) | https://api.glider.fi/v2/docs | Try-it-out UI with live request builder |
Base URL
https://staging-api.glider.fi/v2 is available for
integration testing. Contact [email protected] for a staging API key.
Authentication
Every endpoint exceptGET /v2/scopes requires an API key in the x-api-key
header. HTTP header names are case-insensitive but the canonical form used
throughout v2 is lowercase.
GET /v2/whoami returns your tenant identity and granted scopes. Call it
first to confirm the key works.
Response Envelope
V2 uses a consistent envelope. Tracing identifiers live in response headers, not in the JSON body. This is a deliberate break from v1.Success
Paginated success
nextCursor is a sibling of data, never nested inside it. Collections inside
data are always wrapped under a named key (e.g. data.portfolios, not
data directly).
Error
details is optional and omitted when there is nothing to say beyond
message.
Tracing Headers
Every response, success or error, includes:| Header | Purpose |
|---|---|
X-Correlation-Id | Cross-service trace id. Quote this when reporting issues. |
X-Request-Id | Unique per request. |
correlationId, requestId, or timestamp inside the body.
Read them from headers only.
Scopes
Every authenticated endpoint declares the single scope it requires. If your key lacks the scope you get403 API_104.
| Scope | Tier | Grants |
|---|---|---|
strategies:read | default | List and view strategies |
strategies:write | standard | Create strategies and publish versions |
portfolios:read | default | List and view user portfolios, poll operations |
portfolios:write | standard | Start, stop, and trigger rebalances |
portfolios:withdraw | standard | Prepare and submit user-signed withdrawal authorizations |
enroll:write | standard | Enroll new users (create vaults + strategy mirror) |
- default — granted to every new key at issuance.
- standard — enabled per-integrator on request. Contact
[email protected]to upgrade. - restricted — gated behind a commercial agreement.
GET /v2/scopes (no auth required). To see what
your specific key has, call GET /v2/whoami.
Identifiers (CAIP)
All on-chain identifiers use CAIP so the same request shape works on every supported chain. Never send bare hex addresses — they will be rejected at the route boundary.| Identifier | Form | When to use |
|---|---|---|
| End-user wallet (EOA) | Chain-agnostic CAIP-10: eip155:0:0x<addr> | Owner addresses in enrollment and portfolio reads. The same EOA works on every EIP-155 chain, so the chain reference is 0 per CAIP-10 §Abstract Account Addresses. |
| Vault / smart-contract account | Chain-bound CAIP-10: eip155:<chainId>:0x<addr> | Vaults, session-key agents, withdrawal recipients. The contract exists only at that (chain, address) tuple. |
| Asset (ERC-20) | CAIP-19: eip155:<chainId>/erc20:0x<addr> | Strategy allocations, withdrawal assets. |
| Asset (SPL, Solana) | CAIP-19: solana:<ref>/spl:<mint> | Same surface, Solana-native assets. |
Supported Chains
Chain availability is deployment-configured. The canonical list for a given deployment is whicheverJSON_RPC_URL_<chainId> env vars are set on the
server. Production today supports:
| Chain | ID |
|---|---|
| Ethereum Mainnet | 1 |
| Optimism | 10 |
| Polygon | 137 |
| Base | 8453 |
| Arbitrum | 42161 |
| Linea | 59144 |
| Blast | 81457 |
| Plume | 98866 |
400 with the exact allowed list in the error details.
Monetary Values
All money is expressed as decimal strings, never numbers, to avoid IEEE 754 precision loss.| Field | Format | Example |
|---|---|---|
totalValueUsd, valueUsd | 6 decimal places | "1500.500000" |
balance | Full precision, trailing zeros trimmed | "14562044.3028598485" |
balanceRaw, amountRaw | Integer string, no decimal, no scientific notation | "14562044302859848500000000" |
priceUsd | 6 decimal places | "1.000000" |
weight | Percent with up to 2 decimal places | "60" or "33.33" |
decimals | Integer (the only numeric financial field) | 6 |
balanceRaw from
GET /v2/portfolios/{portfolioId}/positions and echo it as amountRaw —
do not re-derive from balance.
Pagination
Cursor-based (keyset) pagination on(createdAt, id).
limitquery param — min 1, max 200, default 50.cursorquery param — opaque base64url string.nextCursorresponse field —nullwhen there are no more pages.
nextCursor
verbatim.
Idempotency
Write endpoints that produce irreversible side effects accept an idempotency anchor supplied by the caller. Replays with the same anchor return the original response; replays with a conflicting body return409 API_008.
| Route | Anchor | Sourced from |
|---|---|---|
POST /v2/enroll | flowId | POST /v2/enroll/signature response |
POST /v2/portfolios/{id}/withdraw | message.nonce | POST /v2/portfolios/{id}/withdraw/signature response |
Async Operations
Write endpoints that dispatch onchain work (e.g. withdraw) return202 with
an operationId. Poll
GET /v2/portfolios/{portfolioId}/operations/{operationId} at 2–5s
intervals until the state reaches completed, failed, or cancelled.
Error Codes
All v2 error codes use theAPI_XXX format. The range prefix signals the
category; specific codes below are the ones you are likely to see from v2
endpoints.
| Code | HTTP | Meaning |
|---|---|---|
API_006 | 404 | Resource not found |
API_007 | 409 | Idempotency replay in progress — retry after a short wait |
API_008 | 409 | Idempotency key conflict — same anchor, different body |
API_101 | 401 | x-api-key header missing |
API_102 | 401 | API key invalid |
API_104 | 403 | Missing required scope |
API_200 | 404 | Portfolio not found or not owned by tenant |
API_202 | 409 | Portfolio already exists for this (strategyId, ownerAccountId) |
API_210 | 400 | Insufficient balance for withdrawal |
API_211 | 400 | Invalid recipient |
API_212 | 400 | Duplicate assetId in withdrawal |
API_213 | 400 | Withdrawal chain mismatch (recipient vs asset chain) |
API_214 | 400 | Withdrawal message.portfolioId mismatches the path param |
API_215 | 400 | Portfolio has no vault on the recipient’s chain |
API_216 | 400 | Withdrawal authorization expired (past message.expiresAt) |
API_217 | 400 | Withdrawal signature does not recover to the portfolio owner |
API_400 | 400 | Request validation failed — see details[] |
API_506 | 503 | Signature verifier temporarily unavailable — safe to retry |
API_600 | 500 | Internal server error |
Tracing and Support
When reporting an issue, include theX-Correlation-Id header from the
failing response. It lets us join logs across services without asking you to
reproduce.
Next Steps
- Two-stage enrollment — the signable-message round trip that creates a portfolio
- Two-stage withdrawal — EIP-712 authorization flow for user-signed withdrawals
- Idempotency — retry rules and the three 409 sub-codes
- CAIP identifiers — chain-agnostic vs chain-bound, worked examples