The core Rust crate for the Quicknode SDK.
This is one of four language bindings published from the same Rust core. See the project README for the polyglot overview, development setup, and release process.
Pre-1.0: While on
0.x, releases may contain breaking changes. Check the release notes before upgrading.
- Installation
- Quick Start
- Configuration
- Platform Support
- API Reference
- Error Handling
- License
cargo add quicknode-sdk
Construct the SDK once, then reach into the five sub-clients (admin, streams, webhooks, kvstore, sql). Subsequent API Reference snippets assume you have a qn handle from one of these blocks.
// Rust
use quicknode_sdk::{QuicknodeSdk, SdkFullConfig};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let qn = QuicknodeSdk::from_env()?;
let resp = qn.admin.get_endpoints(&Default::default()).await?;
println!("{} endpoints", resp.data.len());
Ok(())
}There are two ways to configure the SDK.
// Rust
let qn = QuicknodeSdk::new(&SdkFullConfig::builder().api_key("your-key").build())?;// Rust
let qn = QuicknodeSdk::from_env()?;Environment variables (prefix QN_SDK__, separator __):
| Variable | Required | Default | Description |
|---|---|---|---|
QN_SDK__API_KEY |
yes | — | Your Quicknode API key |
QN_SDK__HTTP__TIMEOUT_SECS |
no | 30 | HTTP request timeout in seconds |
QN_SDK__HTTP__POOL_MAX_IDLE_PER_HOST |
no | — | Max idle HTTP connections per host |
QN_SDK__ADMIN__BASE_URL |
no | https://api.quicknode.com/v0/ |
Override admin API base URL (HTTPS, must end with /) |
QN_SDK__STREAMS__BASE_URL |
no | https://api.quicknode.com/streams/rest/v1/ |
Override streams base URL |
QN_SDK__WEBHOOKS__BASE_URL |
no | https://api.quicknode.com/webhooks/rest/v1/ |
Override webhooks base URL |
QN_SDK__KVSTORE__BASE_URL |
no | https://api.quicknode.com/kv/rest/v1/ |
Override KV store base URL |
QN_SDK__SQL__BASE_URL |
no | https://api.quicknode.com/sql/rest/v1/ |
Override SQL Explorer base URL |
QN_SDK__HTTP__HEADERS__<NAME> |
no | — | Custom HTTP header sent on every request. Overrides SDK-managed headers (see below). |
Every outbound HTTP request includes an auto-generated User-Agent of the form:
quicknode-sdk-<language>/<sdk-version> (<os>-<arch>; <language>-<runtime-version>)
You can attach arbitrary headers via HttpConfig.headers. These headers OVERRIDE any SDK-managed header with the same name, including User-Agent, x-api-key, Accept, and Content-Type. Use this to inject correlation IDs, proxy auth, or to replace the default User-Agent. Header names are matched case-insensitively.
use std::collections::HashMap;
use quicknode_sdk::{HttpConfig, QuicknodeSdk, SdkFullConfig};
let mut headers = HashMap::new();
headers.insert("X-Correlation-Id".to_string(), "abc-123".to_string());
headers.insert("User-Agent".to_string(), "my-app/1.0".to_string()); // overrides SDK default
let qn = QuicknodeSdk::new(
&SdkFullConfig::builder()
.api_key("your-key")
.http(HttpConfig { headers: Some(headers), ..Default::default() })
.build(),
)?;quicknode-sdk is a pure-Rust source crate — it builds wherever rustc and reqwest are supported. It is regularly tested on Linux (glibc) and macOS (Apple Silicon). Windows is not tested.
If you are using one of the language bindings (quicknode-sdk on PyPI, @quicknode/sdk on npm, quicknode_sdk on RubyGems), see that package's README for the precompiled-binary platform matrix.
Snippets assume qn was already constructed via the Quick Start. Optional parameters are skipped unless showing one is needed to illustrate usage.
- Methods are
asyncand returnResult<T, SdkError>. Request structs use thebonbuilder pattern via::builder().
Accessed as qn.admin. Manages endpoints, tags, teams, billing, usage, metrics, security, and rate limits. Backed by https://api.quicknode.com/v0/.
Returns a paginated list of endpoints on the account with optional search, filters (networks, statuses, labels, tags, dedicated, flat-rate), sorting, and pagination.
Parameters (all optional): limit (i32), offset (i32), search (string), sort_by (string), sort_direction ("asc" | "desc"), networks (string[]), statuses (string[]), labels (string[]), dedicated (bool), is_flat_rate (bool), tag_ids (i32[]), tag_labels (string[]).
Returns: GetEndpointsResponse — { data: Endpoint[], pagination?: Pagination }.
// Rust
let params = GetEndpointsRequest::builder()
.limit(20)
.sort_by("created_at".to_string())
.sort_direction("desc".to_string())
.build();
let resp = qn.admin.get_endpoints(¶ms).await?;Creates a new endpoint for the given blockchain and network.
Parameters: chain (string, optional), network (string, optional).
Returns: CreateEndpointResponse with data: SingleEndpoint.
// Rust
let params = CreateEndpointRequest::builder()
.chain("ethereum".to_string())
.network("mainnet".to_string())
.build();
let resp = qn.admin.create_endpoint(¶ms).await?;Fetches a single endpoint by id, including its full security configuration and rate limits.
Parameters: id (string, required).
Returns: ShowEndpointResponse with data: SingleEndpoint.
// Rust
let resp = qn.admin.show_endpoint("ep-123").await?;Updates editable fields on an endpoint. Currently supports label.
Parameters: id (string, required); body: label (string, optional).
Returns: nothing.
// Rust
let params = UpdateEndpointRequest::builder().label("my label".to_string()).build();
qn.admin.update_endpoint("ep-123", ¶ms).await?;Archives an endpoint. The HTTP verb is DELETE but the effect is archival, not permanent deletion.
Parameters: id (string, required).
Returns: nothing.
// Rust
qn.admin.archive_endpoint("ep-123").await?;Pauses or unpauses an endpoint.
Parameters: id (string, required); body: status (string, required — "active" or "paused").
Returns: UpdateEndpointStatusResponse.
// Rust
let params = UpdateEndpointStatusRequest::builder().status("paused".to_string()).build();
qn.admin.update_endpoint_status("ep-123", ¶ms).await?;Per-endpoint tag add/remove. For account-wide tag management see Account Tags.
Tags an endpoint with the given label. Creates the tag on the account if it does not exist.
Parameters: id (string, required); body: label (string, optional).
Returns: nothing.
// Rust
let params = CreateTagRequest::builder().label("prod".to_string()).build();
qn.admin.create_tag("ep-123", ¶ms).await?;Removes a tag from a specific endpoint.
Parameters: id (endpoint id, string, required), tag_id (string, required).
Returns: nothing.
// Rust
qn.admin.delete_tag("ep-123", "42").await?;Lists all teams on the account.
Parameters: none.
Returns: ListTeamsResponse with data: TeamSummary[].
// Rust
let resp = qn.admin.list_teams().await?;Creates a new team.
Parameters: name (string, required).
Returns: CreateTeamResponse with data: CreateTeamData.
// Rust
let params = CreateTeamRequest::builder().name("Payments".to_string()).build();
let resp = qn.admin.create_team(¶ms).await?;Fetches team detail including pending invites.
Parameters: id (i64, required).
Returns: GetTeamResponse with data: TeamDetail.
// Rust
let resp = qn.admin.get_team(42).await?;Deletes a team.
Parameters: id (i64, required).
Returns: DeleteTeamResponse.
// Rust
qn.admin.delete_team(42).await?;Lists endpoints accessible to a team.
Parameters: id (i64, required).
Returns: ListTeamEndpointsResponse with data: TeamEndpoint[].
// Rust
let resp = qn.admin.list_team_endpoints(42).await?;Replaces the set of endpoints associated with a team. Pass an empty array to remove all.
Parameters: id (i64, required); body: endpoint_ids (string[], required).
Returns: UpdateTeamEndpointsResponse.
// Rust
let params = UpdateTeamEndpointsRequest::builder()
.endpoint_ids(vec!["ep-123".to_string(), "ep-456".to_string()])
.build();
qn.admin.update_team_endpoints(42, ¶ms).await?;Invites a user to a team. Existing users only need email; new users require full_name and role.
Parameters: id (i64, required); body: email (string, required), full_name (string, optional), role (string, optional — admin | viewer | billing).
Returns: InviteTeamMemberResponse.
// Rust
let params = InviteTeamMemberRequest::builder()
.email("alice@example.com".to_string())
.role("viewer".to_string())
.build();
qn.admin.invite_team_member(42, ¶ms).await?;Removes a user from a team.
Parameters: id (team id, i64, required), user_id (i64, required).
Returns: RemoveTeamMemberResponse.
// Rust
qn.admin.remove_team_member(42, 7).await?;Re-sends a pending team invitation.
Parameters: id (team id, i64, required), user_id (i64, required).
Returns: ResendTeamInviteResponse.
// Rust
qn.admin.resend_team_invite(42, 7).await?;All usage methods accept optional start_time and end_time Unix timestamps. Omit both for account-to-date totals.
Aggregate account usage for a time window.
Returns: GetUsageResponse with data: UsageData (credits_used, credits_remaining, limit, overages, start_time, end_time).
// Rust
let resp = qn.admin.get_usage(&GetUsageRequest::default()).await?;Per-endpoint usage breakdown.
Returns: GetUsageByEndpointResponse with data.endpoints: EndpointUsage[].
// Rust
let resp = qn.admin.get_usage_by_endpoint(&GetUsageRequest::default()).await?;Per-RPC-method usage breakdown.
Returns: GetUsageByMethodResponse with data.methods: MethodUsage[].
// Rust
let resp = qn.admin.get_usage_by_method(&GetUsageRequest::default()).await?;Per-chain usage breakdown.
Returns: GetUsageByChainResponse with data.chains: ChainUsage[].
// Rust
let resp = qn.admin.get_usage_by_chain(&GetUsageRequest::default()).await?;Per-tag usage breakdown.
Returns: GetUsageByTagResponse with data.tags: TagUsage[].
// Rust
let resp = qn.admin.get_usage_by_tag(&GetUsageRequest::default()).await?;Fetches a page of request logs for an endpoint. Set include_details=true for full request/response payloads (truncated at 2 KB each).
Parameters: id (endpoint id, required); body: from (string timestamp, required), to (string timestamp, required), include_details (bool, optional), limit (i32, optional), next_at (string cursor, optional).
Returns: GetEndpointLogsResponse — { data: EndpointLog[], next_at?: string }.
// Rust
let params = GetEndpointLogsRequest::builder()
.from("2026-04-01T00:00:00Z".to_string())
.to("2026-04-02T00:00:00Z".to_string())
.limit(100)
.build();
let resp = qn.admin.get_endpoint_logs("ep-123", ¶ms).await?;Returns the full request/response payloads for a single log entry.
Parameters: id (endpoint id, required), request_id (log request uuid, required).
Returns: GetLogDetailsResponse with data: LogDetails.
// Rust
let resp = qn.admin.get_log_details("ep-123", "req-abc").await?;Returns the full security configuration for an endpoint: tokens, JWTs, referrers, domain masks, IPs, request filters, and their per-feature toggles.
Parameters: id (string, required).
Returns: GetEndpointSecurityResponse with data: EndpointSecurity.
// Rust
let resp = qn.admin.get_endpoint_security("ep-123").await?;Returns the list of security features and their enabled state for an endpoint.
Parameters: id (string, required).
Returns: GetSecurityOptionsResponse with data: SecurityOption[].
// Rust
let resp = qn.admin.get_security_options("ep-123").await?;Enables or disables individual security features. Each field accepts "enabled" or "disabled".
Parameters: id (string, required); options: SecurityOptionsUpdate (tokens, referrers, jwts, ips, domain_masks, hsts, cors, request_filters, ip_custom_header).
Returns: UpdateSecurityOptionsResponse with updated SecurityOption[].
// Rust
let options = SecurityOptionsUpdate::builder()
.tokens("enabled".to_string())
.jwts("disabled".to_string())
.build();
let params = UpdateSecurityOptionsRequest { options };
qn.admin.update_security_options("ep-123", ¶ms).await?;Generates a new auth token on an endpoint.
Parameters: id (endpoint id, required).
Returns: nothing.
// Rust
qn.admin.create_token("ep-123").await?;Revokes a token on an endpoint.
Parameters: id (endpoint id, required), token_id (string, required).
Returns: nothing.
// Rust
qn.admin.delete_token("ep-123", "tok-1").await?;Whitelists a referrer URL or domain on an endpoint.
Parameters: id (endpoint id, required); body: referrer (string, required).
Returns: nothing.
// Rust
let params = CreateReferrerRequest::builder().referrer("example.com".to_string()).build();
qn.admin.create_referrer("ep-123", ¶ms).await?;Removes a referrer from the whitelist.
Parameters: id (endpoint id, required), referrer_id (string, required).
Returns: nothing.
// Rust
qn.admin.delete_referrer("ep-123", "ref-1").await?;Whitelists an IP address on an endpoint.
Parameters: id (endpoint id, required); body: ip (string, required).
Returns: nothing.
// Rust
let params = CreateIpRequest::builder().ip("198.51.100.7".to_string()).build();
qn.admin.create_ip("ep-123", ¶ms).await?;Removes an IP from the whitelist.
Parameters: id (endpoint id, required), ip_id (string, required).
Returns: DeleteBoolResponse.
// Rust
qn.admin.delete_ip("ep-123", "ip-1").await?;Adds a custom domain mask to an endpoint.
Parameters: id (endpoint id, required); body: domain_mask (string, optional).
Returns: nothing.
// Rust
let params = CreateDomainMaskRequest::builder()
.domain_mask("rpc.example.com".to_string())
.build();
qn.admin.create_domain_mask("ep-123", ¶ms).await?;Removes a domain mask.
Parameters: id (endpoint id, required), domain_mask_id (string, required).
Returns: nothing.
// Rust
qn.admin.delete_domain_mask("ep-123", "dm-1").await?;Configures JWT validation on an endpoint.
Parameters: id (endpoint id, required); body: public_key (string, required), kid (string, required), name (string, required).
Returns: nothing.
// Rust
let params = CreateJwtRequest::builder()
.public_key("-----BEGIN PUBLIC KEY-----\n...".to_string())
.kid("key-1".to_string())
.name("primary".to_string())
.build();
qn.admin.create_jwt("ep-123", ¶ms).await?;Removes a JWT configuration.
Parameters: id (endpoint id, required), jwt_id (string, required).
Returns: nothing.
// Rust
qn.admin.delete_jwt("ep-123", "jwt-1").await?;Whitelist specific RPC methods on an endpoint. Requests for methods not on the list are blocked when the feature is enabled.
Parameters: id (endpoint id, required); body: method (string[], required). Ruby's Hash key is methods (plural).
Returns: CreateRequestFilterResponse with data.id.
// Rust
let params = CreateRequestFilterRequest::builder()
.method(vec!["eth_blockNumber".to_string(), "eth_getBalance".to_string()])
.build();
let resp = qn.admin.create_request_filter("ep-123", ¶ms).await?;Parameters: id (endpoint id, required), request_filter_id (string, required); body: method (string[], optional). Ruby's Hash keys are request_filter_id and methods (plural).
Returns: nothing.
// Rust
let params = UpdateRequestFilterRequest::builder()
.method(vec!["eth_call".to_string()])
.build();
qn.admin.update_request_filter("ep-123", "f-1", ¶ms).await?;Parameters: id (endpoint id, required), request_filter_id (string, required).
Returns: nothing.
// Rust
qn.admin.delete_request_filter("ep-123", "f-1").await?;Enables multichain on an endpoint.
Parameters: id (endpoint id, required).
Returns: nothing.
// Rust
qn.admin.enable_multichain("ep-123").await?;Disables multichain on an endpoint.
Parameters: id (endpoint id, required).
Returns: nothing.
// Rust
qn.admin.disable_multichain("ep-123").await?;Sets the custom header used to identify the client IP (e.g. when traffic is proxied).
Parameters: id (endpoint id, required); body: header_name (string, required).
Returns: CreateOrUpdateIpCustomHeaderResponse with data.header_name.
// Rust
let params = CreateOrUpdateIpCustomHeaderRequest::builder()
.header_name("X-Forwarded-For".to_string())
.build();
qn.admin.create_or_update_ip_custom_header("ep-123", ¶ms).await?;Removes the custom IP header configuration.
Parameters: id (endpoint id, required).
Returns: DeleteBoolResponse.
// Rust
qn.admin.delete_ip_custom_header("ep-123").await?;Lists method-level rate limiters configured on an endpoint.
Parameters: id (endpoint id, required).
Returns: GetMethodRateLimitsResponse with data.rate_limiters: MethodRateLimiter[].
// Rust
let resp = qn.admin.get_method_rate_limits("ep-123").await?;Creates a new method-level rate limiter.
Parameters: id (endpoint id, required); body: interval (string, e.g. "second"), methods (string[]), rate (i32).
Returns: CreateMethodRateLimitResponse with data: MethodRateLimiter.
// Rust
let params = CreateMethodRateLimitRequest::builder()
.interval("second".to_string())
.methods(vec!["eth_call".to_string()])
.rate(10)
.build();
let resp = qn.admin.create_method_rate_limit("ep-123", ¶ms).await?;Updates an existing rate limiter. Only provided fields change.
Parameters: id (endpoint id, required), method_rate_limit_id (string, required); body: methods (string[], optional), status ("enabled" | "disabled", optional), rate (i32, optional).
Returns: UpdateMethodRateLimitResponse.
// Rust
let params = UpdateMethodRateLimitRequest::builder().rate(50).build();
qn.admin.update_method_rate_limit("ep-123", "rl-1", ¶ms).await?;Deletes a rate limiter.
Parameters: id (endpoint id, required), method_rate_limit_id (string, required).
Returns: nothing.
// Rust
qn.admin.delete_method_rate_limit("ep-123", "rl-1").await?;Partial update of the endpoint-level RPS / RPM / RPD caps. Only buckets included in the request are modified — omitted buckets are left unchanged. Values are capped by the account's plan tier. Sends PATCH.
Parameters: id (endpoint id, required); rate_limits: RateLimitSettings (rps, rpm, rpd, all optional).
Returns: nothing.
// Rust
let rate_limits = RateLimitSettings::builder().rps(100).rpm(5000).build();
let params = UpdateRateLimitsRequest { rate_limits };
qn.admin.update_rate_limits("ep-123", ¶ms).await?;Returns the rate-limit rows currently enforced on the endpoint, each identifying its bucket ("rps" / "rpm" / "rpd"), rate_limit, and source ("plan_default" or "user_override"). User-set overrides expose an id you can pass to delete_rate_limit_override.
Parameters: id (endpoint id, required).
Returns: GetRateLimitsResponse with data.rate_limits: Vec<RateLimitEntry>.
// Rust
let resp = qn.admin.get_rate_limits("123").await?;
for row in resp.data.unwrap().rate_limits {
println!("{} {} {} {:?}", row.bucket, row.rate_limit, row.source, row.id);
}Deletes a user-set rate-limit override by UUID. Plan defaults are not deletable — passing a UUID that does not match a user-set override on the endpoint returns 404.
Parameters: id (endpoint id, required); override_id (UUID returned by get_rate_limits, required).
Returns: nothing.
// Rust
qn.admin.delete_rate_limit_override("123", "ovr-uuid").await?;Returns the HTTP and WebSocket URLs for the endpoint without fetching the full endpoint record. For multichain endpoints, multichain_urls is a per-network map of additional URLs; for single-chain endpoints it is None.
Parameters: id (endpoint id, required).
Returns: GetEndpointUrlsResponse with data.http_url, data.wss_url, and data.multichain_urls.
// Rust
let resp = qn.admin.get_endpoint_urls("123").await?;
if let Some(data) = resp.data {
println!("{}", data.http_url);
if let Some(mc) = data.multichain_urls {
for (network, urls) in mc {
println!("{network} {}", urls.http_url);
}
}
}Returns metric series for an endpoint over a time period.
Parameters: id (endpoint id, required); body: period ("hour" | "day" | "week" | "month"), metric (e.g. "method_calls_over_time", "response_status_breakdown").
Returns: GetEndpointMetricsResponse with data: Vec<EndpointMetric>. Each EndpointMetric has tag: Vec<String> and data: Vec<Vec<i64>> of [timestamp, value] pairs. Single-axis series (e.g. response_time_over_time with a percentile) come back as a one-element tag like vec!["p95"]; multi-axis series come back as vec!["network", "arbitrum-mainnet"].
// Rust
let params = GetEndpointMetricsRequest {
period: "day".to_string(),
metric: "method_calls_over_time".to_string(),
};
let resp = qn.admin.get_endpoint_metrics("ep-123", ¶ms).await?;Returns account-level metric series. Supports an optional percentile (e.g. "p50", "p95", "p99") for latency metrics.
Parameters: period (required), metric (required), percentile (string, optional).
Returns: GetAccountMetricsResponse with data: Vec<EndpointMetric>. See get_endpoint_metrics above for the tag: Vec<String> shape.
// Rust
let params = GetAccountMetricsRequest {
period: "day".to_string(),
metric: "credits_over_time".to_string(),
percentile: None,
};
let resp = qn.admin.get_account_metrics(¶ms).await?;Lists the blockchains supported by Quicknode along with their networks.
Parameters: none.
Returns: ListChainsResponse with data: Chain[].
// Rust
let resp = qn.admin.list_chains().await?;Returns details about the account, including its id, name, creation timestamp, billing version, and current subscription.
Parameters: none.
Returns: AccountInfoResponse with data: AccountInfo (including a nested subscription: AccountSubscription).
// Rust
let resp = qn.admin.account_info().await?;Returns the per-method API credit costs for a chain, identified by its slug (the same slugs returned by list_chains, e.g. ethereum). An unknown chain slug returns a 404 (surfaced as ApiError).
Parameters: chain (string, required) — the chain slug.
Returns: GetApiCreditsResponse with data: Vec<ApiCredit>, where each ApiCredit has method and credits.
// Rust
let resp = qn.admin.get_api_credits("ethereum").await?;Lists invoices on the account.
Parameters: none.
Returns: ListInvoicesResponse with data.invoices: Invoice[].
// Rust
let resp = qn.admin.list_invoices().await?;Lists payments on the account.
Parameters: none.
Returns: ListPaymentsResponse with data.payments: Payment[].
// Rust
let resp = qn.admin.list_payments().await?;Activates or pauses many endpoints at once.
Parameters: ids (string[], required), status ("active" | "paused", required).
Returns: BulkUpdateEndpointStatusResponse with per-endpoint results.
// Rust
let params = BulkUpdateEndpointStatusRequest::builder()
.ids(vec!["ep-1".to_string(), "ep-2".to_string()])
.status("paused".to_string())
.build();
let resp = qn.admin.bulk_update_endpoint_status(¶ms).await?;Applies a tag (created if missing) to many endpoints at once.
Parameters: ids (string[], required), label (string, required).
Returns: BulkAddTagResponse.
// Rust
let params = BulkAddTagRequest::builder()
.ids(vec!["ep-1".to_string(), "ep-2".to_string()])
.label("prod".to_string())
.build();
let resp = qn.admin.bulk_add_tag(¶ms).await?;Removes a tag from many endpoints at once.
Parameters: ids (string[], required), tag_id (i32, required).
Returns: BulkRemoveTagResponse.
// Rust
let params = BulkRemoveTagRequest::builder()
.ids(vec!["ep-1".to_string(), "ep-2".to_string()])
.tag_id(42)
.build();
let resp = qn.admin.bulk_remove_tag(¶ms).await?;Lists every tag on the account along with usage counts.
Parameters: none.
Returns: ListTagsResponse with data.tags: AccountTag[].
// Rust
let resp = qn.admin.list_tags().await?;Renames an account-level tag.
Parameters: tag_id (i32, required); body: label (string, required).
Returns: RenameTagResponse with updated AccountTag.
// Rust
let params = RenameTagRequest::builder().label("staging".to_string()).build();
let resp = qn.admin.rename_tag(42, ¶ms).await?;Deletes a tag from the account. The tag must first be removed from any endpoints using it.
Parameters: id (i32, required).
Returns: DeleteAccountTagResponse.
// Rust
qn.admin.delete_account_tag(42).await?;Accessed as qn.streams. Creates and manages blockchain data streams that deliver filtered on-chain events to configured destinations. Backed by https://api.quicknode.com/streams/rest/v1/.
Enums used across stream methods:
StreamRegion:UsaEast,EuropeCentral,AsiaEast(wire values:usa_east,europe_central,asia_east).StreamDataset:Block,BlockWithReceipts,Transactions,Logs,Receipts,TraceBlocks,DebugTraces,BlockWithReceiptsDebugTrace,BlockWithReceiptsTraceBlock,BlobSidecars,ProgramsWithLogs,Ledger,Events,Orders,Trades,BookUpdates,Twap,WriterActions.StreamStatus:Active,Paused,Terminated,Completed,Blocked.FilterLanguage:Javascript,Go,Wasm.StreamMetadataLocation:Body,Header,None.
Destinations are expressed via DestinationAttributes. Each variant wraps an attribute struct:
| Variant | Struct | Key fields |
|---|---|---|
Webhook |
WebhookAttributes |
url, max_retry, retry_interval_sec, post_timeout_sec, compression, security_token? |
S3 |
S3Attributes |
endpoint, access_key, secret_key, bucket, object_prefix, compression, file_type, max_retry, retry_interval_sec, use_ssl? |
Azure |
AzureAttributes |
storage_account, sas_token, container, compression, file_type, max_retry, retry_interval_sec, blob_prefix? |
Postgres |
PostgresAttributes |
host, port, username, password, database, table_name, sslmode, max_retry, retry_interval_sec |
Kafka |
KafkaAttributes |
bootstrap_servers, topic_name, compression_type, batch_size, linger_ms, max_message_bytes, timeout_sec, max_retry, retry_interval_sec, username?, password?, protocol?, mechanisms? |
Wrapper naming per language:
- Rust:
DestinationAttributes::Webhook(WebhookAttributes { .. })etc. - Python:
StreamWebhookDestination(WebhookAttributes(...)),StreamS3Destination(S3Attributes(...)), etc. - Node.js: a discriminated object
{ destination: "webhook", attributes: { ... } }using string discriminators. - Ruby: factory methods on
QuicknodeSdk::DestinationAttributes, e.g.QuicknodeSdk::DestinationAttributes.webhook(url: ..., ...).
Creates a new stream that delivers filtered data to the configured destination. Start from a specific block for backfills or from the tip for real-time streaming. Supports filters, reorg handling, distance-from-tip, elastic batching, notification emails, and extra destinations.
Parameters: CreateStreamParams — required: name, region, network, dataset, start_range (i64), end_range (i64, -1 = follow tip), destination_attributes, plan, threshold_fetch_buffer. Common optional fields: dataset_batch_size, include_stream_metadata, fix_block_reorgs, keep_distance_from_tip, elastic_batch_enabled, filter_function, filter_language, status, notification_email, extra_destinations.
Returns: Stream.
// Rust
let params = CreateStreamParams::builder()
.name("My Stream".to_string())
.region(StreamRegion::UsaEast)
.network("ethereum-mainnet".to_string())
.dataset(StreamDataset::Block)
.start_range(24691804)
.end_range(24691904)
.destination_attributes(DestinationAttributes::Webhook(WebhookAttributes {
url: "https://webhook.site/...".to_string(),
max_retry: 3,
retry_interval_sec: 1,
post_timeout_sec: 10,
compression: "none".to_string(),
security_token: None,
}))
.plan("growth_plan".to_string())
.threshold_fetch_buffer(1000)
.status(StreamStatus::Active)
.build();
let stream = qn.streams.create_stream(¶ms).await?;Paginated list of streams on the account.
Parameters (all optional): offset (i64), limit (i64), order_by (string), order_direction ("asc" | "desc"), stream_type (string).
Returns: ListStreamsResponse with data: Stream[] and page_info.
// Rust
let resp = qn.streams.list_streams(&ListStreamsParams::default()).await?;Fetches one stream by id.
Parameters: id (string, required).
Returns: Stream.
// Rust
let stream = qn.streams.get_stream("stream-id").await?;Partially updates a stream. Omitted fields are left unchanged.
Parameters: id (string, required); body: any field from CreateStreamParams (all optional).
Returns: updated Stream.
// Rust
let params = UpdateStreamParams {
name: Some("Renamed".to_string()),
..Default::default()
};
let stream = qn.streams.update_stream("stream-id", ¶ms).await?;Deletes one stream by id.
Parameters: id (string, required).
Returns: nothing.
// Rust
qn.streams.delete_stream("stream-id").await?;Deletes every stream on the account. Destructive and takes no arguments.
Parameters: none.
Returns: nothing.
// Rust
qn.streams.delete_all_streams().await?;Resumes delivery on a stream from its current position.
Parameters: id (string, required).
Returns: nothing.
// Rust
qn.streams.activate_stream("stream-id").await?;Halts delivery on a stream.
Parameters: id (string, required).
Returns: nothing.
// Rust
qn.streams.pause_stream("stream-id").await?;Runs a filter function against a block so it can be validated before being attached to a live stream.
Parameters: network (string, required), dataset (StreamDataset, required), block (string, required), filter_function (string, optional), filter_language (FilterLanguage, optional), address_book_config (optional).
Returns: TestFilterResponse with result and logs.
// Rust
let params = TestFilterParams {
network: "ethereum-mainnet".to_string(),
dataset: StreamDataset::Block,
block: "17811625".to_string(),
filter_function: None,
filter_language: None,
address_book_config: None,
};
let resp = qn.streams.test_filter(¶ms).await?;Counts currently enabled (active) streams, optionally filtered by type.
Parameters: stream_type (string, optional).
Returns: EnabledCountResponse with total.
// Rust
let resp = qn.streams.get_enabled_count(None).await?;Accessed as qn.webhooks. Creates webhooks from filter templates and manages their lifecycle. Backed by https://api.quicknode.com/webhooks/rest/v1/.
WebhookTemplateId identifies the filter template:
| Variant | Wire value |
|---|---|
EvmWalletFilter |
evmWalletFilter |
EvmContractEvents |
evmContractEvents |
EvmAbiFilter |
evmAbiFilter |
SolanaWalletFilter |
solanaWalletFilter |
BitcoinWalletFilter |
bitcoinWalletFilter |
XrplWalletFilter |
xrplWalletFilter |
HyperliquidWalletEventsFilter |
hyperliquidWalletEventsFilter |
StellarWalletTransactionsSourceAccountFilter |
stellarWalletTransactionsSourceAccountFilter |
TemplateArgs carries the arguments. Each template supports two input forms — inline values or a reference to a pre-created list by name. Construct one per template via the variant + the appropriate input enum (<Template>Input::Inline | ByList):
| Variant | Inline struct (fields) | ByList struct (fields) |
|---|---|---|
EvmWalletFilter |
EvmWalletFilterTemplate { wallets: string[] } |
EvmWalletFilterByListTemplate { wallets_list_name: string } |
EvmContractEvents |
EvmContractEventsTemplate { contracts: string[], event_hashes: string[] } |
EvmContractEventsByListTemplate { contracts_list_name: string, event_hashes_list_name?: string } |
EvmAbiFilter |
EvmAbiFilterTemplate { abi: string, contracts: string[] } |
EvmAbiFilterByListTemplate { abi_json: string, contracts_list_name?: string } |
SolanaWalletFilter |
SolanaWalletFilterTemplate { accounts: string[] } |
SolanaWalletFilterByListTemplate { accounts_list_name: string } |
BitcoinWalletFilter |
BitcoinWalletFilterTemplate { wallets: string[] } |
BitcoinWalletFilterByListTemplate { wallets_list_name: string } |
XrplWalletFilter |
XrplWalletFilterTemplate { wallets: string[] } |
XrplWalletFilterByListTemplate { wallets_list_name: string } |
HyperliquidWalletEventsFilter |
HyperliquidWalletEventsFilterTemplate { wallets: string[] } |
HyperliquidWalletEventsFilterByListTemplate { wallets_list_name: string } |
StellarWalletTransactionsSourceAccountFilter |
StellarWalletTransactionsFilterTemplate { wallets: string[] } |
StellarWalletTransactionsFilterByListTemplate { wallets_list_name: string } |
WebhookDestinationAttributes: url (required), compression (required — "none" | "gzip"), security_token (optional — auto-generated if omitted).
WebhookStartFrom: Last (resume from last delivered block) or Latest (start from newest).
In Ruby, template_args is passed as a JSON string under the key template_args_json; destination is passed as a JSON string under destination_attributes_json.
Paginated list of webhooks.
Parameters (all optional): limit (i64), offset (i64).
Returns: ListWebhooksResponse with data: Webhook[] and pageInfo: WebhookPageInfo { limit, offset, total }.
// Rust
let resp = qn.webhooks.list_webhooks(&GetWebhooksParams::default()).await?;Fetches a webhook by id.
Parameters: id (string, required).
Returns: Webhook.
// Rust
let webhook = qn.webhooks.get_webhook("wh-1").await?;Creates a webhook from a predefined filter template.
Parameters: name (required), network (required), destination_attributes (WebhookDestinationAttributes, required), template_args (required — use the TemplateArgs enum variant for the chosen template), notification_email (optional).
Returns: Webhook.
// Rust
let template_args = TemplateArgs::EvmWalletFilter(EvmWalletFilterTemplate {
wallets: vec!["0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48".to_string()],
});
let params = CreateWebhookFromTemplateParams {
name: "Wallet Webhook".to_string(),
network: "ethereum-mainnet".to_string(),
notification_email: None,
destination_attributes: WebhookDestinationAttributes {
url: "https://webhook.site/...".to_string(),
security_token: None,
compression: "none".to_string(),
},
template_args,
};
let webhook = qn.webhooks.create_webhook_from_template(¶ms).await?;Partially updates a webhook's name, notification email, and/or destination. If destination_attributes is supplied without security_token, a new token is generated automatically.
Parameters: id (required); body — all optional: name, notification_email, destination_attributes. In Ruby, destination_attributes is passed as a JSON string under the key destination_attributes_json.
Returns: updated Webhook.
// Rust
let params = UpdateWebhookParams {
name: Some("Renamed Webhook".to_string()),
..Default::default()
};
let webhook = qn.webhooks.update_webhook("wh-1", ¶ms).await?;Updates the template args (and optionally name, email, destination) on an existing template-backed webhook.
Parameters: webhook_id (required), template_args (required); optional: name, notification_email, destination_attributes.
Returns: updated Webhook.
// Rust
let template_args = TemplateArgs::EvmWalletFilter(EvmWalletFilterTemplate {
wallets: vec!["0xnewwallet".to_string()],
});
let params = UpdateWebhookTemplateParams {
name: None,
notification_email: None,
destination_attributes: None,
template_args,
};
let webhook = qn.webhooks.update_webhook_template("wh-1", ¶ms).await?;Deletes a webhook.
Parameters: id (required).
Returns: nothing.
// Rust
qn.webhooks.delete_webhook("wh-1").await?;Deletes every webhook on the account. Destructive and takes no arguments.
Parameters: none.
Returns: nothing.
// Rust
qn.webhooks.delete_all_webhooks().await?;Pauses a webhook so it stops delivering events.
Parameters: id (required).
Returns: nothing.
// Rust
qn.webhooks.pause_webhook("wh-1").await?;Activates a paused or new webhook so it resumes delivering events. start_from determines where processing resumes.
Parameters: id (required), start_from (WebhookStartFrom, required — Last or Latest).
Returns: nothing.
// Rust
let params = ActivateWebhookParams { start_from: WebhookStartFrom::Latest };
qn.webhooks.activate_webhook("wh-1", ¶ms).await?;Counts currently enabled webhooks.
Parameters: none.
Returns: WebhookEnabledCountResponse with total.
// Rust
let resp = qn.webhooks.get_enabled_count().await?;Accessed as qn.kvstore. Provides two primitives — sets (single string values under a key) and lists (ordered collections of strings under a key). Backed by https://api.quicknode.com/kv/rest/v1/.
Stores a single string value under a key.
Parameters: key (string, required), value (string, required).
Returns: nothing.
// Rust
qn.kvstore.create_set(&CreateSetParams {
key: "my-key".to_string(),
value: "hello".to_string(),
}).await?;Paginated page of key/value entries.
Parameters (all optional): limit (i64), cursor (string).
Returns: GetSetsResponse — { data: KvSetEntry[], cursor: string }.
// Rust
let resp = qn.kvstore.get_sets(&Default::default()).await?;Returns the value stored under a key.
Parameters: key (string, required).
Returns: GetSetResponse with value.
// Rust
let resp = qn.kvstore.get_set("my-key").await?;Adds and/or deletes multiple sets in a single request.
Parameters (at least one required): add_sets (map<string,string>, optional), delete_sets (string[], optional).
Returns: nothing.
// Rust
use std::collections::HashMap;
let mut add_sets = HashMap::new();
add_sets.insert("k1".to_string(), "v1".to_string());
qn.kvstore.bulk_sets(&BulkSetsParams {
add_sets: Some(add_sets),
delete_sets: Some(vec!["old-key".to_string()]),
}).await?;Deletes a single set.
Parameters: key (string, required).
Returns: nothing.
// Rust
qn.kvstore.delete_set("my-key").await?;Creates a list under a key, seeded with the initial items.
Parameters: key (string, required), items (string[], required).
Returns: nothing.
// Rust
qn.kvstore.create_list(&CreateListParams {
key: "my-list".to_string(),
items: vec!["0xabc".to_string(), "0xdef".to_string()],
}).await?;Paginated page of list keys.
Parameters (all optional): limit (i64), cursor (string).
Returns: GetListsResponse — { data: { keys: string[] }, cursor: string }.
// Rust
let resp = qn.kvstore.get_lists(&Default::default()).await?;Paginated page of items for a specific list.
Parameters: key (string, required); optional limit (i64), cursor (string).
Returns: GetListResponse — { data: { items: string[] }, cursor: string }.
// Rust
let resp = qn.kvstore.get_list("my-list", &Default::default()).await?;Adds and/or removes items in a single operation.
Parameters: key (string, required); optional: add_items (string[]), remove_items (string[]).
Returns: nothing.
// Rust
qn.kvstore.update_list(
"my-list",
&UpdateListParams {
add_items: Some(vec!["0x456".to_string()]),
remove_items: Some(vec!["0xabc".to_string()]),
},
).await?;Appends a single item to a list.
Parameters: key (string, required), item (string, required).
Returns: nothing.
// Rust
qn.kvstore.add_list_item(
"my-list",
&AddListItemParams { item: "0x123".to_string() },
).await?;Checks whether a list contains a specific item.
Parameters: key (string, required), item (string, required).
Returns: ListContainsItemResponse with exists: bool.
// Rust
let resp = qn.kvstore.list_contains_item("my-list", "0x123").await?;Removes a single item from a list.
Parameters: key (string, required), item (string, required).
Returns: nothing.
// Rust
qn.kvstore.delete_list_item("my-list", "0x123").await?;Deletes a list and all of its items.
Parameters: key (string, required).
Returns: nothing.
// Rust
qn.kvstore.delete_list("my-list").await?;Accessed as qn.sql. Runs SQL queries against indexed blockchain data and fetches the database schema. Backed by https://api.quicknode.com/sql/rest/v1/.
Executes a SQL query against a cluster and returns the result set. Paginate by writing LIMIT/OFFSET into the SQL.
Parameters: QueryParams with query (String, required) and cluster_id (String, required).
Returns: QueryResponse — meta (Vec<ColumnMeta>, each with name and column_type), data (Vec<serde_json::Value>, rows as JSON objects keyed by column name), rows, rows_before_limit_at_least, statistics (QueryStatistics with elapsed, rows_read, bytes_read), and credits.
// Rust
let resp = qn
.sql
.query(&QueryParams {
query: "SELECT action_type, user FROM hyperliquid_system_actions ORDER BY block_time DESC LIMIT 100".to_string(),
cluster_id: "hyperliquid-core-mainnet".to_string(),
})
.await?;
println!("{} rows, {:?}", resp.rows, resp.data.first());Fetches the database schema for a cluster: table names, columns, types, sort keys, and partition strategies.
Parameters: cluster_id (&str, required).
Returns: ChainSchema — chain, cluster_id, and tables (Vec<TableSchema>, each with name, engine, total_rows, partition_key, sorting_key, and columns of ColumnSchema { name, column_type }).
// Rust
let schema = qn.sql.get_schema("hyperliquid-core-mainnet").await?;
println!("{} tables", schema.tables.len());Every binding exposes a typed exception hierarchy derived from the core SdkError
enum (crates/core/src/errors.rs). Catch the base class (SdkError) for any SDK-originated failure, or a specific
subclass to branch on transport vs. API semantics.
| Logical class | When it fires | Extra fields |
|---|---|---|
QuicknodeError |
base class; catches everything below | — |
ConfigError |
invalid config or URL surfaced at construction time | — |
HttpError |
transport failure that isn't a timeout/connect | — |
TimeoutError |
request timed out (subclass of HttpError) |
— |
ConnectionError |
connection refused / DNS / TLS (subclass of HttpError) |
— |
ApiError |
non-2xx HTTP response | status, body |
DecodeError |
2xx response but JSON parse failed | body |
Variants: pattern-match on SdkError { Http, Api, Decode, UrlParse, Config }; use err.http_kind() to classify Http into Timeout, Connect, or Other.
// Rust
match qn.admin.show_endpoint("missing").await {
Ok(resp) => println!("{:?}", resp.data),
Err(SdkError::Api { status, body }) if status.as_u16() == 404 => {
eprintln!("not found: {body}")
}
Err(e) if matches!(e.http_kind(), Some(HttpKind::Timeout)) => eprintln!("timed out"),
Err(e) => eprintln!("other: {e}"),
}MIT