openrouter-rs

Library Listed

A type-safe OpenRouter Rust SDK

Checked · Sources

Downloads
8,599
Dependents
3
Stars
98
Forks
24
Contributors
10
Commits
408
Latest release
0.24.0 ·

About

From the project README ·

Type-safe, async Rust SDK for the OpenRouter API.

docs.rs | examples | crate | docs map | openrouter-cli | contributing | changelog

openrouter-rs is a community-maintained Rust SDK for OpenRouter, with typed requests, streaming, tool calling, and access to OpenRouter's model, usage, and management APIs. A companion CLI is available for terminal and automation workflows.

Installation

[dependencies]
openrouter-rs = "0.24.0"
tokio = { version = "1", features = ["full"] }

Requires Rust 1.93+ and Tokio 1.x. To try it in a new project:

cargo new openrouter-quickstart
cd openrouter-quickstart

Add the dependencies above to Cargo.toml, then set your API key:

export OPENROUTER_API_KEY="your-openrouter-api-key"

Quick Start

Save this as src/main.rs and run cargo run:

Read the full README
use openrouter_rs::{
    OpenRouterClient,
    api::chat::{ChatCompletionRequest, Message},
    types::Role,
};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = OpenRouterClient::builder()
        .api_key(std::env::var("OPENROUTER_API_KEY")?)
        .build()?;

    let request = ChatCompletionRequest::builder()
        .model(std::env::var("OPENROUTER_MODEL").unwrap_or_else(|_| "openai/gpt-4o-mini".into()))
        .messages(vec![Message::new(
            Role::User,
            "Explain Rust ownership in plain English.",
        )])
        .max_tokens(256)
        .build()?;

    let response = client.chat().create(&request).await?;
    let choice = response.choices.first().ok_or("OpenRouter returned no choices")?;
    println!("{}", choice.content().unwrap_or(""));

    Ok(())
}

Chat response messages and raw streaming deltas preserve reasoning_content and reasoning_text; Message::try_from replays these fields on follow-up requests. Read completion-token breakdowns through usage.completion_tokens_details. Choice::reasoning() and the stream adapters still emit only the canonical reasoning field; inspect raw deltas for provider-specific fields.

Chat responses accept nullable upstream costs and numeric or string choice error codes. Use error.code.as_ref().and_then(|code| code.as_i64()) for numeric handling, and preserve None for unreported costs. See the chat decoding migration for the changed field types.

Use choice.finish_reason().map(|reason| reason.as_str()) to read the finish reason wire name, including unknown provider values preserved by FinishReason::Other.

The SDK keeps setup intentionally narrow: configure runtime values on OpenRouterClient::builder(), then choose the final model on each request builder. File/profile config resolution belongs in the companion CLI or in your application layer, not in the SDK core.

Set OPENROUTER_MODEL to use another model ID available to your account. A successful request prints the model's reply. A missing key fails locally; for API authentication, credit, or model-availability errors, check your OpenRouter account and the returned error before retrying. API calls may consume credits.

Choose a Workflow

These commands run from a checkout of this repository with OPENROUTER_API_KEY set:

GoalRunGuide
Stream a chat responsecargo run --example stream_chat_completionStreaming example
Execute typed tools against fixed demo fixtures in a bounded agent loopcargo run --example typed_tool_agentTyped tool agent
Inspect credits and manage API keyscargo run --example get_creditsCLI usage recipes and key management

Management-governed endpoints require OPENROUTER_MANAGEMENT_KEY; ordinary chat and credits requests use OPENROUTER_API_KEY. For a minimal HTTP server, see the Axum chat gateway.

Why openrouter-rs

  • Domain-oriented clients: chat(), responses(), messages(), rerank(), audio().speech(), audio().transcriptions(), images(), videos(), files(), models(), batches(), vault(), decisions(), management(), and opt-in legacy()
  • Typed request/response models with builder-style ergonomics
  • Tokio-native reqwest + rustls transport by default, or the host's wasi:http on wasm32-wasip2 with the wasip3 feature
  • Streaming support for chat, responses, messages, and image generation, including a unified stream abstraction
  • Typed tools, manual JSON-schema tools, OpenRouter server tools, and multimodal chat content
  • Typed chat usage metadata for token counts, OpenRouter cost, provider cost breakdowns, and BYOK status
  • Opt-in OpenRouter response metadata for chat, Responses API, and Anthropic-compatible Messages requests
  • Discovery, rankings and benchmark datasets, task classifications, rerank, audio speech/transcription, image generation, video generation, provider-backed files, embeddings, API-key management, preset creation/readback/versioning, analytics, BYOK provider credentials, observability destinations, workspace management, SCIM group mappings, organization members/settings, external-user registrations, guardrails, activity, credits, and generation metadata/content coverage
  • A companion CLI for profile resolution, discovery, management, and billing/usage workflows

