SnipKit.eu
Hosted in EU · Frankfurt
Zum Inhalt springen
API-Dokumentation

API-Dokumentation

v1

Vollständige Referenz der SnipKit Video Orchestration API. Ein API-Call — fertig gebrandetes MP4.

Base URL:https://api.snipkit.euInteraktive API-Referenz (Swagger)

Einführung

SnipKit ist eine DSGVO-konforme Video Orchestration API für den DACH-Markt. Du schickst ein kreatives Briefing per JSON-Request — SnipKit generiert vollautomatisch ein geschnittenes, gebrandetes MP4: KI-Storyboard, Video-Generierung, Text-to-Speech und FFmpeg-Compositing. Alle Daten bleiben in der EU.

Async by Default

Jede Anfrage gibt sofort eine job_id zurück. Kein Timeout-Risiko.

BYOK

Verwende deine eigenen Provider-Keys. Volle Kostenkontrolle.

DSGVO

100% EU-Datenhaltung. Frankfurt. Kein Transfer in Drittländer.

Schnellstart

In zwei Schritten zum fertigen Video:

bash
# 1. Video erstellen
curl -X POST https://api.snipkit.eu/v1/videos \
-H "Authorization: Bearer sk_live_dein_key" \
-H "Content-Type: application/json" \
-d '{
"briefing": "30s Instagram Reel ueber Coaching",
"template": "social_reel_9x16",
"byok": {
"video_provider": "veo",
"video_api_key": "dein_veo_key"
}
}'
# Antwort: 202 Accepted
# { "job_id": "vid_abc123", "status": "queued" }
# 2. Status abfragen (pollen bis status = "completed")
curl https://api.snipkit.eu/v1/videos/vid_abc123 \
-H "Authorization: Bearer sk_live_dein_key"
# Antwort wenn fertig:
# { "job_id": "vid_abc123", "status": "completed", "url": "https://..." }

Alternativ: Konfiguriere einen Webhook, um bei Fertigstellung benachrichtigt zu werden — kein Polling nötig. Siehe Sektion .

Authentifizierung

Alle API-Requests benötigen einen API-Key im Authorization-Header.

bash
curl https://api.snipkit.eu/v1/account/credits \
-H "Authorization: Bearer sk_live_dein_key"

Key-Formate

PräfixUmgebungHinweis
sk_live_xxxProduktionCredits werden verbraucht
sk_test_xxxSandboxKostenlos, 5 Credits, kein echtes Video

API-Keys erstellst du im Dashboard.

Auth-Fehler

401Ungültiger oder fehlender API-Key
403Key vorhanden, aber Account gesperrt oder Plan-Limit erreicht

Endpoints

Klicke auf einen Endpoint, um Parameter, Request-Body und Response-Beispiel anzuzeigen.

Templates

Templates definieren Format, Dauer und Schnitt-Stil des generierten Videos.

Template-IDFormatMax. DauerUse Case
social_reel_9x169:1660sInstagram Reels, TikTok
social_post_1x11:160sInstagram Feed, Facebook
linkedin_video_16x916:9120sLinkedIn, Unternehmenskommunikation
product_demo_16x916:9180sProduktvorstellungen, Landing Pages
youtube_short_9x169:1660sYouTube Shorts

Repurposing-Pattern — ein Briefing, N Plattformen

SnipKit hat keinen dedizierten Repurpose-Endpoint — und das ist Absicht. Repurposing entsteht durch mehrere parallele POST /v1/videos-Calls, die sich dasselbe Briefing und dieselbe brand_profile_id teilen, aber unterschiedliche template- und aspect_ratio-Werte verwenden.

Damit liegt die Fan-out-Logik in deiner Pipeline — kein magischer Endpoint, kein impliziter State auf SnipKit-Seite. Du entscheidest, welche Plattformen ausgespielt werden, in welcher Reihenfolge, mit welchen Variationen.

Minimales Repurpose-Beispiel (curl)

bash
# Drei Plattform-Variants aus einem Briefing — parallel.
BRIEF='Q2-Recap: drei lessons learned aus der API-Migration.'
BRAND='bp_acme_main'
for TPL in social_reel_9x16 linkedin_video_16x9 youtube_short_9x16; do
curl -X POST https://api.snipkit.eu/v1/videos \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d "{
\"briefing\": \"$BRIEF\",
\"brand_profile_id\": \"$BRAND\",
\"template\": \"$TPL\",
\"webhook_url\": \"URLhttps://acme.eu/hooks/snipkit\/URL"
}" &
done
wait

