# anakin-sdk (Rust)

Official Rust SDK for [Anakin](https://anakin.io) — web scraping, crawling, search, and Wire actions.

[![Crates.io](https://img.shields.io/crates/v/anakin-sdk.svg)](https://crates.io/crates/anakin-sdk)
[![Docs.rs](https://docs.rs/anakin-sdk/badge.svg)](https://docs.rs/anakin-sdk)
[![License](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE)

> **Status: alpha (v0.1.x).** Public API may change between minor versions until v1.0.

## Install

```toml
[dependencies]
anakin-sdk = "0.1"
tokio = { version = "1", features = ["full"] }
```

The crate name on crates.io is `anakin-sdk`; the import name is `anakin`.

Requires Rust 1.70+.

## Quickstart

```rust
use anakin::Client;

#[tokio::main]
async fn main() -> anakin::Result<()> {
    let client = Client::builder()
        .api_key("ak-...")  // or set ANAKIN_API_KEY
        .build()?;

    let doc = client.scrape("https://example.com").await?;
    println!("{}", doc.markdown.unwrap_or_default());
    Ok(())
}
```

The SDK polls long-running jobs internally — `await` resolves with the final result. No job IDs to manage, no polling loops to write.

## Method overview

| Method | Endpoint | Sync? |
|---|---|---|
| `client.scrape(url)` / `scrape_with(url, opts)` | `POST /url-scraper` → poll | async |
| `client.map(url)` / `map_with(url, opts)` | `POST /map` → poll | async |
| `client.crawl(url)` / `crawl_with(url, opts)` | `POST /crawl` → poll | async |
| `client.search(query)` / `search_with(query, opts)` | `POST /search` | sync |
| `client.agentic_search(prompt)` / `agentic_search_with(...)` | `POST /agentic-search` → poll | async |
| `client.wire(action_id, params)` | `POST /holocron/task` → poll | async |
| `client.sessions().list/create/save/update/delete` | `/browser-sessions/*` | various |
| `anakin::supported_countries()` | offline (bundled) | sync |

## Configuration

```rust
use std::time::Duration;

let client = anakin::Client::builder()
    .api_key("ak-...")                            // or ANAKIN_API_KEY env var
    .base_url("https://api.anakin.io/v1")
    .timeout(Duration::from_secs(60))
    .max_retries(4)                               // on 429 / 5xx / transient
    .poll_interval(Duration::from_secs(1))        // initial polling delay
    .poll_max_interval(Duration::from_secs(10))   // capped backoff
    .poll_timeout(Duration::from_secs(300))       // total poll budget
    .build()?;
```

## Errors

All errors come back as variants of `anakin::Error`:

```rust
use anakin::Error;

match client.scrape("https://example.com").await {
    Ok(doc) => println!("{}", doc.markdown.unwrap_or_default()),
    Err(Error::InsufficientCredits { balance, required, .. }) => {
        eprintln!("out of credits: balance={balance}, needed={required}");
    }
    Err(Error::Authentication { .. }) => {
        eprintln!("invalid API key — get a fresh one at anakin.io/dashboard");
    }
    Err(Error::RateLimit { retry_after, .. }) => {
        eprintln!("rate limited; retry after {retry_after:?}");
    }
    Err(Error::JobFailed { reason, .. }) => {
        eprintln!("job failed: {reason}");
    }
    Err(e) => {
        eprintln!("unknown error: {e}");
    }
}
```

The error enum:

| Variant | When |
|---|---|
| `Error::Authentication` | 401 — invalid or missing API key |
| `Error::InsufficientCredits` | 402 — out of credits (with `balance`, `required`) |
| `Error::InvalidRequest` | 400 — validation failure |
| `Error::RateLimit` | 429 — after retry budget exhausted (with `retry_after`) |
| `Error::JobFailed` | Polled job came back with `status="failed"` (with `reason`) |
| `Error::JobTimeout` | Polling budget exhausted before terminal status |
| `Error::Server` | 5xx — after retries exhausted |
| `Error::Network` | DNS / connect / read-timeout |
| `Error::Other` | Decoding failures, missing fields |

## Build from source

```bash
git clone https://github.com/Anakin-Inc/anakin-rust
cd anakin-rust
cargo build
cargo test
```

## Related packages

- [`@anakin-io/sdk`](https://www.npmjs.com/package/@anakin-io/sdk) — Node.js / TypeScript SDK
- [`anakin-sdk`](https://pypi.org/project/anakin-sdk/) — Python SDK
- [`github.com/Anakin-Inc/anakin-go`](https://github.com/Anakin-Inc/anakin-go) — Go SDK
- [`io.anakin:anakin-sdk`](https://search.maven.org/artifact/io.anakin/anakin-sdk) — Java SDK
- [`anakin-sdk` (rubygems)](https://rubygems.org/gems/anakin-sdk) — Ruby SDK
- [`Anakin` (NuGet)](https://www.nuget.org/packages/Anakin) — .NET SDK
- [`@anakin-io/mcp`](https://www.npmjs.com/package/@anakin-io/mcp) — Model Context Protocol server for AI agents

## License

[Apache 2.0](LICENSE)
