A thin client for the Anthropic API, built on Req.
Request bodies are plain maps, sent unchanged. Jibu has no model list and no parameter schema. New API fields therefore work without a new release.
client = Jibu.new(api_key: System.fetch_env!("ANTHROPIC_API_KEY"))
{:ok, response} =
Jibu.messages(client, %{
model: "claude-opus-5-5",
max_tokens: 1024,
messages: [%{role: "user", content: "Hello"}]
})
Jibu.Response.text(response)Start with the Getting started guide.
Summary
Functions
Sends prompt as a user message and returns the text of the answer.
Counts the input tokens of a Messages API request body. The body is sent unchanged. The API does not bill this call.
Sends prompt with schema as structured output and returns the decoded JSON.
Sends a Messages API request. The body is sent unchanged.
Builds a client as a Req.Request.
Sends a Messages API request as a stream and calls fun with each event.
Functions
@spec ask(Req.Request.t(), String.t() | [map()], keyword()) :: {:ok, String.t()} | {:error, Jibu.Error.t()}
Sends prompt as a user message and returns the text of the answer.
prompt is a string or a list of content blocks, see Jibu.Content.
Shortcuts
:system- the system prompt.:cache-truemarks the system prompt for prompt caching.:effort- setsoutput_config.effort, for example:low.:messages- an earlier conversation;promptis appended to it.:on_text- a function that receives each piece of text as it streams in. The answer then goes throughstream/3.
Every other keyword becomes a body field unchanged, for example temperature: 0.
A refusal and output cut off at max_tokens or at the context window are errors.
Use messages/2 when you need the whole response.
@spec count_tokens(Req.Request.t(), map()) :: {:ok, map()} | {:error, Jibu.Error.t()}
Counts the input tokens of a Messages API request body. The body is sent unchanged. The API does not bill this call.
@spec extract(Req.Request.t(), String.t() | [map()], map(), keyword()) :: {:ok, term()} | {:error, Jibu.Error.t()}
Sends prompt with schema as structured output and returns the decoded JSON.
Takes the shortcuts of ask/3 except :on_text.
See the structured output guide.
@spec messages(Req.Request.t(), map()) :: {:ok, Jibu.Response.t()} | {:error, Jibu.Error.t()}
Sends a Messages API request. The body is sent unchanged.
@spec new(keyword()) :: Req.Request.t()
Builds a client as a Req.Request.
Options
:api_key- defaults to theANTHROPIC_API_KEYenvironment variable.:betas- beta names sent in theanthropic-betaheader.:base_url- defaults tohttps://api.anthropic.com.:model,:max_tokens- defaults formessages/2bodies.count_tokens/2takes only the model.:defaults- a map of further body defaults, for example%{temperature: 0}.
A field set in a request body always wins over its default.
Every other option goes to Req.merge/2, for example :receive_timeout, :headers
or plug: {Req.Test, MyStub}. Headers merge by name with the API headers.
Jibu retries transient failures. Pass retry: false to turn that off.
The errors guide lists the rules.
@spec stream(Req.Request.t(), map(), (map() -> any())) :: {:ok, Jibu.Response.t()} | {:error, Jibu.Error.t()}
Sends a Messages API request as a stream and calls fun with each event.
Jibu sets stream: true and sends the body otherwise unchanged.
fun receives every server-sent event as a decoded map, including ping and unknown types.
The result is the assembled message as a Jibu.Response.
An error event returns {:error, %Jibu.Error{}} with the partial message in body.
Jibu does not retry once events have arrived when :retry is a function.
See the streaming guide.