Liking cljdoc? Tell your friends :D

openai-clj

Clojars Project cljdoc test

Idiomatic Clojure wrapper over the stable OpenAI API surface exposed by the official Java SDK.

Stack

Clojure OpenAI

Installation

deps.edn:

net.clojars.savya/openai-clj {:mvn/version "0.7.0"}

Leiningen:

[net.clojars.savya/openai-clj "0.7.0"]

Tracks com.openai/openai-java 4.42.0.

Documentation

Usage

(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"]}}}

Chat Completions

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)

API namespaces

All functions take an openai.core/client as their first argument and accept kebab-case request maps.

(require '[openai.images :as images]
         '[openai.audio :as audio]
         '[openai.moderations :as moderations]
         '[openai.completions :as completions]
         '[openai.vector-stores :as vector-stores]
         '[openai.uploads :as uploads]
         '[openai.containers :as containers]
         '[openai.conversations :as conversations]
         '[openai.fine-tuning :as fine-tuning]
         '[openai.evals :as evals]
         '[openai.skills :as skills]
         '[openai.videos :as videos]
         '[openai.webhooks :as webhooks]
         '[openai.admin :as admin]
         '[openai.admin.projects :as admin-projects])

(images/generate client {:model "gpt-image-1" :prompt "A Clojure logo"})
(audio/create-speech client {:model "gpt-4o-mini-tts" :voice :alloy
                             :input "Hello"})
(moderations/create client {:input "text"})
(completions/create client {:model "gpt-3.5-turbo-instruct" :prompt "Once"})
(vector-stores/create client {:name "docs" :file-ids ["file_..."]})
(uploads/create client {:filename "data.jsonl" :bytes 100
                        :mime-type "application/jsonl" :purpose :fine-tune})
(containers/create client {:name "sandbox"})
(conversations/create client {:items [{:role :user :content "Hello"}]})
(fine-tuning/create-job client {:model "gpt-4.1-mini"
                                :training-file "file_..."})
(evals/list client {:limit 20})
(skills/list client {:limit 20})
(videos/create client {:model "sora-2" :prompt "Ocean sunrise"
                       :size "1280x720" :seconds "8"})
(webhooks/unwrap webhook-client raw-body request-headers)
(admin/project-list admin-client {:limit 20})
(admin-projects/service-account-list admin-client {:project-id "proj_..."})

openai.core also contains Responses, Chat Completions, embeddings, files, batches, models, and stored Chat Completions. openai.graders reflects the stable grader-model service, which exposes no operations in SDK 4.42.0.

Out of scope: beta APIs, realtime WebSockets, async clients, raw-response accessors, and per-call RequestOptions.

Running tests

clojure -M:test

Unit tests are no-network; ^:integration tests, if added later, should be skipped without OPENAI_API_KEY.

License

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

Keyboard shortcuts
Ctrl+kJump to recent docs
Move to previous article
Move to next article
Ctrl+/Jump to the search field
× close