claude-api
Type-safe Rust client for the Anthropic API.
Sibling project to claude-wrapper. That one wraps the claude CLI; this
one wraps the HTTP API. They do not depend on each other.
Status
v0.5 -- full API surface. Every documented Anthropic endpoint is now reachable through a typed Rust namespace:
- Messages, Models, Batches, Files, count_tokens, streaming (carried forward from v0.1-v0.4)
- Admin API (27 endpoints): organization, invites, users, workspaces + members, api_keys, usage_report, cost_report, rate_limits
- Skills API (8 endpoints): full CRUD + skill versions, multipart upload
- User Profiles API (5 endpoints) including the enrollment-URL flow
- Managed Agents preview: sessions, agents, environments, vaults
- credentials, memory_stores + memories + memory_versions, session resources, events (list/send/SSE stream), and the multi-agent threads endpoints
- Bedrock auth via a sigv4
RequestSignerextension point - Typed
BetaHeaderenum for the 23 canonicalanthropic-betavalues, withOther(String)forward-compat fallthrough - Live-test harness with 15 record-or-replay tests covering the cheap and read-only surfaces; cassettes committed for free CI replay
- Spec-diff tooling that compares every public Rust struct to its OpenAPI schema field-by-field
Carried forward from v0.4 and earlier:
- v0.4 Agent-loop guardrails (parallel dispatch + cost budget +
cancellation), streaming callbacks,
dry_run,cost_preview,#[derive(Tool)]proc macro - v0.3 Typed
Citationenum, context compaction, full Batches API, Files API beta, typedBuiltinToolwrappers - v0.2
ToolRegistry+ agent loop,Conversationhelper,PricingTable, vision and document blocks, prompt-cache sugar, sync feature - v0.1 Messages + Models endpoints, forward-compatible serde,
retry policy that honors
Retry-After,request-idpropagation, structuredtracing
See CHANGELOG.md for per-version detail.
Quick start
[]
= "0.5"
= { = "1", = ["macros", "rt-multi-thread"] }
use ;
async
See examples/ for streaming, streaming-with-callbacks,
tool use, derived tools, vision, document, conversation, and the agent
loop.
Why another Anthropic Rust client?
-
Forward-compatible by design. New
ContentBlock,StreamEvent,ContentDelta,Citation, andBuiltinToolvariants from the API are preserved as raw JSON via anOther(Value)arm rather than breaking older SDK versions. Newtypetags round-trip byte-for-byte. No other Rust crate (and no official SDK in any language) does this.Upgrade contract: when a server-side
typetag that previously fell through toOtherbecomes a recognizedKnownvariant in a new release, that's a minor version bump. Code that pattern-matched onOther(v) if v["type"] == "thinking"will silently stop matching -- the value now arrives asKnown(KnownBlock::Thinking { .. }). When you bump claude-api, sweep yourOthermatches and route the newly-known variants explicitly. Releases that promote variants will call them out in the changelog. -
Retry-Afterhonored. Most existing Rust crates for the Anthropic API ignore the header. This one respects it, with configurableRetryPolicy { max_attempts, initial_backoff, max_backoff, jitter, respect_retry_after }. -
Cost-aware by default.
PricingTableships with bundled rates for current models;Conversation::cost(&PricingTable)andcost_preview(&request, &pricing)give you live and pre-flight USD numbers. Agent loop accepts acost_budgetthat aborts a run before the next iteration if a cap is exceeded. -
Operational quality from day one.
request-idis surfaced on every error (critical for support tickets),ApiKey: Debugredacts the secret, base-URL override makes wiremock-based testing the default story, structuredtracingspans on every request and retry. -
Tools you can derive.
#[derive(Tool)]on a struct generates theToolimpl from the struct'sJsonSchemaand an inherentasync fn run(self). No string-literal schemas, no boilerplatename/descriptionoverrides unless you want them. -
No surprise abstractions. No prompt-template DSL, no multi-provider routing, no response caching, no bundled CLI. If you want those, use a different crate.
Feature flags
| Flag | Default | Adds |
|---|---|---|
async |
yes | Async client (tokio + reqwest) |
rustls |
yes | rustls TLS backend |
streaming |
yes | SSE streaming + EventStream::aggregate + callback hooks |
sync |
Blocking client (reqwest blocking) | |
native-tls |
native-tls backend instead of rustls | |
schemars-tools |
Tool::from_schemars::<T: JsonSchema> ctor |
|
derive |
#[derive(Tool)] (pulls in claude-api-derive) |
|
pricing |
PricingTable + cost calculation + cost_preview |
|
conversation |
Multi-turn Conversation helper |
|
bedrock |
AWS sigv4 BedrockSigner (custom auth signer) |
|
vertex |
GCP Vertex auth -- v0.6+ (placeholder; not wired yet) | |
admin |
Admin API (organizations, users, workspaces, etc.) | |
skills |
Skills API (CRUD + versions, multipart upload) | |
user-profiles |
User Profiles API + enrollment-URL flow | |
managed-agents-preview |
Managed Agents preview (sessions, agents, vaults, ...) |
Disable defaults if you only want the type definitions:
= { = "0.5", = false }
Tool example with #[derive(Tool)]
use Tool;
use ;
use JsonSchema;
use Deserialize;
use ;
/// Get the current weather for a city.
let mut registry = new;
registry.register_tool;
The tool name (get_weather) is derived from the struct name; the
description from the doc comment. Override either with
#[tool(name = "...", description = "...")].
Roadmap
- v0.1 Messages, Models, streaming, retry, forward-compat
- v0.2
ToolRegistry+ agent loop,Conversationhelper,PricingTable, vision and document blocks, prompt-cache sugar, sync feature - v0.3 Batches (with poller), Files API, citations, typed built-in tool wrappers, context compaction
- v0.4 Agent-loop guardrails (parallel dispatch + cost budget +
cancellation), streaming callbacks,
dry_run,cost_preview,#[derive(Tool)]proc macro, mid-stream tool approval gates, record/replay test harness, Bedrock auth (sigv4 signer) - v0.5 Admin / Skills / User Profiles / Managed Agents preview
endpoints, typed
BetaHeaderenum, spec-diff tooling, live-test cassettes - v0.6+ Vertex AI auth, Tower
Service->Toolintegration, typed promotions forstop_details/context_management/ModelCapabilities, streaming-SSE cassette recording, vault credential live tests
Anti-goals
If a feature request comes in for any of these, the answer is "different crate":
- Local prompt templating
- Multi-provider routing (OpenAI, Gemini, etc.)
- Response caching layer
- Background queues or scheduling
- Vector store integrations
- Embedding API (Anthropic does not have one; do not stub)
- Legacy
/v1/completeCompletions API
MSRV
Rust 1.82 or later.
License
Licensed under either of Apache-2.0 or MIT at your option. Contributions are dual-licensed under the same terms.