Was bleibt gleich, was variiert?

FeldBei RepurposingWarum
briefinggleichInhaltlicher Kern — die KI passt Tonalität pro Template an
brand_profile_idgleichFarben, Logo, Stimme bleiben konsistent
templatepro PlattformBestimmt Schnitt-Stil und Default-Dauer
aspect_ratiopro Plattform9:16 für Reel, 16:9 für LinkedIn etc.
duration_targetpro Plattform30s Reel, 60s LinkedIn, 45s Short
voiceover.voice_idgleichWenn du Voice-Cloning nutzt: dieselbe Stimme über alle Outputs
webhook_urlgleich oder pro PlattformDein Webhook erhält N Events, einen pro Variant
Storyboard-Sharing. Aktuell generiert jeder Call sein eigenes Storyboard (mit deterministischem Seed via brand_profile_id). Brauchst du identische Szenen-Struktur über alle Outputs — z.B. dieselbe Hook-Variante in Reel und Short — generiere das Storyboard einmal via und nutze die zurückgegebenen Szenen als angereichertes Briefing. Wir bewerten ein dediziertes Storyboard-Sharing-Feature, sobald es echten Use-Case-Pull gibt — bis dahin: keine Magie, kein Hidden State.

Brand-Memory — der Kontext-Layer

Ohne persistenten Brand-Kontext ist jeder Render eine Insel. Brand-Profile sind SnipKits Antwort: ein einziges Objekt pro Marke, das Farben, Fonts, Logo, Default-Stimme, Default-Avatar und einen Komponenten-Katalog (HTML-Snippets für Lower-Thirds, Stat-Cards etc.) bündelt. Beim Render-Job wird es einmal geladen und für alle Stufen verwendet — Storyboard-Prompt, TTS-Voice-Auswahl, Compositor-Overlay.

Brand-Profile anlegen

bash
curl -X POST https://api.snipkit.eu/v1/brand-profiles \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{
"name": "Acme Main",
"is_default": true,
"primary_color": "#176FBF",
"secondary_color": "#0B2545",
"font": "Inter",
"logo_url": "URLhttps://acme.eu/brand/logo.svg/URL",
"default_voice_id": "voice_clone_markus_de",
"default_avatar_id": null,
"component_catalog": [
{ "id": "lower_third_a", "html": "<div class=\"lt\">...</div>" }
]
}'

Verwendung im Video-Request

json
{
"briefing": "...",
"template": "social_reel_9x16",
"brand_profile_id": "bp_acme_main",
"byok": { "video_provider": "veo", "video_api_key": "..." }
}

Mehrere Profile pro Account sind möglich (z.B. Sub-Brands, Kunden-Workspaces in Agenturen). Ein Profil kann is_default: true sein — dann greift es automatisch, wenn kein brand_profile_id im Request steht. Felder werden CRUD-bar via /v1/brand-profiles verwaltet.

Was Brand-Memory nicht ist. SnipKit hält bewusst kein „was hat in den letzten 30 Tagen gut performed“-Wissen vor. Engagement-Daten, Trend-Recherche, A/B-Tests gehören in deine Plattform — z.B. in dein Dashboard, dein DWH, deinen CRM. SnipKit ist der Render-Layer, kein Analytics-Layer.

Integration-Cookbook (TypeScript / Node)

Wenn du SnipKit aus einer Next.js-, NestJS- oder Node-App ansprichst (z.B. assistflow, Agentur-Stack, internes Tool), helfen dir diese Snippets beim sauberen Einbau. Native fetch — kein SDK nötig.

1. Thin client (~20 Zeilen)

json
// lib/snipkit.ts
type CreateVideoBody = {
briefing: string;
template: string;
brand_profile_id?: string;
aspect_ratio?: string;
duration_target?: number;
voiceover?: { voice_id?: string; provider?: string };
byok: { video_provider: string; video_api_key: string;
tts_provider?: string; tts_api_key?: string };
webhook_url?: string;
};
export async function createVideo(body: CreateVideoBody) {
const res = await fetch("https://api.snipkit.eu/v1/videos", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.SNIPKIT_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify(body),
});
if (!res.ok) throw new Error(`SnipKit ${res.status}: ${await res.text()}`);
return res.json() as Promise<{ job_id: string; status: string; poll_url: string }>;
}
export async function getVideo(jobId: string) {
const res = await fetch(`https://api.snipkit.eu/v1/videos/${jobId}`, {
headers: { "Authorization": `Bearer ${process.env.SNIPKIT_API_KEY}` },
});
if (!res.ok) throw new Error(`SnipKit ${res.status}`);
return res.json();
}