Accepted endpoint coverage and live-test status are recorded separately in the endpoint matrix. See the changelog for release details and migration guide when upgrading, including the 0.19 speech input change.

0.20 transport migration: The SDK now uses reqwest 0.13, including the reqwest::Client accepted by .http_client(...). Default native TLS uses platform certificate verification and AWS-LC; Linux deployments need an up-to-date OS CA bundle. See the transport migration guide for custom-client, trust-store, and Tokio feature changes.

Legacy text completions are opt-in:

[dependencies]
openrouter-rs = { version = "0.24.0", features = ["legacy-completions"] }
HTTP backends and WASI

Requests go through one of two backends, chosen by cargo feature:

FeatureDefaultBackend
reqwestyesreqwest 0.13 with rustls; needs a Tokio runtime; enables .http_client(...)
wasip3nothe host's wasi:http/client (WASI 0.3) on wasm32-wasip2; no effect on other targets

For a WASI component, disable the default reqwest backend and enable wasip3:

[dependencies]
openrouter-rs = { version = "0.24.0", default-features = false, features = ["wasip3"] }

The client API is the same on both backends, including streaming. When both features are on a WASI target, the default client uses wasi:http. The embedding host controls TLS, networking, redirects and timeouts; configure those policies in the host rather than assuming reqwest settings apply.

See tests/fixtures/wasip3-smoke/src/lib.rs for a runnable WASI 0.3 command component. just test-wasip3 runs it against a loopback mock server using Wasmtime 50.0.0 (wasmtime on PATH, or set WASMTIME). It checks authentication, query encoding, multipart upload, binary download, API/body errors, incremental SSE and stream cancellation without an OpenRouter account. Install the compilation target with rustup target add wasm32-wasip2.

API Surface

The canonical public surface is domain-oriented, and each endpoint family has exactly one entry path. The api::<module>::<function>(base_url, api_key, …) helpers and the flat OpenRouterClient methods were removed in 0.23.0 because they could not honor the configured client; see the 0.23 migration notes.

