**Status**: Production Ready ✅ | **Last Verified**: 2025-11-26
/plugin marketplace add secondsky/claude-skills/plugin install cloudflare-images@claude-skillsThis skill inherits all available tools. When active, it can use any tool Claude has access to.
references/api-reference.mdreferences/direct-upload-complete-workflow.mdreferences/format-optimization.mdreferences/responsive-images-patterns.mdreferences/setup-guide.mdreferences/signed-urls-guide.mdreferences/top-errors.mdreferences/transformation-options.mdreferences/variants-guide.mdscripts/check-versions.shtemplates/batch-upload.tstemplates/direct-creator-upload-backend.tstemplates/direct-creator-upload-frontend.htmltemplates/package.jsontemplates/responsive-images-srcset.htmltemplates/signed-urls-generation.tstemplates/transform-via-url.tstemplates/transform-via-workers.tstemplates/upload-api-basic.tstemplates/upload-via-url.tsStatus: Production Ready ✅ | Last Verified: 2025-11-26
Two powerful features:
Key benefits:
Dashboard → Images → Enable
Get your Account ID and create API token (Cloudflare Images: Edit permission)
curl --request POST \
--url https://api.cloudflare.com/client/v4/accounts/<ACCOUNT_ID>/images/v1 \
--header 'Authorization: Bearer <API_TOKEN>' \
--header 'Content-Type: multipart/form-data' \
--form 'file=@./image.jpg'
CRITICAL: Use multipart/form-data, not JSON
<img src="https://imagedelivery.net/<ACCOUNT_HASH>/<IMAGE_ID>/public" />
Dashboard → Images → Transformations → Enable for zone
Transform ANY image:
<img src="/cdn-cgi/image/width=800,quality=85/uploads/photo.jpg" />
export default {
async fetch(request: Request): Promise<Response> {
return fetch("https://example.com/image.jpg", {
cf: {
image: {
width: 800,
quality: 85,
format: "auto" // WebP/AVIF
}
}
});
}
};
Load references/setup-guide.md for complete walkthrough.
Upload methods:
Load templates/upload-api-basic.ts for file upload example.
Load references/direct-upload-complete-workflow.md for user uploads.
Optimize ANY image (uploaded or external).
Methods:
/cdn-cgi/image/width=800,quality=85/path/to/image.jpgcf.image fetch optionLoad references/transformation-options.md for all options.
Load templates/transform-via-workers.ts for Workers example.
Predefined transformations (up to 100).
Examples:
thumbnail: 200x200, fit=coverhero: 1920x1080, quality=90mobile: 640, quality=75Load references/variants-guide.md for complete guide.
/cdn-cgi/image/// Backend: Generate upload URL
const response = await fetch(
`https://api.cloudflare.com/client/v4/accounts/${ACCOUNT_ID}/images/v2/direct_upload`,
{
method: 'POST',
headers: { 'Authorization': `Bearer ${API_TOKEN}` }
}
);
const { result } = await response.json();
return Response.json({ uploadURL: result.uploadURL });
// Frontend: Upload file
const formData = new FormData();
formData.append('file', file);
await fetch(uploadURL, {
method: 'POST',
body: formData
});
Load templates/direct-creator-upload-backend.ts for complete example.
<img
srcset="
https://imagedelivery.net/abc/xyz/width=400 400w,
https://imagedelivery.net/abc/xyz/width=800 800w,
https://imagedelivery.net/abc/xyz/width=1200 1200w
"
sizes="(max-width: 600px) 400px, (max-width: 1000px) 800px, 1200px"
src="https://imagedelivery.net/abc/xyz/width=800"
/>
Load templates/responsive-images-srcset.html for complete example.
<!-- Original image on your server -->
<img src="/uploads/photo.jpg" />
<!-- Transformed via URL -->
<img src="/cdn-cgi/image/width=800,quality=85,format=auto/uploads/photo.jpg" />
Load references/transformation-options.md for all options.
// Generate signed URL (backend)
const expiryTimestamp = Math.floor(Date.now() / 1000) + 3600; // 1 hour
const message = `/${imageId}/${variant}/${expiryTimestamp}`;
const encoder = new TextEncoder();
const data = encoder.encode(message);
const hashBuffer = await crypto.subtle.digest('SHA-256', data);
const signature = btoa(String.fromCharCode(...new Uint8Array(hashBuffer)));
const signedURL = `https://imagedelivery.net/${ACCOUNT_HASH}/${imageId}/${variant}?exp=${expiryTimestamp}&sig=${signature}`;
Load references/signed-urls-guide.md for complete implementation.
const files = ['img1.jpg', 'img2.jpg', 'img3.jpg'];
const uploadPromises = files.map(file =>
fetch(`https://api.cloudflare.com/client/v4/accounts/${ACCOUNT_ID}/images/v1`, {
method: 'POST',
headers: { 'Authorization': `Bearer ${API_TOKEN}` },
body: createFormData(file)
})
);
const results = await Promise.all(uploadPromises);
Load templates/batch-upload.ts for complete example.
/cdn-cgi/image/width=800,height=600,fit=cover/image.jpg
fit options:
scale-down: Never enlargecontain: Fit within dimensionscover: Fill dimensions, crop excesscrop: Crop to exact sizepad: Add padding/cdn-cgi/image/quality=85,format=auto/image.jpg
format options:
auto: WebP/AVIF for supporting browserswebp: Force WebPavif: Force AVIFjpeg, png: Force format/cdn-cgi/image/blur=10,sharpen=3,brightness=1.1/image.jpg
Load references/transformation-options.md for complete reference.
Problem: Browser blocks direct upload
Solution: Configure CORS headers
const response = await fetch(
`https://api.cloudflare.com/client/v4/accounts/${ACCOUNT_ID}/images/v2/direct_upload`,
{
method: 'POST',
headers: {
'Authorization': `Bearer ${API_TOKEN}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
requireSignedURLs: false,
metadata: { source: 'user-upload' }
})
}
);
Load references/top-errors.md for all 10 errors.
Problem: JSON encoding fails for file uploads
Solution: Use multipart/form-data
// ✅ CORRECT
const formData = new FormData();
formData.append('file', file);
// ❌ WRONG
const json = JSON.stringify({ file: base64File });
Problem: Transformations not enabled for zone
Solution: Enable in dashboard
Dashboard → Images → Transformations → Enable for zone
Problem: Trying to create >100 variants
Solution: Use flexible variants or combine similar sizes
// Instead of: thumbnail-100, thumbnail-150, thumbnail-200...
// Use: thumbnail (configurable in URL)
<img src="https://imagedelivery.net/abc/xyz/thumbnail?width=150" />
Problem: Private images accessible without signature
Solution: Enable signed URLs
await fetch(`https://api.cloudflare.com/client/v4/accounts/${ACCOUNT_ID}/images/v1/${imageId}`, {
method: 'PATCH',
headers: {
'Authorization': `Bearer ${API_TOKEN}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
requireSignedURLs: true
})
});
Load references/top-errors.md for all 10 errors with solutions.
references/setup-guide.md when:references/direct-upload-complete-workflow.md when:references/transformation-options.md when:references/variants-guide.md when:references/signed-urls-guide.md when:references/top-errors.md when:references/responsive-images-patterns.md when:references/format-optimization.md when:references/api-reference.md when:Images API: $5/100k stored, $1/100k delivered Transformations: $0.50/1k (100k/month free per zone) Direct Upload: Included in API pricing