Switchboard: the customisable oracle, queues, jobs, and aggregators
Switchboard is Solana's customisable oracle network. Queues, oracles, jobs, aggregators, randomness — here's the on-chain shape and how to wire each up.
devrels.xyz/a/79short linkSwitchboard is Solana's other major oracle. Pyth handles a curated list of canonical asset prices; Switchboard lets you publish a feed of anything by writing a job definition. Sports scores, custom CEX prices, weather data, election results, on-chain randomness — same primitive across all of them.
The four account types
Queue → the oracle network that processes update requests
Oracle → a participant in a queue, runs the off-chain worker
Aggregator → the on-chain feed account holding the latest aggregated value
Job → a definition of how to fetch + transform raw data
(referenced by Aggregators; each Aggregator can have N Jobs)
Crank → a permissionless turn-the-handle account that triggers
due updatesSwitchboard's permissionless design: anyone can create an Aggregator with their own Jobs, pay into a queue, and start receiving updates from the queue's oracles. The on-chain program enforces validation; the off-chain oracles compete to publish.
What a Job looks like
Jobs are serialized protobuf describing a pipeline of tasks: HTTP fetch → JSON path extract → math transform. Each oracle in the queue runs the same job, posts its result, and the aggregator takes the median (with outlier rejection).
{
"tasks": [
{
"httpTask": {
"url": "https://api.coingecko.com/api/v3/coins/markets?vs_currency=usd&ids=solana"
}
},
{
"jsonParseTask": {
"path": "$[0].current_price"
}
}
]
}That's the entire definition for a SOL/USD feed. Switch solana to bitcoin and you have BTC/USD. Replace the URL with a sports API and JSON path with a score field, and you have a live game score feed.
The Aggregator account
pub struct AggregatorAccountData {
pub name: [u8; 32],
pub metadata: [u8; 128],
pub author_wallet: Pubkey,
pub queue_pubkey: Pubkey, // which queue this feed lives in
pub oracle_request_batch_size: u32, // how many oracles must respond
pub min_oracle_results: u32, // minimum valid responses for an update
pub min_job_results: u32,
pub min_update_delay_seconds: u32, // throttle — minimum seconds between updates
pub start_after: i64,
pub variance_threshold: SwitchboardDecimal, // % change required to trigger an update
pub force_report_period: i64,
pub expiration: i64,
pub consecutive_failure_count: u64,
pub next_allowed_update_time: i64,
pub is_locked: bool,
pub crank_pubkey: Pubkey,
pub latest_confirmed_round: AggregatorRound {
num_success: u32,
num_error: u32,
is_closed: bool,
round_open_slot: u64,
round_open_timestamp: i64,
result: SwitchboardDecimal, // the actual aggregated value
std_deviation: SwitchboardDecimal,
min_response: SwitchboardDecimal,
max_response: SwitchboardDecimal,
oracle_pubkeys_data: [Pubkey; 16],
medians_data: [SwitchboardDecimal; 16],
current_payout: [i64; 16],
errors_fulfilled: [bool; 16],
medians_fulfilled: [bool; 16],
},
pub current_round: AggregatorRound,
pub job_pubkeys_data: [Pubkey; 16],
pub job_hashes: [Hash; 16],
pub job_pubkeys_size: u32,
pub jobs_checksum: [u8; 32],
pub authority: Pubkey,
pub history_buffer: Pubkey, // optional ring-buffer of past results
pub previous_confirmed_round_result: SwitchboardDecimal,
pub previous_confirmed_round_slot: u64,
pub disable_crank: bool,
pub job_weights: [u8; 16],
pub creation_timestamp: i64,
pub _ebuf: [u8; 130],
}Reading a Switchboard feed
use anchor_lang::prelude::*;
use switchboard_solana::AggregatorAccountData;
#[derive(Accounts)]
pub struct UseSwitchboard<'info> {
/// CHECK: validated by Switchboard
pub aggregator: AccountLoader<'info, AggregatorAccountData>,
}
pub fn read_price(ctx: Context<UseSwitchboard>) -> Result<()> {
let agg = ctx.accounts.aggregator.load()?;
// Returns SwitchboardDecimal { mantissa: i128, scale: u32 }
let result = agg.get_result()?;
let price_f64: f64 = result.try_into()?;
// Reject if stale (>5 minutes old)
agg.check_staleness(Clock::get()?.unix_timestamp, 300)?;
// Reject if confidence too wide (variance > 1%)
agg.check_confidence_interval(SwitchboardDecimal::from_f64(0.01))?;
msg!("price: {}", price_f64);
Ok(())
}Switchboard randomness (VRF)
Beyond price feeds, Switchboard publishes a verifiable random function — on-chain randomness backed by an oracle's cryptographic proof. Useful for games, fair draws, mint ordering.
use switchboard_solana::VrfAccountData;
pub fn use_random(ctx: Context<UseVrf>) -> Result<()> {
let vrf = ctx.accounts.vrf_account.load()?;
let randomness = vrf.get_result()?; // [u8; 32]
// Use first 8 bytes as u64
let n = u64::from_le_bytes(randomness[..8].try_into().unwrap());
let dice = (n % 6) + 1;
msg!("rolled: {}", dice);
Ok(())
}Switchboard vs Pyth
Pyth Switchboard
─────────────────────────────────────────────────────────────────
Model Push (account) Push (account)
Custom feeds No — curated symbols Yes — any job definition
Setup cost Free (read the account) Pay queue lease + per-update
Update cadence Every slot Configurable (variance + delay)
Confidence First-class (1-sigma) Variance + std deviation
Randomness No Yes (VRF)
Best for Canonical asset prices Custom data, long-tail symbolsReferences
Pyth for canonical asset prices, Switchboard for everything else. Both run in production on every major Solana DeFi protocol's read path.
Keep reading
Collector Crypt has a marketplace program (non-custodial, delegation-based), a gacha program with RFC 9381 VRF for provably fair pack opens, and a shipping API for physical card vault operations. API partnerships are rolling out. Here's what's available to build on today.
TxODDS publishes Merkle roots of every data packet to Solana, making sports data tamper-evident and independently verifiable. Developers subscribe on-chain using TxL tokens (USDT → TxL → program subscription → API token), then query live odds, scores, and settlement feeds. Free tier covers the 2026 World Cup.
ProofNetwork is a serverless JavaScript runtime where every execution is proof-backed. Its MCP server doesn't run contracts — it serves the documentation an agent needs to write them: four tools over Streamable HTTP, two skills, real VRF and key-storage APIs. A look at the docs-as-MCP pattern.
Get new articles in your inbox
Technical deep-dives on Solana tooling, infrastructure, and ecosystem. No noise.
