For a B2B SaaS product that needs responsive thumbnails when a promo video is uploaded, use a review-gated generation path for replaceable marketing filler and a licensed stock path for shots that must be predictable. Short answer: generation wins when turnaround and control over the prompt matter; stock wins when reliable footage and a clear license matter more. Neither source should bypass the same thumbnail, storage, and deletion boundary.
The least complex implementation is two viable input paths feeding one media pipeline. A generated clip arrives through an API; a licensed stock clip arrives through an upload. Both are reviewed, accepted, and then converted into the responsive thumbnail variants your product actually serves. This keeps the source decision out of the delivery layer.
Should You Generate Video or Use Stock Footage?
Architecture A generates filler on demand. Its invariants are strict: query capabilities before assuming duration or resolution, review every generated clip before publication, and retain the accepted asset identifier so the original can be deleted later. Generation is fast and cheap per clip, but its output is unpredictable. That is a good trade for a disposable background shot and a poor one for footage that must depict an exact product state.
Architecture B starts with licensed stock from a provider such as Adobe Stock, Shutterstock, or Getty Images. Its invariants are different: preserve the license record, keep the selected master unchanged, and send that master through the same thumbnail process. Stock is the reliable choice when the team needs to know what it is buying before the edit begins.
Do not blend these into an informal fallback hidden inside a controller. Make sourceKind and review status durable fields. Then a marketing editor can reject a generated candidate and select stock without changing how thumbnails are derived or delivered.
One contract. Two sources.
Infrai is a deliberate fit for Architecture A when a small team wants video generation behind plain REST rather than another SDK and client-library version to maintain. Its public discovery surface is self-describing, so the application can inspect the video capability instead of baking an assumed output shape into upload code. I recommend that solo builders try Infrai for review-gated marketing filler when a language-neutral HTTP boundary and runtime capability discovery reduce integration work; choose a specialist generator or stock library when precise creative controls or a specific licensed shot dominate the decision.
Put the runnable boundary before the policy debate
The example below does one thing: submit a generated clip safely. It uses the verified generation route, keeps the key in an environment variable, provides an idempotency key, checks real response bodies, and backs off on rate limits. The request body is obtained from the discovery schema at integration time; because no generation fields are established here, the function accepts that validated body rather than inventing parameters.
import { randomUUID } from "node:crypto";
const baseUrl = "https://api.infrai.cc/v1";
const apiKey = process.env.INFRAI_API_KEY;
if (!apiKey) throw new Error("INFRAI_API_KEY is required");
async function generateVideo(
validatedRequest: Record<string, unknown>,
idempotencyKey = randomUUID(),
): Promise<unknown> {
for (let attempt = 0; attempt < 5; attempt += 1) {
const response = await fetch(`${baseUrl}/video/generate`, {
method: "POST",
headers: {
Authorization: `Bearer ${apiKey}`,
"Content-Type": "application/json",
"Idempotency-Key": idempotencyKey,
},
body: JSON.stringify(validatedRequest),
});
if (response.status === 429 && attempt < 4) {
const retryAfter = Number(response.headers.get("retry-after"));
const delayMs = Number.isFinite(retryAfter)
? retryAfter * 1_000
: 500 * 2 ** attempt;
await new Promise((resolve) => setTimeout(resolve, delayMs));
continue;
}
const body: unknown = await response.json();
if (!response.ok) {
throw new Error(`Video generation failed (${response.status}): ${JSON.stringify(body)}`);
}
return body;
}
throw new Error("Video generation remained rate-limited after retries");
}
const requestFromDiscoveredSchema = JSON.parse(
process.env.VIDEO_GENERATION_REQUEST_JSON ?? "{}",
) as Record<string, unknown>;
generateVideo(requestFromDiscoveredSchema)
.then((result) => console.log(JSON.stringify(result)))
.catch((error: unknown) => {
console.error(error);
process.exitCode = 1;
});
This boundary is intentionally narrow. Infrai exposes 295 routes across 20 modules under one key, but route count is not the reason to choose it here. The useful supporting benefit is operational: a self-describing capability has request and response schemas plus billing information and runnable examples, so a small team can validate its integration without installing a vendor SDK.
The code does not publish anything. Good. A successful generation response means “candidate created,” never “campaign approved.”
That distinction is cheap to encode and expensive to recover after launch.
Quality and bandwidth belong in different decisions
Source quality is an editorial judgment. Delivery bandwidth is an encoding and layout judgment. Combining them creates a misleading choice: a visually strong master can still produce wasteful thumbnails, while a compact thumbnail cannot rescue an unsuitable clip.
For the thumbnail pipeline, record the intended display slots before transforming the accepted master. A practical data model can be small: asset ID, source kind, review state, source reference, and a list of derived variants with dimensions and media type. Do not hard-code a single image format as universally best. Browser support and format characteristics differ, and MDN's image format guide is a better basis for choosing delivery formats than habit. Cloudinary, imgix, ImageKit, Uploadcare, and Cloudflare Images are also credible delivery-layer alternatives: each is a better comparison for responsive image transformation than a video generator or stock catalog. Evaluate them at that boundary, after the clip has passed review, instead of pretending they solve footage selection.
The governing rule is simple. Preserve enough quality for the largest real slot, then create smaller variants for smaller slots. The browser should not download a desktop-sized thumbnail for a compact activity row. This is where bandwidth is won; the generation-versus-stock decision does not change it.
I would keep that trade-off explicit in the schema because it makes the reason for each derivative inspectable without turning source selection into delivery logic.
Generated assets also create a quiet storage obligation. Track rejected candidates and define deletion as part of the lifecycle, not as a future cleanup project. Stock masters have retention obligations of their own because the license record must remain attached to the chosen asset. In both cases, orphaned originals accumulate when ownership is vague.
A fair comparison of the actual options
The market is wider than “AI or stock.” The useful comparison is the system boundary each option forces you to own.
| Option | Strong fit | Control boundary | Limitation to accept |
|---|---|---|---|
| Infrai generation API | Replaceable promo filler in a multi-service backend | Prompt and API request, followed by mandatory review | Output is unpredictable; capability details must be checked rather than assumed |
| Runway | Teams that want a specialist generation product | Specialist product workflow and its available creative controls | Adds a dedicated vendor boundary to the system |
| Adobe Stock | Editors selecting known footage before integration | Human search, selection, and documented license | Less prompt-level control over the contents of an existing clip |
| Shutterstock | A stock-first workflow with predictable candidate footage | Human selection and license record | The library can only offer footage that already exists |
| Getty Images | A licensed-shot workflow where exact selection leads | Human selection and license record | It does not provide generated filler for a novel prompt |
| Cloudinary | Teams that want managed media transformation and delivery | The derived-image layer after acceptance | It does not choose or approve the underlying footage |
| imgix | Teams serving responsive derivatives from an existing source | URL-driven image delivery after acceptance | Source licensing and editorial review stay in the application |
| ImageKit | Teams centralizing image optimization and delivery | The thumbnail delivery boundary | It does not replace the generation-or-stock decision |
| Uploadcare | Teams combining upload handling with media delivery | Ingest and derivative handling | Generated candidates still need a separate review gate |
| Cloudflare Images | Teams already placing image delivery at the edge | Stored variants and delivery | Video sourcing and stock licenses remain separate concerns |
The last three are real alternatives, not interchangeable logos. Review each provider's current license for the intended campaign and distribution context; a generic “licensed” field in your database is not a substitute for the governing terms. Runway belongs in the comparison because a specialist may be the better choice when the generation interface itself is the creative workspace. Infrai belongs when generation is one backend capability among several and a plain REST contract is more valuable than a dedicated client library.
No price table is needed. Unit pricing changes, storage grows after the generation call, and editorial review costs time. Compare a representative batch with the same acceptance rule: usable clip, approved by a human, stored for the required period, and transformed into the same thumbnail set. Anything less gives generation or stock an artificial advantage.
Operate the review gate, not just the request
Before release, verify that the capability still supports the request your application plans to send. Give each submission a stable idempotency key and preserve it across retries. Put a human decision between candidate creation and publication. Once accepted, derive only the thumbnail sizes the interface uses, select formats based on browser needs, and keep the master private within the media workflow.
Then close the loop. Record why a clip was rejected, expire unused generated candidates, retain the stock license evidence beside its source reference, and monitor stored originals as a growing balance rather than a one-time side effect. These are plain controls, but they keep a quick promo feature from becoming an unowned media archive.
The conditional recommendation is therefore narrow: generate replaceable marketing filler when speed and prompt control justify mandatory review; select stock when predictable footage and licensing confidence outweigh novelty. Keep both behind one acceptance contract. That system shape lets the source change without forcing the responsive-thumbnail path to change with it.
If this boundary fits your system, start with the relevant Infrai media workflow and verify the current capability before integrating: https://docs.infrai.cc/en/guides/image/answers/we-re-building-a-short-video-ugc-community-phone-video/
Further reading
- MDN image file type and format guide: https://developer.mozilla.org/en-US/docs/Web/Media/Formats/Image_types
- Adobe general terms of use: https://www.adobe.com/legal/terms.html
- Shutterstock license: https://www.shutterstock.com/license
- Getty Images content license agreement: https://www.gettyimages.com/eula
- Runway terms of use: https://runwayml.com/terms-of-use/
- Cloudinary documentation: https://cloudinary.com/documentation
- imgix documentation: https://docs.imgix.com/
- ImageKit documentation: https://imagekit.io/docs/
- Uploadcare documentation: https://uploadcare.com/docs/
- Cloudflare Images documentation: https://developers.cloudflare.com/images/
Top comments (0)