Idiomatic Clojure wrapper over the official OpenAI Java SDK, focused on the Responses API.
deps.edn:
net.clojars.savya/openai-clj {:mvn/version "0.6.0"}
Leiningen:
[net.clojars.savya/openai-clj "0.6.0"]
Tracks com.openai/openai-java 4.41.0.
(require '[openai.core :as openai])
(def client (openai/client)) ; reads OPENAI_API_KEY
(def configured-client
(openai/client {:api-key "sk-..."
:organization "org_..."
:project "proj_..."
:base-url "https://api.openai.com/v1"
:timeout-ms 60000
:max-retries 2}))
(openai/create-response
client
{:model "gpt-5.2"
:input "Write one sentence about Clojure maps."
:instructions "Be precise."
:max-output-tokens 256
:temperature 0.2
:top-p 1.0
:metadata {:app "docs"}
:store true
:reasoning {:effort :low}})
;; => {:id "resp_..."
;; :model "gpt-5.2"
;; :status :completed
;; :output [{:type :message
;; :role :assistant
;; :id "msg_..."
;; :content [{:type :text :text "Clojure maps are ..."}]}]
;; :text "Clojure maps are ..."
;; :usage {:input-tokens 14 :output-tokens 12 :total-tokens 26}
;; :created-at 1790000000.0}
Request maps support :model, :input, :instructions,
:max-output-tokens, :max-tool-calls, :temperature, :top-p,
:top-logprobs, :metadata, :previous-response-id, :store, :user,
:reasoning, :tools, :tool-choice, :parallel-tool-calls, :background,
:include, :truncation, :prompt-cache-key, :safety-identifier,
:service-tier, :json-schema, :verbosity (:low/:medium/:high),
:conversation (a conversation id string), :stream-options
({:include-obfuscation true}), and :moderation ({:model "..."}).
Input can be a string or a vector of message items. Message content can be a string or a vector of multimodal parts:
{:model "gpt-5.2"
:input [{:role :user
:content [{:type :text :text "Summarize this image."}
{:type :image
:image-url "https://example.test/chart.png"
:detail :high}
{:type :file
:filename "notes.pdf"
:file-data "data:application/pdf;base64,..."}]}]}
Structured outputs use :json-schema:
{:model "gpt-5.2"
:input "Return an answer object."
:json-schema {:name "answer"
:description "One answer"
:strict true
:schema {:type "object"
:properties {:answer {:type "string"}}
:required ["answer"]}}}
Prefer the Responses API for new OpenAI work. Chat Completions is exposed as the compatibility path for OpenAI-compatible endpoints that do not support Responses, including local LLMs and hosted compat providers.
(openai/create-chat-completion
client
{:model "gpt-4o-mini"
:messages [{:role :system :content "Be terse."}
{:role :user :content "Write one sentence about Clojure maps."}]})
;; => {:id "chatcmpl_..."
;; :model "gpt-4o-mini"
;; :created 1790000000
;; :choices [{:index 0
;; :finish-reason :stop
;; :message {:role :assistant
;; :content "Clojure maps are ..."}}]
;; :text "Clojure maps are ..."
;; :usage {:prompt-tokens 14 :completion-tokens 12 :total-tokens 26}}
Function tools use the same JSON-schema-shaped :parameters maps as Responses:
(openai/create-chat-completion
client
{:model "gpt-4o-mini"
:messages [{:role :user :content "Weather in Denver?"}]
:tools [{:type :function
:name "get_weather"
:description "Get current weather"
:strict true
:parameters {:type "object"
:properties {:location {:type "string"}}
:required ["location"]}}]
:tool-choice {:type :function :name "get_weather"}})
Streaming returns the concatenated content and calls the callback for each normalized chunk:
(openai/stream-chat-completion-text
client
{:model "gpt-4o-mini"
:messages [{:role :user :content "Count to three."}]
:stream-options {:include-usage true}}
println)
In scope: Responses API, Chat Completions compatibility, structured outputs, multimodal input parts, response streaming, response lifecycle subservices, response compaction, token counting, built-in Responses tools, MCP tools, client options (including Azure OpenAI endpoints), embeddings, files, batches, and models.
Out of scope: images API, audio output, realtime, and stored Chat Completions CRUD.
clojure -M:test
Unit tests are no-network; ^:integration tests, if added later, should be
skipped without OPENAI_API_KEY.
Copyright © 2026 Savyasachi.
Distributed under the Eclipse Public License 2.0.
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 |