● Operational

Image hosting with an API,
and URLs that just work.

Upload with one request, get back a clean URL, resize and convert on the fly with a query string. Built and hosted by ProSolutionX.

1 · UploadPOST /api/v1/assets
→
2 · Get a URLhttps://cdn.prosolutionx.com/site/name.jpg
→
3 · Resize anywhere?w=800&f=webp

Quick start

You need an API key. Ask us for one — we create a space for your site and send you a key. It takes a minute.

Upload a file

# slug is optional — leave it out and the filename is used
curl -X POST https://cdn.prosolutionx.com/api/v1/assets \
  -H "Authorization: Bearer <YOUR_API_KEY>" \
  -F "file=@photo.jpg" \
  -F "slug=blue-widget-hero" \
  -F "alt=Blue widget on a white background"

What comes back

{
  "id": 12,
  "slug": "blue-widget-hero",
  "url": "https://cdn.prosolutionx.com/yoursite/blue-widget-hero.jpg",
  "immutableUrl": "https://cdn.prosolutionx.com/yoursite/9f2c…a1.jpg",
  "width": 1600, "height": 900,
  "size": 184320,
  "contentType": "image/jpeg"
}
Two URLs, on purpose. url is readable and can be renamed — use it in pages, it is the one search engines like. immutableUrl is the content hash: it can never point at different bytes, so it is cached forever. Use it for things like email templates where a URL must never change meaning.

API reference

Base URL https://cdn.prosolutionx.com. Every call takes Authorization: Bearer <key> (or X-Api-Key). A key belongs to exactly one site and can only see that site's files.

POST/api/v1/assets upload

Multipart. Field file is required; slug, alt and title are optional.

curl -X POST https://cdn.prosolutionx.com/api/v1/assets \
  -H "Authorization: Bearer $KEY" \
  -F "file=@photo.jpg" -F "slug=my-photo"

Uploading the same bytes twice returns the existing file instead of making a duplicate.

GET/api/v1/assets list & search

?limit=50 ?cursor=<id> ?q=search

curl -H "Authorization: Bearer $KEY" \
  "https://cdn.prosolutionx.com/api/v1/assets?q=widget&limit=20"
GET/api/v1/assets/:id fetch one

Takes the numeric id or the readable name.

curl -H "Authorization: Bearer $KEY" \
  https://cdn.prosolutionx.com/api/v1/assets/blue-widget-hero
PATCH/api/v1/assets/:id rename, alt, title

JSON body. Renaming changes the readable URL; the immutableUrl is unaffected.

curl -X PATCH https://cdn.prosolutionx.com/api/v1/assets/12 \
  -H "Authorization: Bearer $KEY" \
  -H "Content-Type: application/json" \
  -d '{"slug":"blue-widget-2026","alt":"New caption"}'

If the name is taken, a number is appended rather than failing.

PUT/api/v1/assets/:id replace the file

Multipart, same as upload. Swaps the bytes and keeps the name, so every page already pointing at that URL picks up the new image.

curl -X PUT https://cdn.prosolutionx.com/api/v1/assets/12 \
  -H "Authorization: Bearer $KEY" -F "file=@photo-v2.jpg"
DELETE/api/v1/assets/:id delete
curl -X DELETE https://cdn.prosolutionx.com/api/v1/assets/12 \
  -H "Authorization: Bearer $KEY"
GET/api/v1/me check a key

Returns the site the key belongs to plus its usage. Handy for a health check.

{ "site": "yoursite", "assets": 187, "bytes": 232784691 }

Errors

400Bad request — missing file, or an invalid slug
401Missing, revoked or unknown API key
404No such file under your site
413File over the 25 MB limit
415File type not accepted

Every error is JSON: {"error":"…"}.

Delivery & transforms

Delivery needs no key — these are public URLs. Add a query string to get a resized or converted copy; it renders once and is cached from then on.

# the original
https://cdn.prosolutionx.com/yoursite/blue-widget-hero.jpg

# 800px wide, converted to WebP
https://cdn.prosolutionx.com/yoursite/blue-widget-hero.jpg?w=800&f=webp

# 400px AVIF at quality 70
https://cdn.prosolutionx.com/yoursite/blue-widget-hero.jpg?w=400&f=avif&q=70

w

Width in pixels. Images are never enlarged beyond their original size.

f

webp avif jpeg png

q

Quality 1–100, default 82.

Accepted on upload

image/jpeg image/png image/webp image/avif image/gif image/svg+xml application/pdf

Up to 25 MB per file. SVG and PDF are stored and served as-is — they are not resized.

Client libraries

Small, dependency-light helpers for the common languages. Each one already has this server's address built in — download, drop in, add your key.

Node, in three lines

import CdnClient from './cdn-client.mjs'

const cdn = new CdnClient({ apiKey: process.env.CDN_API_KEY })
const asset = await cdn.upload('./photo.jpg', { slug: 'blue-widget-hero' })

console.log(asset.url)
// https://cdn.prosolutionx.com/yoursite/blue-widget-hero.jpg

Need a key?

Tell us the site you want to host images for and we will set it up and send you a key. Each site gets its own URL prefix, its own keys and its own usage.

Already have an account?

Sign in to the admin panel →