2. Repurpose-Helper

json
// lib/snipkit-repurpose.ts
import { createVideo } from "./snipkit";
const PLATFORM_PRESETS = {
reel: { template: "social_reel_9x16", aspect_ratio: "9:16", duration_target: 30 },
linkedin: { template: "linkedin_video_16x9", aspect_ratio: "16:9", duration_target: 60 },
short: { template: "youtube_short_9x16", aspect_ratio: "9:16", duration_target: 45 },
post: { template: "social_post_1x1", aspect_ratio: "1:1", duration_target: 30 },
demo: { template: "product_demo_16x9", aspect_ratio: "16:9", duration_target: 90 },
} as const;
export async function repurpose(opts: {
briefing: string;
brand_profile_id: string;
platforms: (keyof typeof PLATFORM_PRESETS)[];
byok: { video_provider: string; video_api_key: string };
webhook_url?: string;
}) {
return Promise.all(
opts.platforms.map((p) =>
createVideo({
briefing: opts.briefing,
brand_profile_id: opts.brand_profile_id,
byok: opts.byok,
webhook_url: opts.webhook_url,
...PLATFORM_PRESETS[p],
})
)
);
}

3. Next.js Route-Handler (App Router)

json
// app/api/videos/repurpose/route.ts
import { NextResponse } from "next/server";
import { repurpose } from "@/lib/snipkit-repurpose";
export async function POST(req: Request) {
const { briefing, platforms } = await req.json();
const jobs = await repurpose({
briefing,
brand_profile_id: process.env.SNIPKIT_BRAND_ID!,
platforms: platforms ?? ["reel", "linkedin", "short"],
byok: {
video_provider: "veo",
video_api_key: process.env.VEO_API_KEY!,
},
webhook_url: `${process.env.APP_URL}/api/webhooks/snipkit`,
});
return NextResponse.json({ jobs });
}

4. Webhook-Handler mit Signatur-Check

json
// app/api/webhooks/snipkit/route.ts
import { createHmac, timingSafeEqual } from "crypto";
import { NextResponse } from "next/server";
export async function POST(req: Request) {
const sig = req.headers.get("x-snipkit-signature") ?? "";
const raw = await req.text();
const expected = createHmac("sha256", process.env.SNIPKIT_WEBHOOK_SECRET!)
.update(raw)
.digest("hex");
const ok =
sig.length === expected.length &&
timingSafeEqual(Buffer.from(sig), Buffer.from(expected));
if (!ok) return new NextResponse("invalid signature", { status: 401 });
const event = JSON.parse(raw) as {
event: "video.completed" | "video.failed" | "video.scene_rendered";
job_id: string;
url?: string;
error?: string;
};
// Persistiere — z.B. Supabase / Postgres / dein DWH
// await db.snipkitJobs.update({ id: event.job_id, ... });
return NextResponse.json({ ok: true });
}

5. ENV-Setup

bash
# .env.local — Integration-Seite (assistflow / dein Stack)
SNIPKIT_API_KEY=sk_live_...
SNIPKIT_BRAND_ID=bp_acme_main
SNIPKIT_WEBHOOK_SECRET=whsec_...
# BYOK-Provider — landen via Request-Body bei SnipKit, nicht in deren Env
VEO_API_KEY=...
ELEVENLABS_API_KEY=...
Drei Patterns, die du sparen kannst. (a) Kein SDK installieren — fetch reicht. (b) Keinen Job-Polling-Loop in deiner Web-Request bauen — Webhook ist günstiger und blockiert keinen Worker. (c) Keine Server-Action mit langer Laufzeit — Vercel/Cloudflare killen die nach 10–60s, SnipKit-Jobs laufen länger. Submitten und auf den Webhook warten.

Credit-System

