Manage hosted images with Workers·续

return Response.json(image); }, };


```ts
export default {
    async fetch(request, env) {
        if (!request.body) {
            return new Response("Missing body", { status: 400 });
        }

const image = await env.IMAGES.hosted.upload(request.body, {
            encoding: "base64",
            filename: "upload.png",
        });

return Response.json(image);
    },
};

List images with pagination

export default {
    async fetch(request, env) {
        let cursor;
        const ids = [];

do {
            const page = await env.IMAGES.hosted.list({ limit: 100, cursor });
            ids.push(...page.images.map((image) => image.id));
            cursor = page.cursor;
        } while (cursor);

return Response.json({ count: ids.length, ids });
    },
};
export default {
    async fetch(request, env) {
        let cursor: string | undefined;
        const ids: string[] = [];

do {
            const page = await env.IMAGES.hosted.list({ limit: 100, cursor });
            ids.push(...page.images.map((image) => image.id));
            cursor = page.cursor;
        } while (cursor);

return Response.json({ count: ids.length, ids });
    },
};

Get the details for a single image

export default {
    async fetch(request, env) {
        const details = await env.IMAGES.hosted.image("IMAGE_ID").details();
        if (!details) {
            return new Response("Not found", { status: 404 });
        }
        return Response.json(details);
    },
};
export default {
    async fetch(request, env) {
        const details = await env.IMAGES.hosted.image("IMAGE_ID").details();
        if (!details) {
            return new Response("Not found", { status: 404 });
        }
        return Response.json(details);
    },
};

Stream the original bytes for an image

export default {
    async fetch(request, env) {
        const bytes = await env.IMAGES.hosted.image("IMAGE_ID").bytes();
        if (!bytes) {
            return new Response("Not found", { status: 404 });
        }
        return new Response(bytes);
    },
};
export default {
    async fetch(request, env) {
        const bytes = await env.IMAGES.hosted.image("IMAGE_ID").bytes();
        if (!bytes) {
            return new Response("Not found", { status: 404 });
        }
        return new Response(bytes);
    },
};

Update image metadata

export default {
    async fetch(request, env) {
        const updated = await env.IMAGES.hosted.image("IMAGE_ID").update({
            metadata: { reviewed: true },
        });
        return Response.json(updated);
    },
};
export default {
    async fetch(request, env) {
        const updated = await env.IMAGES.hosted.image("IMAGE_ID").update({
            metadata: { reviewed: true },
        });
        return Response.json(updated);
    },
};

Delete an image

export default {
    async fetch(request, env) {
        const deleted = await env.IMAGES.hosted.image("IMAGE_ID").delete();
        return new Response(deleted ? "Deleted" : "Not found", {
            status: deleted ? 200 : 404,
        });
    },
};
export default {
    async fetch(request, env) {
        const deleted = await env.IMAGES.hosted.image("IMAGE_ID").delete();
        return new Response(deleted ? "Deleted" : "Not found", {
            status: deleted ? 200 : 404,
        });
    },
};

Generate a signed URL for a private image

Redirect the browser to a short-lived signed URL so it can fetch a private image directly without streaming the bytes through your Worker.

export default {
    async fetch(request, env) {
        const url = await env.IMAGES.hosted.image("IMAGE_ID").signedUrl({
            variant: "private",
            expiresIn: 86_400,
        });

return Response.redirect(url, 302);
    },
};
export default {
    async fetch(request, env) {
        const url = await env.IMAGES.hosted.image("IMAGE_ID").signedUrl({
            variant: "private",
            expiresIn: 86_400,
        });

return Response.redirect(url, 302);
    },
};

Create a Direct Creator Upload URL

Create a one-time upload URL and return it to a client, which can then upload an image straight to Cloudflare without your Worker handling the bytes or an API token.

export default {
    async fetch(request, env) {
        const { id, uploadURL } = await env.IMAGES.hosted.createDirectUpload({
            metadata: { userId: "abc123" },
            requireSignedURLs: true,
            expiresIn: 600,
        });

return Response.json({ id, uploadURL });
    },
};
export default {
    async fetch(request, env) {
        const { id, uploadURL } = await env.IMAGES.hosted.createDirectUpload({
            metadata: { userId: "abc123" },
            requireSignedURLs: true,
            expiresIn: 600,
        });

return Response.json({ id, uploadURL });
    },
};

Ingest a remote image into Images storage

This example fetches an image from a remote URL, uploads it into your Images account, and returns the first variant URL.

export default {
    async fetch(request, env) {
        const upstream = await fetch("https://example.com/photo.jpg");
        if (!upstream.ok || !upstream.body) {
            return new Response("Upstream fetch failed", { status: 502 });
        }

const image = await env.IMAGES.hosted.upload(upstream.body, {
            filename: "photo.jpg",
            metadata: { source: "example.com" },
        });

return Response.json({
            id: image.id,
            variant: image.variants[0],
        });
    },
};
export default {
    async fetch(request, env) {
        const upstream = await fetch("https://example.com/photo.jpg");
        if (!upstream.ok || !upstream.body) {
            return new Response("Upstream fetch failed", { status: 502 });
        }

const image = await env.IMAGES.hosted.upload(upstream.body, {
            filename: "photo.jpg",
            metadata: { source: "example.com" },
        });

return Response.json({
            id: image.id,
            variant: image.variants[0],
        });
    },
};

Type definitions

ImageMetadata

Returned by operations that retrieve, create, or update an image.

  • id string
  • The unique identifier for the image.
  • filename string optional
  • The original filename supplied at upload time.
  • uploaded string optional
  • The date and time the image was uploaded, as an ISO 8601 string.
  • requireSignedURLs boolean
  • Whether signed URLs are required to access this image. Refer to Serve private images.
  • meta Record<string, unknown> optional
  • User-supplied metadata associated with the image.
  • variants Array<string>
  • Fully-formed URLs for each variant configured on your account. Refer to Create variants.
  • draft boolean optional
  • Whether the image is in a draft state (no bytes uploaded yet). Drafts are typically only seen on accounts using Direct Creator Uploads.
  • creator string optional
  • A user-defined identifier for the image creator.

ImageList

Returned by list().

  • images Array<ImageMetadata>
  • The images in this page of results.
  • cursor string optional
  • A continuation token to pass to the next list() call. Only present when there are more results.
  • listComplete boolean
  • true when there are no further pages, false otherwise.

DirectUploadResult

Returned by createDirectUpload().

  • id string
  • The ID that the uploaded image will have.
  • uploadURL string
  • The one-time URL that a client uploads the image bytes to.

Error handling

Methods that fail throw an ImagesError — .upload(), .list(), .createDirectUpload(), .update(), and .signedUrl() — with the following properties:

  • code number
  • A numeric error code that identifies the failure mode.
  • message string
  • A human-readable description of the error.

Methods that fetch a single image — .details(), .bytes(), and .delete() — return null or false for "not found" rather than throwing.

You may want to wrap operations that can throw in a try...catch block.

Local development

When you run wrangler dev, operations for managing hosted images are served by a local mock that stores images in an embedded KV namespace. The mock supports every method documented on this page, so you can develop and test your Worker offline.

The mock is only suitable for local development. To exercise the real Images service from your local environment, run wrangler dev --remote.

Was this helpful?

YesNo

On this page

Manage hosted images with Workers·续 - 图1Docs

{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/images/storage/binding/#page","headline":"Manage hosted images with Workers","description":"Use the Images binding to upload, list, retrieve, update, and delete hosted images from a Worker.","url":"https://developers.cloudflare.com/images/storage/binding/","inLanguage":"en","image":"https://developers.cloudflare.com/images/storage/binding/og.png?v=5aa2b6e200e33867","dateModified":"2026-09-02","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}


description: Remove images from Cloudflare Images storage using the dashboard or API. title: Delete images image: https://developers.cloudflare.com/images/storage/manage-images/delete-images/og.png?v=f81f630393ab85a8


Skip to content

Documentation Index
Fetch the complete documentation index at: https://developers.cloudflare.com/images/llms.txt
Use this file to discover all available pages before exploring further.