Desktop Pricing Docs Blog About GitHub Get started
← Back to blog

How to host AI-generated images

The image your model just generated lives at a URL that expires in about an hour — or comes back as raw base64 with nowhere to go. Here's how to turn any generated image into a permanent CDN URL with a single API call.

You call the DALL·E or GPT Image API, get back a URL, drop it in your app — and an hour later it's a broken image. This surprises almost everyone the first time. The URLs image-generation APIs hand you are short-lived by design: OpenAI's image URLs expire roughly 60 minutes after generation. If you want the image to stick around, hosting it is your job.

The usual advice — "download it and upload it to S3" — means IAM policies, a bucket, a CDN in front, and egress bills for every view. That's a lot of yak-shaving to make one generated image durable. Here's the lean version instead.

The fix: grab the bytes, upload once

Fetch the generated image before its URL expires, then hand the bytes to PixelVault in a single POST. You get back a permanent CDN URL — no S3 bucket, no CloudFront distribution, no egress bill to wire up.

# DALL·E / GPT Image gave you a URL that dies in ~1 hour.
# 1. Grab the bytes before it expires:
curl -s -o gen.png "https://oaidalleapiprodscus.blob.core.windows.net/.../gen.png"

# 2. Upload to PixelVault — permanent CDN URL back:
curl -s -X POST https://api.pixelvault.dev/v1/images \
  -H "Authorization: Bearer pv_live_xxx" \
  -F "file=@gen.png" | jq -r '.url'

# → https://img.pixelvault.dev/proj_abc/img_xyz.png — never expires

That returned URL is served from a global edge CDN, has zero egress fees, and never expires. Register once for an API key, and re-hosting each new generation is one upload call.

When your model returns base64, not a URL

GPT Image can return b64_json, and local Stable Diffusion pipelines hand you raw bytes. There's nothing to download — you already have the image. Decode it and upload the bytes directly:

# Some models return base64 instead of a URL (e.g. GPT Image, Stable Diffusion).
# Send the bytes straight to PixelVault — no temp file, no S3 setup.
const b64 = gen.data[0].b64_json;
const bytes = Buffer.from(b64, "base64");

const form = new FormData();
form.append("file", new Blob([bytes], { type: "image/png" }), "gen.png");

const res = await fetch("https://api.pixelvault.dev/v1/images", {
  method: "POST",
  headers: { "Authorization": `Bearer ${process.env.PIXELVAULT_API_KEY}` },
  body: form,
});
const { url } = await res.json(); // permanent CDN URL

Works with every generator

The pattern is the same whichever model you use — download the bytes if you got a URL, upload them directly if you already have them:

  • DALL·E 3 / GPT Image (OpenAI). URLs expire in ~1 hour, or use b64_json. Re-host either way.
  • Midjourney. CDN links can rot and are tied to your account. Persist the ones you want to keep under your own URL.
  • Flux / Nano Banana (via Replicate, fal, etc.). Output URLs on inference hosts are temporary — re-host on generation.
  • Stable Diffusion (local or hosted). Raw bytes out; upload them directly and get a shareable link back.

Why this matters for AI agents

If an agent is generating images — thumbnails, mockups, marketing assets — a URL that expires in an hour is useless downstream. The agent needs a durable link it can put in a PR, a doc, or a database. Because PixelVault registration and upload are both plain API calls, an agent can host a generated image with no browser and no human in the loop. It's the same two calls, just made by the model instead of you.

Free to start

PixelVault's free tier includes 200 MB storage, 500 uploads/month, and 1 GB bandwidth — no credit card, no trial expiry. Enough to persist a lot of generated images before you pay a cent. Paid plans start at $9/month.

Read the API docs →