When I plan an AI product video, I separate five jobs: product identity,
demonstration, atmosphere, story and the final edit. I do not put them all
into one prompt.
Here is the shot-manifest template I recommend before calling the video API.
It is a design proposal with illustrative examples, not a report of a paid
generation experiment or a customer result.
Disclosure: I work on XPLA. The XPLA fields below describe the contract I
checked against the public documentation on September 4, 2026. This is not a price, speed, access or fidelity
guarantee.
One shot owns one buyer question
“Make a premium product ad” is not a testable requirement.
“Show where the touch control is and what changes after one tap” is.
I split a sequence into:
- evidence — establish product identity;
- action — show one mechanism;
- context — show where the product is used.
The evidence shot runs first. If the product is wrong in a restrained shot, I
do not spend more generations adding hands, moving props and dramatic camera
motion.
The manifest
type ReviewState = "draft" | "approved" | "submitted" |
"completed" | "accept" | "repair" | "reject";
type ShotManifest = {
shotId: string;
role: "evidence" | "action" | "context";
buyerQuestion: string;
referenceMode: "frame" | "ingredient";
mustPreserve: string[];
allowedMotion: string[];
prohibitedImplications: string[];
acceptIf: string[];
repairIf: string[];
rejectIf: string[];
state: ReviewState;
};
Example:
const shot: ShotManifest = {
shotId: "sku-014-action-01",
role: "action",
buyerQuestion: "What does the closure look like in use?",
referenceMode: "frame",
mustPreserve: ["cap shape", "label geometry", "bottle color"],
allowedMotion: ["slow hand approach", "small camera push"],
prohibitedImplications: ["leakproof unless verified"],
acceptIf: ["closure visible", "label readable"],
repairIf: ["crop hides contact point"],
rejectIf: ["cap, label or product count changes"],
state: "approved"
};
The prompt is derived from this record. The QA decision returns to the same
record.
I enforce a motion budget
Each shot has three motion variables:
- product or hand action;
- camera movement;
- environmental movement.
Only one gets to be high variance.
If a hand performs a precise mechanism, the camera and background stay quiet.
If the camera performs an orbit, the product stays still. This is not a model
rule; it is an application rule that makes failures explainable.
I validate the model contract separately
The current XPLA public model is veo-3.1-fast on POST /v1/videos.
Its verified wrapper accepts:
- fixed eight-second tasks;
- 720p or 1080p;
- 16:9 or 9:16;
- up to two ordered frame references;
- up to three ingredient references.
Reference-video input is unsupported. Google's native Veo API has a different
request shape, so I do not copy native provider fields into this wrapper.
function validateShot(s: ShotManifest) {
const errors: string[] = [];
if (!s.buyerQuestion.trim()) errors.push("Missing buyer question");
if (s.mustPreserve.length === 0) errors.push("Missing product truth");
if (s.allowedMotion.length > 2) errors.push("Motion budget too broad");
const outcomes =
s.acceptIf.length + s.repairIf.length + s.rejectIf.length;
if (outcomes === 0) errors.push("Missing review rules");
return errors;
}
A timeout is not a new creative
The API task is asynchronous. I persist the intent before submitting:
type GenerationRecord = {
shotId: string;
intent: "first_calibration" | "repair" | "new_creative";
requestHash: string;
taskId: string | null;
state: "approved" | "submitted" | "transport_unknown" |
"completed" | "failed";
attempt: number;
nextAction: "submit" | "poll" | "reconcile" | "review";
};
If the client times out, the state becomes transport_unknown. The application
reconciles the original task before creating another generation.
That distinction matters because a timeout does not prove the first task never
started.
Product QA runs before cinematic review
My review order is:
- identity;
- geometry and count;
- label and text;
- mechanism and contact points;
- physical plausibility;
- crop and channel fit;
- lighting and rhythm.
The outcome is explicit:
- accept — the shot answers its question and preserves product truth;
- repair — the product is correct and a local layer can be fixed;
- reject — the product, mechanism, count, label or claim changed.
A technically completed task is not publication approval.
The final ad is an edit
An eight-second generation is a production unit, not necessarily the delivery
length.
I may trim an evidence clip to two seconds, an action clip to three and a
context clip to three. Captions, approved voice, licensed sound and the CTA
belong in the editing timeline.
No paid generation was run for this article, and the diagram is a workflow
explanation—not video evidence.
The current wrapper details and request examples are in the
XPLA Veo 3.1 Fast guide.
That page currently uses noindex,follow; I am linking it for documentation,
not claiming it is indexed or ranked.
My stop rule is simple: if the first evidence shot changes a non-negotiable
product fact twice, I return to the source material instead of growing the
batch.