https://apimonaco.xyz; public market data needs no authentication, and trading, account, deposit and withdrawal calls need a Monaco client ID and a wallet-authorized session key.
REST client
monaco-sdk is generated from Monaco’s OpenAPI spec and covers the REST API surface.
Add Dependencies
Market Data
No authentication is required to read trading pairs.Authenticate
Monaco authenticates with a wallet-authorized ed25519 session key. Generate a keypair, have the wallet sign a challenge that commits to it, then sign every authenticated request with the session key.Sign Authenticated Requests
On native targets, the SDK can sign session-authenticated requests automatically:Client::new and Client::new_authenticated send User-Agent: monaco-sdk-rust/<version>. Client::new_with_client uses the reqwest::Client you pass unchanged, so set a User-Agent on it (reqwest::Client::builder().user_agent(...)): Monaco’s API edge rejects requests without one with 403.
Use your registered session signing key as session_key. RFC 9421 signing is opt-in and requires a server that supports it. Use RequestSigning::Legacy for existing servers. The authenticated client disables redirects; public operations remain unsigned. See HTTP message signatures for the signing profile and migration steps.
The manual example below uses legacy signing. Legacy authenticated REST requests carry X-Monaco-PublicKey, X-Monaco-Timestamp, and X-Monaco-Signature. The signature covers:
?.
Place a Limit Order
The raw generated client keepsidempotency_key optional and does not generate it. Set it yourself (idempotencyKey in JSON) before serialization and signing. Retain the prepared payload and key; persist them before sending if recovery must survive a process restart.
create unchanged and sign again with a fresh timestamp. Use a distinct key for each batch-create item, generated before signing the batch. The key protects the original submission for 15 minutes after acceptance; retries do not extend that window. Do not retry an unresolved submission after expiry. This example does not retry automatically.
A GTC order rests on the book until filled or cancelled. See Order Management for other time-in-force options.
Cancel an Order
gRPC client
monaco-grpc-sdk is generated from Monaco’s protobuf module on the Buf Schema Registry.
Add Dependencies
Optional serde feature
Turn on the serde feature to derive serde::Serialize and serde::Deserialize on every generated message and enum, in the same JSON shape the REST API (/api/v1/...) sends and accepts:
- Field names are camelCase, and the REST snake_case aliases are accepted on input.
- The uint64 lease and quote fences (
generation,quoteRevision,expectedGeneration) are decimal strings. - An unset optional field is omitted where REST omits it and serialized as
nullelsewhere (an unsetPosition.opened_atserializes as"openedAt": null). A key the server omits reads as unset. - The request types that REST refuses unknown fields on refuse them here too.
Connect and List Pairs
The gRPC service is exposed on the same host as the REST API. Connect to the host on port443; the load balancer routes gRPC method paths such as /monaco.api.* to Monaco’s gRPC API.
Authenticate requests
Market data is public. Trading and account RPCs are tokenless: sign every request with the ed25519 session key you registered throughAuthService.Challenge/Verify, and attach the signature as metadata. The
server verifies it against your stored public key.
The signature covers the canonical string POST\n<method-path>\n<timestamp-ms>\nSHA256(request bytes),
where the request bytes are the prost-encoded message — the same bytes tonic
sends — so hash msg.encode_to_vec() and bind the full leading-slash method
path. Add ed25519-dalek, prost, sha2, and hex alongside the SDK.
The raw generated client keeps idempotency_key optional and does not generate it. Create and retain the key before protobuf encoding or signing. Persist the prepared message and key before sending if recovery must survive a process restart.
create.clone() with a fresh timestamp; keep the same payload and key. Give every batch-create item a distinct key before encoding and signing the batch. Protection lasts 15 minutes after acceptance and retries do not extend it. Do not retry an unresolved submission after expiry. This example does not retry automatically.
Each call re-signs with a fresh timestamp and body hash, so signatures are never
reused. A UNAUTHENTICATED status on a previously working call means the session
expired or was revoked — re-run challenge/verify and retry; do not loop against a
persistent UNAUTHENTICATED. The authenticated gRPC quickstart
covers the metadata, error handling, and golden signing vectors
you can check a Rust signer against.
Release Channels
Release candidates and dev snapshots use a SemVer pre-release suffix, so a default
cargo add monaco-grpc-sdk ignores them. Pin explicitly to opt in:

