Install & Authenticate
Install the SDK in your language of choice, then construct a client with your seq_live_* or seq_test_* Bearer token. Token validation happens on the first request — constructing a client doesn't hit the network.
Install
[dependencies]
sequence-sdk = { path = "crates/sdk/sequence-sdk" }
tokio = { version = "1", features = ["rt-multi-thread", "macros"] }
futures-util = "0.3" # only needed for streamingThe crate is internal-only — add it as a workspace path dep (inside the monorepo) or a git dep against the private repo:
sequence-sdk = { git = "ssh://git@github.com/Bai-Funds/execution-engine.git", package = "sequence-sdk" }Construct a client
use sequence_sdk::Sequence;
let seq = Sequence::new("seq_live_…"); // production
let seq = Sequence::new("seq_test_…")
.base_url("http://localhost:50052"); // local CCThe client wraps a shared reqwest::Client with a 30s timeout and the auth header baked into default headers. Sequence is Arc-backed — clones are cheap, share it across tasks.
Token format
Two prefixes, two routing modes:
| Prefix | Mode | What it does |
|---|---|---|
seq_live_<64hex> | Live | Real fills against connected venues |
seq_test_<64hex> | Sandbox | Paper fills against the live NBBO with realistic slippage + fees. Balances + positions stay isolated from your live account |
A seq_test_* key forces sandbox routing on every order in the session, even if you don't pass a per-call sandbox flag. Mix sandbox and live in the same session by holding two clients with different keys.
Sandbox
There are two ways into sandbox routing:
// 1. Per-call — works on a seq_live_* key
seq.buy("SOL-USD", 100.0).sandbox().submit().await?;
// 2. Session-wide — log in with a seq_test_* key, no flag needed
let seq = Sequence::new("seq_test_…");
seq.buy("BTC-USD", 0.1).submit().await?; // routes to sandboxConfiguring your paper portfolio
Sandbox positions are read from the same positions_v2 table as live, so GET /v1/positions with a seq_test_* key returns whatever you've configured. To seed an explicit per-venue paper portfolio (instead of the $1B default), POST /v1/sandbox/positions:
curl -X POST https://api.sequencemkts.com/v1/sandbox/positions \
-H "Authorization: Bearer $SEQ_TEST_KEY" \
-d '{
"positions":[
{"venue":"polymarket","kind":"crypto","symbol":"USDC","qty":10000.0},
{"venue":"kalshi","kind":"fiat","symbol":"USD","qty":5000.0}
],
"replace": true
}'Full reference: API → Sandbox. Architecture: Sandbox Mode.
Health check
A free unauthenticated call to verify connectivity end-to-end before issuing real traffic:
let alive: bool = seq.health().await?;Returns true on any 2xx from /v1/health/live. Never raises — useful for liveness probes.
Error handling
Every fallible call surfaces the same error envelope. Match on HTTP status to branch:
use sequence_sdk::SequenceError;
match seq.buy("ETH-USD", 50.0).submit().await {
Ok(ok) => println!("graph_id={}", ok.graph_id),
Err(SequenceError::Api { status: 429, .. }) => backoff().await,
Err(SequenceError::Api { status: 409, message }) => kill_switch_check(&message),
Err(SequenceError::CapabilityMissing { venue, reason, .. }) => {
eprintln!("{venue}: {reason}");
}
Err(e) => return Err(e.into()),
}| Variant | When |
|---|---|
Api { status, message } | Non-2xx from CC. Code + message come from the error envelope. |
Network(reqwest::Error) | TCP / TLS / timeout. |
Deserialize(String) | Response JSON didn't match the expected type — file an SDK issue with the body. |
Validation(String) | Client-side pre-flight failed (e.g. amend() with no fields). |
CapabilityMissing { verb, venue, reason } | Verb isn't available through the selected SDK/API surface. |