Skip to content
CanaryDocsAPI and SDK
  • Start
  • Use Canary
  • Build on Canary
  • Whitepaper

Start

  • What Canary is
  • Connect a wallet

Use Canary

  • Fund a bounty
  • Trade rung-event markets
  • Keep funds in a Q-Vault
  • Claim a rung
  • Fees and settlement
  • The CANARY token

Build on Canary

  • Read RungState
  • API and SDK

Reference

  • FAQ

Papers

  • Litepaper
  • Whitepaper

API and SDK

Canary's public API serves everything the app shows: rungs, bounties, markets, vaults, prices and the status feed, all indexed from the chain at finalized commitment. It is read-only. Anything that changes state is a Solana transaction your wallet signs; the API's RPC relay can carry it to the network for you.

https://API_ORIGIN

No key or account is needed.

Conventions

FormatJSON over HTTPS
Envelope{ "data": …, "meta": … }, except the status feed, which is served as is
Lists{ "items": [...], "nextCursor": "…" or null }; pass limit (1–100, default 50) and cursor
Amounts{ "asset": { "symbol": "USDC", "decimals": 6, "mint": "…", … }, "amountAtomic": "…" }: atomic units as a decimal string, so 1 USDC is "1000000"
Slots and large integersDecimal strings
TimesISO 8601, UTC
Rate limit1,200 requests per minute per client

meta.freshness says how current the answer is: the slot it was indexed at, how far behind the chain head it is, and a state of fresh, indexer-behind or rpc-unreachable. While the deployment is still being initialized, data routes answer CONFIGURATION_REQUIRED and /v1/app-config reports state: "waiting".

Endpoints

EndpointReturns
GET /v1/app-configThe deployment: cluster, program ids, USDC mint, rungs with their public parameters, the RPC relay URL, and whether the service is ready
GET /v1/programsProgram ids, upgrade authorities, the protocol constants and the buyback: its vault, the CANARY mint, the USDC spent and the CANARY burned
GET /v1/rungsEvery rung with its state, parameters, verification method, bounty and open interest
GET /v1/rungs/{rungId}One rung; rungId is Q-160, Q-192, Q-224, C-160, T-256k or T-255e
GET /v1/rungs/{rungId}/eventsThe rung's fall, once it has fallen
GET /v1/rungs/{rungId}/claim-jobsStaged claims in flight on the rung
GET /v1/claim-jobs/{jobId}One claim job and its progress
GET /v1/transcripts/{hash}A rung's parameter transcript, byte for byte
GET /v1/bountiesEvery bounty vault: balance, totals funded and paid, fees received, sponsors
GET /v1/marketsEvery market; rungId filters by target or control rung
GET /v1/markets/{marketId}One market: outcome, open interest and cap, fees, latest price
GET /v1/markets/{marketId}/pricesPrice history, read from Jupiter's price API once a minute
GET /v1/q-dateThe date the markets imply for each rung's fall
GET /v1/totalsTotals across bounties, markets and vaults
GET /v1/wallets/{wallet}/receiptsA wallet's sponsor receipts and their reclaim status
GET /v1/wallets/{wallet}/positionsA wallet's YES and NO balances
GET /v1/wallets/{wallet}/vaultsA wallet's Q-Vaults
GET /v1/vaults/{vaultId}One Q-Vault: mode, trigger, budget, balances, key status
GET /v1/vaults/{vaultId}/queued-spendsThe vault's queued Ed25519 spends and when each unlocks
GET /v1/eligibilityWhether markets are available to you
GET /v1/status-feedEvery rung's state in one document, canary.status.v1
POST /v1/rpcThe RPC relay

For example:

curl -s "https://API_ORIGIN/v1/markets?rungId=Q-160&limit=10"

Errors

Errors use the same envelope with an error object:

{ "error": { "code": "NOT_FOUND", "message": "…", "requestId": "…", "retryable": false, "details": {} }, "meta": { … } }
CodeHTTPMeaning
VALIDATION_FAILED400A parameter is missing or malformed; details.issues says which
NOT_FOUND404No such rung, market, vault or job
RATE_LIMITED429Too many requests; details.retryAfterSeconds says when to retry
FORBIDDEN403The route is not available on this deployment
UPSTREAM_UNAVAILABLE503The database or the chain could not be read; retry
CONFIGURATION_REQUIRED503The deployment has not configured something the route needs
INTERNAL_ERROR500Retry; report it if it persists

The RPC relay

POST https://API_ORIGIN/v1/rpc accepts Solana JSON-RPC and forwards it to the deployment's RPC provider. It is how the app reads accounts and sends your signed transactions without publishing an RPC key. You can point any Solana client at it:

import { Connection } from '@solana/web3.js'

const connection = new Connection('https://API_ORIGIN/v1/rpc', 'finalized')
Allowed
ReadsgetAccountInfo, getMultipleAccounts (up to 100), getBalance, getTokenAccountBalance, getTokenAccountsByOwner, getTokenSupply, getMinimumBalanceForRentExemption, getSignaturesForAddress (limit up to 20), getTransaction, getSignatureStatuses (up to 32)
ChaingetVersion, getGenesisHash, getSlot, getBlockHeight, getEpochInfo, getLatestBlockhash, isBlockhashValid, getFeeForMessage
TransactionssimulateTransaction, sendTransaction: signed, base64, at most 1,232 bytes
Limits1 to 5 requests per batch; 600 requests and 60 transactions per minute per client

The relay holds no key and cannot sign anything; it only forwards what a wallet has already signed. It has no WebSocket endpoint, so confirm transactions by polling getSignatureStatuses. For heavy use, run your own RPC endpoint; nothing in Canary depends on the relay.

Building transactions

Every Canary action is an ordinary Solana transaction against the three programs. The app builds them with TypeScript clients that prepare transactions without signing or sending them:

ClientPrepares
RungsClientFunding a bounty; a claim from your secret scalar, which never leaves your machine
MarketsClientMinting, merging and redeeming pairs
VaultTransactionClientCreating a Q-Vault and registering its key, deposits, Ed25519 spends and queues, executing queues, Falcon spends and vetoes, tripping
Falcon SDKGenerating a Falcon-512 key, saving and importing the key file, and signing vault actions offline
createCanaryClientTyped calls to every endpoint above

Each prepared transaction has an explicit compute limit, your wallet as fee payer, a recent blockhash and a distinct memo, and stays within 1,082 bytes so your wallet can add its own instructions. Send them in order and wait for each to confirm. The program ids and every account layout are in the whitepaper's appendices.

Market eligibility

Markets exclude US persons in v0. GET /v1/eligibility returns whether market actions are available:

{ "data": { "markets": { "allowed": true, "reason": "eligible-region", "countryCode": "DE" }, "source": "self-attestation" } }

Where the deployment has no location source, pass your country and an attestation: ?countryCode=DE&attestNonUs=true. This is an interface policy; the programs themselves don't check location.

PreviousRead RungStateNextFAQ

On this page

  • Conventions
  • Endpoints
  • Errors
  • The RPC relay
  • Building transactions
  • Market eligibility
Canary
AppDocsLitepaperWhitepaperHow a rung fallsMarketsQ-VaultCANARY tokenStatus feed JSON

Logical-qubit and Toffoli estimates: Roetteler, Naehrig, Svore, Lauter 2017. Scaled figures: Google Quantum AI 2026.