# openrouter-rs
Type-safe, async Rust SDK for the OpenRouter API.
[](https://crates.io/crates/openrouter-rs)
[](https://docs.rs/openrouter-rs)
[](https://github.com/realmorrisliu/openrouter-rs/actions/workflows/ci.yml)
[](https://opensource.org/licenses/MIT)
[docs.rs](https://docs.rs/openrouter-rs) |
[examples](https://github.com/realmorrisliu/openrouter-rs/tree/main/examples) |
[crate](https://crates.io/crates/openrouter-rs) |
[docs map](docs/README.md) |
[openrouter-cli](https://github.com/realmorrisliu/openrouter-rs/tree/main/crates/openrouter-cli) |
[contributing](CONTRIBUTING.md) |
[changelog](CHANGELOG.md)
`openrouter-rs` is a community-maintained Rust SDK for OpenRouter. It exposes a domain-oriented client for chat, responses, messages, rerank, audio speech/transcription, image generation, video generation, models, embeddings, files, presets, analytics, and management APIs, plus a companion CLI in the same repository.
The current repo snapshot implements `89 / 89` official OpenAPI method/path entries, with published live integration coverage tracked in [`docs/operations/official-endpoint-test-matrix.md`](docs/operations/official-endpoint-test-matrix.md).
## Why `openrouter-rs`
- Domain-oriented clients: `chat()`, `responses()`, `messages()`, `rerank()`, `audio().speech()`, `audio().transcriptions()`, `images()`, `videos()`, `files()`, `models()`, `management()`, and opt-in `legacy()`
- Typed request/response models with builder-style ergonomics
- Tokio-native `reqwest + rustls` transport with no `surf` / `curl` dependency chain
- 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, files, embeddings, API-key management, preset creation/readback/versioning, analytics, BYOK provider credentials, observability destinations, workspace management, organization members, guardrails, activity, credits, and generation metadata/content coverage
- A companion CLI for profile resolution, discovery, management, and billing/usage workflows
## Installation
```toml
[dependencies]
openrouter-rs = "0.13.0"
tokio = { version = "1", features = ["full"] }
```
Legacy text completions are opt-in:
```toml
[dependencies]
openrouter-rs = { version = "0.13.0", features = ["legacy-completions"] }
tokio = { version = "1", features = ["full"] }
```
Requirements:
- Rust `1.85+`
- Tokio `1.x`
- `OPENROUTER_API_KEY` for API-backed examples and live tests
- `OPENROUTER_MANAGEMENT_KEY` for management-governed examples and tests
## Quick Start
```rust
use openrouter_rs::{
OpenRouterClient,
api::chat::{ChatCompletionRequest, Message},
types::Role,
};
#[tokio::main]
async fn main() -> Result<(), Box> {
let client = OpenRouterClient::builder()
.api_key(std::env::var("OPENROUTER_API_KEY")?)
.http_referer("https://yourapp.example")
.x_title("my-openrouter-app")
.app_categories(["cli-agent"])
.build()?;
let request = ChatCompletionRequest::builder()
.model("anthropic/claude-sonnet-4")
.messages(vec![Message::new(
Role::User,
"Explain Rust ownership in plain English.",
)])
.build()?;
let response = client.chat().create(&request).await?;
println!("{}", response.choices[0].content().unwrap_or(""));
Ok(())
}
```
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 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 |
| `audio().speech()` | `create` | `/audio/speech` (legacy `/tts` fallback) | API key |
| `audio().transcriptions()` | `create` | `/audio/transcriptions` | API 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 |
| `models()` | `list`, `list_filtered`, `list_by_category`, `list_by_parameters`, `get`, `list_endpoints`, `list_providers`, `list_user_models`, `get_model_count`, `get_rankings_daily`, `get_rankings_daily_filtered`, `get_app_rankings`, `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`, `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`, `list_workspaces`, `create_workspace`, `get_workspace`, `update_workspace`, `delete_workspace`, `list_workspace_budgets`, `upsert_workspace_budget`, `delete_workspace_budget`, `list_workspace_members`, `add_workspace_members`, `remove_workspace_members`, `get_activity`, `get_credits`, `create_coinbase_charge`, `get_generation`, `get_generation_content`, `submit_generation_feedback` | `/keys*`, `/presets*`, `/analytics*`, `/byok*`, `/observability/destinations*`, `/auth/keys*`, `/guardrails*`, `/organization/members`, `/workspaces*`, `/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_url`
- `api_key`
- `management_key`
- `http_referer`
- `x_title`
- `app_categories`
- `http_client`
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/`](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:
```rust
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
| Example | Focus |
| --- | --- |
| [`examples/axum_chat_gateway.rs`](examples/axum_chat_gateway.rs) | Minimal `axum` server that proxies prompts through `OpenRouterClient` |
| [`examples/typed_tool_agent.rs`](examples/typed_tool_agent.rs) | Practical typed-tool agent loop with explicit tool dispatch |
| [`examples/domain_chat_completion.rs`](examples/domain_chat_completion.rs) | Canonical `chat()` request with the domain-oriented client |
| [`examples/custom_http_client.rs`](examples/custom_http_client.rs) | Inject a custom `reqwest::Client` (proxies, timeouts, middleware) |
### Tokio Streaming
| Example | Focus |
| --- | --- |
| [`examples/stream_chat_completion.rs`](examples/stream_chat_completion.rs) | Stream chat deltas into a Tokio task/stdout |
| [`examples/stream_chat_with_tools.rs`](examples/stream_chat_with_tools.rs) | Tool-aware streaming aggregation plus a second round after execution |
| [`examples/stream_response.rs`](examples/stream_response.rs) | `responses()` streaming |
| [`examples/stream_messages.rs`](examples/stream_messages.rs) | `messages()` streaming |
### API Surface Demos
| Example | Focus |
| --- | --- |
| [`examples/basic_tool_calling.rs`](examples/basic_tool_calling.rs) | Manual tool-calling loop |
| [`examples/typed_tool_calling.rs`](examples/typed_tool_calling.rs) | Typed tools with generated schema |
| [`examples/create_response.rs`](examples/create_response.rs) | `responses()` create |
| [`examples/create_message.rs`](examples/create_message.rs) | `messages()` create |
| [`examples/create_rerank.rs`](examples/create_rerank.rs) | `rerank().create(...)` |
| [`examples/create_speech.rs`](examples/create_speech.rs) | `audio().speech().create(...)` |
| [`examples/create_transcription.rs`](examples/create_transcription.rs) | `audio().transcriptions().create(...)` |
| [`examples/create_image_generation.rs`](examples/create_image_generation.rs) | `images().create(...)` |
| [`examples/create_video_generation.rs`](examples/create_video_generation.rs) | `videos().create(...)` |
| [`examples/create_embedding.rs`](examples/create_embedding.rs) | `models().create_embedding(...)` |
| [`examples/domain_management_api_keys.rs`](examples/domain_management_api_keys.rs) | API-key management via `management()` |
| [`examples/list_byok_keys.rs`](examples/list_byok_keys.rs) | `management().list_byok_keys(...)` |
| [`examples/list_observability_destinations.rs`](examples/list_observability_destinations.rs) | `management().list_observability_destinations(...)` |
| [`examples/list_organization_members.rs`](examples/list_organization_members.rs) | `management().list_organization_members(...)` |
| [`examples/list_workspaces.rs`](examples/list_workspaces.rs) | `management().list_workspaces(...)` |
| [`examples/exchange_code_for_api_key.rs`](examples/exchange_code_for_api_key.rs) | PKCE/auth-code flow |
| [`examples/send_completion_request.rs`](examples/send_completion_request.rs) | Legacy completions (`legacy-completions` required) |
Typical local usage:
```bash
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`](docs/operations/cli-automation-workflows.md).
## CLI Companion
This workspace also contains [`crates/openrouter-cli`](crates/openrouter-cli), a companion CLI for profile resolution, discovery, management, and usage/billing workflows.
Examples:
```bash
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`](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`](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 fully implemented at the SDK surface (`89 / 89`)
- Live integration coverage and gaps are published in [`docs/operations/official-endpoint-test-matrix.md`](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`](MIGRATION.md)
- Legacy `POST /completions` support remains available behind the `legacy-completions` feature
### 🔁 0.10 Public Model Migration
Full migration guide: [`MIGRATION.md`](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`](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`](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:
```bash
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`](tests/integration/README.md). A starter env file lives at [`.env.example`](.env.example).
## Docs Map
Start with [`docs/README.md`](docs/README.md) for grouped navigation across root docs, `docs/`, `specs/`, and subsystem READMEs.
### Users And Setup
- [`MIGRATION.md`](MIGRATION.md) for upgrade guidance across breaking SDK changes
- [`crates/openrouter-cli/README.md`](crates/openrouter-cli/README.md) for CLI behavior, examples, and auth/config precedence
- [`CHANGELOG.md`](CHANGELOG.md) for release-by-release history
### Contributors And Project Policies
- [`CONTRIBUTING.md`](CONTRIBUTING.md) for contributor workflow and review expectations
- [`docs/policies/maintenance-policy.md`](docs/policies/maintenance-policy.md) for release, MSRV, and breaking-change policy
- [`docs/policies/compatibility-update-policy.md`](docs/policies/compatibility-update-policy.md) for upstream compatibility reporting cadence, templates, and update rules
- [`SECURITY.md`](SECURITY.md) for vulnerability reporting
- [`SUPPORT.md`](SUPPORT.md) for support boundaries and issue-reporting guidance
### Design And Roadmap
- [`docs/design/generated-core-architecture.md`](docs/design/generated-core-architecture.md) for the generated-core plus idiomatic-wrapper design baseline
- [`docs/design/http-transport-migration.md`](docs/design/http-transport-migration.md) for the historical design baseline behind the completed `reqwest + rustls` transport migration
### Operations, Validation, And Distribution
- [`docs/operations/official-endpoint-test-matrix.md`](docs/operations/official-endpoint-test-matrix.md) for endpoint-by-endpoint implementation and test status
- [`docs/operations/openapi-drift-reporting.md`](docs/operations/openapi-drift-reporting.md) for weekly upstream-spec drift detection and baseline refresh workflow
- [`docs/operations/cli-automation-workflows.md`](docs/operations/cli-automation-workflows.md) for JSON-first shell and CI recipes built around `openrouter-cli`
- [`tests/integration/README.md`](tests/integration/README.md) for live test pools and env switches
- [`docs/community/awesome-openrouter/README.md`](docs/community/awesome-openrouter/README.md) for the Awesome OpenRouter submission kit and directory-safe assets
## 📈 Release History
### Unreleased
- No unreleased changes yet.
### Version 0.13.0 *(Latest)*
- 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`](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:
- [`docs/policies/maintenance-policy.md`](docs/policies/maintenance-policy.md)
- [`SECURITY.md`](SECURITY.md)
- [`SUPPORT.md`](SUPPORT.md)
## License
MIT. See [LICENSE](LICENSE).