Image Upload API
Upload an Image by API and Get a CDN URL Back
Upload an image from your app and get a CDN URL back. Three REST calls, presigned PUT, permanent public links or expiring signed ones. No SDK.
Image upload API
An image upload API has one job. Take the bytes of a JPEG or PNG out of your app and hand back a URL that renders in a browser. cdn22.net does that in three REST calls with no SDK to install, and a public image is live on a global CDN the moment the third call returns.
Here is the whole flow from curl. Step 1 posts the image metadata and gets back a presigned PUT target plus a file id. size is required and must be the exact byte count. type becomes the stored Content-Type, which is what decides whether a browser renders the image or downloads it.
# 1. ask for a presigned upload URL
curl -sf -X POST https://api.cdn22.net/v1/files/<FOLDER_ID> \
-H "Authorization: $CDN22_API_KEY" \
-H "Content-Type: application/json" \
-d '{"filesMetadata":[{"name":"avatar.png","size":48213,"type":"image/png"}]}'
# {"success":true,"urls":[{
# "url": "https://<bucket>.s3.<region>.amazonaws.com/...&X-Amz-Signature=...",
# "id": "1b9d6bcd-bbfd-4b2d-9b5d-ab8dfbbd4bed",
# "key": "<owner>/<folder>/avatar.png" }]}
# 2. PUT the bytes straight to storage. No Authorization header on this one.
curl -sf --upload-file ./avatar.png \
-H "Content-Type: image/png" \
"<PRESIGNED_URL>"
# 3. confirm, and the CDN URL goes live
curl -sf -X POST https://api.cdn22.net/v1/files/confirm-upload \
-H "Authorization: $CDN22_API_KEY" \
-H "Content-Type: application/json" \
-d '{"ids":["1b9d6bcd-bbfd-4b2d-9b5d-ab8dfbbd4bed"]}'
# public image now at https://cdn.cdn22.net/<owner>/<folder>/avatar.pngStep 2 carries no Authorization header. The signature baked into the presigned URL is the authorization, and sending your API key on top of it returns 403 SignatureDoesNotMatch. That is the most common way this flow breaks the first time.
In JavaScript the same three calls split across your server and the browser. Keep the two key-bearing calls on the server so CDN22_API_KEY never ships to a client, and let the browser do only the PUT. A 12-megapixel phone photo then goes straight to storage instead of through your Node process.
// server: mint the presigned target and finalize
const api = 'https://api.cdn22.net/v1';
const auth = { Authorization: process.env.CDN22_API_KEY, 'Content-Type': 'application/json' };
export async function startImageUpload({ name, size, type }) {
const res = await fetch(`${api}/files/${FOLDER_ID}`, {
method: 'POST', headers: auth,
body: JSON.stringify({ filesMetadata: [{ name, size, type }] }),
});
const { urls } = await res.json();
return urls[0]; // { url, id, key }
}
export async function finishImageUpload(id) {
await fetch(`${api}/files/confirm-upload`, {
method: 'POST', headers: auth, body: JSON.stringify({ ids: [id] }),
});
}
// browser: only the PUT, against the url your server returned
async function putImage(file, presignedUrl) {
await fetch(presignedUrl, {
method: 'PUT',
headers: { 'Content-Type': file.type },
body: file,
});
}That shape fits most places images enter a product. A CMS or an admin panel posts an editor upload and stores the returned URL on the row. An avatar form checks dimensions client-side, uploads, and writes the CDN URL to the user record. A product catalog pushes photos per SKU into one folder per product. A support widget attaches screenshots to a ticket. A bot re-hosts an incoming attachment so the link still resolves after the chat platform's own signature expires, which Discord bot file storage walks through end to end.
A few boundaries worth knowing before you wire this in. One metadata call covers up to 100 images and confirm-upload takes the matching ids in one batch. Your storage quota is checked at step 1, so an over-quota request fails there with a 400 instead of after the bytes have moved. For a file big enough that a single PUT is a liability, the same API exposes multipart upload, which splits it into parts you can send in parallel and retry individually.
Pass ttlSeconds with the metadata, anywhere from 60 seconds to 365 days, and the image is deleted automatically once it passes. Leave it out and the file stays until you call DELETE /v1/files/{id}.
A public image is a plain HTTPS CDN address with no token in it, so it works in an <img> tag, an email, a webhook payload, or an OpenGraph card, and it keeps resolving until you delete the file. There is no referrer check and no hotlink protection. Anything that should not be freely embeddable goes in a private folder instead, where no public URL is ever minted and your backend calls GET /v1/files/signed/{id}?expiresIn=SECONDS for a link valid between 60 seconds and 7 days, 600 seconds by default.
The one thing this API will not do is transform your images. cdn22.net serves the exact bytes you sent, so there is no resize query parameter and no automatic WebP or AVIF conversion. Generate the srcset sizes and formats you need with sharp, squoosh, a CI step, or your framework's image component, upload each variant, and the CDN delivers them all. That is also why nothing here bills per transformation.
Nothing is image-specific under the hood either, so JPEG, PNG, WebP, AVIF, GIF, and SVG take the same path as a PDF or a zip.
Pricing is prepaid credits, not a free image host. Storage, CDN delivery, and requests draw from one balance with no subscription and no separate egress line, so an image library that gets written once and read often costs what the bandwidth costs. Affordable CDN file hosting works through the arithmetic. To start, create a project, mint a key on your API keys page, and run the three calls above against a real folder.
The file upload API documents the same endpoints for non-image files, the image CDN covers the delivery side, and the file upload CLI is the shell version of this flow.
Benefits With No Complexity
Global CDN delivery
Edge-cached worldwide
Signed-URL security
What You Get
Unlimited files
Unlimited storage
Public + Private storage
CDN ready links
Prepaid credits
More coming soon
How cdn22.net Works
1. Upload
2. Copy
3. Use Anywhere
Why Developers Choose cdn22.net
A Better Way to Store & Deliver Files
| ImgBB API | Cloudinary | Uploadcare | Filestack | cdn22.net | |
|---|---|---|---|---|---|
| On-the-fly resize and format transforms | |||||
| Drop-in upload widget included | |||||
| No per-transformation charges | |||||
| Expiring signed URLs for private images | |||||
| Per-file auto-delete TTL set at upload | |||||
| Same endpoints store non-image files | |||||
| Prepaid usage credits, no monthly plan |
Calculate Your Needs
Storage
Egress
CDN Bandwidth
Need storage, egress, and request fees broken out — and compared against AWS list price for the same bytes? Use the CDN & storage cost calculator.
Upload Your First Image and Copy the URL
Create a project, mint an API key, and run the three calls. Prepaid usage covers the storage and bandwidth you actually use, with no subscription and no separate egress invoice.
- Global CDN delivery
- Edge-cached worldwide
- Signed-URL security
- Unlimited files
- Unlimited storage
- Public + Private storage
- No subscription — prepaid credits keep spend predictable