blog/developers·Sep 9, 2026·6 min·by the eroq team

Storing and serving AI-generated media — from render to CDN

What the eroq API actually hands back, how the free creation library differs from the eroq Store, what CDN delivery costs and what to keep on your side.


Generating the media is the half everyone plans for. The half that ambushes you is what happens in the ninety seconds after — whether you got bytes or a link, how long that link lives, where the file goes, and who is paying to serve it to a hundred thousand people on a Friday night.

This is what the eroq API returns for each media type, the difference between the free creation library and the paid Store, and the short list of things you should keep on your own side no matter what.

What the API actually hands you

Three endpoints, three different answers.

ImagesPOST /v1/images/generations returns the image inline as base64 in b64_json by default, or a URL when the engine answers with one. You can ask for the URL form with response_format. Details on /docs/images.

{
  "created": 1756118400,
  "model": "eroq-image-one",
  "data": [{ "b64_json": "UklGRl4jAABXRUJQ…" }],
  "usage": { "credits_spent": 10, "credits_remaining": 987 }
}

Video — asynchronous. You submit, you poll, and the finished job carries the clip inline as base64 MP4. That payload is kept for 24 hours. After that the job is a record, not a file. See /docs/video.

SpeechPOST /v1/audio/speech does not return JSON at all. The response body is the MP3, audio/mpeg, ready to pipe to a file or an audio element. /docs/speech has the voice parameters.

The single sentence to take from this section: nothing here is a permanent URL unless you ask for one. A base64 payload is a delivery mechanism, not storage, and a 24-hour window is a grace period for your pipeline to act, not a retention policy you can build a product on.

The creation library — free, and not your storage layer

Every image, video and speech render made through /v1 is also saved to your creation library automatically, at no charge, with the full recipe in meta — model, rack settings, seconds, references, everything needed to reproduce it. Each generated item carries a library_id.

curl https://eroq.ai/v1/creations \
  -H "Authorization: Bearer $EROQ_API_KEY"
{
  "folders": [{ "id": "…", "name": "Campaign A" }],
  "creations": [{
    "id": "…", "kind": "video", "url": "https://…", "model": "eroq-motion-one",
    "prompt": "slow pan over the rooftop", "meta": { "seconds": 10, "shot": "push-in" }
  }]
}

GET /v1/creations/{id} fetches one with its full recipe, PATCH moves it between folders, DELETE removes it and its file, and there is a matching folder CRUD. It is the same library the studio shows, which means a render your backend made is visible to your team and a render your team made is visible to your backend.

Use it as a recipe log and a shared workspace, not as your product's CDN. It is the answer to "what exactly did we send to produce this", which is a question you will ask more often than you expect — usually the week after a client approves a look and you need forty more like it.

The eroq Store — durable URLs on a CDN

When you want a link that outlives the request, upload it:

curl -X POST https://eroq.ai/v1/storage/objects \
  -H "Authorization: Bearer $EROQ_API_KEY" \
  -F [email protected] \
  -F name="poster.webp"
{
  "id": "0b52…",
  "object": "storage.object",
  "url": "https://store.eroq.ai/acc_…/8c1f2-poster.webp",
  "bytes": 482133,
  "content_type": "image/webp",
  "usage": { "credits_spent": 2, "credits_remaining": 880 }
}

The URL is live immediately and served over a global CDN. Files go up to 100 MB per object, GET /v1/storage/objects lists your live objects with their URLs, and DELETE /v1/storage/objects/{id} removes one — immediately at the origin, with edge caches draining within minutes.

Pricing is a one-time 2 credits per started 10 MB. "Started" is the operative word: a 1024×1024 image is one block, so 2 credits. A 4 MB clip is one block. An 11 MB clip is two, so 4 credits. The charge happens once, at upload — storage then stays as long as the account does, with serving included within fair use. Deletion does not refund it, because the storage was consumed.

There is also a one-call shortcut. Both generation endpoints accept store: true, which persists the render and answers with a durable CDN URL instead of base64, with the Store's rate charged on top and itemized separately in your ledger:

curl -X POST https://eroq.ai/v1/videos/generations \
  -H "Authorization: Bearer $EROQ_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "eroq-motion-one",
    "prompt": "Rain crawls down a diner window while a waitress refills a cup without looking up, street neon bleeding through the glass. Static shot, 35mm film, practicals, neon noir palette, calm tempo.",
    "seconds": 5,
    "aspect": "9:16",
    "store": true
  }'

For a pipeline that always keeps its output, this is one round trip instead of two and removes the window where a render exists only in memory.

Why adult-friendly hosting is a separate decision

Generation policy and hosting policy are not the same policy, and plenty of stacks have discovered this the hard way — the model renders, the product converts, and then the bucket provider's acceptable-use policy, written for the entire internet and enforced as an account termination, takes the whole library offline.

The Store is governed by the same written acceptable-use policy as the models themselves. What the API will generate for you within policy, the Store will host. That is the actual reason it exists; the CDN is table stakes. If you are choosing infrastructure for a mature product, the trade-offs are laid out in the NSFW AI API guide.

What to keep on your own side

Whatever you choose for the bytes, keep these in your own database. All of them are cheap to store and expensive to reconstruct.

  • The full request payload. Prompt, model, seconds, aspect, every rack parameter. The library keeps the recipe too, but yours is the one that survives you moving providers.
  • The job id and the customer it belonged to. Per-customer cost accounting is your job on a shared wallet, and it is a join you cannot do after the fact.
  • usage.credits_spent, per render. Copy it from the response. Reconstructing spend from a price list later is how billing disputes start.
  • The seed, on engines that honor one — it is the difference between "we can make another take like that" and "we got lucky once". More on /glossary/seed, and the per-engine capability flags are on /models.
  • A copy of the bytes, if the media is a deliverable you owe someone. Not because any particular URL will break, but because a file a client paid for should not have exactly one home.

Serving it without paying twice

Point your <img> and <video> tags at the CDN URL directly. Do not proxy media through your application server — you will pay for the bandwidth twice, add a hop of latency, and turn a static asset into a request your autoscaler has to think about.

Two practical notes for video. Give every clip a poster image, because an unposted video element is a grey rectangle until the first frame decodes, and on a feed that reads as a broken page. And set the durable URL at the moment the render lands — your webhook handler or your poll loop is the right place to copy or store, not a nightly job that runs after the 24-hour window has already closed.

FAQ

How long does eroq keep a generated video?

The finished clip is available inline on the job for 24 hours. Persist it before that — either with store: true on the generation call, or by uploading it to the eroq Store afterward — if you need a durable URL.

What does hosting media on the eroq Store cost?

A one-time 2 credits per started 10 MB, charged at upload. A typical 1024×1024 image is one block, an 11 MB clip is two. Serving over the CDN is included within fair use, and deleting an object does not refund the upload.

Is the creation library the same thing as the Store?

No. The library saves every render automatically and for free with its full recipe, and is meant for retrieval and remixing. The Store is paid, durable object hosting with CDN URLs you can put in front of your users.

Read the storage and media endpoints on /docs, then pick where each render is going before you render it.

Tagsstoragecdnmediaapicreations

Make this with the models behind the post — start with 50 free credits , or browse every engine and its price .