Cloudflare Images: store, manage, and serve images.
Unlike R2 (which speaks S3 and is signed with SigV4), Images has two distinct surfaces, and this namespace covers both:
internal.api) — for uploading, listing, updating and
deleting images; andimagedelivery.net/<hash>/<id>/ <variant>, a URL this namespace builds (and, for private images, signs)
with no network round-trip.The public API:
(client m) ; build a client handle (upload client body) ; upload a File/byte[]/InputStream (upload-url client url) ; ingest a remote image by URL (direct-upload-url client) ; a one-time URL the browser uploads to (get client id) ; fetch details; also head-less exists? (list client) / (list-seq …) ; enumerate images (v2 cursor pagination) (update client id m) ; edit metadata / requireSignedURLs (delete client id) ; remove an image (idempotent) (get-bytes client id) ; original bytes; also get-stream (stats client) ; usage counts (signing-keys client) ; the URL-signing keys (delivery-url client id v) ; build (optionally signed) a delivery URL (request client req) ; escape hatch to the raw v4 API
get/list/update shadow clojure.core names, so this namespace excludes
them; refer to them qualified (e.g. images/get).
Cloudflare Images: store, manage, and serve images.
Unlike R2 (which speaks S3 and is signed with SigV4), Images has two distinct
surfaces, and this namespace covers both:
- the **management API** — Cloudflare's REST API v4, authenticated with a
Bearer token (see `internal.api`) — for uploading, listing, updating and
deleting images; and
- **delivery** — images are *served* from `imagedelivery.net/<hash>/<id>/
<variant>`, a URL this namespace builds (and, for private images, signs)
with no network round-trip.
The public API:
(client m) ; build a client handle
(upload client body) ; upload a File/byte[]/InputStream
(upload-url client url) ; ingest a remote image by URL
(direct-upload-url client) ; a one-time URL the browser uploads to
(get client id) ; fetch details; also head-less exists?
(list client) / (list-seq …) ; enumerate images (v2 cursor pagination)
(update client id m) ; edit metadata / requireSignedURLs
(delete client id) ; remove an image (idempotent)
(get-bytes client id) ; original bytes; also get-stream
(stats client) ; usage counts
(signing-keys client) ; the URL-signing keys
(delivery-url client id v) ; build (optionally signed) a delivery URL
(request client req) ; escape hatch to the raw v4 API
`get`/`list`/`update` shadow `clojure.core` names, so this namespace excludes
them; refer to them qualified (e.g. `images/get`).(client {:keys [account-id api-token account-hash signing-key base-url
http-client]})Build a Cloudflare Images client handle from a config map:
{:account-id "abc123" ; required — drives the management API :api-token "…" ; required — a Cloudflare API token :account-hash "aBcD…" ; for building delivery URLs (a different ; value from :account-id; find it in the ; Images dashboard) :signing-key "…"} ; optional — the URL-signing key, needed only ; for signed (private-image) delivery URLs
:account-hash and :signing-key are only consulted by delivery-url; the
management calls need just :account-id and :api-token. Returns a handle
suitable for every function in this namespace.
Build a Cloudflare Images client handle from a config map:
{:account-id "abc123" ; required — drives the management API
:api-token "…" ; required — a Cloudflare API token
:account-hash "aBcD…" ; for building delivery URLs (a *different*
; value from :account-id; find it in the
; Images dashboard)
:signing-key "…"} ; optional — the URL-signing key, needed only
; for signed (private-image) delivery URLs
`:account-hash` and `:signing-key` are only consulted by `delivery-url`; the
management calls need just `:account-id` and `:api-token`. Returns a handle
suitable for every function in this namespace.(content-type-for name)Infer an image Content-Type from the extension of name, defaulting to
"application/octet-stream" when the extension is unknown or absent.
Infer an image Content-Type from the extension of `name`, defaulting to "application/octet-stream" when the extension is unknown or absent.
(delete client id)Delete the image id. Idempotent — succeeds whether or not it existed.
Returns true.
Delete the image `id`. Idempotent — succeeds whether or not it existed. Returns `true`.
(delivery-url client id variant & [{:keys [signed expires signing-key]}])Build a delivery URL that serves image id through variant. variant is a
named variant (string/keyword like "public") or, if flexible variants are
enabled on your account, a transform map (e.g. {:w 400 :h 300 :fit "cover"}).
Needs :account-hash on the client. Pure — builds a string, no network call.
Options: :signed when true, append an HMAC signature so the URL serves a private (requireSignedURLs) image. Needs a signing key. :expires signature lifetime in seconds (default 3600) :signing-key the key to sign with (defaults to the client's :signing-key)
Returns the URL string, e.g.
https://imagedelivery.net/<hash>/<id>/public or, signed,
…/public?exp=<unix-ts>&sig=<hex>.
Build a delivery URL that serves image `id` through `variant`. `variant` is a
named variant (string/keyword like "public") or, if flexible variants are
enabled on your account, a transform map (e.g. `{:w 400 :h 300 :fit "cover"}`).
Needs `:account-hash` on the client. Pure — builds a string, no network call.
Options:
:signed when true, append an HMAC signature so the URL serves a
private (requireSignedURLs) image. Needs a signing key.
:expires signature lifetime in seconds (default 3600)
:signing-key the key to sign with (defaults to the client's :signing-key)
Returns the URL string, e.g.
`https://imagedelivery.net/<hash>/<id>/public` or, signed,
`…/public?exp=<unix-ts>&sig=<hex>`.(direct-upload-url client
&
[{:keys [id metadata require-signed-urls expiry-seconds]}])Create a one-time upload URL the browser can POST an image to directly,
without your API token ever reaching the client. Your server calls this, hands
the returned :upload-url to the browser, and the browser POSTs the file (form
field file) to it. Options (all optional):
:id custom image id for the eventual upload
:metadata map of arbitrary metadata
:require-signed-urls gate the resulting image behind signed URLs
:expiry-seconds how long the upload URL stays valid (Cloudflare
requires 120–21600s; default 1800 = 30 min)
Returns {:id <future-image-id> :upload-url <one-time-url>}.
Create a one-time upload URL the browser can POST an image to directly,
without your API token ever reaching the client. Your server calls this, hands
the returned `:upload-url` to the browser, and the browser POSTs the file (form
field `file`) to it. Options (all optional):
:id custom image id for the eventual upload
:metadata map of arbitrary metadata
:require-signed-urls gate the resulting image behind signed URLs
:expiry-seconds how long the upload URL stays valid (Cloudflare
requires 120–21600s; default 1800 = 30 min)
Returns `{:id <future-image-id> :upload-url <one-time-url>}`.(exists? client id)Whether an image with id exists.
Whether an image with `id` exists.
(get client id)Fetch an image's details by id, or nil if no such image exists. Returns
the same map shape as upload.
Fetch an image's details by `id`, or `nil` if no such image exists. Returns the same map shape as `upload`.
(get-bytes client id)Fetch an image's original bytes as a byte[], or nil if it doesn't exist.
Buffers the whole image in memory — use get-stream for large originals.
Fetch an image's original bytes as a `byte[]`, or `nil` if it doesn't exist. Buffers the whole image in memory — use `get-stream` for large originals.
(get-stream client id)Fetch an image's original bytes as an InputStream, or nil if it doesn't
exist. The caller must close the stream (e.g. with with-open).
Fetch an image's original bytes as an `InputStream`, or `nil` if it doesn't exist. The caller must close the stream (e.g. with `with-open`).
(list client & [{:keys [per-page continuation-token sort-order]}])List one page of images (newest first). Uses the v2 cursor-paginated endpoint. Options: :per-page page size (Cloudflare default 1000, max 10000) :continuation-token fetch the page following a previous result :sort-order :asc or :desc (by upload time)
Returns {:images [image-map …] :continuation-token <token-or-nil>}. When the
token is non-nil there may be more pages — pass it back (or use list-seq).
List one page of images (newest first). Uses the v2 cursor-paginated
endpoint. Options:
:per-page page size (Cloudflare default 1000, max 10000)
:continuation-token fetch the page following a previous result
:sort-order :asc or :desc (by upload time)
Returns `{:images [image-map …] :continuation-token <token-or-nil>}`. When the
token is non-nil there may be more pages — pass it back (or use `list-seq`).(list-seq client & [opts])Lazily enumerate every image matching opts (same options as list, minus
:continuation-token), transparently following pagination. Each element is an
image map. Pages are fetched as the seq is consumed, so realizing it performs
I/O and may throw.
Lazily enumerate every image matching `opts` (same options as `list`, minus `:continuation-token`), transparently following pagination. Each element is an image map. Pages are fetched as the seq is consumed, so realizing it performs I/O and may throw.
(request client req)Escape hatch to the raw Cloudflare v4 API for anything this namespace doesn't
wrap. req is {:method :path :query :headers :json :multipart :body}; the
:path is taken relative to the account's Images root (e.g. "/v1/keys").
Returns the raw response {:status :headers :body} (body a string) without
throwing on 4xx/5xx, so the caller controls error handling.
Escape hatch to the raw Cloudflare v4 API for anything this namespace doesn't
wrap. `req` is `{:method :path :query :headers :json :multipart :body}`; the
`:path` is taken relative to the account's Images root (e.g. `"/v1/keys"`).
Returns the raw response `{:status :headers :body}` (body a string) without
throwing on 4xx/5xx, so the caller controls error handling.(signing-keys client)The account's URL-signing keys, as [{:name … :value …} …]. The :value of
a key is what you pass as :signing-key when building a signed delivery-url
(or when configuring the client).
The account's URL-signing keys, as `[{:name … :value …} …]`. The `:value` of
a key is what you pass as `:signing-key` when building a signed `delivery-url`
(or when configuring the client).(stats client)Current Images usage for the account: {:current n :allowed n} (image count
against the plan's allowance).
Current Images usage for the account: `{:current n :allowed n}` (image count
against the plan's allowance).(update client id changes)Update an image's mutable properties. changes may contain:
:metadata replace the image's metadata map
:require-signed-urls toggle whether serving needs a signed URL
Returns the updated image map (same shape as upload).
Update an image's mutable properties. `changes` may contain: :metadata replace the image's metadata map :require-signed-urls toggle whether serving needs a signed URL Returns the updated image map (same shape as `upload`).
(upload client
body
&
[{:keys [id metadata require-signed-urls filename content-type]}])Upload body — a java.io.File, byte[], or InputStream — to Cloudflare
Images. Options (all optional):
:id custom image id (else Cloudflare assigns a UUID)
:metadata map of arbitrary metadata (never shown to end users)
:require-signed-urls when true, the image can only be served via a signed
delivery URL (see delivery-url)
:filename name recorded for the image (defaults to the File's
name, else "upload")
:content-type Content-Type for the upload part (else inferred from
the filename extension)
Returns {:id :filename :uploaded :require-signed-urls :meta :variants}
(:variants are ready-to-use delivery URLs). Throws ex-info on failure.
Upload `body` — a `java.io.File`, `byte[]`, or `InputStream` — to Cloudflare
Images. Options (all optional):
:id custom image id (else Cloudflare assigns a UUID)
:metadata map of arbitrary metadata (never shown to end users)
:require-signed-urls when true, the image can only be served via a signed
delivery URL (see `delivery-url`)
:filename name recorded for the image (defaults to the File's
name, else "upload")
:content-type Content-Type for the upload part (else inferred from
the filename extension)
Returns `{:id :filename :uploaded :require-signed-urls :meta :variants}`
(`:variants` are ready-to-use delivery URLs). Throws `ex-info` on failure.(upload-url client url & [{:keys [id metadata require-signed-urls]}])Ingest a remote image by url — Cloudflare fetches it directly, so the bytes
never pass through your process. Options are the same as upload minus the
file-specific ones: :id, :metadata, :require-signed-urls. Returns the
same image map as upload.
Ingest a remote image by `url` — Cloudflare fetches it directly, so the bytes never pass through your process. Options are the same as `upload` minus the file-specific ones: `:id`, `:metadata`, `:require-signed-urls`. Returns the same image map as `upload`.
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 |