The short version
Baue die REST-Integration in etwa zehn Minuten und behandle Rendering danach als dauerhaften asynchronen Job.
Dieses Tutorial verwandelt eine öffentliche URL in einen 30-sekündigen 16:9-Motion-Graphics-Job. Upload, Create, Status und Download sind schnell integriert. Das Rendering ist asynchron und nicht in zehn Minuten garantiert. Unser Test dauerte deutlich länger, deshalb speichert der Code die Job-ID und übersteht Netzwerkfehler.
Review TapVid API and MCP access
01
Was Text-to-Video-API hier bedeutet
Text-to-Video kann Prompt-Clips, Bildanimation, Avatare oder Stock-Montage bedeuten. TapVid verwandelt vorhandene Quellen in strukturierte Informationsvideos mit mehreren Szenen. Hier liefern eine öffentliche Seite und ein präzises Briefing Fakten, Zielgruppe, Länge und Verbote. Eine einzelne Szene kann neu erzeugt werden, während der Rest erhalten bleibt.
„In 10 Minuten“ bezeichnet die Integration der vier REST-Operationen, nicht eine garantierte Renderzeit. Create liefert sofort `202 Accepted`, Status kann lange gleich bleiben und Export nach completed weiterarbeiten. Ein ehrlicher Client trennt Request- von Generation-Latenz und erstellt nach Verbindungsverlust keinen Doppeljob.
Das eingebettete Video ist ein fertiges TapVid-Beispiel aus einem anderen verifizierten Workflow. Es ist nicht das Endergebnis dieses REST-Tests, weil der Poller vor einem beobachteten Terminalstatus die Verbindung verlor.
02
Den Vertrag vor dem Code verstehen
Das Gateway ist `https://api.tapvid.ai/api/public/v1`. Jede Anfrage nutzt einen Bearer Key über HTTPS. Erstelle ihn unter API Keys und lade ihn serverseitig als `process.env.TAPVID_API_KEY`. Er gehört nie in Browsercode, Screenshots oder Repository.
- REST Base über HTTPS verwenden.
- Key serverseitig aus `process.env.TAPVID_API_KEY` laden.
- Genau URL oder Datei pro Materialaufruf senden.
- `materialId` und nach HTTP 202 sofort `videoId` speichern.
- Nach `pollAfterSeconds` mit resumierbarem Timeout pollen.
| Feld | Grenze | Hinweis |
|---|---|---|
| Datei | 100 MB | multipart |
| URL | HTTPS, 4.096 Zeichen | keine internen Hosts |
| Materialien | 30 | IDs speichern |
| Prompt | 12.000 Zeichen | quellennah |
| Format | `16:9` oder `9:16` | Enum exakt |
| Länge | `30s` bis `5m` | Enum exakt |
03
Schritt 1: URL oder Datei hochladen
Sende für URLs JSON mit einer HTTPS-Adresse oder für Dateien multipart bis 100 MB. Die URL darf 4.096 Zeichen haben. Speichere den zurückgegebenen `materialId` als privaten Anwendungszustand.
export TAPVID_API_KEY="replace-with-your-local-secret"
curl -X POST https://api.tapvid.ai/api/public/v1/materials \
-H "Authorization: Bearer ${TAPVID_API_KEY}" \
-H "Content-Type: application/json" \
-d '{ "url": "https://tapvid.ai/api-mcp" }'Das cURL-Beispiel ist lokal verständlich; in CI gehört der Key in einen Secret Store. Bei `payload_too_large` muss das Material korrigiert werden. Bei einer abgewiesenen URL prüfst du HTTPS, Länge, Erreichbarkeit und Redirects.
04
Schritt 2: asynchronen Videojob erstellen
Erstelle erst nach erfolgreichem Upload. Das Briefing nennt Publikum, Quelle, 30 Sekunden, 16:9, Englisch, Pflichtablauf und verbotene Behauptungen. HTTP 202 mit `videoId` bedeutet angenommen, nicht fertig oder redaktionell genehmigt.
curl -X POST https://api.tapvid.ai/api/public/v1/video/create \
-H "Authorization: Bearer ${TAPVID_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"materialIds": ["MATERIAL_ID_FROM_UPLOAD"],
"userPrompt": "Create a concise 30-second English explainer for developers. Stay faithful to the supplied source and do not invent claims.",
"title": "TapVid API developer explainer",
"aspectRatio": "16:9",
"duration": "30s",
"language": "en"
}'
Speichere `videoId` vor dem nächsten Netzwerkaufruf. Ein Prozess kann nach Create abstürzen. Ohne gespeicherte ID kann er nicht fortsetzen und verursacht leicht einen zweiten bezahlten Job. Beachte `videoId` in der Antwort und `video_id` in der Statusabfrage.
05
Schritt 3: speichern, pollen und herunterladen
Poll `GET /video/status` nach `pollAfterSeconds`. Progress von 0 bis 1 ist keine Restzeit. Nach completed kann Credits-Abrechnung folgen. Fordere erst dann den signierten Download an; er läuft nach ungefähr einer Stunde ab.
import { writeFile } from 'node:fs/promises'
const apiKey = process.env.TAPVID_API_KEY
if (!apiKey) throw new Error('TAPVID_API_KEY is required')
const base = 'https://api.tapvid.ai/api/public/v1'
const headers = { Authorization: `Bearer ${apiKey}` }
async function request(path, init = {}, { attempts = 1 } = {}) {
let lastError
for (let attempt = 1; attempt <= attempts; attempt += 1) {
try {
const response = await fetch(`${base}${path}`, {
...init,
headers: { ...headers, ...init.headers },
})
const data = await response.json()
if (response.ok) return { response, data }
if (response.status !== 429 && response.status < 500) {
const error = new Error(`HTTP ${response.status}: ${data.code ?? 'unknown'}`)
error.retryable = false
throw error
}
lastError = new Error(`retryable HTTP ${response.status}`)
} catch (error) {
if (error?.retryable === false) throw error
lastError = error
}
if (attempt === attempts) break
await new Promise((resolve) => setTimeout(resolve, attempt * 1000))
}
throw lastError
}
const { data: material } = await request('/materials', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ url: 'https://tapvid.ai/api-mcp' }),
})
const { response: createResponse, data: video } = await request('/video/create', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
materialIds: [material.materialId],
userPrompt: 'Create a concise 30-second English explainer for developers. Stay faithful to the source.',
title: 'TapVid API developer explainer',
aspectRatio: '16:9',
duration: '30s',
language: 'en',
}),
})
if (createResponse.status !== 202) throw new Error('Expected 202 Accepted')
// Persist before the next network call. A lost poll must not cause a duplicate create.
await writeFile('.tapvid-job.json', JSON.stringify({ videoId: video.videoId }))
let status
for (let poll = 0; poll < 180; poll += 1) {
const result = await request(
`/video/status?video_id=${encodeURIComponent(video.videoId)}`,
{},
{ attempts: 4 },
)
status = result.data
if (status.status === 'completed' || status.status === 'failed') break
await new Promise((resolve) =>
setTimeout(resolve, Math.max(status.pollAfterSeconds ?? 5, 5) * 1000),
)
}
if (!status) throw new Error('No status received')
if (status.status === 'failed') throw new Error(status.error?.code ?? 'generation_failed')
if (status.status !== 'completed') throw new Error('Polling timeout; resume with the saved videoId')
const query = new URLSearchParams({
video_id: video.videoId,
resolution: '1080P',
watermark: 'true',
subtitle: 'false',
})
const { data: download } = await request(`/video/download?${query}`, {}, { attempts: 4 })
console.log({ status: download.status, expiresAt: download.expiresAt })Das Node-Beispiel speichert die ID und wiederholt nur geeignete Reads begrenzt. In Produktion ersetzt eine Datenbank die lokale JSON-Datei. 400 und 401 werden nicht blind wiederholt; 429, Server- und Netzwerkfehler erhalten Backoff.
06
Was der echte REST-Test zeigte
Im Test dauerte Upload etwa 1,4 Sekunden und Create 0,3 Sekunden mit HTTP 202. Running bei 50 Prozent erschien nach rund 81 Sekunden und blieb bis mindestens 331 Sekunden. Dann endete der lokale Poller mit `ECONNRESET` vor dem TLS-Aufbau.

