You found a clip with exactly the look you want: the handheld drift, the cold morning light, the 4:3 camcorder texture. Getting a text-to-video model to produce something like it means describing all of that in words, shot by shot, and getting it right is slow.
The Video API can write that description for you. Send a video file or a public YouTube link and ask for the prompt output. You get a paste-ready prompt for the whole video, a style line, the aspect ratio, a negative prompt, and one self-contained prompt per shot. These are made for Veo, Sora, Runway, Kling and similar generators.
What you get
{
"results": {
"prompt": {
"prompt": "Medium handheld shot of a young man ... in front of an elephant enclosure at a zoo under overcast daylight ...",
"style": "Early 2000s low-res consumer digital camcorder vlog",
"aspect_ratio": "4:3",
"negative_prompt": "high definition, 4k, cinematic color grade, studio lighting",
"shots": [
{ "start": "00:00", "end": "00:19", "start_seconds": 0.0, "end_seconds": 19.0,
"prompt": "Continuous medium handheld shot of a young man ... talking to the camera outside an elephant pen ..." }
]
}
}
}| Field | What it is |
|---|---|
prompt |
One dense paragraph, roughly 80 to 180 words: subject and appearance, action, setting and time of day, camera (shot size, angle, movement, lens feel), lighting, colour grade and style, mood and pacing, and sound |
style |
A short style line you can reuse across generations |
aspect_ratio |
The source's ratio, such as 16:9, 9:16, 4:3 or 1:1 |
negative_prompt |
Artefacts to avoid, plus things the source does not have but generators tend to add (above: "4k, cinematic color grade") |
shots |
One entry per shot or cut, in order, each with its timing and a 40 to 100 word prompt |
Why one prompt per shot
Text-to-video models generate short clips and remember nothing between prompts. A shot prompt that says "the same man walks away" produces a different man. Every shot prompt in shots therefore restates the subject's appearance and the setting, so it can be generated on its own and still match its neighbours. Keep the style line identical across shots for the same reason.
The sound description covers paraphrased dialogue, sound effects, ambience and music. That matters for generators that produce audio along with the picture.
Step 1: Request the prompt output
curl -X POST https://api.opencorpo.com/v1/video/analyze \
-H "X-API-Key: $OPENCORPO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"source": {"type": "youtube", "url": "https://www.youtube.com/watch?v=jNQXAC9IVRw"},
"outputs": ["prompt"],
"wait": true
}'wait: true holds the request until the job finishes, for up to 90 seconds. For longer videos, poll GET /v1/video/jobs/{id}?wait=60, as shown in the transcript guide. To use your own footage, upload it first through /v1/uploads and pass {"type": "upload", "upload_id": "up_..."} as the source.
The price is per started minute of video, whatever you ask for. Adding "summary", "description" or "transcript" to outputs costs nothing extra.
Step 2: Read the prompt object
In Python, turn the result into a storyboard you can review or hand to a generation queue:
import json
import os
import requests
API = "https://api.opencorpo.com"
HEADERS = {"X-API-Key": os.environ["OPENCORPO_API_KEY"]}
def video_to_prompt(source):
r = requests.post(f"{API}/v1/video/analyze", headers=HEADERS,
json={"source": source, "outputs": ["prompt"], "wait": True}, timeout=120)
job = r.json()
if not r.ok:
raise RuntimeError(job["error"]["message"])
while job["status"] in ("queued", "processing"):
job = requests.get(f"{API}/v1/video/jobs/{job['id']}", headers=HEADERS,
params={"wait": 60}, timeout=100).json()
if job["status"] != "completed":
raise RuntimeError(f"job {job['id']} {job['status']}: {job.get('error')}")
return job["results"]["prompt"]
p = video_to_prompt({"type": "youtube", "url": "https://www.youtube.com/watch?v=jNQXAC9IVRw"})
storyboard = [
{
"shot": i,
"seconds": round(s["end_seconds"] - s["start_seconds"], 1),
"prompt": f'{s["prompt"]} Style: {p["style"]}.',
"negative_prompt": p["negative_prompt"],
"aspect_ratio": p["aspect_ratio"],
}
for i, s in enumerate(p["shots"], 1)
]
print(json.dumps(storyboard, indent=2))The same in Node.js:
const API = "https://api.opencorpo.com";
const headers = { "X-API-Key": process.env.OPENCORPO_API_KEY };
export async function videoToPrompt(source) {
let res = await fetch(`${API}/v1/video/analyze`, {
method: "POST",
headers: { ...headers, "Content-Type": "application/json" },
body: JSON.stringify({ source, outputs: ["prompt"], wait: true }),
});
let job = await res.json();
if (!res.ok) throw new Error(job.error.message);
while (job.status === "queued" || job.status === "processing") {
job = await (await fetch(`${API}/v1/video/jobs/${job.id}?wait=60`, { headers })).json();
}
if (job.status !== "completed") throw new Error(`job ${job.id} ${job.status}`);
return job.results.prompt;
}
const p = await videoToPrompt({ type: "youtube", url: "https://www.youtube.com/watch?v=jNQXAC9IVRw" });
p.shots.forEach((s, i) => console.log(`Shot ${i + 1} [${s.start}-${s.end}]\n${s.prompt}\n`));You can also download the prompts as a file: GET /v1/video/jobs/{id}/export?source=prompt&format=txt returns the whole-video prompt, the negative prompt and every shot with its timing. format=json returns the raw object.
Step 3: Generate shot by shot
Generators differ in what they accept, so map the fields to each tool's settings instead of pasting everything into one box:
- Aspect ratio. Most generators have a setting for it. Use
aspect_ratiothere rather than writing it into the prompt. - Clip length. Generators cap clip duration, and the cap varies by model and plan. Use
start_secondsandend_secondsto choose a duration for each shot. Split a long shot into two prompts, or merge very short cuts. - Negative prompt. Some tools have a separate negative prompt field; others ignore negatives. Where there is no field, rewrite the most important exclusions as positive descriptions. For example, "soft overcast daylight" instead of "no studio lighting".
- Style consistency. Append the same
styleline to every shot, and keep seeds or reference settings fixed if your generator supports them. - Edit afterwards. Generate each shot, then cut them together in order. The shot timings tell you how long each clip should run.
Treat the output as a first draft written by someone with a good eye. It gets you to a usable prompt in seconds, and you still choose what to keep and what to change.
Good uses
- Pre-visualisation. Turn a reference reel into a shot list and test generations before a shoot.
- Ad and social variants. Recreate the structure of a format that works, with your own product and setting.
- Prompt libraries. Build a searchable catalogue of looks, with
styleandnegative_promptas tags. - Captioning video datasets. Combine
descriptionandpromptto label clips for search or training data you have the rights to.
Limits and responsible use
- Similar, not identical. The prompt describes the video; generators interpret it, and results vary between models and runs.
- No real people, no brands by name. People are described only by visible appearance, clothing and role, never by name, even if the video names them. Logos become generic ("a red soda can"). On-screen text is left out unless essential, because generators render text poorly.
- Rights are yours to check. Using someone else's video as a reference does not give you rights to its characters, music or distinctive creative elements.
- What you generate is AI-generated content. If you publish it to people in the EU, Article 50 of the AI Act may require it to be marked or disclosed. See our Article 50 overview.
- Source limits apply. Public YouTube videos or your own uploads, up to 20 minutes analysed per video.
Frequently asked questions
Which video generators do the prompts work with?
Any text-to-video model that takes an English prompt: Veo, Sora, Runway, Kling and similar. The prompt is plain text; aspect ratio and negative prompt are separate fields so you can map them to each tool's own settings.
Will the prompt name the people in the video?
No. People are described by visible appearance, clothing and role, never by name, even when the video names them. Logos and brands are described generically.
Can I request only the prompt?
Yes: set outputs to ["prompt"]. The price is the same whatever outputs you request, so you can also get the transcript and summary at no extra cost.
Does it copy the video exactly?
No. It describes the video so a generator can make something similar in look, framing and pacing. Generated results vary by model and by run.
How much does it cost?
Like any analysis, €0.05 per started minute of video on the default model. Your first 3 analyses are free, each covering up to the first 5 minutes.