Public API
Base URL: https://<api host>
The API serves public data to anyone and builds transactions for signed-in wallets. Responses are JSON with a data field and a meta field (requestId, asOf, slot, mode). Amounts are decimal integer strings: USDC has 6 decimals, shares 9, weights and fees are in basis points.
Public reads
| Method | Path | Returns |
|---|---|---|
| GET | /v1/platform | Total AUM, platform cap, live strategies, epochs verified, commitment chain head |
| GET | /v1/deployment | Cluster, genesis hash, program IDs, USDC mint, the executor's key and its current attestation |
| GET | /v1/protocol | The protocol fee account, the $UNSEEN mint, fees awaiting the next buyback, total USDC spent and $UNSEEN burned, the last buyback's signature |
| GET | /v1/strategies | Strategies with terms, status and attested stats |
| GET | /v1/strategies/:strategyId | One strategy |
| GET | /v1/strategies/:strategyId/stats | Hourly attested return, drawdown and exposure band |
| GET | /v1/strategies/:strategyId/epochs | Epochs with NAV and state |
| GET | /v1/strategies/:strategyId/revealed-trades | Revealed trades with their openings |
| GET | /v1/revealed-executions/:executionId | One revealed trade |
| GET | /v1/revealed-strategies/:strategyId/nav | NAV rebuilt from revealed data |
| GET | /v1/executions | Every execution, unattributed: market, side, notional, slot, exec account, commitment |
| GET | /v1/guardian/outcomes | Pauses, challenge resolutions and voided epochs |
| GET | /v1/events | Server-sent events: execution.observed, platform.updated, heartbeats |
Lists take limit and cursor; the response carries the next cursor.
curl https://<api host>/v1/executions?limit=5
Sign in
POST /v1/auth/challenge { "wallet": "<address>" }
POST /v1/auth/verify { "wallet": "<address>", "challengeId": "…", "signature": "<base64>" }
Sign the challenge's message (UTF-8) with the wallet; the signature is the raw 64-byte Ed25519 signature in base64. verify returns an accessToken; send it as Authorization: Bearer <token>.
Your account
| Method | Path | |
|---|---|---|
| GET | /v1/me | Your wallet and roles |
| GET | /v1/me/portfolio | Holdings, pending requests, claimable amounts |
| GET | /v1/me/eligibility/:strategyId | Whether you can deposit, and what is missing |
Transactions
Each action returns a transaction plan: unsigned Solana transaction bytes (base64), its blockhash and expiry. Sign the exact bytes with the wallet, submit them, and poll the plan until it is confirmed.
| Method | Path | Body |
|---|---|---|
| POST | /v1/transactions/deposit | { strategyId, amountUsdc } |
| POST | /v1/transactions/withdrawal | { strategyId, shares } |
| POST | /v1/transactions/claim-withdrawal | { strategyId } |
| POST | /v1/transactions/cancel-request | { strategyId } |
| POST | /v1/transactions/create-strategy | leaders: name, kind, stake, signal key, fee, delay, markets, leverage, drawdown stop |
| POST | /v1/transactions/signal-key | leaders: { strategyId, signalKey, action: "register" | "rotate" } |
| POST | /v1/transactions/claim-leader-fee | leaders: { strategyId } |
| POST | /v1/transactions/:id/submit | { signedTransaction } |
| GET | /v1/transactions/:id | The plan and its state |
Every write takes an Idempotency-Key header. Keep the key when you retry the same request; a new request needs a new key.
Signals
| Method | Path | Body |
|---|---|---|
| POST | /v1/signals/sealed | leaders: a sealed envelope { version, ephemeralPublicKey, nonce, ciphertext } from the SDK; returns the executor's signed admission receipt |
| POST | /v1/leader/strategies/:strategyId/console | leaders: a one-minute proof signed by the leader's wallet; returns the private console |
The API relays the envelope to the executor without being able to read it. Build envelopes with the SDK.
Applications
| Method | Path | Body |
|---|---|---|
| POST | /v1/leader-applications | { name, leaderKind, markets, bookSize, wallet?, contact } |
| POST | /v1/follower-access-requests | { wallet, contact?, notUSPerson: true, notInEU: true } |
Errors
Errors carry { "error": { "code", "message", "retryable", "details" } }. details maps field names to messages for form errors. Retry only when retryable is true, with the same idempotency key.
The contract package
@unseen/contract types every route and response, and includes the client, commitment verification and the leader-console proof helper:
import { createUnseenClient } from '@unseen/contract'
const api = createUnseenClient({ baseUrl: 'https://<api host>' })
const { data } = await api.request('strategies', { query: { limit: '20' } })