Elixir SDK

Official Elixir SDK for Anakin (anakin.io)

Official Elixir Hex package for the Anakin API. Wraps every documented endpoint, runs internal polling, and returns idiomatic {:ok, result} / {:error, exception} tuples. Built on Req and Jason.

StatusAlpha (v0.1.x)
LanguageElixir 1.14+
Hex nameanakin on Hex
Docshexdocs.pm/anakin (auto-generated)
Sourcegithub.com/Anakin-Inc/anakin-elixir
LicenseApache 2.0

Install

Add to your mix.exs:

def deps do
  [{:anakin, "~> 0.1"}]
end

Then:

mix deps.get

Quickstart

{:ok, client} = Anakin.Client.new(api_key: "ak-...")  # or set ANAKIN_API_KEY env var

# Scrape a single URL — returns {:ok, result} or {:error, exception}
case Anakin.scrape(client, "https://example.com") do
  {:ok, doc} -> IO.puts(doc["markdown"])
  {:error, e} -> IO.warn(Exception.message(e))
end

# Discover URLs on a site
{:ok, sitemap} = Anakin.map(client, "https://example.com", limit: 200)
IO.inspect(sitemap["links"])

# Crawl pages and get content for each
{:ok, crawl} = Anakin.crawl(client, "https://example.com", max_pages: 20)
Enum.each(crawl["pages"], fn page ->
  IO.puts("#{page["url"]}: #{String.length(page["markdown"] || "")}")
end)

What's in v0.1

FunctionReturns
Anakin.scrape(client, url, opts \\ []){:ok, map} — the document
Anakin.map(client, url, opts \\ []){:ok, map} — discovered links
Anakin.crawl(client, url, opts \\ []){:ok, map} — crawled pages
Anakin.search(client, query, opts \\ []){:ok, map} — search results (synchronous API)
Anakin.agentic_search(client, prompt, opts \\ []){:ok, map} — AI-synthesised answer
Anakin.wire(client, action_id, params){:ok, map} — Wire action result (run a Wire action)
Anakin.list_sessions/1, create_session/3, save_session/3, update_session/3, delete_session/2Browser session CRUD

All response functions return {:ok, parsed_json_map} on success or {:error, %Anakin.Error{...}} on failure. The body of {:ok, ...} is the parsed JSON map — strict struct types are on the v0.2 roadmap.

Configuration

{: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 HTTP timeout
  max_retries:          4,                              # retries on 429 / 5xx
  poll_interval_ms:     1_000,                          # initial polling delay
  poll_max_interval_ms: 10_000,                         # cap on exponential backoff
  poll_timeout_ms:      300_000,                        # total wait before %JobTimeout{}
  req_options:          []                              # extra options forwarded to Req.request/2
)

You can also use Anakin.Client.new!/1 to raise on missing API key (useful in app config / supervision trees).

Errors

Pattern-match on the struct module to react to specific failure modes:

case Anakin.scrape(client, "https://example.com") do
  {:ok, doc} ->
    IO.puts(doc["markdown"])

  {: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("anakin error: #{Exception.message(e)}")
end

The hierarchy:

ModuleWhen
Anakin.Error.Authentication401 — invalid or missing API key
Anakin.Error.InsufficientCredits402 — out of credits (:balance, :required)
Anakin.Error.InvalidRequest400 — validation failure
Anakin.Error.RateLimit429 — after retry budget exhausted (:retry_after seconds)
Anakin.Error.JobFailedPolled job came back with status="failed" (:reason)
Anakin.Error.JobTimeoutPolling budget exhausted before terminal status
Anakin.Error.Server5xx — after retries exhausted
Anakin.Error.NetworkDNS / connect / read-timeout
Anakin.ErrorBase struct; unmatched failures fall back here

Stability

v0.1.x is alpha. The public API may change between minor versions until v1.0. Pin a specific version in production:

{:anakin, "0.1.0"}

Raise issues on GitHub.