---
title: "Images"
description: "Images are an automatic specialization of files stored in Cloudflare Images, keyed 1:1 by file id."
section: "General"
group: "Concepts"
---

# Images

Images are an automatic specialization of [files](/concepts/files). Every image is backed by a regular file row — there is no separate image id. When you upload a file with an `image/*` MIME type, an event handler provisions it in Cloudflare Images and inserts a 1:1 side-table row keyed by the underlying file id. The result: Cloudflare-scale global CDN delivery, signed URLs, and on-the-fly transformations (resize, crop, format conversion) with no separate upload flow to learn.

## Storage model

Images live in **Cloudflare Images**, not in the workspace R2 bucket. The `image` row records:

- `fileId` — the primary key, matches the file row id
- `cfImageId` — the Cloudflare Images ID returned from the
  copy-from-URL call
- `width`, `height`, `size`,
  `exif`
- `workspaceId` — the workspace the image belongs to

## Creating an image

You don't create images directly — just upload a file. On `file.ready` with an `image/*` MIME, the runtime emits `image.provision_requested`; a handler instructs Cloudflare Images to pull the bytes from a signed R2 URL, inserts the image side-table row, and emits `image.created`. On failure the handler emits `image.provision_failed` and transitions the file to `error`.

In the platform UI, the image gallery in the project's **Content** section shows these automatically — uploaded image files appear as images without any extra promotion step.

## Delivery URL

Every image exposes a `url` field with the Cloudflare Images delivery URL:

<pre> ` https://imagedelivery.net/<account-hash>/<cf-image-id>/public ` </pre>

The `public` segment is the variant name. Cloudflare Images supports on-the-fly transformations by appending transformation parameters (e.g. `/width=400,height=300,fit=cover`) — see the [ Cloudflare Images docs ](https://developers.cloudflare.com/images/) for the full list.

## Operations

- `GET /api/images` — list images, filter by
  `workspace_id`
- `GET /api/images/:file_id` — retrieve a single image by
  file id
- `DELETE /api/images/:file_id` — delete the image side table
  row and cascade into the underlying file

All three operations are also available via the CLI ( `aeontel image list/get/delete`), the MCP server ( `list_images`, `get_image`, `delete_image`), and the React hooks ( `useListImages`, `useRetrieveImage`, `useDeleteImage`). There is no `create_image` — upload a file with an `image/*` MIME and the image row is created automatically.
