Übergib eine Quelldatei und die gewünschten Ausgaben. Die Verarbeitung läuft asynchron auf unseren Servern, die Ergebnisse landen per PUT in deinem Speicher oder bei uns, und eine signierte Rückmeldung meldet das Ende.
https://creativeskyline.de/api/media/v1/jobs
https://creativeskyline.de/api/media/v1/uploads
https://creativeskyline.de/api/media/v1/assets
https://creativeskyline.de/api/media/v1/presets
https://creativeskyline.de/api/media/v1/webhook-endpoints
Basis-URL: https://creativeskyline.de/api/media/v1. Jede Anfrage trägt Authorization: Bearer fd_…. Ein Auftrag besteht aus einer Pipeline (oder einem eigenen Preset), einer Eingabe und benannten Ausgaben.
https-URL (zum Beispiel eine signierte GET-URL deines Speichers) oder eine upload_id aus POST /uploads.put_url (presigned PUT in deinen Speicher) oder managed: true (wir speichern 7 Tage und liefern einen Download-Link).callback.endpoint_id) oder eine freie callback.url.queued → downloading → processing → uploading → finished. Jeder laufende Zustand kann in failed enden, ein wartender Auftrag in cancelled. Ein Auftrag wird genau einmal versucht; ob sich ein neuer Versuch lohnt, sagt error.retryable.
Aus einer Quelle wird nur einmal dekodiert, alle Ausgaben entstehen daraus (zum Beispiel watermarked und clean in einem Durchgang). Videos werden als H.264 High (mindestens Level 4.1, bei größeren Bildern und höheren Bildraten das passende höhere Level, yuv420p, faststart) mit AAC 128 kbit/s kodiert, HDR-Quellen (HLG/PQ) werden auf SDR BT.709 umgerechnet, Metadaten wie GPS werden entfernt.
Die Namen entsprechen den festen Profilen. video und image sind Bausteine mit frei benennbaren Ausgaben, deren Typ aus type kommt.
| Pipeline | Ausgaben und Standardwerte | Regeln |
|---|---|---|
ugc_video | watermarked (video): 540×960 crop, crf 23, preset medium, max_fps 30, audio keep, Wasserzeichenclean (video): 540×960 crop, crf 23, preset medium, max_fps 30, audio keepthumbnail (thumbnail): 540×960 crop, format jpg, quality 85 | mindestens eine von: watermarked, cleanStandard-Warteschlange (bis 30 min) |
ugc_image | watermarked (image): 640×640 max, format jpg, quality 85, Wasserzeichenclean (image): 640×640 max, format jpg, quality 85 | mindestens eine von: watermarked, cleanStandard-Warteschlange (bis 30 min) |
video_thumbnail | thumbnail (thumbnail): format jpg, quality 85 | Pflicht: thumbnailStandard-Warteschlange (bis 30 min) |
chat_image | preview (image): 1200×1200 max, format webp, quality 80 | Pflicht: previewStandard-Warteschlange (bis 30 min) |
chat_video | video (video): 1280×720 scale, crf 26, preset medium, max_fps 30, audio keepposter (poster): 640×auto max, format webp, quality 80 | Pflicht: videoStandard-Warteschlange (bis 30 min) |
course_video | video (video): 1280×720 scale, crf 28, preset medium, max_fps 30, audio keep | Pflicht: videolange Warteschlange (bis 3 h) |
audio_extract | audio (audio): format mp3 | Pflicht: audiolange Warteschlange (bis 3 h) |
video | beliebiger Name mit type: video: 1280×720 scale, crf 23, preset medium, max_fps 30, audio keepbeliebiger Name mit type: thumbnail: format jpg, quality 85beliebiger Name mit type: poster: 640×auto max, format webp, quality 80 | Standard-Warteschlange (bis 30 min) |
image | beliebiger Name mit type: image: 1200×1200 max, format jpg, quality 85 | Standard-Warteschlange (bis 30 min) |
Reihenfolge, spätere Ebene gewinnt: Standardwert der Pipeline → Team-Preset options → Team-Preset outputs.<name> → Auftrag options → Auftrag outputs.<name>.
width, height (16 bis 7680 px), max_side, fit (crop füllt und schneidet zu, scale passt ein, max verkleinert nur)crf (18 bis 32), preset (x264, ultrafast bis veryslow), max_fps (nur wenn die Quelle schneller ist), audio (keep / strip)format (jpg, webp, png), quality (1 bis 100)watermark (true / false) je Video- oder Bildausgabeoptions.watermark: asset, width_percent (1 bis 100), opacity (0 bis 1), position (center, top_center, bottom_center, top_left, top_right, bottom_left, bottom_right, center_left, center_right), margin_x, margin_y (px)Ein Team-Preset bündelt eine Basis-Pipeline mit eigenen options und outputs-Vorlagen und wird mit "preset": "<key>" statt pipeline verwendet. Die Vorlagen werden beim Speichern mit denselben Regeln wie ein Auftrag geprüft.
/api/media/v1/presets
Alle System-Pipelines (system: true) und die Presets deines Teams.
/api/media/v1/presets
Legt ein Team-Preset an (201) oder ersetzt eines mit gleichem Schlüssel (200). System-Namen sind reserviert.
key
string
*
1 bis 64 Zeichen aus a-z, 0-9, _ und -
name
string
Bezeichnung, höchstens 191 Zeichen
pipeline
string
*
Basis-Pipeline, zum Beispiel ugc_video
options
object
Optionen für alle Ausgaben inklusive watermark
outputs
object
Überschreibungen je Ausgabename
/api/media/v1/presets/{key}
Löscht ein Team-Preset. Bereits angelegte Aufträge sind nicht betroffen, sie tragen eine Kopie ihrer Einstellungen.
/api/media/v1/jobs
Legt einen Auftrag an und antwortet mit 202 und queue_position. Genau eines von pipeline und preset, genau eines von input.url und input.upload_id, je Ausgabe genau eines von put_url und managed: true. Alle URLs müssen https sein und auf öffentliche Adressen zeigen.
pipeline
string
System-Pipeline (siehe Tabelle), alternativ preset
preset
string
Schlüssel eines Team-Presets, alternativ pipeline
reference
string
Deine eigene Kennung (höchstens 191 Zeichen), abfragbar über GET /jobs?reference=
priority
string
high, normal (Standard) oder low; course_video ist standardmäßig low
input.url
string
Öffentliche https-URL der Quelle, bis zu 3 Weiterleitungen
input.upload_id
string
ID aus POST /uploads, einmal verwendbar
input.filename
string
Originaler Dateiname (nur zur Anzeige)
input.size
integer
Größe in Bytes; wird vorab gegen das Limit geprüft und verbessert die Kostenreservierung
outputs.<name>.put_url
string
Presigned PUT-URL für das Ergebnis
outputs.<name>.managed
boolean
true: wir speichern das Ergebnis 7 Tage
outputs.<name>.content_type
string
Content-Type beim PUT, Standard passend zum Format
outputs.<name>.*
mixed
Überschreibungen wie width, height, fit, crf, format, quality, watermark
options
object
Optionen für alle Ausgaben, inklusive watermark.asset
callback.endpoint_id
string
ID eines registrierten Webhook-Endpunkts
callback.url
string
Freie https-URL; signiert mit dem Geheimnis des Standard-Endpunkts, sonst unsigniert
callback.events
array
job.finished und/oder job.failed (Standard: beide)
metadata
object
Beliebiges JSON bis 4 KB, kommt unverändert in der Rückmeldung zurück
/api/media/v1/jobs/{job_id}
Liefert den Auftrag in derselben Form wie die Rückmeldung. Bei managed-Ausgaben enthält download_url einen signierten Link, der bis expires_at gilt.
/api/media/v1/jobs
Die bis zu 20 neuesten Aufträge mit dieser reference.
reference
string
*
Deine Referenz aus POST /jobs
/api/media/v1/jobs/{job_id}
Ein wartender Auftrag wird sofort cancelled (ohne Rückmeldung, Reservierung wird freigegeben). Ein laufender Auftrag erhält eine Abbruchanforderung (cancel_requested: true), der Worker stoppt innerhalb weniger Sekunden und meldet job.failed mit error.code = cancelled. Ein beendeter Auftrag ergibt 409 conflict.
/api/media/v1/uploads
Für Quellen ohne öffentliche URL: liefert eine presigned PUT-URL in unseren Speicher. Die Datei dort hochladen und danach als input.upload_id verwenden. Gültig 24 Stunden, einmal verwendbar. Je Team sind höchstens acht Direkt-Uploads und zusammen 10 GB gemeldete Größe gleichzeitig offen. Ein Upload zählt weiter, nachdem er einem Auftrag zugeordnet wurde, bis die Zeile entfernt ist.
filename
string
Dateiname, höchstens 255 Zeichen
size
integer
*
Größe in Bytes, Pflicht. Die presigned PUT-URL signiert genau diese Content-Length; ein größerer Körper wird vom Speicher abgelehnt.
content_type
string
Content-Type, der beim PUT gesendet werden muss
/api/media/v1/usage
Aufträge, Fehlschläge, Rechenzeit und Eingabevolumen im Zeitraum (Standard: aktueller Monat). Kosten und Guthaben stehen in der App unter FlowData → Guthaben.
from
string
Startdatum YYYY-MM-DD
to
string
Enddatum YYYY-MM-DD
/api/media/v1/health
Ohne Anmeldung. ok, degraded (Wartung oder Bildverarbeitung eingeschränkt) oder down, dazu die Länge der Warteschlange.
Wasserzeichen sind PNG-Dateien mit Transparenz (Alphakanal oder tRNS), höchstens 2 MB und 8000 × 8000 px. Jede Version wird unter ihrem SHA-256 abgelegt; ein Auftrag merkt sich den Hash (options.watermark.asset_sha256), ein späteres Ersetzen ändert also keinen wartenden Auftrag. Verwalten lassen sie sich auch in der App unter FlowData → Wasserzeichen.
/api/media/v1/assets/{key}
Body als rohes PNG (Content-Type: image/png) oder multipart mit dem Feld file. Antwort 201 für einen neuen Schlüssel, 200 für eine neue Version.
file
file
*
PNG mit Alphakanal, höchstens 2 MB
/api/media/v1/assets/{key}
Gleich wie PUT, für Clients, die multipart nur mit POST senden können.
file
file
*
PNG mit Alphakanal, höchstens 2 MB
/api/media/v1/assets
Alle Wasserzeichen deines Teams mit aktueller Version.
Ereignisse: job.finished (alle Ausgaben hochgeladen) und job.failed (inklusive Abbruch). Body: {"event": "job.finished", "job": { …wie GET /jobs/{id}… }, "metadata": { …deine metadata… }}. Eine Testzustellung aus der App trägt "event": "webhook.test".
webhook-id: ID der Zustellung, bei Wiederholungen gleich (zur Duplikaterkennung)webhook-timestamp: Unix-Sekunden des Versandswebhook-signature: v1,<base64>, HMAC-SHA256 über {webhook-id}.{webhook-timestamp}.{body} mit dem base64-dekodierten Teil des Geheimnisses nach whsec_. Während einer Rotation (24 Stunden) stehen zwei Signaturen, durch Leerzeichen getrennt, im Header.X-Media-Event mit dem Ereignisnamen und User-Agent: CreativeSkyline-Media/1.0.Eine freie callback.url wird mit dem Geheimnis des Standard-Endpunkts deines Teams signiert; gibt es keinen, geht sie unsigniert raus. Jede Standard-Webhooks-Bibliothek kann die Signatur prüfen, alternativ so:
// Laravel-Controller, der eine FlowData-Rückmeldung prüft (Standard Webhooks).
$secret = 'whsec_...'; // aus FlowData → Webhooks
$key = base64_decode(substr($secret, 6)); // HMAC-Schlüssel = Teil nach "whsec_"
$id = $request->header('webhook-id');
$timestamp = (int) $request->header('webhook-timestamp');
$body = $request->getContent(); // roher Body, nicht neu kodieren
if (abs(time() - $timestamp) > 300) {
abort(400, 'timestamp outside tolerance');
}
$expected = base64_encode(hash_hmac('sha256', "{$id}.{$timestamp}.{$body}", $key, true));
$valid = false;
// Während einer Rotation stehen zwei Signaturen im Header: "v1,<a> v1,<b>".
foreach (explode(' ', (string) $request->header('webhook-signature')) as $candidate) {
[$version, $signature] = array_pad(explode(',', $candidate, 2), 2, '');
if ($version === 'v1' && hash_equals($expected, $signature)) {
$valid = true;
}
}
abort_unless($valid, 401);
// webhook-id ist je Zustellung stabil: bereits verarbeitete IDs überspringen.
$event = json_decode($body, true); // {"event":"job.finished","job":{...},"metadata":{...}}Erfolgreich ist jede Antwort mit 2xx innerhalb von 10 Sekunden. Weiterleitungen werden nicht verfolgt. Sonst folgen Wiederholungen nach 30 s, 2 min, 10 min, 30 min, 1 h, 3 h und 6 h. Rückmeldungen eines Auftrags gehen in Reihenfolge und nie gleichzeitig raus. In der App lässt sich jede Zustellung am Auftrag erneut senden.
/api/media/v1/webhook-endpoints
Alle Endpunkte deines Teams, ohne Geheimnis.
/api/media/v1/webhook-endpoints
Legt einen Endpunkt an und liefert das Geheimnis einmalig im Feld secret. is_default: true nimmt die Markierung einem anderen Endpunkt ab.
url
string
*
Öffentliche https-URL
events
array
job.finished und/oder job.failed (Standard: beide)
description
string
Höchstens 191 Zeichen
is_default
boolean
Signiert auch freie callback.url
/api/media/v1/webhook-endpoints/{endpoint_id}/rotate-secret
Erzeugt ein neues Geheimnis und liefert es einmalig. Das alte signiert 24 Stunden lang mit (previous_secret_expires_at).
/api/media/v1/webhook-endpoints/{endpoint_id}
Löscht den Endpunkt. Offene Zustellungen an ihn werden aufgegeben.
Jede Fehlerantwort hat die Form {"error": {"code", "message", "details", "type"}}. Ein fehlgeschlagener Auftrag trägt error = {"code", "message", "stage", "retryable"}.
| HTTP | code | Bedeutung |
|---|---|---|
| 400 | bad_request | Kein gültiges JSON-Objekt oder ungültiger Idempotency-Key |
| 401 | unauthenticated | Fehlender oder ungültiger Schlüssel |
| 403 | forbidden | Schlüssel ohne FlowData-Zugriff |
| 404 | not_found | Unbekannte oder fremde ID |
| 409 | idempotency_conflict | Idempotency-Key mit anderem Body |
| 409 | conflict | Abbruch eines bereits beendeten Auftrags |
| 413 | input_too_large | input.size oder Wasserzeichen über dem Limit |
| 422 | validation_failed | Ungültige Felder; details.field und details.errors nennen sie |
| 429 | rate_limited | Zu viele Anfragen oder mehr als 200 wartende Aufträge; Retry-After beachten |
| 429 | upload_quota_exceeded | Zu viele offene Direkt-Uploads (Anzahl oder Summe der gemeldeten Bytes, auch bereits zugeordnete) |
| 429 | insufficient_quota | Prepaid: das Guthaben reicht nicht. Postpaid: Kreditrahmen oder Monatslimit reicht nicht |
| 429 | spend_limit_exceeded | Ausgabenlimit des Schlüssels oder Monatslimit des Teams erreicht |
| 500 / 503 | internal_error / unavailable | Fehler bei uns |
| code | retryable | Bedeutung |
|---|---|---|
input_download_failed | ja | Quelle vorübergehend nicht ladbar |
input_not_found | nein | Quelle abgelaufen, gelöscht oder gesperrt (403/404) |
input_too_large | nein | Größe, Dauer oder Bildmaße über dem Limit |
input_unreadable | nein | Datei beschädigt oder Format nicht unterstützt |
input_no_video_stream | nein | Video-Pipeline ohne Videospur |
input_no_audio_stream | nein | audio_extract ohne Tonspur |
processing_failed | nein | Kodierung oder Qualitätsprüfung fehlgeschlagen |
output_upload_failed | ja | PUT auf deine URL mit 5xx oder Netzfehler |
output_url_expired | nein | PUT-URL abgelaufen oder abgelehnt (403) |
timeout | ja | Maximale Verarbeitungszeit überschritten |
cancelled | nein | Per DELETE abgebrochen |
insufficient_quota | nein | Nach der Analyse reicht das Guthaben (Prepaid) oder der Kreditrahmen bzw. das Monatslimit (Postpaid) nicht für die tatsächliche Dauer |
spend_limit_exceeded | nein | Ausgabenlimit von Schlüssel oder Team während der Verarbeitung erreicht, oder Abrechnung gesperrt |
forbidden | nein | Der Schlüssel wurde während der Verarbeitung deaktiviert oder darf nicht mehr abrechnen |
internal_error | ja | Fehler bei uns |
| Pipeline | Max. Größe | Max. Dauer |
|---|---|---|
| Video (ugc_video, chat_video, video, video_thumbnail) | 2 GB | 10 min |
| Langes Video (course_video) | 5 GB | 3 h |
| Audio (audio_extract) | 5 GB | 3 h |
| Bild (ugc_image, chat_image, image) | 50 MB | – |
Bilder höchstens 16000 × 16000 px. Standardmäßig 60 Auftragsanlagen pro Minute je Schlüssel und höchstens 200 wartende Aufträge je Team. metadata höchstens 4 KB. Bis zu vier Aufträge laufen gleichzeitig, Kursvideos und Tonspuren in einer eigenen Warteschlange.
Abgerechnet wird über das FlowData-Guthaben, und zwar nur für tatsächlich hochgeladene Ausgaben: Video 0,010 € je angefangene Minute, Audio 0,005 € je angefangene Minute, Bild, Vorschaubild und Poster 0,002 € je Ausgabe (Listenpreise, abweichende Vereinbarungen möglich). Bei der Anlage wird eine Schätzung reserviert und am Ende mit dem tatsächlichen Wert verrechnet. Auch bei einem teilweise fehlgeschlagenen Auftrag werden die hochgeladenen Ausgaben berechnet.
Bei uns gespeicherte Ausgaben (managed) werden nach 7 Tagen gelöscht, Direkt-Uploads mit dem Ende ihres Auftrags (unbenutzt nach 24 Stunden), Auftragsdaten nach 90 Tagen. Abrechnungsdaten bleiben dauerhaft. Signierte URLs werden verschlüsselt gespeichert und nie protokolliert.
/api/media/v1/presets
curl -X GET "https://creativeskyline.de/api/media/v1/presets" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Accept: application/json"
use Illuminate\Support\Facades\Http;
$response = Http::withToken('YOUR_API_TOKEN')
->get('https://creativeskyline.de/api/media/v1/presets');
$data = $response->json();
const response = await fetch('https://creativeskyline.de/api/media/v1/presets', {
method: 'GET',
headers: {
'Authorization': 'Bearer YOUR_API_TOKEN',
'Accept': 'application/json',
},
});
const data = await response.json();
import requests
headers = {
'Authorization': 'Bearer YOUR_API_TOKEN',
'Accept': 'application/json',
}
response = requests.get(
'https://creativeskyline.de/api/media/v1/presets',
headers=headers,
)
data = response.json()
{
"data": [
{
"key": "ugc_video",
"system": true,
"pipeline": "ugc_video",
"outputs": [
"watermarked",
"clean",
"thumbnail"
]
},
{
"key": "ugc_hd",
"system": false,
"name": "UGC in HD",
"pipeline": "ugc_video",
"options": {
"width": 720,
"height": 1280
},
"outputs": {
"clean": {
"crf": 20
}
},
"updated_at": "2026-09-28T10:00:00Z"
}
]
}
/api/media/v1/presets
curl -X POST "https://creativeskyline.de/api/media/v1/presets" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"key": "ugc_hd", "name": "UGC in HD", "pipeline": "ugc_video", "options": {"width":720,"height":1280,"watermark":{"asset":"brand_white","opacity":0.3}}, "outputs": {"clean":{"crf":20}}}'
use Illuminate\Support\Facades\Http;
$response = Http::withToken('YOUR_API_TOKEN')
->post('https://creativeskyline.de/api/media/v1/presets', [
'key' => 'ugc_hd',
'name' => 'UGC in HD',
'pipeline' => 'ugc_video',
'options' => array (
'width' => 720,
'height' => 1280,
'watermark' =>
array (
'asset' => 'brand_white',
'opacity' => 0.3,
),
),
'outputs' => array (
'clean' =>
array (
'crf' => 20,
),
),
]);
$data = $response->json();
const response = await fetch('https://creativeskyline.de/api/media/v1/presets', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_TOKEN',
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
key: "ugc_hd",
name: "UGC in HD",
pipeline: "ugc_video",
options: {"width":720,"height":1280,"watermark":{"asset":"brand_white","opacity":0.3}},
outputs: {"clean":{"crf":20}},
}),
});
const data = await response.json();
import requests
headers = {
'Authorization': 'Bearer YOUR_API_TOKEN',
'Accept': 'application/json',
}
payload = {
'key': "ugc_hd",
'name': "UGC in HD",
'pipeline': "ugc_video",
'options': {"width": 720, "height": 1280, "watermark": {"asset": "brand_white", "opacity": 0.3}},
'outputs': {"clean": {"crf": 20}},
}
response = requests.post(
'https://creativeskyline.de/api/media/v1/presets',
headers=headers,
json=payload,
)
data = response.json()
{
"key": "ugc_hd",
"system": false,
"name": "UGC in HD",
"pipeline": "ugc_video",
"options": {
"width": 720,
"height": 1280,
"watermark": {
"asset": "brand_white",
"opacity": 0.3
}
},
"outputs": {
"clean": {
"crf": 20
}
},
"updated_at": "2026-09-28T10:00:00Z"
}
/api/media/v1/presets/{key}
curl -X DELETE "https://creativeskyline.de/api/media/v1/presets/{key}" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Accept: application/json"
use Illuminate\Support\Facades\Http;
$response = Http::withToken('YOUR_API_TOKEN')
->delete('https://creativeskyline.de/api/media/v1/presets/{key}');
$data = $response->json();
const response = await fetch('https://creativeskyline.de/api/media/v1/presets/{key}', {
method: 'DELETE',
headers: {
'Authorization': 'Bearer YOUR_API_TOKEN',
'Accept': 'application/json',
},
});
const data = await response.json();
import requests
headers = {
'Authorization': 'Bearer YOUR_API_TOKEN',
'Accept': 'application/json',
}
response = requests.delete(
'https://creativeskyline.de/api/media/v1/presets/{key}',
headers=headers,
)
data = response.json()
{
"deleted": true,
"key": "ugc_hd"
}
/api/media/v1/jobs
curl -X POST "https://creativeskyline.de/api/media/v1/jobs" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"pipeline": "ugc_video", "reference": "orderfile:12345", "input": {"url":"https://files.example.com/in/abc.mov?X-Amz-Signature=…","filename":"abc.mov"}, "outputs": {"watermarked":{"put_url":"https://uploads.example.com/out/wm.mp4?X-Amz-Signature=…"},"clean":{"managed":true},"thumbnail":{"put_url":"https://uploads.example.com/out/thumb.jpg?X-Amz-Signature=…"}}, "options": {"watermark":{"asset":"brand_white"}}, "callback": {"endpoint_id":"01J8Z6Q4T0M3S1V7B2X9K5N4WH"}, "metadata": {"entity":"order_file"}}'
use Illuminate\Support\Facades\Http;
$response = Http::withToken('YOUR_API_TOKEN')
->post('https://creativeskyline.de/api/media/v1/jobs', [
'pipeline' => 'ugc_video',
'reference' => 'orderfile:12345',
'input' => array (
'url' => 'https://files.example.com/in/abc.mov?X-Amz-Signature=…',
'filename' => 'abc.mov',
),
'outputs' => array (
'watermarked' =>
array (
'put_url' => 'https://uploads.example.com/out/wm.mp4?X-Amz-Signature=…',
),
'clean' =>
array (
'managed' => true,
),
'thumbnail' =>
array (
'put_url' => 'https://uploads.example.com/out/thumb.jpg?X-Amz-Signature=…',
),
),
'options' => array (
'watermark' =>
array (
'asset' => 'brand_white',
),
),
'callback' => array (
'endpoint_id' => '01J8Z6Q4T0M3S1V7B2X9K5N4WH',
),
'metadata' => array (
'entity' => 'order_file',
),
]);
$data = $response->json();
const response = await fetch('https://creativeskyline.de/api/media/v1/jobs', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_TOKEN',
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
pipeline: "ugc_video",
reference: "orderfile:12345",
input: {"url":"https://files.example.com/in/abc.mov?X-Amz-Signature=…","filename":"abc.mov"},
outputs: {"watermarked":{"put_url":"https://uploads.example.com/out/wm.mp4?X-Amz-Signature=…"},"clean":{"managed":true},"thumbnail":{"put_url":"https://uploads.example.com/out/thumb.jpg?X-Amz-Signature=…"}},
options: {"watermark":{"asset":"brand_white"}},
callback: {"endpoint_id":"01J8Z6Q4T0M3S1V7B2X9K5N4WH"},
metadata: {"entity":"order_file"},
}),
});
const data = await response.json();
import requests
headers = {
'Authorization': 'Bearer YOUR_API_TOKEN',
'Accept': 'application/json',
}
payload = {
'pipeline': "ugc_video",
'reference': "orderfile:12345",
'input': {"url": "https://files.example.com/in/abc.mov?X-Amz-Signature=…", "filename": "abc.mov"},
'outputs': {"watermarked": {"put_url": "https://uploads.example.com/out/wm.mp4?X-Amz-Signature=…"}, "clean": {"managed": True}, "thumbnail": {"put_url": "https://uploads.example.com/out/thumb.jpg?X-Amz-Signature=…"}},
'options': {"watermark": {"asset": "brand_white"}},
'callback': {"endpoint_id": "01J8Z6Q4T0M3S1V7B2X9K5N4WH"},
'metadata': {"entity": "order_file"},
}
response = requests.post(
'https://creativeskyline.de/api/media/v1/jobs',
headers=headers,
json=payload,
)
data = response.json()
{
"id": "01J8Z6Q4T0M3S1V7B2X9K5N4RD",
"status": "queued",
"pipeline": "ugc_video",
"reference": "orderfile:12345",
"priority": "normal",
"outputs": {
"watermarked": {
"status": "pending",
"target": "put"
},
"clean": {
"status": "pending",
"target": "managed",
"download_url": null,
"expires_at": null
},
"thumbnail": {
"status": "pending",
"target": "put"
}
},
"error": null,
"queue_position": 1
}
/api/media/v1/jobs/{job_id}
curl -X GET "https://creativeskyline.de/api/media/v1/jobs/{job_id}" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Accept: application/json"
use Illuminate\Support\Facades\Http;
$response = Http::withToken('YOUR_API_TOKEN')
->get('https://creativeskyline.de/api/media/v1/jobs/{job_id}');
$data = $response->json();
const response = await fetch('https://creativeskyline.de/api/media/v1/jobs/{job_id}', {
method: 'GET',
headers: {
'Authorization': 'Bearer YOUR_API_TOKEN',
'Accept': 'application/json',
},
});
const data = await response.json();
import requests
headers = {
'Authorization': 'Bearer YOUR_API_TOKEN',
'Accept': 'application/json',
}
response = requests.get(
'https://creativeskyline.de/api/media/v1/jobs/{job_id}',
headers=headers,
)
data = response.json()
{
"id": "01J8Z6Q4T0M3S1V7B2X9K5N4RD",
"status": "finished",
"pipeline": "ugc_video",
"preset": null,
"reference": "orderfile:12345",
"priority": "normal",
"created_at": "2026-09-28T10:00:00Z",
"started_at": "2026-09-28T10:00:02Z",
"finished_at": "2026-09-28T10:00:31Z",
"input": {
"size": 48211234,
"duration": 27.4,
"width": 1080,
"height": 1920,
"video_codec": "hevc",
"has_audio": true
},
"outputs": {
"watermarked": {
"status": "uploaded",
"target": "put",
"size": 6123456,
"width": 540,
"height": 960,
"duration": 27.4,
"sha256": "9f2c…"
},
"clean": {
"status": "uploaded",
"target": "managed",
"size": 6101234,
"width": 540,
"height": 960,
"duration": 27.4,
"sha256": "4b1a…",
"download_url": "https://…",
"expires_at": "2026-10-05T10:00:31Z"
}
},
"options": {
"watermark": {
"asset": "brand_white",
"asset_sha256": "c0ff…"
}
},
"error": null,
"processing_seconds": 28.6,
"cancel_requested": false
}
/api/media/v1/jobs
curl -X GET "https://creativeskyline.de/api/media/v1/jobs?reference=orderfile%3A12345" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Accept: application/json"
use Illuminate\Support\Facades\Http;
$response = Http::withToken('YOUR_API_TOKEN')
->get('https://creativeskyline.de/api/media/v1/jobs?reference=orderfile%3A12345');
$data = $response->json();
const response = await fetch('https://creativeskyline.de/api/media/v1/jobs?reference=orderfile%3A12345', {
method: 'GET',
headers: {
'Authorization': 'Bearer YOUR_API_TOKEN',
'Accept': 'application/json',
},
});
const data = await response.json();
import requests
headers = {
'Authorization': 'Bearer YOUR_API_TOKEN',
'Accept': 'application/json',
}
response = requests.get(
'https://creativeskyline.de/api/media/v1/jobs?reference=orderfile%3A12345',
headers=headers,
)
data = response.json()
{
"data": [
{
"id": "01J8Z6Q4T0M3S1V7B2X9K5N4RD",
"status": "finished",
"pipeline": "ugc_video",
"preset": null,
"reference": "orderfile:12345",
"priority": "normal",
"created_at": "2026-09-28T10:00:00Z",
"started_at": "2026-09-28T10:00:02Z",
"finished_at": "2026-09-28T10:00:31Z",
"input": {
"size": 48211234,
"duration": 27.4,
"width": 1080,
"height": 1920,
"video_codec": "hevc",
"has_audio": true
},
"outputs": {
"watermarked": {
"status": "uploaded",
"target": "put",
"size": 6123456,
"width": 540,
"height": 960,
"duration": 27.4,
"sha256": "9f2c…"
},
"clean": {
"status": "uploaded",
"target": "managed",
"size": 6101234,
"width": 540,
"height": 960,
"duration": 27.4,
"sha256": "4b1a…",
"download_url": "https://…",
"expires_at": "2026-10-05T10:00:31Z"
}
},
"options": {
"watermark": {
"asset": "brand_white",
"asset_sha256": "c0ff…"
}
},
"error": null,
"processing_seconds": 28.6,
"cancel_requested": false
}
]
}
/api/media/v1/jobs/{job_id}
curl -X DELETE "https://creativeskyline.de/api/media/v1/jobs/{job_id}" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Accept: application/json"
use Illuminate\Support\Facades\Http;
$response = Http::withToken('YOUR_API_TOKEN')
->delete('https://creativeskyline.de/api/media/v1/jobs/{job_id}');
$data = $response->json();
const response = await fetch('https://creativeskyline.de/api/media/v1/jobs/{job_id}', {
method: 'DELETE',
headers: {
'Authorization': 'Bearer YOUR_API_TOKEN',
'Accept': 'application/json',
},
});
const data = await response.json();
import requests
headers = {
'Authorization': 'Bearer YOUR_API_TOKEN',
'Accept': 'application/json',
}
response = requests.delete(
'https://creativeskyline.de/api/media/v1/jobs/{job_id}',
headers=headers,
)
data = response.json()
{
"id": "01J8Z6Q4T0M3S1V7B2X9K5N4RD",
"status": "cancelled",
"error": null,
"cancel_requested": false
}
/api/media/v1/uploads
curl -X POST "https://creativeskyline.de/api/media/v1/uploads" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"filename": "kurs-01.mp4", "size": 734003200, "content_type": "video/mp4"}'
use Illuminate\Support\Facades\Http;
$response = Http::withToken('YOUR_API_TOKEN')
->post('https://creativeskyline.de/api/media/v1/uploads', [
'filename' => 'kurs-01.mp4',
'size' => 734003200,
'content_type' => 'video/mp4',
]);
$data = $response->json();
const response = await fetch('https://creativeskyline.de/api/media/v1/uploads', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_TOKEN',
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
filename: "kurs-01.mp4",
size: 734003200,
content_type: "video/mp4",
}),
});
const data = await response.json();
import requests
headers = {
'Authorization': 'Bearer YOUR_API_TOKEN',
'Accept': 'application/json',
}
payload = {
'filename': "kurs-01.mp4",
'size': 734003200,
'content_type': "video/mp4",
}
response = requests.post(
'https://creativeskyline.de/api/media/v1/uploads',
headers=headers,
json=payload,
)
data = response.json()
{
"id": "01J8Z6Q4T0M3S1V7B2X9K5N4UP",
"upload_url": "https://…",
"method": "PUT",
"headers": {
"Content-Type": "video/mp4",
"Content-Length": "734003200"
},
"expires_at": "2026-09-29T10:00:00Z"
}
/api/media/v1/usage
curl -X GET "https://creativeskyline.de/api/media/v1/usage?from=2026-09-01&to=2026-09-30" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Accept: application/json"
use Illuminate\Support\Facades\Http;
$response = Http::withToken('YOUR_API_TOKEN')
->get('https://creativeskyline.de/api/media/v1/usage?from=2026-09-01&to=2026-09-30');
$data = $response->json();
const response = await fetch('https://creativeskyline.de/api/media/v1/usage?from=2026-09-01&to=2026-09-30', {
method: 'GET',
headers: {
'Authorization': 'Bearer YOUR_API_TOKEN',
'Accept': 'application/json',
},
});
const data = await response.json();
import requests
headers = {
'Authorization': 'Bearer YOUR_API_TOKEN',
'Accept': 'application/json',
}
response = requests.get(
'https://creativeskyline.de/api/media/v1/usage?from=2026-09-01&to=2026-09-30',
headers=headers,
)
data = response.json()
{
"from": "2026-09-01",
"to": "2026-09-30",
"jobs": 2143,
"failed": 12,
"processing_seconds": 61234.5,
"input_bytes": 98765432100,
"by_pipeline": {
"ugc_video": 2051,
"ugc_image": 92
}
}
/api/media/v1/health
curl -X GET "https://creativeskyline.de/api/media/v1/health" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Accept: application/json"
use Illuminate\Support\Facades\Http;
$response = Http::withToken('YOUR_API_TOKEN')
->get('https://creativeskyline.de/api/media/v1/health');
$data = $response->json();
const response = await fetch('https://creativeskyline.de/api/media/v1/health', {
method: 'GET',
headers: {
'Authorization': 'Bearer YOUR_API_TOKEN',
'Accept': 'application/json',
},
});
const data = await response.json();
import requests
headers = {
'Authorization': 'Bearer YOUR_API_TOKEN',
'Accept': 'application/json',
}
response = requests.get(
'https://creativeskyline.de/api/media/v1/health',
headers=headers,
)
data = response.json()
{
"status": "ok",
"queue": {
"pending": 3,
"processing": 4
},
"version": "1.0.0"
}
/api/media/v1/assets/{key}
curl -X PUT "https://creativeskyline.de/api/media/v1/assets/brand_white" \
-H "Authorization: Bearer fd_dein_api_key" \
-H "Content-Type: image/png" \
--data-binary @logo.png
use Illuminate\Support\Facades\Http;
$response = Http::withToken('fd_dein_api_key')
->withBody(file_get_contents('logo.png'), 'image/png')
->put('https://creativeskyline.de/api/media/v1/assets/brand_white');
const response = await fetch('https://creativeskyline.de/api/media/v1/assets/brand_white', {
method: 'PUT',
headers: { Authorization: 'Bearer fd_dein_api_key', 'Content-Type': 'image/png' },
body: pngBlob,
});
import requests
with open('logo.png', 'rb') as file:
response = requests.put(
'https://creativeskyline.de/api/media/v1/assets/brand_white',
headers={'Authorization': 'Bearer fd_dein_api_key', 'Content-Type': 'image/png'},
data=file,
)
{
"key": "brand_white",
"sha256": "c0ffee…",
"width": 800,
"height": 200,
"size": 18234,
"updated_at": "2026-09-28T10:00:00Z"
}
/api/media/v1/assets/{key}
curl -X POST "https://creativeskyline.de/api/media/v1/assets/{key}" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"file": "value"}'
use Illuminate\Support\Facades\Http;
$response = Http::withToken('YOUR_API_TOKEN')
->post('https://creativeskyline.de/api/media/v1/assets/{key}', [
'file' => 'value',
]);
$data = $response->json();
const response = await fetch('https://creativeskyline.de/api/media/v1/assets/{key}', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_TOKEN',
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
file: 'value',
}),
});
const data = await response.json();
import requests
headers = {
'Authorization': 'Bearer YOUR_API_TOKEN',
'Accept': 'application/json',
}
payload = {
'file': 'value',
}
response = requests.post(
'https://creativeskyline.de/api/media/v1/assets/{key}',
headers=headers,
json=payload,
)
data = response.json()
{
"key": "brand_white",
"sha256": "c0ffee…",
"width": 800,
"height": 200,
"size": 18234,
"updated_at": "2026-09-28T10:00:00Z"
}
/api/media/v1/assets
curl -X GET "https://creativeskyline.de/api/media/v1/assets" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Accept: application/json"
use Illuminate\Support\Facades\Http;
$response = Http::withToken('YOUR_API_TOKEN')
->get('https://creativeskyline.de/api/media/v1/assets');
$data = $response->json();
const response = await fetch('https://creativeskyline.de/api/media/v1/assets', {
method: 'GET',
headers: {
'Authorization': 'Bearer YOUR_API_TOKEN',
'Accept': 'application/json',
},
});
const data = await response.json();
import requests
headers = {
'Authorization': 'Bearer YOUR_API_TOKEN',
'Accept': 'application/json',
}
response = requests.get(
'https://creativeskyline.de/api/media/v1/assets',
headers=headers,
)
data = response.json()
{
"data": [
{
"key": "brand_white",
"sha256": "c0ffee…",
"width": 800,
"height": 200,
"size": 18234,
"updated_at": "2026-09-28T10:00:00Z"
}
]
}
/api/media/v1/webhook-endpoints
curl -X GET "https://creativeskyline.de/api/media/v1/webhook-endpoints" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Accept: application/json"
use Illuminate\Support\Facades\Http;
$response = Http::withToken('YOUR_API_TOKEN')
->get('https://creativeskyline.de/api/media/v1/webhook-endpoints');
$data = $response->json();
const response = await fetch('https://creativeskyline.de/api/media/v1/webhook-endpoints', {
method: 'GET',
headers: {
'Authorization': 'Bearer YOUR_API_TOKEN',
'Accept': 'application/json',
},
});
const data = await response.json();
import requests
headers = {
'Authorization': 'Bearer YOUR_API_TOKEN',
'Accept': 'application/json',
}
response = requests.get(
'https://creativeskyline.de/api/media/v1/webhook-endpoints',
headers=headers,
)
data = response.json()
{
"data": [
{
"id": "01J8Z6Q4T0M3S1V7B2X9K5N4WH",
"url": "https://example.com/hooks/media",
"description": null,
"events": [
"job.finished",
"job.failed"
],
"is_default": true,
"active": true,
"previous_secret_expires_at": null,
"created_at": "2026-09-28T10:00:00Z"
}
]
}
/api/media/v1/webhook-endpoints
curl -X POST "https://creativeskyline.de/api/media/v1/webhook-endpoints" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com/hooks/media", "events": ["job.finished","job.failed"], "is_default": true}'
use Illuminate\Support\Facades\Http;
$response = Http::withToken('YOUR_API_TOKEN')
->post('https://creativeskyline.de/api/media/v1/webhook-endpoints', [
'url' => 'https://example.com/hooks/media',
'events' => array (
0 => 'job.finished',
1 => 'job.failed',
),
'is_default' => true,
]);
$data = $response->json();
const response = await fetch('https://creativeskyline.de/api/media/v1/webhook-endpoints', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_TOKEN',
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
url: "https://example.com/hooks/media",
events: ["job.finished","job.failed"],
is_default: true,
}),
});
const data = await response.json();
import requests
headers = {
'Authorization': 'Bearer YOUR_API_TOKEN',
'Accept': 'application/json',
}
payload = {
'url': "https://example.com/hooks/media",
'events': ["job.finished", "job.failed"],
'is_default': True,
}
response = requests.post(
'https://creativeskyline.de/api/media/v1/webhook-endpoints',
headers=headers,
json=payload,
)
data = response.json()
{
"id": "01J8Z6Q4T0M3S1V7B2X9K5N4WH",
"url": "https://example.com/hooks/media",
"events": [
"job.finished",
"job.failed"
],
"is_default": true,
"active": true,
"secret": "whsec_BEISPIEL00000000000000000000000"
}
/api/media/v1/webhook-endpoints/{endpoint_id}/rotate-secret
curl -X POST "https://creativeskyline.de/api/media/v1/webhook-endpoints/{endpoint_id}/rotate-secret" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Accept: application/json"
use Illuminate\Support\Facades\Http;
$response = Http::withToken('YOUR_API_TOKEN')
->post('https://creativeskyline.de/api/media/v1/webhook-endpoints/{endpoint_id}/rotate-secret');
$data = $response->json();
const response = await fetch('https://creativeskyline.de/api/media/v1/webhook-endpoints/{endpoint_id}/rotate-secret', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_TOKEN',
'Accept': 'application/json',
},
});
const data = await response.json();
import requests
headers = {
'Authorization': 'Bearer YOUR_API_TOKEN',
'Accept': 'application/json',
}
response = requests.post(
'https://creativeskyline.de/api/media/v1/webhook-endpoints/{endpoint_id}/rotate-secret',
headers=headers,
)
data = response.json()
{
"id": "01J8Z6Q4T0M3S1V7B2X9K5N4WH",
"previous_secret_expires_at": "2026-09-29T10:00:00Z",
"secret": "whsec_…"
}
/api/media/v1/webhook-endpoints/{endpoint_id}
curl -X DELETE "https://creativeskyline.de/api/media/v1/webhook-endpoints/{endpoint_id}" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Accept: application/json"
use Illuminate\Support\Facades\Http;
$response = Http::withToken('YOUR_API_TOKEN')
->delete('https://creativeskyline.de/api/media/v1/webhook-endpoints/{endpoint_id}');
$data = $response->json();
const response = await fetch('https://creativeskyline.de/api/media/v1/webhook-endpoints/{endpoint_id}', {
method: 'DELETE',
headers: {
'Authorization': 'Bearer YOUR_API_TOKEN',
'Accept': 'application/json',
},
});
const data = await response.json();
import requests
headers = {
'Authorization': 'Bearer YOUR_API_TOKEN',
'Accept': 'application/json',
}
response = requests.delete(
'https://creativeskyline.de/api/media/v1/webhook-endpoints/{endpoint_id}',
headers=headers,
)
data = response.json()
{
"deleted": true,
"id": "01J8Z6Q4T0M3S1V7B2X9K5N4WH"
}
curl -X GET "https://creativeskyline.de/api/media/v1/presets" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Accept: application/json"
use Illuminate\Support\Facades\Http;
$response = Http::withToken('YOUR_API_TOKEN')
->get('https://creativeskyline.de/api/media/v1/presets');
$data = $response->json();
const response = await fetch('https://creativeskyline.de/api/media/v1/presets', {
method: 'GET',
headers: {
'Authorization': 'Bearer YOUR_API_TOKEN',
'Accept': 'application/json',
},
});
const data = await response.json();
import requests
headers = {
'Authorization': 'Bearer YOUR_API_TOKEN',
'Accept': 'application/json',
}
response = requests.get(
'https://creativeskyline.de/api/media/v1/presets',
headers=headers,
)
data = response.json()
{
"data": [
{
"key": "ugc_video",
"system": true,
"pipeline": "ugc_video",
"outputs": [
"watermarked",
"clean",
"thumbnail"
]
},
{
"key": "ugc_hd",
"system": false,
"name": "UGC in HD",
"pipeline": "ugc_video",
"options": {
"width": 720,
"height": 1280
},
"outputs": {
"clean": {
"crf": 20
}
},
"updated_at": "2026-09-28T10:00:00Z"
}
]
}
curl -X POST "https://creativeskyline.de/api/media/v1/presets" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"key": "ugc_hd", "name": "UGC in HD", "pipeline": "ugc_video", "options": {"width":720,"height":1280,"watermark":{"asset":"brand_white","opacity":0.3}}, "outputs": {"clean":{"crf":20}}}'
use Illuminate\Support\Facades\Http;
$response = Http::withToken('YOUR_API_TOKEN')
->post('https://creativeskyline.de/api/media/v1/presets', [
'key' => 'ugc_hd',
'name' => 'UGC in HD',
'pipeline' => 'ugc_video',
'options' => array (
'width' => 720,
'height' => 1280,
'watermark' =>
array (
'asset' => 'brand_white',
'opacity' => 0.3,
),
),
'outputs' => array (
'clean' =>
array (
'crf' => 20,
),
),
]);
$data = $response->json();
const response = await fetch('https://creativeskyline.de/api/media/v1/presets', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_TOKEN',
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
key: "ugc_hd",
name: "UGC in HD",
pipeline: "ugc_video",
options: {"width":720,"height":1280,"watermark":{"asset":"brand_white","opacity":0.3}},
outputs: {"clean":{"crf":20}},
}),
});
const data = await response.json();
import requests
headers = {
'Authorization': 'Bearer YOUR_API_TOKEN',
'Accept': 'application/json',
}
payload = {
'key': "ugc_hd",
'name': "UGC in HD",
'pipeline': "ugc_video",
'options': {"width": 720, "height": 1280, "watermark": {"asset": "brand_white", "opacity": 0.3}},
'outputs': {"clean": {"crf": 20}},
}
response = requests.post(
'https://creativeskyline.de/api/media/v1/presets',
headers=headers,
json=payload,
)
data = response.json()
{
"key": "ugc_hd",
"system": false,
"name": "UGC in HD",
"pipeline": "ugc_video",
"options": {
"width": 720,
"height": 1280,
"watermark": {
"asset": "brand_white",
"opacity": 0.3
}
},
"outputs": {
"clean": {
"crf": 20
}
},
"updated_at": "2026-09-28T10:00:00Z"
}
curl -X DELETE "https://creativeskyline.de/api/media/v1/presets/{key}" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Accept: application/json"
use Illuminate\Support\Facades\Http;
$response = Http::withToken('YOUR_API_TOKEN')
->delete('https://creativeskyline.de/api/media/v1/presets/{key}');
$data = $response->json();
const response = await fetch('https://creativeskyline.de/api/media/v1/presets/{key}', {
method: 'DELETE',
headers: {
'Authorization': 'Bearer YOUR_API_TOKEN',
'Accept': 'application/json',
},
});
const data = await response.json();
import requests
headers = {
'Authorization': 'Bearer YOUR_API_TOKEN',
'Accept': 'application/json',
}
response = requests.delete(
'https://creativeskyline.de/api/media/v1/presets/{key}',
headers=headers,
)
data = response.json()
{
"deleted": true,
"key": "ugc_hd"
}
curl -X POST "https://creativeskyline.de/api/media/v1/jobs" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"pipeline": "ugc_video", "reference": "orderfile:12345", "input": {"url":"https://files.example.com/in/abc.mov?X-Amz-Signature=…","filename":"abc.mov"}, "outputs": {"watermarked":{"put_url":"https://uploads.example.com/out/wm.mp4?X-Amz-Signature=…"},"clean":{"managed":true},"thumbnail":{"put_url":"https://uploads.example.com/out/thumb.jpg?X-Amz-Signature=…"}}, "options": {"watermark":{"asset":"brand_white"}}, "callback": {"endpoint_id":"01J8Z6Q4T0M3S1V7B2X9K5N4WH"}, "metadata": {"entity":"order_file"}}'
use Illuminate\Support\Facades\Http;
$response = Http::withToken('YOUR_API_TOKEN')
->post('https://creativeskyline.de/api/media/v1/jobs', [
'pipeline' => 'ugc_video',
'reference' => 'orderfile:12345',
'input' => array (
'url' => 'https://files.example.com/in/abc.mov?X-Amz-Signature=…',
'filename' => 'abc.mov',
),
'outputs' => array (
'watermarked' =>
array (
'put_url' => 'https://uploads.example.com/out/wm.mp4?X-Amz-Signature=…',
),
'clean' =>
array (
'managed' => true,
),
'thumbnail' =>
array (
'put_url' => 'https://uploads.example.com/out/thumb.jpg?X-Amz-Signature=…',
),
),
'options' => array (
'watermark' =>
array (
'asset' => 'brand_white',
),
),
'callback' => array (
'endpoint_id' => '01J8Z6Q4T0M3S1V7B2X9K5N4WH',
),
'metadata' => array (
'entity' => 'order_file',
),
]);
$data = $response->json();
const response = await fetch('https://creativeskyline.de/api/media/v1/jobs', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_TOKEN',
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
pipeline: "ugc_video",
reference: "orderfile:12345",
input: {"url":"https://files.example.com/in/abc.mov?X-Amz-Signature=…","filename":"abc.mov"},
outputs: {"watermarked":{"put_url":"https://uploads.example.com/out/wm.mp4?X-Amz-Signature=…"},"clean":{"managed":true},"thumbnail":{"put_url":"https://uploads.example.com/out/thumb.jpg?X-Amz-Signature=…"}},
options: {"watermark":{"asset":"brand_white"}},
callback: {"endpoint_id":"01J8Z6Q4T0M3S1V7B2X9K5N4WH"},
metadata: {"entity":"order_file"},
}),
});
const data = await response.json();
import requests
headers = {
'Authorization': 'Bearer YOUR_API_TOKEN',
'Accept': 'application/json',
}
payload = {
'pipeline': "ugc_video",
'reference': "orderfile:12345",
'input': {"url": "https://files.example.com/in/abc.mov?X-Amz-Signature=…", "filename": "abc.mov"},
'outputs': {"watermarked": {"put_url": "https://uploads.example.com/out/wm.mp4?X-Amz-Signature=…"}, "clean": {"managed": True}, "thumbnail": {"put_url": "https://uploads.example.com/out/thumb.jpg?X-Amz-Signature=…"}},
'options': {"watermark": {"asset": "brand_white"}},
'callback': {"endpoint_id": "01J8Z6Q4T0M3S1V7B2X9K5N4WH"},
'metadata': {"entity": "order_file"},
}
response = requests.post(
'https://creativeskyline.de/api/media/v1/jobs',
headers=headers,
json=payload,
)
data = response.json()
{
"id": "01J8Z6Q4T0M3S1V7B2X9K5N4RD",
"status": "queued",
"pipeline": "ugc_video",
"reference": "orderfile:12345",
"priority": "normal",
"outputs": {
"watermarked": {
"status": "pending",
"target": "put"
},
"clean": {
"status": "pending",
"target": "managed",
"download_url": null,
"expires_at": null
},
"thumbnail": {
"status": "pending",
"target": "put"
}
},
"error": null,
"queue_position": 1
}
curl -X GET "https://creativeskyline.de/api/media/v1/jobs/{job_id}" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Accept: application/json"
use Illuminate\Support\Facades\Http;
$response = Http::withToken('YOUR_API_TOKEN')
->get('https://creativeskyline.de/api/media/v1/jobs/{job_id}');
$data = $response->json();
const response = await fetch('https://creativeskyline.de/api/media/v1/jobs/{job_id}', {
method: 'GET',
headers: {
'Authorization': 'Bearer YOUR_API_TOKEN',
'Accept': 'application/json',
},
});
const data = await response.json();
import requests
headers = {
'Authorization': 'Bearer YOUR_API_TOKEN',
'Accept': 'application/json',
}
response = requests.get(
'https://creativeskyline.de/api/media/v1/jobs/{job_id}',
headers=headers,
)
data = response.json()
{
"id": "01J8Z6Q4T0M3S1V7B2X9K5N4RD",
"status": "finished",
"pipeline": "ugc_video",
"preset": null,
"reference": "orderfile:12345",
"priority": "normal",
"created_at": "2026-09-28T10:00:00Z",
"started_at": "2026-09-28T10:00:02Z",
"finished_at": "2026-09-28T10:00:31Z",
"input": {
"size": 48211234,
"duration": 27.4,
"width": 1080,
"height": 1920,
"video_codec": "hevc",
"has_audio": true
},
"outputs": {
"watermarked": {
"status": "uploaded",
"target": "put",
"size": 6123456,
"width": 540,
"height": 960,
"duration": 27.4,
"sha256": "9f2c…"
},
"clean": {
"status": "uploaded",
"target": "managed",
"size": 6101234,
"width": 540,
"height": 960,
"duration": 27.4,
"sha256": "4b1a…",
"download_url": "https://…",
"expires_at": "2026-10-05T10:00:31Z"
}
},
"options": {
"watermark": {
"asset": "brand_white",
"asset_sha256": "c0ff…"
}
},
"error": null,
"processing_seconds": 28.6,
"cancel_requested": false
}
curl -X GET "https://creativeskyline.de/api/media/v1/jobs?reference=orderfile%3A12345" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Accept: application/json"
use Illuminate\Support\Facades\Http;
$response = Http::withToken('YOUR_API_TOKEN')
->get('https://creativeskyline.de/api/media/v1/jobs?reference=orderfile%3A12345');
$data = $response->json();
const response = await fetch('https://creativeskyline.de/api/media/v1/jobs?reference=orderfile%3A12345', {
method: 'GET',
headers: {
'Authorization': 'Bearer YOUR_API_TOKEN',
'Accept': 'application/json',
},
});
const data = await response.json();
import requests
headers = {
'Authorization': 'Bearer YOUR_API_TOKEN',
'Accept': 'application/json',
}
response = requests.get(
'https://creativeskyline.de/api/media/v1/jobs?reference=orderfile%3A12345',
headers=headers,
)
data = response.json()
{
"data": [
{
"id": "01J8Z6Q4T0M3S1V7B2X9K5N4RD",
"status": "finished",
"pipeline": "ugc_video",
"preset": null,
"reference": "orderfile:12345",
"priority": "normal",
"created_at": "2026-09-28T10:00:00Z",
"started_at": "2026-09-28T10:00:02Z",
"finished_at": "2026-09-28T10:00:31Z",
"input": {
"size": 48211234,
"duration": 27.4,
"width": 1080,
"height": 1920,
"video_codec": "hevc",
"has_audio": true
},
"outputs": {
"watermarked": {
"status": "uploaded",
"target": "put",
"size": 6123456,
"width": 540,
"height": 960,
"duration": 27.4,
"sha256": "9f2c…"
},
"clean": {
"status": "uploaded",
"target": "managed",
"size": 6101234,
"width": 540,
"height": 960,
"duration": 27.4,
"sha256": "4b1a…",
"download_url": "https://…",
"expires_at": "2026-10-05T10:00:31Z"
}
},
"options": {
"watermark": {
"asset": "brand_white",
"asset_sha256": "c0ff…"
}
},
"error": null,
"processing_seconds": 28.6,
"cancel_requested": false
}
]
}
curl -X DELETE "https://creativeskyline.de/api/media/v1/jobs/{job_id}" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Accept: application/json"
use Illuminate\Support\Facades\Http;
$response = Http::withToken('YOUR_API_TOKEN')
->delete('https://creativeskyline.de/api/media/v1/jobs/{job_id}');
$data = $response->json();
const response = await fetch('https://creativeskyline.de/api/media/v1/jobs/{job_id}', {
method: 'DELETE',
headers: {
'Authorization': 'Bearer YOUR_API_TOKEN',
'Accept': 'application/json',
},
});
const data = await response.json();
import requests
headers = {
'Authorization': 'Bearer YOUR_API_TOKEN',
'Accept': 'application/json',
}
response = requests.delete(
'https://creativeskyline.de/api/media/v1/jobs/{job_id}',
headers=headers,
)
data = response.json()
{
"id": "01J8Z6Q4T0M3S1V7B2X9K5N4RD",
"status": "cancelled",
"error": null,
"cancel_requested": false
}
curl -X POST "https://creativeskyline.de/api/media/v1/uploads" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"filename": "kurs-01.mp4", "size": 734003200, "content_type": "video/mp4"}'
use Illuminate\Support\Facades\Http;
$response = Http::withToken('YOUR_API_TOKEN')
->post('https://creativeskyline.de/api/media/v1/uploads', [
'filename' => 'kurs-01.mp4',
'size' => 734003200,
'content_type' => 'video/mp4',
]);
$data = $response->json();
const response = await fetch('https://creativeskyline.de/api/media/v1/uploads', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_TOKEN',
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
filename: "kurs-01.mp4",
size: 734003200,
content_type: "video/mp4",
}),
});
const data = await response.json();
import requests
headers = {
'Authorization': 'Bearer YOUR_API_TOKEN',
'Accept': 'application/json',
}
payload = {
'filename': "kurs-01.mp4",
'size': 734003200,
'content_type': "video/mp4",
}
response = requests.post(
'https://creativeskyline.de/api/media/v1/uploads',
headers=headers,
json=payload,
)
data = response.json()
{
"id": "01J8Z6Q4T0M3S1V7B2X9K5N4UP",
"upload_url": "https://…",
"method": "PUT",
"headers": {
"Content-Type": "video/mp4",
"Content-Length": "734003200"
},
"expires_at": "2026-09-29T10:00:00Z"
}
curl -X GET "https://creativeskyline.de/api/media/v1/usage?from=2026-09-01&to=2026-09-30" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Accept: application/json"
use Illuminate\Support\Facades\Http;
$response = Http::withToken('YOUR_API_TOKEN')
->get('https://creativeskyline.de/api/media/v1/usage?from=2026-09-01&to=2026-09-30');
$data = $response->json();
const response = await fetch('https://creativeskyline.de/api/media/v1/usage?from=2026-09-01&to=2026-09-30', {
method: 'GET',
headers: {
'Authorization': 'Bearer YOUR_API_TOKEN',
'Accept': 'application/json',
},
});
const data = await response.json();
import requests
headers = {
'Authorization': 'Bearer YOUR_API_TOKEN',
'Accept': 'application/json',
}
response = requests.get(
'https://creativeskyline.de/api/media/v1/usage?from=2026-09-01&to=2026-09-30',
headers=headers,
)
data = response.json()
{
"from": "2026-09-01",
"to": "2026-09-30",
"jobs": 2143,
"failed": 12,
"processing_seconds": 61234.5,
"input_bytes": 98765432100,
"by_pipeline": {
"ugc_video": 2051,
"ugc_image": 92
}
}
curl -X GET "https://creativeskyline.de/api/media/v1/health" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Accept: application/json"
use Illuminate\Support\Facades\Http;
$response = Http::withToken('YOUR_API_TOKEN')
->get('https://creativeskyline.de/api/media/v1/health');
$data = $response->json();
const response = await fetch('https://creativeskyline.de/api/media/v1/health', {
method: 'GET',
headers: {
'Authorization': 'Bearer YOUR_API_TOKEN',
'Accept': 'application/json',
},
});
const data = await response.json();
import requests
headers = {
'Authorization': 'Bearer YOUR_API_TOKEN',
'Accept': 'application/json',
}
response = requests.get(
'https://creativeskyline.de/api/media/v1/health',
headers=headers,
)
data = response.json()
{
"status": "ok",
"queue": {
"pending": 3,
"processing": 4
},
"version": "1.0.0"
}
curl -X PUT "https://creativeskyline.de/api/media/v1/assets/brand_white" \
-H "Authorization: Bearer fd_dein_api_key" \
-H "Content-Type: image/png" \
--data-binary @logo.png
use Illuminate\Support\Facades\Http;
$response = Http::withToken('fd_dein_api_key')
->withBody(file_get_contents('logo.png'), 'image/png')
->put('https://creativeskyline.de/api/media/v1/assets/brand_white');
const response = await fetch('https://creativeskyline.de/api/media/v1/assets/brand_white', {
method: 'PUT',
headers: { Authorization: 'Bearer fd_dein_api_key', 'Content-Type': 'image/png' },
body: pngBlob,
});
import requests
with open('logo.png', 'rb') as file:
response = requests.put(
'https://creativeskyline.de/api/media/v1/assets/brand_white',
headers={'Authorization': 'Bearer fd_dein_api_key', 'Content-Type': 'image/png'},
data=file,
)
{
"key": "brand_white",
"sha256": "c0ffee…",
"width": 800,
"height": 200,
"size": 18234,
"updated_at": "2026-09-28T10:00:00Z"
}
curl -X POST "https://creativeskyline.de/api/media/v1/assets/{key}" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"file": "value"}'
use Illuminate\Support\Facades\Http;
$response = Http::withToken('YOUR_API_TOKEN')
->post('https://creativeskyline.de/api/media/v1/assets/{key}', [
'file' => 'value',
]);
$data = $response->json();
const response = await fetch('https://creativeskyline.de/api/media/v1/assets/{key}', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_TOKEN',
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
file: 'value',
}),
});
const data = await response.json();
import requests
headers = {
'Authorization': 'Bearer YOUR_API_TOKEN',
'Accept': 'application/json',
}
payload = {
'file': 'value',
}
response = requests.post(
'https://creativeskyline.de/api/media/v1/assets/{key}',
headers=headers,
json=payload,
)
data = response.json()
{
"key": "brand_white",
"sha256": "c0ffee…",
"width": 800,
"height": 200,
"size": 18234,
"updated_at": "2026-09-28T10:00:00Z"
}
curl -X GET "https://creativeskyline.de/api/media/v1/assets" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Accept: application/json"
use Illuminate\Support\Facades\Http;
$response = Http::withToken('YOUR_API_TOKEN')
->get('https://creativeskyline.de/api/media/v1/assets');
$data = $response->json();
const response = await fetch('https://creativeskyline.de/api/media/v1/assets', {
method: 'GET',
headers: {
'Authorization': 'Bearer YOUR_API_TOKEN',
'Accept': 'application/json',
},
});
const data = await response.json();
import requests
headers = {
'Authorization': 'Bearer YOUR_API_TOKEN',
'Accept': 'application/json',
}
response = requests.get(
'https://creativeskyline.de/api/media/v1/assets',
headers=headers,
)
data = response.json()
{
"data": [
{
"key": "brand_white",
"sha256": "c0ffee…",
"width": 800,
"height": 200,
"size": 18234,
"updated_at": "2026-09-28T10:00:00Z"
}
]
}
curl -X GET "https://creativeskyline.de/api/media/v1/webhook-endpoints" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Accept: application/json"
use Illuminate\Support\Facades\Http;
$response = Http::withToken('YOUR_API_TOKEN')
->get('https://creativeskyline.de/api/media/v1/webhook-endpoints');
$data = $response->json();
const response = await fetch('https://creativeskyline.de/api/media/v1/webhook-endpoints', {
method: 'GET',
headers: {
'Authorization': 'Bearer YOUR_API_TOKEN',
'Accept': 'application/json',
},
});
const data = await response.json();
import requests
headers = {
'Authorization': 'Bearer YOUR_API_TOKEN',
'Accept': 'application/json',
}
response = requests.get(
'https://creativeskyline.de/api/media/v1/webhook-endpoints',
headers=headers,
)
data = response.json()
{
"data": [
{
"id": "01J8Z6Q4T0M3S1V7B2X9K5N4WH",
"url": "https://example.com/hooks/media",
"description": null,
"events": [
"job.finished",
"job.failed"
],
"is_default": true,
"active": true,
"previous_secret_expires_at": null,
"created_at": "2026-09-28T10:00:00Z"
}
]
}
curl -X POST "https://creativeskyline.de/api/media/v1/webhook-endpoints" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com/hooks/media", "events": ["job.finished","job.failed"], "is_default": true}'
use Illuminate\Support\Facades\Http;
$response = Http::withToken('YOUR_API_TOKEN')
->post('https://creativeskyline.de/api/media/v1/webhook-endpoints', [
'url' => 'https://example.com/hooks/media',
'events' => array (
0 => 'job.finished',
1 => 'job.failed',
),
'is_default' => true,
]);
$data = $response->json();
const response = await fetch('https://creativeskyline.de/api/media/v1/webhook-endpoints', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_TOKEN',
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
url: "https://example.com/hooks/media",
events: ["job.finished","job.failed"],
is_default: true,
}),
});
const data = await response.json();
import requests
headers = {
'Authorization': 'Bearer YOUR_API_TOKEN',
'Accept': 'application/json',
}
payload = {
'url': "https://example.com/hooks/media",
'events': ["job.finished", "job.failed"],
'is_default': True,
}
response = requests.post(
'https://creativeskyline.de/api/media/v1/webhook-endpoints',
headers=headers,
json=payload,
)
data = response.json()
{
"id": "01J8Z6Q4T0M3S1V7B2X9K5N4WH",
"url": "https://example.com/hooks/media",
"events": [
"job.finished",
"job.failed"
],
"is_default": true,
"active": true,
"secret": "whsec_BEISPIEL00000000000000000000000"
}
curl -X POST "https://creativeskyline.de/api/media/v1/webhook-endpoints/{endpoint_id}/rotate-secret" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Accept: application/json"
use Illuminate\Support\Facades\Http;
$response = Http::withToken('YOUR_API_TOKEN')
->post('https://creativeskyline.de/api/media/v1/webhook-endpoints/{endpoint_id}/rotate-secret');
$data = $response->json();
const response = await fetch('https://creativeskyline.de/api/media/v1/webhook-endpoints/{endpoint_id}/rotate-secret', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_TOKEN',
'Accept': 'application/json',
},
});
const data = await response.json();
import requests
headers = {
'Authorization': 'Bearer YOUR_API_TOKEN',
'Accept': 'application/json',
}
response = requests.post(
'https://creativeskyline.de/api/media/v1/webhook-endpoints/{endpoint_id}/rotate-secret',
headers=headers,
)
data = response.json()
{
"id": "01J8Z6Q4T0M3S1V7B2X9K5N4WH",
"previous_secret_expires_at": "2026-09-29T10:00:00Z",
"secret": "whsec_…"
}
curl -X DELETE "https://creativeskyline.de/api/media/v1/webhook-endpoints/{endpoint_id}" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Accept: application/json"
use Illuminate\Support\Facades\Http;
$response = Http::withToken('YOUR_API_TOKEN')
->delete('https://creativeskyline.de/api/media/v1/webhook-endpoints/{endpoint_id}');
$data = $response->json();
const response = await fetch('https://creativeskyline.de/api/media/v1/webhook-endpoints/{endpoint_id}', {
method: 'DELETE',
headers: {
'Authorization': 'Bearer YOUR_API_TOKEN',
'Accept': 'application/json',
},
});
const data = await response.json();
import requests
headers = {
'Authorization': 'Bearer YOUR_API_TOKEN',
'Accept': 'application/json',
}
response = requests.delete(
'https://creativeskyline.de/api/media/v1/webhook-endpoints/{endpoint_id}',
headers=headers,
)
data = response.json()
{
"deleted": true,
"id": "01J8Z6Q4T0M3S1V7B2X9K5N4WH"
}