The Vercel AI Gateway now reaches both halves of an ecommerce product-launch page from a single API key: Grok Imagine Image 2.0 for the hero still, and Seedance 2.5 for the thirty-second spot that animates it. The two capabilities arrived within forty-eight hours of each other, and the interesting engineering is not in either model — it is in the plumbing between them, which no launch post describes.
That plumbing has three specific shapes. The image call hands back base64 bytes, while every video model that can consume an image wants a hosted URL — so a storage hop sits between the two calls whether you planned for one or not. Long video jobs will outlive a serverless function unless you switch the SDK into its asynchronous polling flow. And the SDK exposes at least one option against gateway models that quietly does nothing at all.
This is a build guide, not a model review. It maps the assets a real launch page needs to the specific calls that produce them, walks the storage and polling steps in order, and is explicit about which parameter names are confirmed in vendor documentation and which are reasonable inference from the closest documented pattern. Where the sources do not support certainty, this piece says so rather than guessing.
- 01One key, two launches, a day apart.Seedance 2.5 opened its API on August 7 as bytedance/seedance-2.5. Grok Imagine Image 2.0 arrived on the Vercel AI Gateway on August 8 as xai/grok-imagine-image-2.0-preview at $0.05 an image. Both are reachable through the same gateway credential.
- 02There is no published direct xAI ID for Image 2.0.xAI shipped Image 2.0 on its consumer surfaces and closed the launch post with a plain statement that API access is coming soon. The gateway preview ID is the only citable way to call it programmatically at the time of writing.
- 03The image output cannot feed the video call directly.generateImage returns base64 and a media type, never a URL. Seedance documentation asks for hosted assets and the asynchronous flow caps inline file data at roughly 300KB — so a Vercel Blob upload sits between the two calls.
- 04Video needs the polling flow to survive serverless.By default the SDK holds one HTTP request open until the video is ready. Passing a top-level poll option switches to short, retryable status requests — the pattern that survives a function timeout. Asynchronous generation requires AI SDK 7.
- 05Hedge the parameter names, not the architecture.The gateway shows worked video code against older Seedance SKUs rather than 2.5 by name, and Grok’s editing tools are documented as app features rather than API parameters. Structure the code so a tag or field rename is a one-line change.
01 — What LandedTwo capabilities, one credential.
Seedance 2.5’s API opened on August 7, announced on Vercel a day before it went live, and sits on the gateway as bytedance/seedance-2.5. We covered the model itself when Seedance 2.5 launched with one-take video, so this piece will not restate its capabilities. Grok Imagine Image 2.0 followed on August 8, added to the gateway as xai/grok-imagine-image-2.0-preview at $0.05 an image per Vercel’s changelog. Note the version number carefully: Image 2.0 is a still-image generation and editing model, distinct from the prior Grok Imagine 1.5 image-to-video release we wrote about for brand ad production. The step up in 2.0 is on image quality and editing, not on video.
The reason to care about the pairing rather than either model alone is credential surface. Routing creative models through a single gateway key is a pattern we have covered on its own terms in our guide to creative model routing through one gateway key, and it applies here in the most literal way possible: the stills call and the video call differ by a model string, not by an auth story, a billing relationship or a second SDK.
Grok Imagine Image 2.0
Added to the Vercel AI Gateway on August 8. xAI shipped the model on grok.com/imagine, iOS and Android as the new Quality Mode; its own launch post closes by saying API access is coming soon, which makes the gateway preview ID the citable programmatic route today.
Seedance 2.5
API opened August 7. The gateway describes it as built for 30-second storytelling with precise reference control and editing. It is token-billed, so there is no per-clip or per-second list price to quote — measure your own jobs to get a unit cost.
02 — Asset MapWhich call produces which asset.
A product-launch page is not one asset. It is a hero still, a set of aspect-ratio crops for paid placements, usually a cutout for overlays and comparison modules, a hero video, and often an extended or looping variant for social. The table below maps that list to specific calls, and marks the one column most build guides skip: where the output has to be hosted before the next step can consume it.
| Asset | Model / gateway ID | Call | Hosting before next step | Caveat |
|---|---|---|---|---|
| Stills | ||||
| Hero product still | xai/grok-imagine-image-2.0-preview | generateImage | Not for the page itself; required before any video call | On the gateway, xAI image models do not support size — use aspectRatio |
| Aspect-ratio crops for ad placements | xai/grok-imagine-image-2.0-preview | generateImage, one call per ratio | No | Smart resize is described as an app feature; treat it as unverified via the API |
| Background-removed cutout | Not confirmed as an API surface on the gateway | Plan a separate step | No | Background removal is documented as a Grok Imagine app capability, not a gateway parameter |
| Motion | ||||
| Hero video from the still | bytedance/seedance-2.5 | experimental_generateVideo | Yes — the still must already be at a public URL | Exact capability tags for 2.5 are not confirmed in the gateway’s modality docs |
| Extended or continuation cut | bytedance/seedance-2.5 | experimental_generateVideo | Yes — the source clip needs a hosted URL too | Extension preserving character, scene and camera continuity is changelog-confirmed; field names are not |
| Native audio on the spot | bytedance/seedance-2.5 | generateAudio flag | No | Documented for the v1.5 Pro and 2.0 series specifically — not named for 2.5 |
Two rows in that table are deliberately negative, and they are the rows that save time. The cutout row is negative because xAI describes background removal alongside a magic wand, segmentation and smart resize as things you do in the Grok Imagine app; no gateway code sample exposes any of them as callable parameters. If your launch page needs a transparent-background subject, budget a separate step rather than assuming a flag exists. The audio row is negative in a softer way: the flag is real and documented, just not documented against this SKU by name.
03 — The Storage HopBase64 in, URL out.
Here is the step that turns a two-call demo into a three-call build. generateImage from the ai package returns result.images[], and each entry exposes base64 and mediaType. It does not return a URL. Seedance, meanwhile, documents that image and video inputs should be hosted at URLs rather than passed as raw buffers, and Vercel’s own docs point at Vercel Blob for exactly this. On the asynchronous flow the constraint gets harder: inline file data is limited to roughly 300KB, which a usable hero still will exceed comfortably.
So the pipeline is generate, upload, then generate again. The illustrative shape below is written against the documented return types; confirm the exact import names against the version of the SDK you install before treating it as working code.
import { generateImage } from "ai";
import { put } from "@vercel/blob";
// 1. Hero still. Note aspectRatio, not size — xAI image models
// on the gateway do not support the size parameter.
const { images } = await generateImage({
model: "xai/grok-imagine-image-2.0-preview",
prompt:
"studio product still, matte ceramic kettle, seamless sand backdrop, soft key light",
aspectRatio: "1:1",
});
// 2. The step nobody writes down: base64 out, hosted URL in.
const still = images[0];
const blob = await put("launch/hero-still.png", Buffer.from(still.base64, "base64"), {
access: "public",
contentType: still.mediaType,
});
// blob.url is what a video model can actually consume.That upload is not incidental housekeeping. It is the seam where most of the operational questions on a launch page live: whether the asset is public or signed, how long it is retained, whether the same URL is what your CDN eventually serves to shoppers, and what happens on a regeneration. Treating it as a real step rather than a workaround also gives you somewhere to put the human approval gate that any commercial creative pipeline needs — which is the point where the licensing questions around AI creative in client work stop being abstract.
Asynchronous flow limit
On the polling flow, inline file data is capped at roughly 300KB. Any real hero still lands above that, so hosted URLs are the practical default rather than an optimisation.
What generateImage hands back
Each entry in result.images[] carries base64 bytes and a media type. There is no URL in the response, which is exactly why the storage hop exists between the image call and the video call.
Version required for async
Asynchronous polling generation requires AI SDK 7. The synchronous single-request flow works on AI SDK 6, which is why an older tutorial can look correct and still fail silently on a serverless function.
04 — Sync vs AsyncWhy video jobs need a polling flow.
By default, experimental_generateVideo holds a single HTTP request open until the video is ready. On your laptop that is fine. On a serverless function it is the exact pattern that dies to a request timeout. Passing a top-level poll: { intervalMs, timeoutMs } option changes the shape entirely: the SDK sends a short start request, the gateway tracks the generation as a background job, and the SDK polls a status endpoint with short, retryable requests instead of holding one connection open.
Four separate ceilings are in play on the same call, and they are easy to confuse. A Vercel Function defaults to 300 seconds under Fluid Compute. Node’s default fetch implementation enforces a five-minute timeout of its own, which can kill a single-request call before a longer render finishes. And the SDK’s own poll.timeoutMs defaults to 600000 milliseconds — ten minutes — while Seedance’s provider-level pollTimeoutMs defaults to 300000 milliseconds, five minutes, with a pollIntervalMs of 3000 against the gateway-wide interval default of 5000. Those are different knobs with different defaults, and conflating them is a real source of confusion.
Four ceilings on one video call · seconds
Sources: Vercel AI Gateway video-generation and image-to-video documentation. Bars are each ceiling as a share of the 600-second top-level poll default.Read those bars as a single instruction: the SDK’s most generous default is twice the length of every other ceiling around it, so the limit that actually bites is whichever runtime you are in. On a Vercel Function, a job that needs more than five minutes has to be asynchronous — there is no configuration of the synchronous flow that survives it.
| Runtime context | Recommended flow | SDK version | Effective ceiling | What breaks if you pick wrong |
|---|---|---|---|---|
| Vercel Function or Route Handler | Polling | 7 | 300 s function default | The held-open request is cut off by the function timeout before the video returns |
| Long-lived Node script | Single request is acceptable; polling still simpler | 6 for sync, 7 for polling | 300 s default fetch timeout | A longer render dies at five minutes unless you build a custom agent with raised timeouts |
| Durable workflow step | Polling, with a durable sleep passed as poll.delay | 7 | 600000 ms poll.timeoutMs default | A live JS timer holds the step open instead of the workflow sleeping properly |
| Anything you hoped to drive by webhook | Polling — there is no alternative | 7 | Not applicable | The webhook option type-checks against gateway models and never fires |
| Your own retry loop around either flow | Either, with an explicit idempotency key | 6 or 7 | Inherits the row above it | Retries can start a second billable generation instead of deduplicating |
That last row deserves its own sentence. Starting a generation is idempotent by design — the SDK sends a stable idempotency key on the start request and the gateway deduplicates on it, so the platform’s own internal retries never double-bill. Your retry loop is outside that guarantee unless you pass your own idempotency key through headers. On a token-billed video model, that is not a hygiene issue; it is a line item.
import { experimental_generateVideo as generateVideo } from "ai";
// Illustrative shape — verify field names on the live model page.
const { videos } = await generateVideo({
model: "bytedance/seedance-2.5",
prompt: "[Image 1] slow dolly-in, steam rising, warm key light, 30 seconds",
inputReferences: [{ type: "image", url: blob.url }],
poll: { intervalMs: 5000, timeoutMs: 600000 },
headers: { "idempotency-key": launchAssetId },
});
// videos[0] exposes uint8Array and base64 — same save-to-Blob
// pattern as the still, if the page serves it from your own CDN.05 — GotchasFour small things that cost a day each.
None of these are exotic. All of them look correct in an editor and fail at runtime, or worse, fail silently.
The content-type trap. If you reach for the OpenAI SDK because its image helpers are familiar, editing will not work against xAI. The OpenAI SDK sends multipart/form-data, while xAI’s editing endpoint requires application/json. Use the xAI SDK, the Vercel AI SDK, or raw HTTP instead.
Size versus aspect ratio. xAI’s own docs describe image size tiers, and it is natural to carry that vocabulary into gateway code. On the gateway specifically, xAI image models do not support the size parameter — use aspectRatio. This is a different failure from the one above and trips people who read only the vendor docs.
The webhook that does nothing. experimental_generateVideo exposes a webhook option, and the gateway does not deliver completion webhooks to it. The code compiles, the call succeeds, the callback never arrives. Polling is the flow, full stop.
The version gate. Asynchronous polling generation requires AI SDK 7; the synchronous flow works on 6. A reader copying from the synchronous quickstart on an older install will not get an error explaining why poll is not behaving asynchronously — they will get a timeout that looks like a model problem.
images.edit() method is not supported for image editing because it uses multipart/form-data, while the xAI API requires application/json.” This is documentation copy, not a named engineer’s statement, and it is the single most concrete portability gotcha in this pipeline.06 — Confirmation StatusWhat is not confirmed.
Both models are days old at the time of writing, and documentation lags shipping. Being explicit about the gaps is more useful than projecting confidence the sources do not support, so here is the honest state of four things a build depends on.
Seedance 2.5 capability tags. The gateway’s modality reference pages for image-to-video and reference-to-video were last updated before Seedance 2.5’s API opened, and their worked examples run against bytedance/seedance-v1.5-pro, bytedance/seedance-v1.0-lite-i2v and bytedance/seedance-2.0 — never 2.5 by name. The closest documented pattern for the 2.x line is reference-to-video via an inputReferences field with [Image 1] and [Video 1] markers in the prompt. It is reasonable to expect 2.5 inherits it. It is not confirmed.
Native audio on 2.5. The generateAudio flag is documented as working for the Seedance v1.5 Pro and 2.0 series specifically. Seedance 2.5 is marketed as a joint audio-video model, so support is a fair expectation — but the parameter is not documented against this SKU by name, so write the call to degrade gracefully if the flag is rejected.
Grok’s editing tools as API parameters. Magic wand, segmentation, background removal and smart resize are described in xAI’s launch post as things the Grok Imagine surfaces do. No gateway sample exposes them as parameters. Treat them as unverified for programmatic use.
Which direct xAI SKU maps to Image 2.0. xAI’s pricing page lists image SKUs of its own, and it is tempting to assume the higher-quality one is Image 2.0 under another name. That mapping is plausible and unconfirmed — xAI has not published a direct API ID for Image 2.0, and the launch post says API access is still to come. Do not encode the assumption.
The practical response to all four gaps is the same, and it is a code-structure decision rather than a research one. Put the model string, the reference-field name and the audio flag behind a single small adapter — a function that takes your asset intent and returns a request object. When the docs catch up or a tag changes, you edit one file. We make the same argument at length in our audit of which AI creative models actually ship into production: the models move faster than the integrations around them, and the teams that stay current are the ones whose integration surface is deliberately small.
07 — BudgetingWhat you can actually budget.
The stills side is easy to model. On the gateway, the Grok Imagine Image 2.0 preview lists at $0.05 an image, so a launch page needing a hero plus six placement crops has a stills cost measured in cents — and the interesting number is not the unit price but how many attempts it takes to get an approved hero. Ten rejected candidates before the keeper is still under a dollar. That asymmetry is why image selection almost never belongs in the cost conversation.
The video side is not modellable the same way, and this is where most coverage goes wrong. Seedance 2.5 is token-billed at $10.70 per million tokens on the gateway. There is no per-clip or per-second list price, and third-party per-second figures circulating for it are derived estimates rather than ByteDance’s or Vercel’s stated billing unit. The correct move is to run three representative jobs, read the actual token spend, and derive your own internal per-spot planning number — one you re-derive when the model or your prompt shape changes.
That difference has a real workflow consequence. When stills are effectively free and motion is the variable cost, the discipline is to converge on the frame before you ever call a video model — which is the same argument as storyboarding on draft tiers before you render, arrived at from a different direction. Grok Imagine Image 2.0 is, in this pipeline, the cheapest possible storyboard.
Flat per-image pricing
The gateway lists the Image 2.0 preview at $0.05 an image. Attempt count barely moves the total, so iterate freely and stop optimising the wrong line.
Token-billed, measure it
Seedance 2.5 bills at $10.70 per million tokens. Publishing a per-clip figure requires arithmetic the vendor has not sanctioned. Run representative jobs and derive your own planning number.
The step you forgot to price
Every still that becomes video input, plus every rendered clip you serve yourself, lands in object storage with its own retention decision. Small money, but it is a real line and it grows per SKU.
Where budgets leak
A retry loop without your own idempotency key can start a second billable generation. On token-billed video that is the most expensive kind of silent bug in this pipeline.
08 — Build OrderShipping the page in five moves.
The sequence below is the order we would actually build it, and the order matters — each step de-risks the one after it. If you are wiring this into a Next.js surface, the routing and streaming patterns overlap heavily with building AI-driven landing pages with the Vercel AI SDK, so the scaffolding is not new work.
- Confirm the model page before you write a line. Open the gateway model page for both IDs and read the current parameter list. Two models this new will change under you; the five minutes here saves the afternoon in section 06.
- Build the storage hop first. Generate one still, upload it, and confirm the URL is reachable from outside your build. Everything downstream depends on this and it is the cheapest thing to verify.
- Run the video call synchronously, once, locally. Before you fight timeouts, prove the prompt and reference shape produce the clip you want on a machine with no request ceiling.
- Then move it to the polling flow. Add
poll: {}, confirm you are on AI SDK 7, and pass your own idempotency key. Only now deploy it to a function. - Put a human approval gate before publish. The generated hero and the generated spot both go in front of a person before they reach a product page — for brand reasons, and for the disclosure and licensing obligations that attach to commercial AI visuals.
The strategic read on this pairing is simpler than the engineering. The constraint on AI creative in ecommerce used to be model quality; increasingly it is integration surface. When the hero still and the hero video are one credential and one SDK apart, the marginal cost of producing a full launch-page asset set collapses toward the cost of deciding what you want — and the bottleneck moves, permanently, to approval and governance. That is a very different operating problem from the one most creative teams are staffed for.
Looking forward, expect the documentation gap this post keeps flagging to close within weeks rather than months, and expect the capability tags to consolidate as the 2.x line settles. What will not resolve on its own is the organisational question: who signs off on a generated hero, on what evidence, and how that decision is recorded. Teams that build that muscle now will absorb the next model launch as a config change. Teams that do not will keep re-litigating the same approval every campaign. Our ecommerce engagements increasingly start at exactly that seam, and the underlying build work sits alongside our web development practice rather than apart from it.
09 — ConclusionOne key, three steps, no guessing.
The models are the easy part. The wiring between them is the work.
Grok Imagine Image 2.0 on the gateway and Seedance 2.5 on the same key make a full product-launch asset set reachable from one credential. The engineering that matters sits between them: a storage hop because the image call returns bytes and the video call wants a URL, and a polling flow because a held-open request does not survive a serverless function. Neither step is difficult. Both are invisible until they break.
The second half of this post is deliberately less confident than the first, and that is the honest state of the sources. The gateway documents its video modalities against older Seedance SKUs, xAI documents its editing tools as app features, and the direct API for Image 2.0 is still described as coming soon. A build that survives those gaps keeps its model strings and field names in one adapter and treats every parameter here as a pattern to confirm rather than a contract to rely on.
The larger shift is worth naming. When a hero still costs cents and a thirty-second spot is a model string away, production capacity stops being the constraint on ecommerce creative. What replaces it is judgement — which frame, which claim, which disclosure, signed off by whom. That is a better problem to have, and it is not one an API key solves.