A lightweight API that fetches Cloudinary delivery URLs and returns the x-cld-error response header. Designed to be used as an Intercom Fin data connector so Fin can diagnose broken Cloudinary URLs and suggest fixes.
The asset itself is never returned — only HTTP status codes and error headers.
Live deployment: https://cld-url-debugger.vercel.app
Debugs a complete Cloudinary URL. Accepts res.cloudinary.com URLs, CNAME hostnames, and private-CDN hostnames.
| Parameter | Required | Description |
|---|---|---|
url |
Yes | Full HTTPS Cloudinary delivery URL |
Examples
# Standard URL — successful delivery
curl "https://cld-url-debugger.vercel.app/debug-url?url=https://res.cloudinary.com/demo/image/upload/sample.jpg"
# Standard URL — asset not found
curl "https://cld-url-debugger.vercel.app/debug-url?url=https://res.cloudinary.com/demo/image/upload/no_such_asset.jpg"
# CNAME hostname
curl "https://cld-url-debugger.vercel.app/debug-url?url=https://media.example.com/demo/image/upload/sample.jpg"
# Private CDN / subdomain delivery
curl "https://cld-url-debugger.vercel.app/debug-url?url=https://demo-res.cloudinary.com/image/upload/sample.jpg"Constructs a Cloudinary URL from its parts, then debugs it. Supports standard, CNAME, and private-CDN delivery.
| Parameter | Required | Description |
|---|---|---|
cloud_name |
Yes | Cloudinary cloud name |
asset_type |
Yes | image, video, or raw |
delivery_type |
Yes | upload, fetch, private, authenticated, etc. |
public_id |
Yes | Asset public ID, including file extension if needed |
transformation |
No | Transformation string, e.g. w_300,c_fill or f_auto,q_auto |
custom_domain |
No | Custom hostname for CNAME or private-CDN delivery, e.g. media.example.com. Leave empty for standard delivery. |
private_cdn |
No | true for private-CDN / subdomain delivery, where the cloud name is not in the URL path. Defaults to false. |
Examples
# Standard — valid asset
curl "https://cld-url-debugger.vercel.app/debug-components?cloud_name=demo&asset_type=image&delivery_type=upload&public_id=sample.jpg&custom_domain=&private_cdn=false"
# Standard — invalid transformation (triggers x-cld-error)
curl "https://cld-url-debugger.vercel.app/debug-components?cloud_name=demo&asset_type=image&delivery_type=upload&transformation=w_abc,c_fill&public_id=sample.jpg&custom_domain=&private_cdn=false"
# CNAME — custom hostname, cloud name stays in path
curl "https://cld-url-debugger.vercel.app/debug-components?cloud_name=demo&asset_type=image&delivery_type=upload&public_id=sample.jpg&custom_domain=media.example.com&private_cdn=false"
# Private CDN — cloud name moves to subdomain (demo-res.cloudinary.com)
curl "https://cld-url-debugger.vercel.app/debug-components?cloud_name=demo&asset_type=image&delivery_type=upload&public_id=sample.jpg&custom_domain=&private_cdn=true"
# Private CDN with custom domain — CDN handles cloud routing, no cloud name in path
curl "https://cld-url-debugger.vercel.app/debug-components?cloud_name=demo&asset_type=image&delivery_type=upload&public_id=sample.jpg&custom_domain=cdn.example.com&private_cdn=true"All responses are JSON.
Success
{
"success": true,
"http_status": 200,
"cld_error": null,
"message": "The asset was delivered successfully. No Cloudinary errors were detected.",
"url": "https://res.cloudinary.com/demo/image/upload/sample.jpg"
}Cloudinary error (x-cld-error present)
{
"success": false,
"http_status": 400,
"cld_error": "Invalid width in transformation: abc",
"message": "Cloudinary returned an error: Invalid width in transformation: abc",
"url": "https://res.cloudinary.com/demo/image/upload/w_abc,c_fill/sample.jpg"
}/debug-components responses also include constructed_url so Fin can show the user the exact URL that was tested.
npm install
npm start # production
npm run dev # watch mode (Node 18+)Server listens on PORT env variable, defaulting to 3000.
The app is deployed to Vercel at https://cld-url-debugger.vercel.app. A vercel.json is included, so any push to main will automatically redeploy.
To deploy your own instance:
npm install -g vercel
vercel deploy --prodThe app can also be hosted on any other Node.js platform (Railway, Render, Fly.io, etc.). Set the PORT environment variable if required by your host.
- Deploy the app to a publicly accessible URL.
- In Intercom, create a new Data connector pointing to your deployment URL.
- Add the two GET endpoints above to the connector's action list.
- Fin will call the appropriate endpoint based on what the user provides (a full URL or individual components) and use the
cld_errorandmessagefields to explain what went wrong and suggest fixes.