Skip to content

API

Seven gRPC services in flint.spot.v1. MarketDataService, StatsService, HistoricalService, NodeService, and AuthService are public. MakerService and TxService require credentials.

ServiceAuthWhat you use it for
AuthServicenoneMint or revoke bearer session tokens.
MarketDataServicenoneStream books, fills, market snapshots; list pairs; snapshot a single book.
StatsServicenonePublic aggregate stats — summary, volume breakdown/series, asset TVLs.
HistoricalServicenoneClickHouse-backed historical fills + candles.
NodeServicenoneInspect node build/proto identity, health, region, and published endpoints.
MakerServicebearer session or org API keyPer-maker balances, fills, market snapshots, volume, and activity stats.
TxServicekeypair bearer sessionSubmit signed transactions, stream blockhash + tx status.

Compatibility notes

NodeService is available on servers built with the current proto; older deployments return gRPC UNIMPLEMENTED for its RPCs.

The LatLng type kept the same fully-qualified name (flint.spot.v1.LatLng) but moved from maker_admin/messages.proto to common.proto. Wire compatibility is unchanged, but generated source imports move with it: use common_pb2.LatLng in Python and common_pb.ts in TypeScript rather than the former maker-admin module path.

Each is fully wire-compatible with vanilla gRPC and gRPC-Web on the same URL. Pick whichever transport fits your stack — the SDKs hide the difference.

Schema

  • api.proto — bundled protobuf source covering every service in the package. Use the checked-in proto/ tree when you want a per-service slice.
  • openapi.yaml — OpenAPI 3.1 schema for the same service URLs used by gRPC-Web clients, suitable for Postman, Insomnia, Stoplight, or client-generation tools.
  • codama.jsonCodama IDL for the on-chain flint program, for generating Solana clients (@codama/*, Kinobi) that build the transactions TxService submits.

CI fails the build if these files diverge from the upstream proto (or, for the IDL, from the on-chain program repo).

URL convention

POST https://<host>/flint.spot.v1.<Service>/<Method>
Content-Type: application/grpc             (gRPC binary, hot path)
              application/grpc-web+proto   (browser-native)

No URL params, no path-based versioning beyond the package name.

Authentication

MarketDataService, StatsService, HistoricalService, NodeService, and AuthService are open. MakerService and TxService expect:

authorization: Bearer <session_token>

Mint a keypair token via AuthService.Challenge → sign → Authenticate. MakerService also accepts passwordless organization sessions and organization API keys. See the Auth flow recipe for the per-SDK helpers.

Rate limits

Every RPC passes through a per-key token-bucket limiter. The key is your maker identity on authenticated calls — the server resolves your bearer token to a maker_id, so refreshing or rotating the token keeps the same bucket — and your client IP on public calls. Going over budget returns RESOURCE_EXHAUSTED (gRPC status 8) without ever invoking the handler; back off exponentially and retry — buckets refill continuously. No Retry-After header is sent.

Default limits, applied per key:

ClassApplies toLimit
Unary readsAll unary RPCs — MarketDataService (GetBook, ListPairs), StatsService, HistoricalService, NodeService, the AuthService handshake, and MakerService reads50 requests/sec
TransactionsTxService.SubmitTx10 tx/sec and 300 tx/min (both apply)
StreamsServer-streaming RPCs (Subscribe, SubscribeFills, SubscribeBlockhash, …)100 concurrent streams

A few consequences worth knowing:

  • Buckets start full. Each refills at its steady rate but tolerates a one-second burst first — up to 50 reads or 10 transactions back-to-back before throttling kicks in.
  • Streams hold a slot, not a per-message charge. One long-lived Subscribe counts as a single connection against your 100 slots until it closes — it doesn't draw down the per-second read bucket. Prefer a single long-lived stream over re-polling GetBook, and reconnect with backoff rather than tearing down and reopening per event.
  • AuthService.RequestLoginCode adds a second limit of one code per email per minute, enforced inside the handler. For enumeration resistance the RPC always returns OK — a throttled request simply doesn't send a new code.
  • Limits are configurable server-side and can be raised per maker. High-throughput integrators who hit these ceilings should get in touch.

See Errors for the RESOURCE_EXHAUSTED mapping and Market data for polling cadence guidance.

Built on Solana