Message Batches, Files, and structured-output message calls go to Anthropic APIs. Anthropic bills them by its billing rules for those APIs. Keep live calls in explicit integration tests or in application code.
create-batch submits multiple Messages requests. Each item has a
:custom-id and :params. :params uses the same map shape as
create-message, except per-request :service-tier is not supported.
(require '[anthropic.core :as anthropic])
(def batch
(anthropic/create-batch
client
[{:custom-id "summary-1"
:params {:model "claude-haiku-4-5"
:max-tokens 64
:messages [{:role :user :content "Summarize Clojure in one sentence."}]}}
{:custom-id "summary-2"
:params {:model "claude-haiku-4-5"
:max-tokens 64
:messages [{:role :user :content "Summarize Java in one sentence."}]}}]))
batch
;; => {:id "msgbatch_..."
;; :processing-status :in-progress
;; :request-counts {:processing 2
;; :succeeded 0
;; :errored 0
;; :canceled 0
;; :expired 0}
;; :created-at "..."
;; :expires-at "..."}
Batch maps contain:
:id:processing-status:request-counts:created-at:expires-at:ended-at when available:results-url when availablePoll with get-batch until :processing-status is :ended.
(anthropic/get-batch client (:id batch))
Other batch helpers:
(anthropic/list-batches client)
(anthropic/cancel-batch client (:id batch))
(anthropic/delete-batch client (:id batch))
When the batch has ended, fetch results:
(anthropic/batch-results client (:id batch))
;; => [{:custom-id "summary-1"
;; :result {:type :succeeded
;; :message {:id "msg_..."
;; :role :assistant
;; :content [...]
;; :usage {...}}}}
;; {:custom-id "summary-2"
;; :result {:type :errored}}]
Result :type values are:
:succeeded:errored:canceled:expired:unknownFor large result sets, use reduce-batch-results. It does not hold the full
collection in memory, and it closes the results stream automatically.
(anthropic/reduce-batch-results
client
(:id batch)
(fn [acc result]
(conj acc (:custom-id result)))
[])
The Files helpers use Anthropic's beta Files API through anthropic.core.
(def uploaded
(anthropic/upload-file client "paper.pdf"))
uploaded
;; => {:id "file_..."
;; :filename "paper.pdf"
;; :mime-type "application/pdf"
;; :size-bytes 12345
;; :created-at "..."}
upload-file accepts:
java.io.Filejava.nio.file.Pathjava.io.InputStreamHelpers:
(anthropic/get-file client (:id uploaded))
(anthropic/list-files client)
(anthropic/delete-file client (:id uploaded))
get-file and list-files return metadata maps like upload-file, plus
:downloadable when the API reports it.
download-file returns a byte array and closes the HTTP response
automatically:
(def bytes
(anthropic/download-file client "file_..."))
You can download the contents of downloadable files only. User uploads can be unavailable for download.
Pass :response-format as a JSON Schema map. The wrapper sends it as the
Messages API output config. It then decodes the first text block as JSON with
keyword keys, and adds the result to the response as :parsed.
(def response
(anthropic/create-message
client
{:model "claude-haiku-4-5"
:max-tokens 256
:response-format {:type "object"
:properties {:capital {:type "string"}}
:required ["capital"]
:additionalProperties false}
:messages [{:role :user
:content "What is the capital of France?"}]}))
(:parsed response)
;; => {:capital "Paris"}
When :response-format is present, create-message parses the first
:content block with {:type :text}. If there is no text block, :parsed is
nil. If the text is not valid JSON, JSON parsing throws.
You can also pass :effort with or without :response-format:
(anthropic/create-message
client
{:model "claude-haiku-4-5"
:max-tokens 256
:effort :low
:messages [{:role :user :content "Answer briefly."}]})
Message content can be a string or a vector of content blocks. Supported input block types include:
:text:image:document:search-result:thinking:redacted-thinking:container-upload:tool-use:tool-resultImage sources support:
{:type :base64 :media-type "image/png" :data "..."}{:type :url :url "https://example.com/image.png"}Document sources support:
{:type :base64 :data "..."}{:type :url :url "https://example.com/file.pdf"}{:type :text :data "plain text"}Blocks that support prompt caching accept :cache-control. The top-level
request also accepts :cache-control.
{:role :user
:content [{:type :image
:source {:type :base64
:media-type "image/png"
:data "<base64>"}}
{:type :document
:source {:type :text :data "reference text"}
:title "Reference"
:cache-control {:ttl :1h}}
{:type :text
:text "Summarize the image and document."
:cache-control true}]}
:cache-control true, :cache-control :ephemeral, and
:cache-control {:ttl :5m} use ephemeral caching. {:ttl :1h} requests a
one-hour TTL where the API supports it.
The README has a broader example. It covers images, PDFs, search-result blocks, thinking round trips, container uploads, server tools, and the beta agents platform.
Can you improve this documentation?Edit on GitHub
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |