sdk
Rust
Async-first. tokio + reqwest with rustls. Not in the Argand workspace, so cargo can pull it without compiling the rest of the engine.
Install
cargo add argand-client --git ssh://git@git.argand.org/nicweyand/argand.git Or pin a revision in Cargo.toml:
[dependencies]
argand-client = { git = "ssh://git@git.argand.org/nicweyand/argand.git", branch = "main" } Source-only from Forgejo. crates.io publish deferred to launch (mid-2026).
Hello world (anonymous)
src/main.rs rust
use argand_client::ArgandClient;
#[tokio::main]
async fn main() -> argand_client::Result<()> {
let client = ArgandClient::new()?;
let response = client.search("rust async runtime", 1, 10).await?;
for hit in &response.results {
println!("{}. {} -> {}", hit.rank, hit.title, hit.url);
}
Ok(())
} Method surface
client.search(query, page, limit).await→Result<SearchResponse>client.lucky(query).await→Result<String>(Location URL)client.fetch(...)/client.cite(...)— returnArgandError::NotImplementeduntil v2.
Auth
let client = ArgandClient::with_api_key("your-argand-api-key")?; Self-hosted + builder
use std::time::Duration;
use argand_client::{ArgandClient, RetryPolicy};
let client = ArgandClient::builder()
.base_url("https://argand.example.org")
.api_key("your-argand-api-key")
.connect_timeout(Duration::from_secs(5))
.request_timeout(Duration::from_secs(20))
.retry(RetryPolicy {
max_attempts: 5,
base_delay: Duration::from_millis(100),
max_delay: Duration::from_secs(4),
})
.build()?; Retry semantics
Default: 3 attempts, 250ms → 8s exponential backoff. 429 and 5xx retry. Retry-After (seconds
form) is honored. 401 / 403 raise ArgandError::Auth immediately and never retry.
Error types
ArgandError variants:
Auth { status, message }— 401/403, never retried.RateLimit { status, retry_after, message }— 429 after retries.Server { status, message }— 5xx after retries.Timeout(message)— transport timeout.Transport(message)— DNS / TLS / connection.Protocol(message)— body doesn't match the contract.NotImplemented(_)— v2-reserved (fetch,cite).Unexpected { status, message }— anything that doesn't bucket above.InvalidUrl(message)— URL construction failed.
use argand_client::{ArgandClient, ArgandError};
let client = ArgandClient::new()?;
match client.search("rust async runtime", 1, 10).await {
Ok(resp) => println!("{} hits", resp.results.len()),
Err(ArgandError::RateLimit { retry_after, .. }) => {
println!("backoff exhausted; retry after {retry_after:?}");
}
Err(ArgandError::Auth { .. }) => println!("bad api key"),
Err(ArgandError::Server { status, .. }) => println!("server {status}"),
Err(ArgandError::NotImplemented(_)) => println!("v2-reserved"),
Err(e) => return Err(e),
}