Skip to main content

Named presets

Define a transform bundle once, reference it by name everywhere. A preset is a saved set of params (w, h, q, fit, gravity, format, plus the text-overlay options) stored per workspace. There are two equivalent ways to reference a preset:
<!-- Query form -->
<img src="https://cdn.convertly.sh/cvly_pub_.../{fileId}?preset=hero" />

<!-- Path form (matches imgix / Cloudinary conventions) -->
<img src="https://cdn.convertly.sh/cvly_pub_.../{fileId}/p/hero" />
Use whichever reads better in your codebase. They resolve identically and share the same edge cache. Individual URL params override the preset’s values for one-off tweaks:
<!-- The hero preset is 1920x720, but for this one card we want 800 wide -->
<img src="https://cdn.convertly.sh/cvly_pub_.../{fileId}/p/hero?w=800" />

Manage presets

MethodEndpointUse
GET/api/cdn-presetsList every preset on the workspace.
POST/api/cdn-presetsCreate a preset. Body: { "name": "hero", "params": { "w": 1920, "h": 720, "fit": "cover", "format": "auto" } }.
PATCH/api/cdn-presets/{id}Replace a preset’s params (provide the full new shape).
DELETE/api/cdn-presets/{id}Delete a preset. URLs using ?preset= for it return 404.
Names must be lowercase letters, digits, dashes, or underscores (32 chars max). You can also manage presets visually from Settings → Image CDN → Transform presets.
curl -X POST "https://convertly.sh/api/cdn-presets" \
  -H "Authorization: Bearer $CONVERTLY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "hero",
    "params": {
      "w": 1920,
      "h": 720,
      "fit": "cover",
      "gravity": "auto",
      "format": "auto",
      "q": "auto"
    }
  }'

When to use a preset vs inline params

Use a preset when:
  • The same transform shows up in more than 2-3 places in your codebase.
  • A design-system component (Hero, Card, Thumb) has a standard variant.
  • You want to be able to retune quality / size without touching markup.
Inline params are fine for one-off transforms. Both work the same way at the cache level.

Signed URLs

By default, CDN URLs are public — anyone with the URL can fetch the image at any size. That’s fine for <img src> on a marketing page. For gated content (paid downloads, subscriber-only assets, signed-link emails), use signed URLs: a server-generated HMAC signature is appended as ?s=…, and any tampering with the URL (changing width, format, swapping the file id or slug) invalidates it.
Public CDN signatures do not expire. Once generated, a signed URL stays valid until you rotate the delivery key or change signing secrets. For time-limited links, use the legacy /api/cdn/image/{id} route or gate access at your application layer.

Generate a signed URL

curl -X POST "https://convertly.sh/api/delivery-keys/{deliveryKeyId}/sign" \
  -H "Authorization: Bearer $CONVERTLY_DELIVERY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "fileId": "11111111-1111-1111-1111-111111111111",
    "params": { "w": 1200, "q": 85, "format": "webp" }
  }'

# {
#   "url": "https://cdn.convertly.sh/cvly_pub_.../{fileId}?w=1200&q=85&format=webp&s=...",
#   "signature": "..."
# }
  • {deliveryKeyId} is the row id you got when you created the key (visible in Settings → Image CDN → Delivery keys).
  • The Authorization header carries the public delivery token — your server keeps both around because the token ends up in the URL.
The returned URL is good only for the exact parameters that were signed. Tampering returns 403. Browsers, CDNs, and <img src> treat it like any other URL — there’s nothing special to do client-side.

When to use signed URLs

  • Paid downloads where you want to bind a URL to a specific transform you priced.
  • Subscriber-only galleries where you don’t want anyone to scrape and serve the same images elsewhere.
  • Email campaigns with one-shot artwork that shouldn’t be reused.
For general marketing pages and product catalogs, signed URLs add server-side work (you need to sign at render time) for no real protection — <img src> is public by nature. Use the unsigned form there.

Programmatic signing

Most apps should use the POST /api/delivery-keys/{id}/sign endpoint above — it returns a ready-to-embed URL. If you need to sign in application code, the algorithm matches what that endpoint uses: canonical query string (sorted keys, excluding s), HMAC over {deliveryKey}:{fileId}:{canonicalQuery} with a per-delivery-key secret. Retrieve the secret from the dashboard when you create or rotate a delivery key.