openrouter-rs
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. It exposes a domain-oriented client for chat, responses, messages, rerank, text-to-speech, video generation, models, embeddings, and management APIs, plus a companion CLI in the same repository.
The current repo snapshot implements 43 / 43 official OpenAPI method/path entries, with published live integration coverage tracked in docs/operations/official-endpoint-test-matrix.md.
Why openrouter-rs
- Domain-oriented clients:
chat(),responses(),messages(),rerank(),tts(),videos(),models(),management(), and opt-inlegacy() - Typed request/response models with builder-style ergonomics
- Tokio-native
reqwest + rustlstransport with nosurf/curldependency chain - Streaming support for chat, responses, and messages, including a unified stream abstraction
- Typed tools, manual JSON-schema tools, and multimodal chat content
- Discovery, rerank, text-to-speech, video generation, embeddings, API-key management, organization members, guardrails, activity, credits, and generation coverage
- A companion CLI for profile resolution, discovery, management, and billing/usage workflows
Installation
[]
= "0.8.1"
= { = "1", = ["full"] }
Legacy text completions are opt-in:
[]
= { = "0.8.1", = ["legacy-completions"] }
= { = "1", = ["full"] }
Requirements:
- Rust
1.85+ - Tokio
1.x OPENROUTER_API_KEYfor API-backed examples and live testsOPENROUTER_MANAGEMENT_KEYfor management-governed examples and tests
Quick Start
use ;
async
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.
API Surface
The canonical public surface in 0.8.x is domain-oriented:
| Domain | Canonical methods | Primary endpoints | Auth note |
|---|---|---|---|
chat() |
create, stream, stream_tool_aware, stream_unified |
/chat/completions |
API key |
responses() |
create, stream, stream_unified |
/responses |
API key |
messages() |
create, stream, stream_unified |
/messages |
API key |
rerank() |
create |
/rerank |
API key |
tts() |
create |
/tts |
API key |
videos() |
create, list_models, get_generation, get_content |
/videos* |
API key |
models() |
list, list_by_category, list_by_parameters, list_endpoints, list_providers, list_user_models, get_model_count, list_zdr_endpoints, create_embedding, list_embedding_models |
/models*, /providers, /endpoints/zdr, /embeddings* |
API key |
management() |
create_api_key, list_api_keys, create_auth_code, create_api_key_from_auth_code, list_guardrails, list_organization_members, get_activity, get_credits, create_coinbase_charge, get_generation |
/keys*, /auth/keys*, /guardrails*, /organization/members, /activity, /credits*, /generation, /key |
Governed endpoints require a management key; billing/session endpoints still use the normal API key because that is how OpenRouter authenticates them |
legacy() |
completions().create |
/completions |
legacy-completions feature + API key |
At runtime, the builder/client exposes the values the SDK directly consumes:
base_urlapi_keymanagement_keyhttp_refererx_titleapp_categories
Common Workflows
openrouter-rs is not just a thin /chat/completions wrapper. The repo currently covers:
- chat completions, responses, and Anthropic-compatible messages
- rerank, text-to-speech, and video generation polling/content retrieval
- unified streaming across chat, responses, and messages
- manual tools and typed tools backed by
schemars - multimodal chat content, including image, audio, video, and file parts
- model discovery, provider discovery, embeddings, and ZDR endpoints
- management-key workflows for keys, auth codes, organization members, guardrails, and activity, plus API-key-authenticated credits and generation endpoints
For deeper examples, prefer the runnable examples in examples/ over long README snippets.
Examples
The repo includes runnable examples for the highest-value workflows:
Application Patterns
| Example | Focus |
|---|---|
examples/axum_chat_gateway.rs |
Minimal axum server that proxies prompts through OpenRouterClient |
examples/typed_tool_agent.rs |
Practical typed-tool agent loop with explicit tool dispatch |
examples/domain_chat_completion.rs |
Canonical chat() request with the domain-oriented client |
Tokio Streaming
| Example | Focus |
|---|---|
examples/stream_chat_completion.rs |
Stream chat deltas into a Tokio task/stdout |
examples/stream_chat_with_tools.rs |
Tool-aware streaming aggregation plus a second round after execution |
examples/stream_response.rs |
responses() streaming |
examples/stream_messages.rs |
messages() streaming |
API Surface Demos
| Example | Focus |
|---|---|
examples/basic_tool_calling.rs |
Manual tool-calling loop |
examples/typed_tool_calling.rs |
Typed tools with generated schema |
examples/create_response.rs |
responses() create |
examples/create_message.rs |
messages() create |
examples/create_rerank.rs |
rerank().create(...) |
examples/create_tts.rs |
tts().create(...) |
examples/create_video_generation.rs |
videos().create(...) |
examples/create_embedding.rs |
models().create_embedding(...) |
examples/domain_management_api_keys.rs |
API-key management via management() |
examples/list_organization_members.rs |
management().list_organization_members(...) |
examples/exchange_code_for_api_key.rs |
PKCE/auth-code flow |
examples/send_completion_request.rs |
Legacy completions (legacy-completions required) |
Typical local usage:
For shell and CI automation recipes built around the companion CLI, see docs/operations/cli-automation-workflows.md.
CLI Companion
This workspace also contains crates/openrouter-cli, a companion CLI for profile resolution, discovery, management, and usage/billing workflows.
Examples:
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
- Full endpoint coverage is tracked against the current OpenAPI snapshot
- Live integration coverage and gaps are published in
docs/operations/official-endpoint-test-matrix.md - Migration guidance for the
0.7.x -> 0.8.0transport/error-surface release, plus the archived0.5.x -> 0.6.xnaming guide, lives inMIGRATION.md - Legacy
POST /completionssupport remains available behind thelegacy-completionsfeature
🔁 0.8 Transport/Error Migration
Full migration guide: MIGRATION.md
OpenRouterError::HttpRequest(surf::Error)->OpenRouterError::HttpRequest(HttpRequestError)ApiErrorContext.status: surf::StatusCode->ApiErrorContext.status: http::StatusCodeopenrouter_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
OpenRouterClientpluschat(),responses(),messages(),rerank(),tts(),videos(),models(),management(), andlegacy()
🔁 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:
OPENROUTER_MANAGEMENT_KEY=...
Focused commands:
just test-unitjust test-libjust test-docjust test-integration-subsetsjust test-clijust check-migration-docsjust test-migration-smokejust 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
MIGRATION.mdfor upgrade guidance across breaking SDK changescrates/openrouter-cli/README.mdfor CLI behavior, examples, and auth/config precedenceCHANGELOG.mdfor release-by-release history
Contributors And Project Policies
CONTRIBUTING.mdfor contributor workflow and review expectationsdocs/policies/maintenance-policy.mdfor release, MSRV, and breaking-change policydocs/policies/compatibility-update-policy.mdfor upstream compatibility reporting cadence, templates, and update rulesSECURITY.mdfor vulnerability reportingSUPPORT.mdfor support boundaries and issue-reporting guidance
Design And Roadmap
docs/design/generated-core-architecture.mdfor the generated-core plus idiomatic-wrapper design baselinedocs/design/http-transport-migration.mdfor the historical design baseline behind the completedreqwest + rustlstransport migration
Operations, Validation, And Distribution
docs/operations/official-endpoint-test-matrix.mdfor endpoint-by-endpoint implementation and test statusdocs/operations/openapi-drift-reporting.mdfor nightly upstream-spec drift detection and baseline refresh workflowdocs/operations/cli-automation-workflows.mdfor JSON-first shell and CI recipes built aroundopenrouter-clitests/integration/README.mdfor live test pools and env switchesdocs/community/awesome-openrouter/README.mdfor the Awesome OpenRouter submission kit and directory-safe assets
📈 Release History
Version 0.8.1 (Latest)
- Added typed
POST /ttssupport with the canonicaltts()client surface and a runnable example. - Added live smoke coverage for
POST /rerankandGET /organization/members, and restored the repo snapshot to43 / 43accepted OpenAPI endpoints. - Added
openrouter-cli organization members listand aligned the CLI/docs surface with the latest management coverage.
Version 0.8.0
- Completed the SDK transport migration to
reqwest + rustlsand removed the legacysurf/curldependency chain. - Made the public HTTP error surface backend-neutral and documented the
0.7.x -> 0.8.0breaking 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.xAPI surface. - Improved error normalization for
HTTP 200payloads 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-ciif you touched migration docs, CLI behavior, or CI-aligned release/test flows
Related policies:
License
MIT. See LICENSE.