Die erste Skriptversion hatte die ID nur im Prozessspeicher und konnte nicht fortsetzen. Es wurde kein Doppeljob erstellt. Der Zähler stieg über MCP und REST auf 180 Credits, also 90 je Create. Deshalb verspricht der Artikel keine fertige Datei in zehn Minuten.
07
Fehler ohne doppelte Kosten behandeln
Behandle Fehler nach Bedeutung: unauthorized repariert den Key, invalid_request den Body, insufficient_credits stoppt, rate_limited wartet auf Retry-After, Netzwerkfehler wiederholen nur sichere Reads. Eine verlorene Antwort nach Create ist kein Grund für einen neuen Create.
| Bedingung | Retry? | Aktion |
|---|---|---|
| unauthorized | Nein | Key reparieren |
| invalid_request | Nein | Body korrigieren |
| insufficient_credits | Nein | Stoppen |
| rate_limited | Ja | Retry-After |
| Netzwerk oder Server | Begrenzt | Read wiederholen |
| Antwort nach Create verloren | Nicht neu erstellen | ID fortsetzen |
08
Produktionscheckliste
Für Produktion brauchst du serverseitige Secrets, atomare ID-Speicherung, getrennte Latenzen, resumierbares Timeout, sichere Logs, erneuerbare Download-URLs und menschliche Prüfung von Quelle, Länge, Rechten und Marke.
- Key nur serverseitig.
- IDs atomar speichern.
- Latenzen getrennt messen.
- Pollintervall und Timeout beachten.
- Reads und Writes getrennt behandeln.
- Signierte URL erneuern.
- Credits sicher protokollieren.
- Mensch prüft und veröffentlicht.
09
API für fertige Erklärvideos statt Zufallsclips
Nutze diese API für ein zusammenhängendes Erklärvideo aus genehmigtem Inhalt, nicht als Versprechen eines beliebigen Kino-Clips. Für Dialog nutze das Claude-MCP-Tutorial, für dauerhafte Kontrolle REST und die aktuelle API/MCP-Übersicht.
10
Frequently asked questions
Ist das Video immer in 10 Minuten fertig?
Nein. Die Integration ist kurz, Rendering und Export sind asynchron. Unser MCP-Test brauchte etwa 28 Minuten bis completed.
Was bedeutet HTTP 202?
Der Job wurde angenommen. Speichere videoId und poll den Status.
Wie oft pollen?
Nutze pollAfterSeconds, begrenzte Retries und ein resumierbares Timeout.
Wie lange gilt die Download-URL?
Laut aktueller Doku ungefähr eine Stunde.
Kann das Wasserzeichen weg?
Standard ist an; Entfernen erfordert ein aktives Abo.
Turn them into a clear, publishable video
Keep reading
Related stories

Motion-Graphics-Videos mit Claude und TapVid MCP erstellen
Praxisanleitung mit einer öffentlichen Quelle, fünf echten MCP-Tools, einem 30-Sekunden-Briefing und einem ehrlichen Produktionstest.
Aug 7, 2026

Claude-Videogenerierung: Seedance 2.5 oder TapVid?
Claude Video Generation braucht ein Rendering-Tool. Erfahren Sie, wann Sie Claude mit Seedance 2.5 oder TapVid kombinieren, mit Aufforderungen und einem praktischen Workflow.
Aug 8, 2026

Text-Animator-Techniken: Schnellere Bewegung ohne visuelles Rauschen
Ein praktisches Text-Animator-Framework für Teams, die lesbare, wirkungsstarke Videobotschaften brauchen.
Apr 16, 2026