DomainCanonical methodsPrimary endpointsAuth note
chat()create, stream, stream_unified/chat/completionsAPI key
responses()create, stream, stream_unified/responsesAPI key
messages()create, stream, stream_unified/messagesAPI key
rerank()create/rerankAPI key
audio().speech()create/audio/speech (legacy /tts fallback)API key
audio().transcriptions()create/audio/transcriptionsAPI key
images()create, stream, list_models, list_model_endpoints/images*API key
videos()create, list_models, get_generation, get_content/videos*API key
files()list, upload, get_metadata, download_content, delete/files*API key
files()list_container_files, get_container_file, download_container_file, promote_container_file/containers/*/files*API key
models()list, list_filtered, list_by_category, list_by_parameters, get, list_endpoints, list_providers, list_user_models, list_for_user_with_params, get_model_count, get_rankings_daily, get_rankings_daily_filtered, get_app_rankings, get_session_cost, get_task_classifications, get_benchmarks, list_zdr_endpoints, create_embedding, list_embedding_models/model*, /models*, /providers, /datasets/*, /classifications/task, /benchmarks, /endpoints/zdr, /embeddings*API key
management()create_api_key, create_api_key_in_workspace, create_api_key_with_options, list_api_keys, list_api_keys_in_workspace, list_presets, get_preset, list_preset_versions, get_preset_version, create_chat_completion_preset, create_response_preset, create_message_preset, get_analytics_meta, query_analytics, list_byok_keys, create_byok_key, get_byok_key, update_byok_key, delete_byok_key, list_observability_destinations, create_observability_destination, get_observability_destination, update_observability_destination, delete_observability_destination, create_auth_code, create_api_key_from_auth_code, list_guardrails, list_guardrails_in_workspace, create_guardrail, list_organization_members, get_organization_settings, update_organization_settings, list_external_users, create_external_user, get_external_user, update_external_user, delete_external_user, list_private_providers, create_private_provider, get_private_provider, update_private_provider, delete_private_provider, list_workspaces, create_workspace, get_workspace, update_workspace, delete_workspace, list_workspace_budgets, get_workspace_budget, upsert_workspace_budget, delete_workspace_budget, list_workspace_members, add_workspace_members, remove_workspace_members, get_activity, get_activity_with_params, get_credits, create_coinbase_charge, get_generation, get_generation_content, submit_generation_feedback/keys*, /presets*, /analytics*, /byok*, /observability/destinations*, /auth/keys*, /guardrails*, /organization/*, /external-users*, /private-providers*, /workspaces*, /activity, /credits*, /generation*, /keyGoverned endpoints require a management key; billing/session endpoints still use the normal API key because that is how OpenRouter authenticates them
batches()list, create, get, delete/batches*API key
vault()list, list_for_intern, list_connections_for_intern, store, store_for_intern, delete, delete_for_intern, copy_to_intern/vault*API key
decisions()create, create_system_one/api/alpha/decisions, /systemoneAPI key
management()get_oauth_jwks, exchange_oauth_token/oauth/jwks, /oauth/tokenPublic signing keys; token exchange authenticates with the workload JWT
management()list_scim_groups, list_scim_group_mappings, create_scim_group_mapping, get_scim_group_mapping, update_scim_group_mapping, delete_scim_group_mapping, create_scim_sync_job, get_scim_sync_job/scim/groups, /scim/group-mappings*, /scim/sync-jobs*Management key
legacy()completions().create/completionslegacy-completions feature + API key

Vault reads follow the same domain-client style:

// Connections (GitHub, Slack, MCP servers, ...) available to one intern.
for connection in client
    .vault()
    .list_connections_for_intern("intern-id")
    .await?
    .data
{
    println!("{}", connection.key);
}

At runtime, the builder/client exposes the values the SDK directly consumes:

  • base_url
  • api_key
  • management_key
  • http_referer
  • x_title
  • app_categories
  • http_client (feature reqwest)

Chat, Responses API, and Anthropic-compatible Messages request builders also expose experimental_metadata(OpenRouterExperimentalMetadata::Enabled) for OpenRouter's opt-in routing metadata response header.

Common Workflows

openrouter-rs is not just a thin /chat/completions wrapper. The repo currently covers:

  • chat completions, responses, and Anthropic-compatible messages
  • rerank, audio speech generation, audio transcription, image generation, and video generation polling/content retrieval
  • unified streaming across chat, responses, and messages
  • manual tools, typed tools backed by schemars, and OpenRouter server tools such as openrouter:web_search and openrouter:datetime
  • multimodal chat content, including image, audio, video, and file parts
  • model discovery, provider discovery, app rankings, task classifications, unified benchmarks, embeddings, and ZDR endpoints
  • typed generation metadata, model voice/benchmark/link metadata, workspace I/O logging controls, video callback URL support, and file upload/download workflows
  • explicit chat prompt-cache breakpoints and static predictions, image provider routing controls, conditional model pricing, and image-only video generation requests
  • assistant-message model annotations, transcription speaker labels, Anthropic compaction/dynamic-tool blocks, and round-tripped BYOK controls for guardrail/workspace budgets
  • management-key workflows for keys, workspace-scoped keys, preset reads/writes, analytics, BYOK provider credentials, observability destinations, auth codes, organization members, workspaces, workspace budgets, workspace member listing/mutation, guardrails, guardrail content filters, workspace-scoped guardrails, and activity, plus API-key-authenticated credits and generation metadata/content endpoints

For deeper examples, prefer the runnable examples in examples/ over long README snippets.

Server Tools

OpenRouter server tools use the same ServerTool type across chat completions, Responses API, Anthropic-compatible Messages, and preset creation request bodies:

use openrouter_rs::{
    api::chat::{ChatCompletionRequest, Message},
    types::{Role, ServerTool},
};
use serde_json::json;

let request = ChatCompletionRequest::builder()
    .model("openai/gpt-5")
    .messages(vec![Message::new(Role::User, "Find current OpenRouter docs.")])
    .server_tool(ServerTool::web_search_with_parameters(json!({
        "max_results": 3
    })))
    .force_server_tool("openrouter:web_search")
    .build()?;

Examples

The repo includes runnable examples for the highest-value workflows:

Application Patterns
ExampleFocus
examples/axum_chat_gateway.rsLocal Axum gateway with JSON and SSE chat, bounded requests, usage forwarding, and disconnect handling
examples/typed_tool_agent.rsPractical typed-tool agent loop with explicit tool dispatch
examples/domain_chat_completion.rsCanonical chat() request with the domain-oriented client
examples/custom_http_client.rsInject a custom reqwest::Client (proxies, timeouts, middleware)
Tokio Streaming
ExampleFocus
examples/stream_chat_completion.rsStream chat deltas into a Tokio task/stdout
examples/stream_chat_with_tools.rsTool-aware streaming aggregation plus a second round after execution
examples/stream_response.rsresponses() streaming
examples/stream_messages.rsmessages() streaming
API Surface Demos
ExampleFocus
examples/basic_tool_calling.rsManual tool-calling loop
examples/typed_tool_calling.rsTyped tools with generated schema
examples/create_response.rsresponses() create
examples/create_message.rsmessages() create
examples/create_rerank.rsrerank().create(...)
examples/create_speech.rsaudio().speech().create(...)
examples/create_transcription.rsaudio().transcriptions().create(...)
examples/create_image_generation.rsimages().create(...)
examples/create_video_generation.rsvideos().create(...)
examples/create_embedding.rsmodels().create_embedding(...)
examples/domain_batches.rsbatches().create(...)
examples/domain_vault.rsvault().list_connections_for_intern(...)
examples/domain_decisions.rsdecisions().create(...)
examples/domain_management_api_keys.rsAPI-key management via management()
examples/list_byok_keys.rsmanagement().list_byok_keys(...)
examples/list_observability_destinations.rsmanagement().list_observability_destinations(...)
examples/list_organization_members.rsOrganization members/settings and external-user registration listing
examples/list_workspaces.rsmanagement().list_workspaces(...)
examples/exchange_code_for_api_key.rsPKCE/auth-code flow
examples/send_completion_request.rsLegacy completions (legacy-completions required)

Typical local usage:

export OPENROUTER_API_KEY=sk-or-v1-...

cargo run --example axum_chat_gateway
cargo run --example domain_chat_completion
cargo run --example stream_chat_completion
cargo run --example typed_tool_agent
cargo run --example typed_tool_calling
cargo run --example create_response
cargo run --example create_message
cargo run --example create_rerank
cargo run --example create_speech
cargo run --example create_transcription
cargo run --example create_image_generation
cargo run --example create_embedding
cargo run --example list_byok_keys
cargo run --example list_observability_destinations
cargo run --example custom_http_client

For shell and CI automation recipes built around the companion CLI, see docs/operations/cli-automation-workflows.md.

Continuing a chat after tool calls

Retain the response message before appending tool results so signed/encrypted reasoning and other modeled assistant metadata survive the next client.chat().create(...) call:

if let Some(message) = choice.message() {
    messages.push(openrouter_rs::api::chat::Message::try_from(message)?);
}
// Then append Message::tool_response(...) for each tool call.

Choice::message() returns None for streaming and legacy text choices. The conversion preserves modeled response fields and rejects missing/unsupported roles; response content parts retain the SDK's existing text normalization. See examples/typed_tool_agent.rs. ReasoningDetail::summary and content() expose reasoning.summary blocks. For streaming tool loops, examples/stream_chat_with_tools.rs collects text/reasoning and retains reasoning-detail objects in arrival order before sending tool results.

Prompt-cache usage is available through response.usage → prompt_tokens_details → cached_tokens / cache_write_tokens. These are optional provider-reported counts; missing data is not evidence of a cache miss. The same usage type is used for streaming.

CLI Companion

This workspace also contains crates/openrouter-cli, a companion CLI for profile resolution, discovery, management, and usage/billing workflows.

Examples:

cargo run -p openrouter-cli -- --help
cargo run -p openrouter-cli -- profile show
cargo run -p openrouter-cli -- models list --category programming
cargo run -p openrouter-cli -- keys list --include-disabled
cargo run -p openrouter-cli -- workspaces list --limit 20
cargo run -p openrouter-cli -- usage activity --date 2026-03-01

See crates/openrouter-cli/README.md for the full command surface and config/auth precedence rules. For copy-paste shell/CI recipes, see docs/operations/cli-automation-workflows.md.

Project Status

  • Community-maintained third-party SDK; not affiliated with OpenRouter
  • Canonical docs and examples prefer the domain clients over older flat helpers
  • Accepted endpoint coverage is tracked against the current OpenAPI snapshot, and the current baseline is reviewed, with 140 / 154 operations implemented at the SDK surface and 14 newer operations deferred
  • Live integration coverage and gaps are published in docs/operations/official-endpoint-test-matrix.md
  • Migration guidance for the 0.9.x -> 0.10.0 public-model future-proofing release, the 0.8.x -> 0.9.0 audio speech release, the 0.7.x -> 0.8.0 transport/error-surface release, and the archived 0.5.x -> 0.6.x naming guide lives in MIGRATION.md
  • Legacy POST /completions support remains available behind the legacy-completions feature
🔁 0.10 Public Model Migration

Full migration guide: MIGRATION.md

  • High-churn public SDK request, response, metadata, usage, pricing, discovery, streaming, and upstream taxonomy types are #[non_exhaustive]
  • Replace affected struct literals with builders, constructors, helpers, or serde deserialization
  • Add wildcard arms when matching affected public enums outside the crate
  • Use constructors such as ResponseUsage::new(...), ToolCall::new(...), FunctionCall::new(...), and JsonSchemaConfig::new(...) for small helper/test fixtures
  • This source-level break lands in 0.10.0
🔁 0.9 Audio Speech Migration
  • client.tts().create(...) -> client.audio().speech().create(...)
  • api::tts::TtsRequest -> api::audio::SpeechRequest
  • api::tts::TtsResponseFormat -> api::audio::SpeechResponseFormat
  • api::tts remains as a deprecated compatibility module, but new examples and docs use api::audio
  • Newly added and high-churn public request/response structs use builder construction and may be marked #[non_exhaustive]; prefer request builders over struct literals
🔁 0.8 Transport/Error Migration

Full migration guide: MIGRATION.md

  • OpenRouterError::HttpRequest(surf::Error) -> OpenRouterError::HttpRequest(HttpRequestError)
  • ApiErrorContext.status: surf::StatusCode -> ApiErrorContext.status: http::StatusCode
  • openrouter_rs::utils::{with_bearer_auth, with_request_metadata, with_client_request_headers, handle_error} -> caller-owned transport helpers or direct use of the canonical domain clients
  • No API migration is required if you only use OpenRouterClient plus chat(), responses(), messages(), rerank(), audio(), images(), videos(), files(), models(), management(), and legacy()
🔁 0.6 Naming/Pagination Migration

Full migration guide: MIGRATION.md

  • models().count() -> models().get_model_count()
  • models().list_for_user() -> models().list_user_models()
  • management().exchange_code_for_api_key(...) -> management().create_api_key_from_auth_code(...)
  • management().list_guardrails(offset, limit) -> management().list_guardrails(Some(PaginationOptions::with_offset_and_limit(offset, limit)))
  • client.list_api_keys(offset, include_disabled) -> management().list_api_keys(Some(PaginationOptions::with_offset(offset)), include_disabled)

0.6.0 removed the transitional aliases above; use the canonical method names shown here.

Development

Prefer the just recipes so local work stays aligned with CI:

just quality
just quality-ci
just test-live-contract
OPENROUTER_MANAGEMENT_KEY=... just test-live-contract-management

Focused commands:

  • just test-unit
  • just test-lib
  • just test-doc
  • just test-integration-subsets
  • just test-cli
  • just check-migration-docs
  • just test-migration-smoke
  • just test-integration

Environment and model-pool details live in tests/integration/README.md. A starter env file lives at .env.example.

Docs Map

Start with docs/README.md for grouped navigation across root docs, docs/, specs/, and subsystem READMEs.

Users And Setup
Contributors And Project Policies
Design And Roadmap
Operations, Validation, And Distribution

📈 Release History

Unreleased
Version 0.24.0 (Latest)
  • Accepted the November 3 OpenAPI snapshot: Model/UserModel expose endpoints, ZDR endpoints expose safety_retention, and Responses requests can opt into OpenAI access programs. POST /api/alpha/extractions stays deferred.
  • Breaking: private providers dropped data_policy upstream, so PrivateProviderDataPolicy and the data_policy fields are removed. See the 0.24 migration notes.
  • The endpoint matrix now matches the shipped surface again, and test_real_tool_call runs in the live workflow instead of being skipped everywhere.
Version 0.23.0
  • Breaking: One entry path per endpoint family: the 162 api::* endpoint functions and 109 flat OpenRouterClient methods are gone, so every call honours the configured client. See the 0.23 migration notes.
  • Breaking: Transport failures carry HttpRequestErrorKind, the request URL, and retry_after; streaming has one event model (UnifiedStreamEvent) whose terminal event carries assembled tool_calls and typed usage.
  • Breaking: Upstream drift accepted in the same release: client.interns() is removed, /end-users* became /external-users*, and management() gained /private-providers*.
  • Reasoning setters keep the request valid: reasoning_effort and reasoning_max_tokens are mutually exclusive, as the API requires.
  • Accepted drift fills gaps that were silently dropped: guardrail harness flag, prompt-cache breakpoint ttl, GET /models/user client filter, and vault routing metadata.
Version 0.22.0
  • Preserve reasoning_content/reasoning_text across chat responses, raw deltas and request replay; expose completion-token details.
  • Decode choices by shape with useful errors, accept omitted tool-call types, and preserve structured API errors with string codes.
  • Breaking: Choice error codes are now Option<ErrorCode> and upstream chat cost fields are Option<f64>. See the migration guide.
Version 0.21.1
  • Expose FinishReason::as_str to read wire names directly, including unknown provider finish reasons.
Version 0.21.0
  • Added opt-in WASI 0.3 HTTP transport for wasm32-wasip2, including streaming and Send futures, plus From<HttpRequestError> for OpenRouterError.
  • Breaking: Raised the SDK and workspace CLI MSRV to Rust 1.93. Consumers using default-features = false must explicitly enable reqwest or wasip3; see the 0.21 migration notes.
  • Preserved native reqwest charset/BOM decoding and added real-host WASI coverage for multipart, binary responses, errors, incremental SSE and cancellation.
Version 0.20.0
  • Breaking: Upgraded the HTTP transport to reqwest 0.13; .http_client(...) now accepts only a reqwest 0.13 client. Default native TLS uses platform certificate verification and AWS-LC, and the SDK's direct Tokio features narrowed to io-util. See the 0.20 migration notes.
  • Added intern icon and vault connection reads, plus the October 20 schema surface: Batch callback/expiry/provider metadata, endpoint service tiers and diarization, guardrail safety-retention controls with clear builders, observability cost-allocation broadcasting, video signed URLs, image privacy controls, and Responses stop.
  • Accepted the October 20 OpenAPI snapshot (140 / 153 operations implemented; 13 deferred), forwarded vault attribution headers, and added adoption-metrics plus Axum streaming coverage.
Version 0.19.0
  • Added Intern daemon signing with an OIDC session carrying vault:read, BYOK declared regions, key budgets/last-used timestamps, expired-key filters, workspace moves and video expiration.
  • Added speech turn input/instructions, portable deferred-tool controls across Chat/Messages/Responses, chat function deferral and Messages tool-search result blocks.
  • Breaking: SpeechRequest::input (including the TTS alias) now uses SpeechInput for text or turns. Existing text builder calls work unchanged; direct field access needs the 0.19 migration notes.
  • Added explicit key-limit clearing and preserved existing PATCH clear operations through JSON round trips. Corrected the legacy reasoning test and accepted the October 13 OpenAPI snapshot (138 / 151 implemented; 13 deferred).
Version 0.18.0
  • Added prompt-cache usage details and assistant-message replay helpers that preserve modeled metadata, including reasoning summaries, signed/encrypted reasoning, and null content. Updated non-streaming and streaming tool-agent examples to retain context.
  • Added end-user registration management and organization settings, plus Batch fallback, audio provider, and activity cache-token fields. Preserved generic server-tool request types.
  • Accepted the October 6 OpenAPI review with 136 / 149 operations implemented and 13 explicitly deferred. Absent reasoning text/data fields now serialize as omitted rather than null.
Version 0.17.0
  • Added asynchronous Batch APIs, Intern invocation/daemon access, shared provider options, audio URL/image references, transcription metadata, and SCIM filters.
  • Hardened credential response errors, forwarded Batch/Intern/SCIM attribution headers, and rejected empty audio URLs.
  • Deprecated daemon-access and Coinbase charge aliases with documented replacements; retained compatibility entry points. Accepted the September 30 OpenAPI review with 129 / 142 operations implemented and 13 explicitly deferred.
Version 0.16.0
  • Added typed Intern lifecycle and streaming chat, workspace/intern vault secrets, and Decisions/System One domain clients, with runnable examples.
  • Accepted the 2026-09-23 OpenAPI drift across all 122 / 122 operations, including current API-key, BYOK, audio, embedding, image, message, rerank, video, workspace, generation, and model-endpoint schemas.
Version 0.15.0
  • Added container files, workload OAuth token exchange/signing keys, SCIM sync jobs, regional management controls, and expanded message/model fields. Accepted the 2026-09-08 OpenAPI review with 105 / 105 tracked operations.

  • Added session-cost datasets, single-interval workspace budgets, activity workspace filters, benchmark search filters, speech voice cloning, observability generation broadcast flags, and stored generation content errors.

  • Breaking: ByokKey::workspace_id is now optional, and delete_workspace(...) takes an optional confirm_default_workspace_deletion argument.

  • Accepted the 2026-08-17 OpenAPI drift review and restored tracked endpoint coverage to 97 / 97.

Version 0.14.0
  • Tool-aware chat streaming now preserves provider-supplied tool-call indices without inventing missing values, and FinishReason::Other keeps unknown provider finish reasons forward-compatible.
  • Added SCIM group and group-role mapping management plus provider-aware Files API support.
  • Accepted the 2026-08-03 OpenAPI drift review and restored tracked endpoint coverage to 95 / 95.
Version 0.13.0
  • Added explicit prompt-cache controls, static predicted output, image provider routing, conditional pricing overrides, cache-creation usage details, and guardrail flag actions.
  • Added assistant-message model annotations, BYOK-aware guardrail/workspace budgets, workspace default guardrail IDs, transcription speaker labels, and Anthropic compaction/dynamic-tool blocks.
  • Enabled image-only video requests and kept the accepted OpenAPI snapshot at 89 / 89 through the 2026-07-28 review.
  • Breaking: workspace budget upserts now return UpsertWorkspaceBudgetResponse; read the budget from .data.
  • Breaking: direct construction or matching of ContentPart::Text must account for prompt_cache_breakpoint; prefer the provided constructors or .. patterns.
Version 0.12.0
  • Added OpenRouter server-tool request helpers for chat completions, Responses API, Anthropic-compatible Messages, and preset creation request bodies.
  • Added management-key SDK support for generation feedback and workspace member listing.
  • Added model/rankings filters, analytics classifier controls, verbose transcription fields, XAI ZDR policy, routed service tiers, server-tool reasoning details, and image text chunks.
  • Accepted OpenAPI drift through 2026-07-14 and restored tracked endpoint coverage to 89 / 89.
Version 0.11.1
  • Accepted OpenRouter's new max reasoning effort and preserved future provider-defined effort strings in model metadata, keeping /models deserialization and CLI model listing forward-compatible with upstream taxonomy additions.
  • Hardened scheduled live Responses checks so transient runtime statuses stay service warnings while completed empty outputs, SDK deserialization failures, and non-retryable API errors remain hard failures.
Version 0.11.0
  • Added typed SDK coverage for image generation, files, analytics, app rankings, task classifications, unified benchmarks, singular model lookup, rankings-daily, preset listing/readback/versioning, workspace budgets, and expanded model filters.
  • Added automatic prompt caching request support through top-level cache_control builders for chat completions and Responses API requests.
  • Refreshed multimodal and metadata schemas, including rerank image-only document echoes, nullable model/generation metadata, Responses debug options, and Anthropic Messages system-role helpers.
  • Accepted OpenAPI drift through the 2026-06-29 review and restored the tracked endpoint snapshot to 87 / 87.
Version 0.10.0
  • Marked high-churn public SDK request, response, metadata, usage, pricing, discovery, streaming, and upstream taxonomy types as #[non_exhaustive]; use builders, constructors, helpers, serde deserialization, or wildcard enum arms when migrating from 0.9.x.
  • Added typed SDK coverage for audio transcriptions, BYOK provider credentials, observability destinations, multimodal embedding media parts, experimental response metadata, and model/generation metadata refreshes.
  • Added OpenRouterClientBuilder::http_client(...) for injecting a custom reqwest::Client while preserving the default transport when omitted.
  • Accepted OpenAPI drift through the 2026-05-19 review and restored the tracked endpoint snapshot to 62 / 62, while preserving OpenRouter metadata on normalized API errors and Anthropic Messages stream stop events.
Version 0.9.0
  • Added the canonical audio().speech() SDK surface for official /audio/speech, with deprecated tts() compatibility aliases.
  • Expanded workspace, workspace-scoped keys/guardrails, workspace I/O logging, generation content/metadata, and video callback coverage while keeping the endpoint snapshot at 51 / 51.
  • Marked high-churn public types as builder-first/future-proof and documented the 0.8.x -> 0.9.0 migration path.
Version 0.8.1
  • Added typed POST /tts support with the canonical tts() client surface and a runnable example.
  • Added live smoke coverage for POST /rerank and GET /organization/members, and restored the repo snapshot to 43 / 43 accepted OpenAPI endpoints.
  • Added openrouter-cli organization members list and aligned the CLI/docs surface with the latest management coverage.
Version 0.8.0
  • Completed the SDK transport migration to reqwest + rustls and removed the legacy surf / curl dependency chain.
  • Made the public HTTP error surface backend-neutral and documented the 0.7.x -> 0.8.0 breaking changes.
  • Expanded the repo snapshot with rerank, video, and organization-member coverage plus refreshed examples and CLI automation docs.
Version 0.7.0
  • Removed the SDK-level config surface and kept file/profile config out of the core crate.
  • Standardized the canonical domain-oriented client docs around the 0.7.x API surface.
  • Improved error normalization for HTTP 200 payloads that actually contain API error bodies.

Contributing

See CONTRIBUTING.md for the full contributor workflow.

At a minimum, if you change public API surface, examples, or docs:

  • update the relevant README/docs in the same change
  • run just quality
  • run just quality-ci if you touched migration docs, CLI behavior, or CI-aligned release/test flows

Related policies:

License

MIT. See LICENSE.

Runs on
GPU support unknown
What shows it
  • no dependency or feature matches a backend row
Native code
None found
  • No native code found
Python bindings
No Python binding crate found
License
MIT

Compare with similar projects

Order: strongest tier first, then most downloads, then name, with unmeasured values last. A library counts downloads over 30 days. An app counts binary downloads per release. An app with none counts its crate downloads over 30 days. ML Rust runs this catalogue, so its closest project always gets a row.

openrouter-rs beside the projects that share a topic with it
ProjectDownloadsDependentsStarsLatest releaseRuns on (GPU)Native codeLicense
openrouter-rs This page Listed

A type-safe OpenRouter Rust SDK

8,599 downloads over 30 days 3 98 0.24.0 GPU support unknown No native code found MIT
aisdk Listed

An open-source Rust library for building AI-powered applications, inspired by the Vercel AI SDK. It provides a robust, type-safe, and easy-to-use interface for interacting with various Large Language Models (LLMs).

36,877 downloads over 30 days 4 263 0.6.1 GPU support unknown No native code found MIT
liter-llm Listed

Universal LLM API client — 174 providers, streaming, tool calling. Rust-powered, type-safe, compiled.

13,151 downloads over 30 days 8 264 2.7.0 GPU support unknown Binds native code: libmimalloc-sys (feature mimalloc), tikv-jemalloc-sys (feature jemalloc) MIT

A Rust SDK for the Google Gemini API

2,207 downloads over 30 days 2 13 0.10.0 GPU support unknown No native code found MIT

An unofficial Rust SDK for Anthropic's Claude AI API

2,116 downloads over 30 days 4 18 0.2.27 GPU support unknown No native code found MIT
antrhopic-rs Listed Dormant

Anthropic Rust SDK.

1,949 downloads over 30 days 6 Not measured 0.0.8 GPU support unknown No native code found MIT
axp App Listed

An open protocol that gives AI agents a secure, sandboxed place to run code and use tools — with lean context usage. AXP works alongside MCP

Not measured Not applicable 3 Not measured Not measured Not measured Apache-2.0
Why ListedNo archive, New or Featured rule places it, so it is Listed.

What it lacks for Featured

  • It has 3 active dependents and 2 new dependents in 365 days. Featured needs 11 active dependents or 9 new dependents in 365 days. The repository route reads 98 stars, 24 forks and 10 contributors. It needs 4,539 stars, 434 forks and 79 contributors together.

What else the check found

  • The last activity is on 3 Nov 2026, 6 days ago. The rules expect an update within 365 days. Dormancy rule

Exact rules: Listed, Featured library. The check on applied thresholds version 9.

Every rule outcome, as the check records it
  • expected-interval: version 0.24.0 base 140, raised to the 365-day floor: E = 365 days
  • dormancy: last activity 2026-11-03, 6 days ago, E = 365: active
  • featured: not featured: active_users 3 < 11 and new_adopters 2 < 9 and repository route stars 98 (needs 4539), forks 24 (needs 434), contributors 10 (needs 79)
  • listed: listed: no archive, new or featured rule applies
Crates2 crates

Measurements and sources

Each signal row shows the raw value, its source and the fetch date. The Sources list gathers every distinct source on this page. Movement needs more history.

Sources6 sources
Adoption3 active dependents, 2 new dependents in 365 days1 not measured
Adoption measurements
SignalValueSourceFetchedCounts
Active dependents3crates.io database dumpYes
New dependents (365 days)2crates.io database dumpYes
Peak active dependents3crates.io database dumpYes
Active dependents as a share of the peak1crates.io database dumpYes
Binary downloads per releaseNot measuredYes
MaintenanceLatest human commit: 6 days ago3 not measured
Maintenance measurements
SignalValueSourceFetchedCounts
Latest human commit2026-11-03GitHub repositoryYes
Latest release2026-11-03crates.io database dumpYes
First release2025-07-29crates.io database dumpYes
Latest version0.24.0crates.io database dumpYes
Days the oldest outside issue waits for a reply0GitHub repositoryYes
Maintainer replies over 365 days57GitHub repositoryYes
Repository archivedfalseGitHub repositoryYes
Repository gonefalseGitHub repositoryYes
Release commit or manifest in the repotruecrates.io packageYes
Published docstruecrates.io database dumpYes
Latest release fails cargo checkNot measuredYes
Build check dateNot measuredYes
Build check toolchainNot measuredYes
SecurityUnpatched vulnerabilities: none
Security measurements
SignalValueSourceFetchedCounts
Unpatched vulnerabilities past the grace windownoneRustSec advisory databaseYes
RustSec unmaintained advisorynoneRustSec advisory databaseYes
Deprecation noticenonecrates.io database dumpYes
Deprecated requirementnonecrates.io database dumpYes
Distribution29 releases, 8,599 downloads over 30 days5 not measured
Distribution measurements
SignalValueSourceFetchedCounts
Releases29crates.io database dumpYes
Downloads over 30 days8599crates.io database dumpYes
Binary downloads over the last 3 releasesNot measuredYes
Homebrew installs on request over 365 daysNot measuredYes
Repology repository familiesNot measuredYes
Docker pull growth over 90 daysNot measuredYes
Docker pulls at the growth baselineNot measuredYes
Every version a prereleasefalsecrates.io database dumpYes
Every version 0.0.xfalsecrates.io database dumpYes
Every version yankedfalsecrates.io database dumpYes
Crate deleted from crates.iofalsecrates.io database dumpYes
Repository98 stars, 24 forks, 10 contributors, 408 commits. Stars alone never qualify a project.
Repository measurements
SignalValueSourceFetchedCounts
GitHub stars98GitHub repositoryYes — one part of the repository route
GitHub forks24GitHub repositoryYes — one part of the repository route
Contributors with a GitHub account10GitHub contributorsYes — one part of the repository route
Commits on the default branch408GitHub repositoryNo
Repository's main crate left out of the entrynonecrates.io database dumpYes
Facts that never count
Facts that never count measurements
SignalValueSourceFetchedCounts
LicenseMITcrates.io database dumpNo
Runs on, from listed crates and their direct dependenciesGPU support unknowncrates.io database dumpNo
What shows each backendno dependency or feature matches a backend rowcrates.io database dumpNo
Native code, from listed crates and their dependenciesNo native code foundcrates.io database dumpNo
Python bindings, from direct dependencies of listed cratesNo Python binding crate foundcrates.io database dumpNo
Crates that depend on a listed crate directly3crates.io database dumpNo

Corrections and review history

Report a correction

No correction applies to this entry.

Judgments

A judgment enters only through an approved issue and a merged pull request.

No judgment applies to this entry.