# anakin-elixir
Official Elixir SDK for [Anakin](https://anakin.io) — web scraping, crawling, search, and Wire actions.
> **Status: alpha (v0.1.x).** Public API may change between minor versions until v1.0.
## Install
Add to your `mix.exs`:
```elixir
def deps do
[{:anakin, "~> 0.1"}]
end
```
Then:
```bash
mix deps.get
```
Requires Elixir 1.14+.
## Quickstart
```elixir
{:ok, client} = Anakin.Client.new(api_key: "ak-...") # or set ANAKIN_API_KEY
case Anakin.scrape(client, "https://example.com") do
{:ok, doc} -> IO.puts(doc["markdown"])
{:error, e} -> IO.warn(Exception.message(e))
end
```
The SDK polls long-running jobs internally — `Anakin.scrape/3` and friends block until the job reaches a terminal status, then return `{:ok, result}`. No job IDs to manage, no polling loops to write.
## Function overview
| Function | Endpoint | Sync? |
|---|---|---|
| `Anakin.scrape(client, url, opts \\ [])` | `POST /url-scraper` → poll | async |
| `Anakin.map(client, url, opts \\ [])` | `POST /map` → poll | async |
| `Anakin.crawl(client, url, opts \\ [])` | `POST /crawl` → poll | async |
| `Anakin.search(client, query, opts \\ [])` | `POST /search` | sync |
| `Anakin.agentic_search(client, prompt, opts \\ [])` | `POST /agentic-search` → poll | async |
| `Anakin.wire(client, action_id, params \\ %{})` | `POST /holocron/task` → poll | async |
| `Anakin.list_sessions/1`, `create_session/3`, `save_session/3`, `update_session/3`, `delete_session/2` | `/browser-sessions/*` | various |
| `Anakin.Countries.supported/0` | offline (bundled) | sync |
## Configuration
```elixir
{:ok, client} = Anakin.Client.new(
api_key: "ak-...", # or ANAKIN_API_KEY env var
base_url: "https://api.anakin.io/v1",
request_timeout_ms: 60_000, # per-request timeout
max_retries: 4, # on 429 / 5xx / transient
poll_interval_ms: 1_000, # initial polling delay
poll_max_interval_ms: 10_000, # capped backoff
poll_timeout_ms: 300_000, # total poll budget
req_options: [] # extra options forwarded to Req.request/2
)
```
Or, with `Anakin.Client.new!/1` to raise on missing key:
```elixir
client = Anakin.Client.new!(api_key: System.fetch_env!("ANAKIN_API_KEY"))
```
## Errors
Every error returned by the SDK is a struct that implements the `Exception` behaviour:
```elixir
case Anakin.scrape(client, "https://example.com") do
{:ok, doc} -> doc
{:error, %Anakin.Error.InsufficientCredits{balance: b, required: r}} ->
IO.puts("out of credits: balance=#{b}, needed=#{r}")
{:error, %Anakin.Error.Authentication{}} ->
IO.puts("invalid API key — get a fresh one at anakin.io/dashboard")
{:error, %Anakin.Error.RateLimit{retry_after: ra}} ->
IO.puts("rate limited; retry after #{ra}s")
{:error, %Anakin.Error.JobFailed{reason: reason}} ->
IO.puts("job failed: #{reason}")
{:error, e} ->
IO.puts("unknown error: #{Exception.message(e)}")
end
```
The error hierarchy:
| Module | When |
|---|---|
| `Anakin.Error.Authentication` | 401 — invalid or missing API key |
| `Anakin.Error.InsufficientCredits` | 402 — out of credits (`:balance`, `:required`) |
| `Anakin.Error.InvalidRequest` | 400 — validation failure |
| `Anakin.Error.RateLimit` | 429 — after retry budget exhausted (`:retry_after` seconds) |
| `Anakin.Error.JobFailed` | Polled job came back with `status="failed"` (`:reason`) |
| `Anakin.Error.JobTimeout` | Polling budget exhausted before terminal status |
| `Anakin.Error.Server` | 5xx — after retries exhausted |
| `Anakin.Error.Network` | DNS / connect / read-timeout |
| `Anakin.Error` | Base struct; unmatched failures fall back here |
## Develop
```bash
git clone https://github.com/Anakin-Inc/anakin-elixir
cd anakin-elixir
mix deps.get
mix 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-sdk` (crates.io)](https://crates.io/crates/anakin-sdk) — Rust SDK
- [`anakin/sdk` (Packagist)](https://packagist.org/packages/anakin/sdk) — PHP SDK
- [`@anakin-io/mcp`](https://www.npmjs.com/package/@anakin-io/mcp) — Model Context Protocol server for AI agents
## License
[Apache 2.0](LICENSE)