curl --request POST \
--url https://api.apimart.ai/v1/videos/generations \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{
"model": "gemini-omni-1.2-flash",
"prompt": "A marble rolling fast on a chain reaction style track, continuous smooth shot.",
"aspect_ratio": "16:9",
"resolution": "720p",
"duration": 15
}'
import time
import requests
base_url = "https://api.apimart.ai"
headers = {"Authorization": "Bearer <token>"}
payload = {
"model": "gemini-omni-1.2-flash",
"prompt": "A marble rolling fast on a chain reaction style track, continuous smooth shot.",
"aspect_ratio": "16:9",
"resolution": "720p",
"duration": 15,
}
response = requests.post(
f"{base_url}/v1/videos/generations",
headers=headers, json=payload, timeout=30,
)
response.raise_for_status()
task_id = response.json()["data"][0]["task_id"]
print(task_id)
deadline = time.monotonic() + 600
while time.monotonic() < deadline:
response = requests.get(
f"{base_url}/v1/tasks/{task_id}", headers=headers, timeout=30,
)
response.raise_for_status()
task = response.json()["data"]
if task["status"] == "completed":
print(task["result"]["videos"][0]["url"][0])
break
if task["status"] == "failed":
raise RuntimeError(task["error"]["message"])
time.sleep(5)
else:
raise TimeoutError(f"Continue polling task {task_id}")
const baseUrl = "https://api.apimart.ai";
const headers = {
Authorization: "Bearer <token>",
"Content-Type": "application/json",
};
const response = await fetch(`${baseUrl}/v1/videos/generations`, {
method: "POST",
headers,
signal: AbortSignal.timeout(30_000),
body: JSON.stringify({
model: "gemini-omni-1.2-flash",
prompt: "A marble rolling fast on a chain reaction style track, continuous smooth shot.",
aspect_ratio: "16:9",
resolution: "720p",
duration: 15,
}),
});
if (!response.ok) throw new Error(await response.text());
const taskId = (await response.json()).data[0].task_id;
console.log(taskId);
async function waitForTask(taskId) {
const deadline = Date.now() + 600_000;
while (Date.now() < deadline) {
const response = await fetch(`${baseUrl}/v1/tasks/${taskId}`, {
headers,
signal: AbortSignal.timeout(30_000),
});
if (!response.ok) throw new Error(await response.text());
const task = (await response.json()).data;
if (task.status === "completed") return task.result.videos[0].url[0];
if (task.status === "failed") throw new Error(task.error.message);
await new Promise(resolve => setTimeout(resolve, 5000));
}
throw new Error(`Continue polling task ${taskId}`);
}
console.log(await waitForTask(taskId));
{
"code": 200,
"data": [
{
"status": "submitted",
"task_id": "task_01EXAMPLE"
}
]
}
Gemini Omni 1.2 Flash
Gemini Omni 1.2 Flash Videogenerierung
Videos aus Text oder Bildern, mehrere Motivvorlagen, Start-/Endbild-Interpolation, Bearbeitung und Verlängerung. Bis zu 4K, 24fps, mit Audio.
POST
/
v1
/
videos
/
generations
curl --request POST \
--url https://api.apimart.ai/v1/videos/generations \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{
"model": "gemini-omni-1.2-flash",
"prompt": "A marble rolling fast on a chain reaction style track, continuous smooth shot.",
"aspect_ratio": "16:9",
"resolution": "720p",
"duration": 15
}'
import time
import requests
base_url = "https://api.apimart.ai"
headers = {"Authorization": "Bearer <token>"}
payload = {
"model": "gemini-omni-1.2-flash",
"prompt": "A marble rolling fast on a chain reaction style track, continuous smooth shot.",
"aspect_ratio": "16:9",
"resolution": "720p",
"duration": 15,
}
response = requests.post(
f"{base_url}/v1/videos/generations",
headers=headers, json=payload, timeout=30,
)
response.raise_for_status()
task_id = response.json()["data"][0]["task_id"]
print(task_id)
deadline = time.monotonic() + 600
while time.monotonic() < deadline:
response = requests.get(
f"{base_url}/v1/tasks/{task_id}", headers=headers, timeout=30,
)
response.raise_for_status()
task = response.json()["data"]
if task["status"] == "completed":
print(task["result"]["videos"][0]["url"][0])
break
if task["status"] == "failed":
raise RuntimeError(task["error"]["message"])
time.sleep(5)
else:
raise TimeoutError(f"Continue polling task {task_id}")
const baseUrl = "https://api.apimart.ai";
const headers = {
Authorization: "Bearer <token>",
"Content-Type": "application/json",
};
const response = await fetch(`${baseUrl}/v1/videos/generations`, {
method: "POST",
headers,
signal: AbortSignal.timeout(30_000),
body: JSON.stringify({
model: "gemini-omni-1.2-flash",
prompt: "A marble rolling fast on a chain reaction style track, continuous smooth shot.",
aspect_ratio: "16:9",
resolution: "720p",
duration: 15,
}),
});
if (!response.ok) throw new Error(await response.text());
const taskId = (await response.json()).data[0].task_id;
console.log(taskId);
async function waitForTask(taskId) {
const deadline = Date.now() + 600_000;
while (Date.now() < deadline) {
const response = await fetch(`${baseUrl}/v1/tasks/${taskId}`, {
headers,
signal: AbortSignal.timeout(30_000),
});
if (!response.ok) throw new Error(await response.text());
const task = (await response.json()).data;
if (task.status === "completed") return task.result.videos[0].url[0];
if (task.status === "failed") throw new Error(task.error.message);
await new Promise(resolve => setTimeout(resolve, 5000));
}
throw new Error(`Continue polling task ${taskId}`);
}
console.log(await waitForTask(taskId));
{
"code": 200,
"data": [
{
"status": "submitted",
"task_id": "task_01EXAMPLE"
}
]
}
Text- und bildbasierte Videogenerierung unterstützt ganze Sekunden von 3 bis 15; Standard ist 10. Start-/Endbild-Interpolation und der hinzugefügte Abschnitt einer Verlängerung unterstützen höchstens 10 Sekunden. Bei Bearbeitung wird
duration ignoriert und die Länge des Quellvideos beibehalten. Videoeingaben werden standardmäßig bearbeitet. Zum Verlängern ist "omni_reference_task_type": "extend" erforderlich.curl --request POST \
--url https://api.apimart.ai/v1/videos/generations \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{
"model": "gemini-omni-1.2-flash",
"prompt": "A marble rolling fast on a chain reaction style track, continuous smooth shot.",
"aspect_ratio": "16:9",
"resolution": "720p",
"duration": 15
}'
import time
import requests
base_url = "https://api.apimart.ai"
headers = {"Authorization": "Bearer <token>"}
payload = {
"model": "gemini-omni-1.2-flash",
"prompt": "A marble rolling fast on a chain reaction style track, continuous smooth shot.",
"aspect_ratio": "16:9",
"resolution": "720p",
"duration": 15,
}
response = requests.post(
f"{base_url}/v1/videos/generations",
headers=headers, json=payload, timeout=30,
)
response.raise_for_status()
task_id = response.json()["data"][0]["task_id"]
print(task_id)
deadline = time.monotonic() + 600
while time.monotonic() < deadline:
response = requests.get(
f"{base_url}/v1/tasks/{task_id}", headers=headers, timeout=30,
)
response.raise_for_status()
task = response.json()["data"]
if task["status"] == "completed":
print(task["result"]["videos"][0]["url"][0])
break
if task["status"] == "failed":
raise RuntimeError(task["error"]["message"])
time.sleep(5)
else:
raise TimeoutError(f"Continue polling task {task_id}")
const baseUrl = "https://api.apimart.ai";
const headers = {
Authorization: "Bearer <token>",
"Content-Type": "application/json",
};
const response = await fetch(`${baseUrl}/v1/videos/generations`, {
method: "POST",
headers,
signal: AbortSignal.timeout(30_000),
body: JSON.stringify({
model: "gemini-omni-1.2-flash",
prompt: "A marble rolling fast on a chain reaction style track, continuous smooth shot.",
aspect_ratio: "16:9",
resolution: "720p",
duration: 15,
}),
});
if (!response.ok) throw new Error(await response.text());
const taskId = (await response.json()).data[0].task_id;
console.log(taskId);
async function waitForTask(taskId) {
const deadline = Date.now() + 600_000;
while (Date.now() < deadline) {
const response = await fetch(`${baseUrl}/v1/tasks/${taskId}`, {
headers,
signal: AbortSignal.timeout(30_000),
});
if (!response.ok) throw new Error(await response.text());
const task = (await response.json()).data;
if (task.status === "completed") return task.result.videos[0].url[0];
if (task.status === "failed") throw new Error(task.error.message);
await new Promise(resolve => setTimeout(resolve, 5000));
}
throw new Error(`Continue polling task ${taskId}`);
}
console.log(await waitForTask(taskId));
{
"code": 200,
"data": [
{
"status": "submitted",
"task_id": "task_01EXAMPLE"
}
]
}
Authentifizierung
string
erforderlich
Bearer-Token verwenden. Einen Schlüssel erhalten Sie in der API-Key-Verwaltung. Anfragen mit
Content-Type: application/json senden.Anfrageparameter
string
erforderlich
Muss
gemini-omni-1.2-flash sein.string
erforderlich
Erforderliche Textanweisung: Bei Text-zu-Video die Szene beschreiben, bei Bild-zu-Video, Bearbeitung oder Verlängerung Bewegung, Stil oder Änderungen.
prompt ist auch bei Referenzbildern, Start-/Endbildern, Videos oder extend_from_task_id erforderlich. Ohne diesen Parameter wird HTTP 400 zurückgegeben.integer
Standard:"10"
Ausgabelänge für text- und bildbasierte Videogenerierung als Ganzzahl von
3 bis 15, Standard 10. Start-/Endbild-Interpolation und Verlängerung erlauben nur 3–10 Sekunden. Bei Verlängerung bezeichnet dies den hinzugefügten Abschnitt; das Ergebnis enthält das Original und den neuen Abschnitt. Bei Bearbeitung wird duration ignoriert und die Länge des Quellvideos beibehalten. Parameterwerte außerhalb des zulässigen Bereichs lassen die Aufgabe mit invalid_duration fehlschlagen.string
Standard:"720p"
360p / 720p / 1080p / 4k, unabhängig von Groß-/Kleinschreibung. 2160p wird als 4k behandelt. 1080p und 4k werden hochskaliert. Die Auflösung beeinflusst Ausgabe-Token und reserviertes Guthaben. Andere Werte führen zu invalid_resolution.string
Standard:"16:9"
Nur
16:9 (Querformat, Standard) und 9:16 (Hochformat). Andere Werte werden als 16:9 behandelt.string[]
Referenzbilder ausschließlich als öffentlich zugängliche direkte HTTP(S)-Bild-URLs. Data-URLs und Base64 werden nicht unterstützt. Ein Bild dient standardmäßig als Startbild; mehrere Bilder als Motivvorlagen. Insgesamt höchstens 10 Bilder einschließlich Start-/Endbildern. Für Figuren werden höchstens 2 Figuren mit je bis zu 3 Bildern empfohlen, insgesamt maximal 6 Bilder.
string
Startbild. Allein verwendet beginnt das Video mit diesem Bild; zusammen mit
last_frame_image wird zwischen Start- und Endbild interpoliert. Nur öffentlich zugängliche direkte HTTP(S)-Bild-URLs werden unterstützt.string
Endbild; erfordert
first_frame_image, sonst schlägt die Aufgabe mit invalid_frame_images fehl. Beide Bilder sollten dasselbe Seitenverhältnis haben und zu aspect_ratio passen. Nur öffentlich zugängliche direkte HTTP(S)-Bild-URLs werden unterstützt.object[]
Bilder mit Rollen als Alternative zu den direkten Start-/Endbild-Feldern. Eine der beiden Schreibweisen wählen. Alle verwendeten Bilder zählen zur Gesamtgrenze von 10.
string[]
Video zur Bearbeitung oder Verlängerung: höchstens 1 Clip mit maximal 15 Sekunden. Nur öffentlich zugängliche direkte HTTP(S)-Video-URLs werden unterstützt. Data-URLs und Base64 werden nicht unterstützt. Videoeingaben werden standardmäßig bearbeitet.
string
Standard:"auto"
Aufgabentyp:
auto (Standard, aus der Eingabe abgeleitet) / edit (Bearbeitung) / extend (Verlängerung) / reference (mehrere Referenzbilder). Auch text_to_video / image_to_video / reference_to_video werden akzeptiert. Ohne Angabe oder bei auto bewirken video_urls und extend_from_task_id standardmäßig eine Bearbeitung. Zum Verlängern explizit extend angeben.string
ID einer eigenen vorherigen Generierungsaufgabe. Das Video wird ohne erneuten Upload verwendet. Standard ist Bearbeitung. Mit
"omni_reference_task_type": "extend" wird am Ende ein Abschnitt von höchstens 10 Sekunden angefügt.Funktionen und Grenzen
- Ausgabe mit 24fps und Dialog, Musik oder Geräuschen. Gewünschten Ton in
promptbeschreiben. - Audioeingaben, System-Prompts,
temperatureund negative Prompt-Parameter werden nicht unterstützt. Ausschlüsse direkt inpromptformulieren. - Regionale Beschränkungen des Anbieters: Im EWR, in der Schweiz und im Vereinigten Königreich werden die Bearbeitung oder Verlängerung hochgeladener Videos sowie die Bearbeitung von Bildern mit Minderjährigen nicht unterstützt.
- Alle Ausgaben enthalten ein unsichtbares SynthID-Wasserzeichen.
Beispiele
Jeden JSON-Body anPOST /v1/videos/generations senden. Beispiel-URLs und Aufgaben-IDs durch eigene nutzbare Eingaben ersetzen.
15 Sekunden in 4K im Hochformat
{
"model": "gemini-omni-1.2-flash",
"prompt": "Aerial shot over a misty mountain lake at sunrise, birds flying, slow forward camera move.",
"aspect_ratio": "9:16",
"resolution": "4k",
"duration": 15
}
Bild-zu-Video und mehrere Motivvorlagen
{
"model": "gemini-omni-1.2-flash",
"prompt": "The cat playfully bats at the ball of yarn.",
"image_urls": [
"https://example.com/cat.png",
"https://example.com/yarn.png"
],
"duration": 12
}
Start-/Endbild-Interpolation
{
"model": "gemini-omni-1.2-flash",
"prompt": "Smooth transition, camera slowly pushes in.",
"first_frame_image": "https://example.com/start.jpg",
"last_frame_image": "https://example.com/end.jpg",
"aspect_ratio": "16:9",
"duration": 8
}
Bilder über Rollen zuweisen
{
"model": "gemini-omni-1.2-flash",
"prompt": "A smooth cinematic transition from sunrise to a starry night.",
"image_with_roles": [
{
"url": "https://example.com/sunrise.jpg",
"role": "first_frame"
},
{
"url": "https://example.com/night.jpg",
"role": "last_frame"
}
],
"duration": 8
}
Videobearbeitung
{
"model": "gemini-omni-1.2-flash",
"prompt": "Make the violin invisible. Keep everything else the same.",
"video_urls": [
"https://example.com/clip.mp4"
]
}
duration hat keine Wirkung.
Kurze, konkrete Bearbeitungsanweisungen verwenden. Für eine lokale Änderung kann Keep everything else the same ergänzt werden.
Vorherige Aufgabe verlängern
{
"model": "gemini-omni-1.2-flash",
"prompt": "The camera continues panning across the mountains.",
"extend_from_task_id": "task_01PREVIOUS",
"omni_reference_task_type": "extend",
"duration": 8
}
extend_from_task_id durch video_urls ersetzen und "omni_reference_task_type": "extend" beibehalten. Das zurückgegebene Video enthält das Original und den am Ende angefügten Abschnitt. duration steuert nur die neue Länge von höchstens 10 Sekunden; berechnet werden nur die hinzugefügten Sekunden. Ein 5 Sekunden langes Original mit duration: 4 ergibt beispielsweise ein Video von etwa 9 Sekunden.
Übermittlungsantwort und Aufgabenstatus
Eine erfolgreiche Übermittlung liefert HTTP 200. Die Aufgaben-ID steht indata[0].task_id. Den Aufgabenstatus alle 5–10 Sekunden bis completed oder failed abfragen. Insgesamt 10 Minuten Wartezeit vorsehen. Bei einem Client-Timeout die ursprüngliche Aufgabe weiter abfragen, statt sie erneut einzureichen.
curl --request GET \
--url https://api.apimart.ai/v1/tasks/task_01EXAMPLE \
--header 'Authorization: Bearer <token>'
{
"code": 200,
"data": {
"id": "task_01EXAMPLE",
"status": "completed",
"progress": 100,
"result": {
"videos": [
{
"url": [
"https://cdn.example.com/gemini_omni_video.mp4"
]
}
]
}
}
}
data der Abfrageantwort ist das Aufgabenobjekt. data.result.videos[0].url ist ein Array; die erste Video-URL lautet data.result.videos[0].url[0]. Direkt abspielen oder herunterladen und für eine dauerhafte Aufbewahrung selbst archivieren. data.cost ist der endgültige Betrag in USD.
| Status | Aktion |
|---|---|
pending / processing | Weiter abfragen; Fortschritt steht in data.progress. |
completed | Video-URL auslesen und speichern. |
failed | data.error.message lesen. Fehlgeschlagene Aufgaben werden nicht berechnet. |
Abrechnung und Guthabenreservierung
Tokenbasierte Abrechnung: Die Auflösung beeinflusst die Ausgabe-Token pro Sekunde. Bei text- und bildbasierter Videogenerierung bestimmtduration die Ausgabelänge. Bei Bearbeitung wird der Wert ignoriert und die Länge des Quellvideos beibehalten; bei Verlängerung bestimmt er nur die Länge des hinzugefügten Abschnitts. Aktuelle Tarife stehen auf der APIMart-Preisseite.
Bei Übermittlung wird Guthaben anhand der Auflösung und max(10, duration) Sekunden reserviert; bei Videoeingaben werden 15 Sekunden geschätzt. Die Reservierung ist nicht der Endbetrag. Nach Erfolg wird anhand der tatsächlichen Nutzung abgerechnet. Den Endbetrag zeigt data.cost.
Verlängerungen werden nur für hinzugefügte Sekunden berechnet. Fehlgeschlagene Aufgaben sind kostenfrei. Reicht das Guthaben für die Reservierung nicht aus, wird HTTP 402 zurückgegeben.
Fehlerbehandlung
Parameterfehler (invalid_* / unsupported_*) setzen die Aufgabe sofort auf failed, ohne Kosten. Auch nach erfolgreicher Übermittlung den Aufgabenstatus prüfen.
| Fehler / Status | Ursache und Lösung |
|---|---|
invalid_duration | duration liegt außerhalb von 3–15 oder Interpolation / Verlängerung überschreitet 10 Sekunden. Eine zulässige Ganzzahl verwenden. |
invalid_task_type | Nicht unterstützter Wert für omni_reference_task_type. auto / edit / extend / reference verwenden; auch text_to_video / image_to_video / reference_to_video werden akzeptiert. |
invalid_resolution | 360p / 720p / 1080p / 4k verwenden; 2160p wird ebenfalls akzeptiert. |
invalid_frame_images | Nur ein Endbild wurde angegeben. Ein Startbild ergänzen. |
unsupported_image_count | Mehr als 10 Bilder einschließlich Start-/Endbildern. Anzahl reduzieren. |
unsupported_video_count | Mehr als 1 Eingabevideo. Nur einen Clip mit höchstens 15 Sekunden verwenden. |
HTTP 400 | Der erforderliche Parameter prompt fehlt. Auch bei Medien Textanweisungen übermitteln. |
HTTP 401 | Ungültiger Schlüssel. Authorization prüfen. |
HTTP 402 | Guthaben reicht nicht für die Reservierung. Aufladen oder Auflösung reduzieren. |
HTTP 429 | Anfragelimit erreicht. Mit wachsendem Abstand wiederholen. |
status: failed | Anbieterfehler oder Ablehnung durch Inhaltsrichtlinien. data.error.message lesen und Anfrage anpassen. |
Häufige Fragen
Ist prompt auch bei Bildern oder Videos erforderlich?
Ja. Alle Modi erfordern prompt, einschließlich Bild-zu-Video, Start-/Endbild-Interpolation, Bearbeitung, Verlängerung und Wiederverwendung eines Videos über extend_from_task_id. Ohne dieses Feld wird HTTP 400 zurückgegeben.
Kann ich Bilder oder Videos direkt als Base64 senden?
Nein.image_urls, first_frame_image, last_frame_image, image_with_roles[].url und video_urls akzeptieren nur öffentlich zugängliche direkte HTTP(S)-URLs. Keine data:image/..., data:video/... oder reinen Base64-Zeichenfolgen senden.