API
The Flint perps exchange exposes these gRPC packages:
| Package | Audience | Auth | Services |
|---|---|---|---|
flint.margin.user.v1 | Traders, frontends, analytics, keepers | None — public | PerpMarketService, MarketDataService, OrderService, FundingService, AccountService, MarketService, RiskService, SponsorshipService |
flint.margin.user.v1.notifications | Account owners | Owner bearer session | NotificationService |
flint.margin.maker.v1 | Market makers | Bearer session (see below); NodeService is public | AuthService, MakerService, TxService, SessionService, SpreadProtectService, NodeService, EscalationService |
These packages are served by the same Flint server processes that
serve the spot API, on the same two listeners. Public margin services
live on the public host. TxService, SessionService,
SpreadProtectService, and EscalationService live only on the
authed (maker) host; AuthService, MakerService, and
NodeService are on both. See Endpoints.
NotificationService lives on the public host and authenticates every method.
It is unavailable until the server enables notifications.
Field-level detail for every message, enum, and RPC is generated from the proto: User API reference and Maker API reference.
Every service speaks vanilla gRPC and gRPC-Web on the same URL. Pick whichever transport fits your stack — see Protocols & transports.
Writes happen on-chain
There is no "place order" or "deposit" RPC. Every trading state change — deposits, withdrawals, perp orders, maker quotes, liquidations — is a Solana transaction against the Flint margin program. The API helps you build, price, submit, and observe those transactions:
- Build instructions with the on-chain clients — see On-chain clients.
- Dry-run them with
OrderService.PreviewOrder,AccountService.SimulateAction, orAccountService.GetActionLimits. - Submit them yourself over Solana RPC, through
SponsorshipService.SponsorTransaction(Flint pays the fee), or — for makers — throughTxService.SubmitTx.
Email notification settings are off-chain writes. The notification service exposes
GetSettings, RequestEmailVerification, VerifyEmail, and DisableEmail.
Public fill history and client-local read/dismiss state power the notification bell
independently of email delivery. See the notification SDK guide.
flint.margin.user.v1 — public
No credentials. Every RPC is keyed for rate limiting by client IP.
Perp markets — PerpMarketService
| RPC | Kind | What it does |
|---|---|---|
ListPerpMarkets | unary | Perp contract catalog: symbol, assets, tick/lot size, margin rates and tiers, open-interest cap. Filtering by statuses and page_token is not supported yet. |
GetPerpMarket | unary | One perp contract by PerpId. |
GetMarketStats | unary | Mark, index, oracle, and last-trade prices, 24 h volume and change, open interest, funding, and top of book for one or more perps. |
GetVolumeBreakdown | unary | Per-perp volume over rolling windows. |
GetVolumeSeries | unary | Bucketed volume time series. |
SubscribeMarketStats | stream | Live market stats. Not yet served. |
Order books, trades, candles — MarketDataService
| RPC | Kind | What it does |
|---|---|---|
GetOrderBook | unary | L2 book snapshot for one perp (depth ≤ 100). |
SubscribeOrderBook | stream | Snapshot, then sequenced deltas. A delta replaces the size at a price; zero deletes the level. |
GetTrades | unary | Archived public trades for a time range. |
SubscribeTrades | stream | Live public trades. Not yet served. |
GetCandles | unary | OHLCV candles. Only the trade price source is archived; mark and index sources return UNIMPLEMENTED. |
SubscribeCandles | stream | Live candle updates. |
Orders — OrderService
| RPC | Kind | What it does |
|---|---|---|
PreviewOrder | unary | Simulates a perp order against the current book and the account's margin without signing or submitting it. |
ListOrders | unary | An account's orders. Not yet served. |
GetOrder | unary | One order. Not yet served. |
SubscribeOrders | stream | Live order updates. Not yet served. |
Funding — FundingService
| RPC | Kind | What it does |
|---|---|---|
GetFundingRates | unary | Current funding rate per perp. rate is a fraction per interval_seconds; positive means longs pay shorts. |
SubscribeFundingRates | stream | Live funding-rate updates. |
GetFundingRateHistory | unary | Historical funding rates. Not yet served. |
GetFundingPayments | unary | An account's funding payments. Not yet served. |
SubscribeFundingPayments | stream | Live funding payments. Not yet served. |
Trader accounts — AccountService
| RPC | Kind | What it does |
|---|---|---|
GetAccount | unary | One trader account: spot collateral legs, perp positions, and cross-margin health. |
SubscribeAccount | stream | Snapshot on subscribe, then account and valuation updates (valuation-driven updates may be coalesced). |
BatchGetAccounts | unary | Several accounts by TraderId. |
SubscribeAccounts | stream | Live updates for a set of accounts; each message replaces the selected set. |
ListAccounts | unary | Trader accounts an authority (base58 pubkey) owns or is a delegate on. |
ListDelegates | unary | Wallet and passkey delegates registered on an account. |
GetActionLimits | unary | Max deposit / withdraw / lend / redeem / borrow / repay per collateral market, with the binding constraint. |
SimulateAction | unary | Simulates a collateral action (deposit, withdraw, lend, redeem, borrow, repay) and returns the post-state, without signing or submitting. Rate limited as a simulation. |
GetFills | unary | An account's perp fills. |
SubscribeFills | stream | Live perp fills for an account. |
GetTradingFees | unary | Fee rates that apply to an account. |
GetTradingLimits | unary | Per-account trading limits. Not yet served. |
GetPositionHistory | unary | Perp position history. Not yet served. |
GetActivity | unary | Archived collateral activity — deposits, withdrawals, lend/redeem, borrow/repay, liquidations, loss socialization. Needs the history archive; observed activity may have gaps and is not proof of settlement. |
SubscribeActivity | stream | Live activity only. Reconcile with GetActivity after a disconnect. |
GetAccountHistory | unary | Archived account value (NAV) and PnL history. |
GetInterestHistory | unary | Archived interest accrued on collateral legs. |
GetRankedAccounts | unary | Leaderboard ranking by metric and timeframe. |
RenameAccount | unary | Sets an account's display label. The request carries an ed25519 signature from the controlling key. |
Collateral markets — MarketService
Collateral is held in cross-margin spot markets that also lend and borrow.
| RPC | Kind | What it does |
|---|---|---|
ListMarkets | unary | Every collateral market: asset metadata (mint, decimals), collateral weight, borrow margin rates, oracle price, APRs, utilisation, caps, flags, and oracle state. |
GetMarket | unary | One collateral market by SpotId. |
SubscribeMarkets | stream | One snapshot per market, then updates. |
GetMarketHistory | unary | Archived APR, utilisation, supply, and price history, bucketed. |
Risk views — RiskService
| RPC | Kind | What it does |
|---|---|---|
GetMarketOverview | unary | Protocol- and market-level risk aggregates, including liquidation shock tables. |
SimulateAccountRisk | unary | Re-values an account under hypothetical price shocks. Rate limited as a simulation. |
GetInsuranceFund | unary | Insurance-fund balances. Rate limited as a simulation. |
ListAccountsAtRisk | unary | Accounts ordered by health ratio, lowest first. |
SubscribeAccountsAtRisk | stream | Full snapshot first, then deltas. |
ListLargestAccounts | unary | Accounts ordered by gross supplied assets. |
Fee sponsorship — SponsorshipService
Flint can pay the network fee for margin transactions. The sponsor is fee payer only; the transaction may invoke only the margin program, the compute-budget program, and the secp256r1 precompile.
| RPC | Kind | What it does |
|---|---|---|
GetSponsorshipPubkey | unary | Base58 fee-payer key to put in the transaction's fee-payer slot. UNAVAILABLE when sponsorship isn't configured. |
SponsorTransaction | unary | Takes a wire-format VersionedTransaction with every signature except the sponsor's, co-signs, submits, and returns the signature after confirmation. Rate limited as a transaction. |
flint.margin.maker.v1 — authenticated
Sessions — AuthService
| RPC | Kind | What it does |
|---|---|---|
Challenge | unary | Issues a single-use nonce (30 s TTL) for a base58 public key. |
Authenticate | unary | Verifies a signature over FLINT-MARGIN-AUTH-V1: ‖ nonce and mints a bearer session (6 h TTL) scoped to one trader account. |
Revoke | unary | Revokes a session token. |
The signing key must be the owner of a trader account or an
active TRADE- or QUOTE-scoped delegate on it. Authenticate
returns every
trader_ids the key controls and selects one (trader_id in the
request, or the lowest controlled id). The domain prefix differs from
the spot API's, so a signed margin challenge can never be replayed as
a spot login.
AuthService is on both hosts. Authenticate against the authed
host if you also need TxService.
Maker reads — MakerService
Every MakerService RPC is scoped to the session's selected trader
account.
| RPC | Kind | What it does |
|---|---|---|
SubscribeMarketSnapshots | stream | Perp book snapshots annotated with your best resting quotes. |
GetFills | unary | Your maker fills, with markouts. |
SubscribeFills | stream | Live maker fills. |
GetVolumeBreakdown | unary | Your maker volume per perp over rolling windows. |
GetVolumeSeries | unary | Your maker volume as a time series. |
GetMarkoutSummary | unary | Whole-window markout summary, without GetFills' page limit. |
GetQuotingState | unary | Latest observed state of your on-chain quoting entries, including sequence numbers. |
SubscribeQuotes | stream | Live quoting updates, filtered by perp and quoter key. |
ListRecentQuotes | unary | Archived quoting updates for a time range, paged by cursor. |
GetQuote | unary | One quoting update by signature, instruction index, and update index. |
GetStats | unary | Your fill, transaction, oracle-update, and quote-update rates over 1 s, 1 m, and 5 m. |
GetActivity | unary | Archived actions by your trader account, newest first (at most 1000). |
GetDecodedTransaction | unary | One of your transactions by signature, decoded into Flint events. |
ListQuotingAuthorities | unary | Keys that opened sessions for your trader: open sessions, best RTT, regions, SDKs, last submit and landing, SOL balance. |
ListQuoterSessions | unary | Live and recent sessions, most recently seen first, with IP, SDK, RTT, and clock drift. |
GetSdkCredentials | unary | The read-only Kellnr registry token for the Rust SDK. Needs an organization (see Authentication). |
GetFills, GetVolumeBreakdown, GetVolumeSeries,
GetMarkoutSummary, ListRecentQuotes, GetQuote, GetActivity,
GetDecodedTransaction, and GetSdkCredentials read the history
archive and return FAILED_PRECONDITION on a deployment without it.
There is no maker balance RPC. Read collateral, positions, and health
with the public AccountService.GetAccount or SubscribeAccount.
Transactions — TxService (authed host only)
| RPC | Kind | What it does |
|---|---|---|
SubmitTx | unary | Submits a fully signed legacy, v0 or v1 transaction. The session's key must be one of its required signers. Returns on acceptance, not confirmation. |
SubscribeTxStatus | stream | Ack / landed / failed transitions for every transaction submitted under this session's trader. |
SubscribeBlockhash | stream | Recent blockhash, last_valid_block_height, and a priority-fee recommendation. |
SubscribeSlots | stream | Slot ticks. |
SubscribeLeaders | stream | Upcoming leader schedule with TPU addresses. |
Session heartbeat — SessionService (authed host only)
| RPC | Kind | What it does |
|---|---|---|
Session | bidi stream | The server sends a Ping every 30 s; reply at once with a Pong echoing its seq. Feeds the RTT and clock drift that ListQuoterSessions reports. |
Session is bidirectional, so it needs HTTP/2 gRPC; gRPC-Web can't
carry it. The Rust maker client answers it for you.
Spread protection — SpreadProtectService (authed host only)
| RPC | Kind | What it does |
|---|---|---|
SubscribeSpreadProtect | stream | A reset_state with the baseline default_spread_mult, then current and future widen_windows: an inclusive slot range and a spread_mult of at least 1.0. |
The feed is advisory and the same for every maker. Nothing on-chain enforces it; widen your own quotes by the highest multiplier active at the current slot.
Nodes — NodeService
Public: no session needed, on both hosts.
| RPC | Kind | What it does |
|---|---|---|
GetNodeInfo | unary | This node's build, proto revision, cluster, region, margin program id, leader proximity, and health. A node whose margin state is stale or not loaded reports itself degraded or halted. |
ListNodes | unary | Published endpoints, optionally for one cluster, with region and a current flag. Listing does not imply health. |
Escalation — EscalationService (authed host only)
| RPC | Kind | What it does |
|---|---|---|
PageTheTeam | unary | Pages Flint's on-call team with your message and returns a page id. Confirms dispatch, not response. |
Authentication
flint.margin.user.v1 and NodeService need nothing. The rest of
flint.margin.maker.v1 expects:
authorization: Bearer <session_token>
Mint the token with AuthService.Challenge → sign → Authenticate
(the Rust and
TypeScript SDKs wrap this as
AuthFlow).
| Service | Accepts |
|---|---|
MakerService (except GetSdkCredentials) | A keypair session, or a Flint organization session or organization API key (x-api-key: <key>) for an organization with perps access. |
MakerService.GetSdkCredentials, EscalationService | A keypair session whose trader belongs to an organization, or the organization credentials above. |
TxService, SessionService, SpreadProtectService | Keypair sessions only. |
URL convention
POST https://<host>/flint.margin.user.v1.<Service>/<Method>
POST https://<host>/flint.margin.maker.v1.<Service>/<Method>
Content-Type: application/grpc (gRPC binary)
application/grpc-web+proto (gRPC-Web, browsers)
No URL parameters and no versioning beyond the package name.
Wire conventions
- Money, prices, quantities, and rates are
Decimal { value: string }— for example"155.14". Never parse them as floats. See Prices, sizes, units. - Timestamps are
Timestamp { micros: uint64 }, Unix microseconds. PerpIdandSpotIdareuint32;TraderIdisuint64.- Many responses carry
DataProvenance(commitment, slot,observed_at) — observation metadata, not a claim that the node is caught up with the chain.
Rate limits
The same per-key token-bucket limiter as the spot API applies. The
key is your trader session on authenticated calls and your client IP
otherwise. Going over budget returns RESOURCE_EXHAUSTED; back off
exponentially and retry.
| Class | Applies to | Default limit |
|---|---|---|
| Reads | Every unary RPC not listed below | 50 requests/sec |
| Simulations | AccountService.SimulateAction, RiskService.SimulateAccountRisk, RiskService.GetInsuranceFund | 5 requests/sec |
| Transactions | TxService.SubmitTx, SponsorshipService.SponsorTransaction | 10 tx/sec and 300 tx/min |
| Streams | Every streaming RPC, including SessionService.Session | 100 concurrent streams |
A stream holds one slot for its lifetime rather than drawing on the per-second budget, so prefer one long-lived subscription to polling. Limits are configurable server-side.
Schema downloads
margin-user.proto— every service and message inflint.margin.user.v1, bundled into one file.margin-maker.proto— the same forflint.margin.maker.v1.margin-user.openapi.yaml(JSON) — OpenAPI 3.1 for the public user API's gRPC-Web URLs, for Postman, Insomnia, or client generators.margin-maker.openapi.yaml(JSON) — the same for the authenticated maker API.codama.json— Codama IDL for the on-chain Flint margin program. See On-chain clients.
The bundles are generated from the canonical per-file tree under
proto/flint/margin/ in the flint-protos repository.