Credits sind die Währung für KI-Operationen. Monatliche Credits werden am Ersten des Monats zurückgesetzt. Credit-Packs (Einmalkauf) verfallen nicht.

AktionCredits
Storyboard generieren (alle Szenen)2
Video-Szene generieren3
Voiceover-Szene (TTS)1
FFmpeg Compositing0
Szene neu generieren3
Beispiel: Ein typisches 30s Reel mit 5 Szenen + Voiceover kostet ~22 Credits (1x Storyboard + 5x Video + 5x TTS = 2 + 15 + 5).

Webhooks

Anstatt den Job-Status zu pollen, kannst du eine Webhook-URL angeben. SnipKit sendet einenPOST-Request, sobald sich der Status ändert.

Events

EventBeschreibung
video.completedVideo fertig, URL verfügbar
video.failedJob fehlgeschlagen, error-Feld gesetzt
video.scene_renderedEine Szene wurde gerendert (Fortschritt)

Webhook-Payload

json
{
"event": "video.completed",
"job_id": "vid_abc123",
"status": "completed",
"url": "https://storage.snipkit.eu/output/vid_abc123.mp4",
"timestamp": "2026-04-20T10:03:42Z"
}

Signatur-Verifizierung (HMAC-SHA256)

Jeder Webhook enthält den Header X-SnipKit-Signature. Verifiziere ihn, um sicherzustellen, dass der Request von SnipKit stammt.

bash
# Signatur pruefen (Node.js Beispiel)
const crypto = require("crypto");
const secret = process.env.SNIPKIT_WEBHOOK_SECRET;
const body = req.rawBody; // unparsed string
const sig = req.headers["x-snipkit-signature"];
const expected = crypto
.createHmac("sha256", secret)
.update(body)
.digest("hex");
if (sig !== expected) {
return res.status(401).send("Invalid signature");
}

Dein Webhook-Secret findest und konfigurierst du im Dashboard.

Retry-Logik

SnipKit versucht einen Webhook bis zu 5 Mal zu senden (exponentielles Backoff: 30s, 5min, 30min, 2h, 12h). Der Job-Status ist immer auch per GET abrufbar.

BYOK — Bring Your Own Key

Mit BYOK verwendest du deine eigenen API-Keys für Video- und TTS-Provider. SnipKit orchestriert die Calls — du bezahlst deine Provider direkt und hast volle Kostenkontrolle. Keine Vendor-Bindung an SnipKit.

Unterstützte Provider

KategorieProviderbyok.video_provider Wert
VideoGoogle Veo 3.1veo
VideoRunway Gen-4runway
VideoKling 1.6kling
TTSElevenLabselevenlabs
TTSOpenAI TTSopenai
TTSEdge-TTS (kostenlos)edge

BYOK im Request

json
{
"briefing": "...",
"template": "social_reel_9x16",
"byok": {
"video_provider": "runway",
"video_api_key": "rw_live_...",
"tts_provider": "elevenlabs",
"tts_api_key": "el_...",
"tts_voice_id": "EXAVITQu4vr4xnSDxMaL"
}
}
DSGVO-Hinweis: BYOK-Keys werden AES-256-GCM verschlüsselt in der SnipKit-Datenbank gespeichert (Frankfurt) und niemals geloggt. Du bist für die Datenschutzbedingungen deiner Provider verantwortlich.

Fehler-Codes

Alle Fehler-Responses folgen diesem Format:

json
{
"error": {
"code": "insufficient_credits",
"message": "Nicht genug Credits. Benötigt: 22, Vorhanden: 5.",
"retryable": false
}
}
HTTP-StatusCodeBedeutung
400validation_errorPflichtfeld fehlt oder ungültiger Wert
401invalid_api_keyUngültiger oder fehlender API-Key
402insufficient_creditsNicht genug Credits für diese Operation
403account_inactiveAccount gesperrt oder Plan-Limit überschritten
404not_foundJob oder Szene nicht gefunden
409invalid_job_statusOperation für aktuellen Job-Status nicht möglich
422unprocessable_briefingBriefing kann nicht in Storyboard umgewandelt werden
429rate_limit_exceededZu viele Requests. Retry-After-Header beachten
500internal_errorInterner Fehler. Retryable: true bei transienten Fehlern

Noch Fragen?

Schreib uns an hello@snipkit.eu — oder nutze den Support-Chat unten rechts.

Interaktive API testen (Swagger)