Medien
Bilder, Videos und Audio hochladen und verwalten
Bild hochladen
/v1/media/imageswrite:assetsRecht: Outreach PlattformschreibtLädt ein Bild zu Cloudflare Images hoch und legt es in der Medienbibliothek an, wie das Hochladen unter Assets, Bilder in der App. Danach steht es dort mit Name und Art (Bild, Logo, Icon) bereit, url ist sofort öffentlich abrufbar. Kostet keine Credits. Jeder Aufruf legt ein neues Bild an.
Genau eines von source_url oder data angeben:
source_url: öffentliche https-Adresse der Bilddatei. Cloudflare holt die Datei selbst ab, dealsky lädt nichts herunter. Adressen mit IP statt Hostname, mit Zugangsdaten,localhost,.localund.internalwerden abgelehnt. Typ und Größe prüft Cloudflare beim Abholen (höchstens 10 MB); ist die Datei kein Bild, zu groß oder nicht erreichbar, kommt 422 mit dem Grund. Der empfohlene Weg für alles über etwa 700 KB.
data: Base64 oder data-URL (data:image/png;base64,…). Weil der ganze Body höchstens 1 MB groß sein darf, passen so Bilder bis etwa 700 KB. Der Typ wird am Dateiinhalt erkannt (JPEG, PNG, WebP, SVG wie in der App, kein GIF); ein abweichendercontent_typewird abgelehnt. SVG mit Skripten, Event-Attributen (onload=…),javascript:-Links oder eingebetteten Inhalten wird abgelehnt.
category wie in der App: logos, icons, images oder pictures. Profilbilder (Avatar) gehören zu einer Person und gehen nicht über die API.
Mit Test-Key wird alles geprüft (Felder, Adresse, Typ, Größe), aber nichts hochgeladen und nichts angelegt.
Body
Genau eines von source_url oder data.
source_urlstring (uri)max. 2048 Zeichenhttps-Adresse der Bilddatei; Cloudflare holt sie ab
datastringBild als Base64 oder data-URL; der Body ist auf 1 MB begrenzt
categorystringPflichtBereich in der Bibliothek: logos, icons, images, pictures
logosimagesiconspicturesfile_namestringmax. 200 ZeichenAnzeigename; fließt bereinigt in die Bild-ID ein
content_typestringNur mit data: angegebener Typ, muss zum Inhalt passen
image/jpegimage/pngimage/webpimage/svg+xml
Mögliche Fehler
curl -X POST "https://api.dealsky.io/functions/v1/api/v1/media/images" \
-H "X-API-Key: $DEALSKY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"source_url": "https://www.beispiel.de/assets/logo-beispiel.png",
"category": "logos"
}'const res = await fetch("https://api.dealsky.io/functions/v1/api/v1/media/images", {
method: "POST",
headers: {
"X-API-Key": process.env.DEALSKY_API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({
"source_url": "https://www.beispiel.de/assets/logo-beispiel.png",
"category": "logos"
}),
});
const { ok, data, error } = await res.json();import os, requests
res = requests.request(
"POST",
"https://api.dealsky.io/functions/v1/api/v1/media/images",
headers={"X-API-Key": os.environ["DEALSKY_API_KEY"]},
json={
"source_url": "https://www.beispiel.de/assets/logo-beispiel.png",
"category": "logos"
},
)
print(res.json()){
"ok": true,
"data": {
"id": "3d4e5f6a-7b8c-4d9e-8f0a-1b2c3d4e5f6a",
"url": "https://imagedelivery.net/Xk3bQ9cR7tLm2pWv8yZa1g/tenants/7c1e2d3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f/logos/1760781120000_9f2c1a7b_logo-beispiel.png/public",
"cf_image_id": "tenants/7c1e2d3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f/logos/1760781120000_9f2c1a7b_logo-beispiel.png",
"type": "logo",
"category": "logos",
"name": "logo-beispiel.png",
"created_at": "2026-10-18T10:12:00.000Z"
},
"meta": {
"request_id": "req_7f3a…"
}
}Medien auflisten
/v1/mediaread:assetsRecht: VideosliestBilder, Logos, Icons, Videos und Sprachnachrichten aus der Medienbibliothek, wie sie in der App unter Assets (Videos und Bilder, Sprachnachrichten) stehen, neueste zuerst. Gelöschte Einträge fehlen wie in der App. Landingpage-Vorlagen stehen nicht hier, sondern unter GET /v1/landing-page-templates. Von dealsky mitgelieferte System-Videos, die die App zusätzlich zeigt, liefert die API nicht.
Filter: kind fasst die Typen zusammen: image (image, logo, icon), video (static_video und die älteren hauptvideo, sprachsync_video, video; dealsky behandelt sie seit September 2026 als eine Videoart), audio (audio, voice). type filtert auf einzelne Typen. Beides kommagetrennt, z. B. kind=image,audio. q sucht im Namen.
Sichtbarkeit wie in der App: Mit dem Recht outreach sieht die Person, der der Key gehört, alles. Mit nur outreach.videos (Mitarbeiter, die eigene Videos aufnehmen) sieht sie nur Videos und davon nur die eigenen. Fragt so ein Key ausdrücklich nach Bildern oder Audio, kommt 403 mit details.required_permission = "outreach".
url ist die öffentliche Adresse, mit der die App die Datei zeigt oder abspielt. Speicherpfade und interne Angaben gibt die API nicht heraus.
Query-Parameter
limitintegerab 1bis 100Einträge pro Seite (Standard 25, höchstens 100)
cursorstringmax. 200 ZeichenWert aus meta.next_cursor der vorigen Seite
kindListe aus stringimage, video, audio; kommagetrennt
imagevideoaudiotypeListe aus stringEinzelne Typen, kommagetrennt, z. B. logo,icon
imagelogoiconstatic_videohauptvideosprachsync_videovideoaudiovoiceqstringmax. 200 ZeichenSuche im Namen (Teilstring, Groß/Klein egal)
Felder der Antwort
idstring (uuid)ID in der Medienbibliothek
namestringAnzeigename wie in der App
typestringTyp in der Bibliothek. Neue Videos haben static_video, ältere auch hauptvideo, sprachsync_video oder video
imagelogoiconstatic_videohauptvideosprachsync_videovideoaudiovoicekindstringArt: image (Bild, Logo, Icon), video, audio (Sprachnachricht)
imagevideoaudiourlstring, kann null seinÖffentliche Adresse, mit der die App die Datei zeigt oder abspielt (Bilder bei Cloudflare Images, Videos und Audio auf cdn.dealskycloud.com)
thumbnail_urlstring, kann null seinVorschaubild eines Videos. Bei Bildern ist url selbst das Bild
descriptionstring, kann null seinBeschreibung (bei Videos in der App pflegbar)
duration_secondsnumber, kann null seinLänge in Sekunden bei Videos und Sprachnachrichten, falls beim Hochladen gemessen
size_mbnumber, kann null seinDateigröße in MB, falls gespeichert (bei Sprachnachrichten)
is_defaultbooleanIn der App als Standard markiert (Stern bei Logos und Icons)
created_atstring (date-time)Zeitpunkt, an dem das Medium in der Bibliothek angelegt wurde
Mögliche Fehler
curl -X GET "https://api.dealsky.io/functions/v1/api/v1/media" \
-H "X-API-Key: $DEALSKY_API_KEY"const res = await fetch("https://api.dealsky.io/functions/v1/api/v1/media", {
method: "GET",
headers: {
"X-API-Key": process.env.DEALSKY_API_KEY,
},
});
const { ok, data, error } = await res.json();import os, requests
res = requests.request(
"GET",
"https://api.dealsky.io/functions/v1/api/v1/media",
headers={"X-API-Key": os.environ["DEALSKY_API_KEY"]},
)
print(res.json()){
"ok": true,
"data": [
{
"id": "3d4e5f6a-7b8c-4d9e-8f0a-1b2c3d4e5f6a",
"name": "logo-beispiel.png",
"type": "logo",
"kind": "image",
"url": "https://imagedelivery.net/Xk3bQ9cR7tLm2pWv8yZa1g/tenants/7c1e2d3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f/logos/1760781120000_9f2c1a7b_logo-beispiel.png/public",
"thumbnail_url": null,
"description": null,
"duration_seconds": null,
"size_mb": null,
"is_default": true,
"created_at": "2026-10-18T10:12:00.000Z"
},
{
"id": "7b8c9d0e-1f2a-4b3c-9d4e-5f6a7b8c9d0e",
"name": "Sprachnachricht · 14.10. 09:12",
"type": "audio",
"kind": "audio",
"url": "https://cdn.dealskycloud.com/tenants/7c1e2d3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f/documents/audio/1760425920000_sprachnachricht.m4a",
"thumbnail_url": null,
"description": null,
"duration_seconds": 23,
"size_mb": 0.37,
"is_default": false,
"created_at": "2026-10-14T07:12:00.000Z"
},
{
"id": "6a7b8c9d-0e1f-4a2b-8c3d-4e5f6a7b8c9d",
"name": "Vorstellung Geschäftsführung",
"type": "static_video",
"kind": "video",
"url": "https://cdn.dealskycloud.com/tenants/7c1e2d3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f/videos/static/1760258400000_vorstellung.mp4",
"thumbnail_url": "https://imagedelivery.net/Xk3bQ9cR7tLm2pWv8yZa1g/tenants/7c1e2d3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f/images/images/1760258460000_vorstellung-vorschau.jpg/public",
"description": "Kurzes Intro für Landingpages und LinkedIn",
"duration_seconds": 74,
"size_mb": null,
"is_default": false,
"created_at": "2026-10-12T08:41:00.000Z"
}
],
"meta": {
"request_id": "req_7f3a…",
"next_cursor": null,
"has_more": false
}
}Ein Medium abrufen
/v1/media/{id}read:assetsRecht: VideosliestEin Eintrag der Medienbibliothek mit denselben Feldern wie in der Liste. 404, wenn es die ID im Konto nicht gibt, der Eintrag gelöscht ist oder keine Mediendatei ist (eine Landingpage-Vorlage steht unter GET /v1/landing-page-templates/{id}). Mit nur dem Recht outreach.videos ergeben fremde Videos 404 und Bilder oder Sprachnachrichten 403 mit details.required_permission = "outreach", wie in der App.
Pfad-Parameter
idstring (uuid)PflichtID des Mediums
Felder der Antwort
idstring (uuid)ID in der Medienbibliothek
namestringAnzeigename wie in der App
typestringTyp in der Bibliothek. Neue Videos haben static_video, ältere auch hauptvideo, sprachsync_video oder video
imagelogoiconstatic_videohauptvideosprachsync_videovideoaudiovoicekindstringArt: image (Bild, Logo, Icon), video, audio (Sprachnachricht)
imagevideoaudiourlstring, kann null seinÖffentliche Adresse, mit der die App die Datei zeigt oder abspielt (Bilder bei Cloudflare Images, Videos und Audio auf cdn.dealskycloud.com)
thumbnail_urlstring, kann null seinVorschaubild eines Videos. Bei Bildern ist url selbst das Bild
descriptionstring, kann null seinBeschreibung (bei Videos in der App pflegbar)
duration_secondsnumber, kann null seinLänge in Sekunden bei Videos und Sprachnachrichten, falls beim Hochladen gemessen
size_mbnumber, kann null seinDateigröße in MB, falls gespeichert (bei Sprachnachrichten)
is_defaultbooleanIn der App als Standard markiert (Stern bei Logos und Icons)
created_atstring (date-time)Zeitpunkt, an dem das Medium in der Bibliothek angelegt wurde
Mögliche Fehler
curl -X GET "https://api.dealsky.io/functions/v1/api/v1/media/5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10" \
-H "X-API-Key: $DEALSKY_API_KEY"const res = await fetch("https://api.dealsky.io/functions/v1/api/v1/media/5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10", {
method: "GET",
headers: {
"X-API-Key": process.env.DEALSKY_API_KEY,
},
});
const { ok, data, error } = await res.json();import os, requests
res = requests.request(
"GET",
"https://api.dealsky.io/functions/v1/api/v1/media/5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10",
headers={"X-API-Key": os.environ["DEALSKY_API_KEY"]},
)
print(res.json()){
"ok": true,
"data": {
"id": "6a7b8c9d-0e1f-4a2b-8c3d-4e5f6a7b8c9d",
"name": "Vorstellung Geschäftsführung",
"type": "static_video",
"kind": "video",
"url": "https://cdn.dealskycloud.com/tenants/7c1e2d3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f/videos/static/1760258400000_vorstellung.mp4",
"thumbnail_url": "https://imagedelivery.net/Xk3bQ9cR7tLm2pWv8yZa1g/tenants/7c1e2d3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f/images/images/1760258460000_vorstellung-vorschau.jpg/public",
"description": "Kurzes Intro für Landingpages und LinkedIn",
"duration_seconds": 74,
"size_mb": null,
"is_default": false,
"created_at": "2026-10-12T08:41:00.000Z"
},
"meta": {
"request_id": "req_7f3a…"
}
}Medium aus der Bibliothek entfernen
/v1/media/{id}write:assetsRecht: VideosschreibtEntfernt ein Bild, Video oder eine Sprachnachricht aus der Medienbibliothek. Danach fehlt es in jeder Auswahl der App und in GET /v1/media. Die Datei selbst bleibt erhalten, darum zeigen ältere Nachrichten, Landingpages und Vorlagen weiter darauf. Kostet nichts.
Wird das Medium noch verwendet, bleibt es stehen und es kommt 409 mit details.used_by (Liste aus type, id, name). Geprüft wird wie in der App: Videos in laufenden oder pausierten Kampagnen (als Sprecher-Video) und aktiven Landingpages, Sprachnachrichten in laufenden Kampagnen, Bilder als Logo in Landingpages oder als Firmenlogo. Vorlagen sperren wie in der App nicht.
Rechte wie in der App: Bilder und Sprachnachrichten nur mit outreach. Mit nur outreach.videos lassen sich eigene Videos entfernen; fremde ergeben 404.
Mit Test-Key wird alles geprüft (auch die Verwendung), aber nichts entfernt.
Pfad-Parameter
idstring (uuid)PflichtID des Mediums
Felder der Antwort
idstring (uuid)ID des entfernten Mediums
kindstringArt: image (Bild, Logo, Icon), video, audio (Sprachnachricht)
imagevideoaudiotypestringTyp in der Bibliothek, z. B. static_video, audio, logo
archivedbooleanImmer true: das Medium ist aus der Bibliothek entfernt, die Datei selbst bleibt erhalten
Mögliche Fehler
curl -X DELETE "https://api.dealsky.io/functions/v1/api/v1/media/5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10" \
-H "X-API-Key: $DEALSKY_API_KEY"const res = await fetch("https://api.dealsky.io/functions/v1/api/v1/media/5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10", {
method: "DELETE",
headers: {
"X-API-Key": process.env.DEALSKY_API_KEY,
},
});
const { ok, data, error } = await res.json();import os, requests
res = requests.request(
"DELETE",
"https://api.dealsky.io/functions/v1/api/v1/media/5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10",
headers={"X-API-Key": os.environ["DEALSKY_API_KEY"]},
)
print(res.json()){
"ok": true,
"data": {
"id": "6a7b8c9d-0e1f-4a2b-8c3d-4e5f6a7b8c9d",
"kind": "video",
"type": "static_video",
"archived": true
},
"meta": {
"request_id": "req_7f3a…"
}
}Video oder Audio hochladen (Adresse holen)
/v1/media/uploadswrite:assetsRecht: VideosschreibtErster Schritt für Videos und Sprachnachrichten. Liefert eine vorsignierte Adresse, an die die Datei direkt per HTTP PUT geht (nicht über die API, deren Body auf 1 MB begrenzt ist), wie das Hochladen in der App. Danach r2_path an POST /v1/media/videos bzw. POST /v1/media/audio übergeben. Kostet keine Credits. Erst der zweite Schritt legt etwas in der Bibliothek an.
So geht es weiter: PUT {upload_url} mit genau den Headern aus upload_headers und der Datei als Body, innerhalb von 24 Stunden (expires_at). Antwortet der Speicher mit 200, liegt die Datei bereit.
Erlaubt wie in der App: Video als .mp4 (video/mp4), .mov (video/quicktime) oder .webm (video/webm) bis 1 GB; jedes Video wird danach in MP4 gewandelt. Audio als .m4a oder .mp4 (audio/mp4) bis 20 MB, das Format, das LinkedIn für Sprachnachrichten verlangt. Andere Audio-Formate (MP3, WAV, OGG) wandelt die App beim Hochladen um und wartet darauf; über die API bitte vorher in M4A umwandeln. content_type muss zur Endung von file_name passen, size_bytes ist die Größe der Datei.
Rechte wie in der App: Videos mit outreach.videos (Medienseite), Sprachnachrichten nur mit outreach (Seite Sprachnachrichten). Ohne outreach kommt bei kind=audio 403 mit details.required_permission = "outreach".
Mit Test-Key wird alles geprüft, aber keine Adresse ausgestellt (would_presign).
Body
kindstringPflichtvideo oder audio (Sprachnachricht)
videoaudiofile_namestringPflichtmax. 200 ZeichenDateiname mit Endung; fließt bereinigt in den Speicherort ein
content_typestringPflichtTyp der Datei, passend zur Endung
video/mp4video/quicktimevideo/webmaudio/mp4size_bytesintegerPflichtab 1bis 1073741824Größe der Datei in Byte
Felder der Antwort
kindstringArt des Uploads wie angefragt: video oder audio (Sprachnachricht)
videoaudior2_pathstringSpeicherort der Datei. Nach dem Hochladen unverändert an POST /v1/media/videos bzw. POST /v1/media/audio übergeben
upload_urlstringVorsignierte Adresse: die Datei per HTTP PUT als Body dorthin schicken. Nicht weitergeben, sie erlaubt das Schreiben dieser einen Datei
upload_methodstringHTTP-Methode für das Hochladen an upload_url, immer PUT
PUTupload_headersobjectHeader, die der PUT genau so tragen muss (Content-Type ist Teil der Signatur)
public_urlstringÖffentliche Adresse der Rohdatei nach dem Hochladen
expires_atstring (date-time)Bis dahin gilt upload_url (24 Stunden, wie in der App)
max_size_bytesintegerHöchstgröße der Datei für diese Art
next_stepstringDer Aufruf nach dem Hochladen
Mögliche Fehler
curl -X POST "https://api.dealsky.io/functions/v1/api/v1/media/uploads" \
-H "X-API-Key: $DEALSKY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"kind": "video",
"file_name": "vorstellung.mp4",
"content_type": "video/mp4",
"size_bytes": 48234112
}'const res = await fetch("https://api.dealsky.io/functions/v1/api/v1/media/uploads", {
method: "POST",
headers: {
"X-API-Key": process.env.DEALSKY_API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({
"kind": "video",
"file_name": "vorstellung.mp4",
"content_type": "video/mp4",
"size_bytes": 48234112
}),
});
const { ok, data, error } = await res.json();import os, requests
res = requests.request(
"POST",
"https://api.dealsky.io/functions/v1/api/v1/media/uploads",
headers={"X-API-Key": os.environ["DEALSKY_API_KEY"]},
json={
"kind": "video",
"file_name": "vorstellung.mp4",
"content_type": "video/mp4",
"size_bytes": 48234112
},
)
print(res.json()){
"ok": true,
"data": {
"kind": "video",
"r2_path": "tenants/7c1e2d3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f/videos/static/1760781120000_3f9a2c1d_vorstellung.mp4",
"upload_url": "https://4f2a9c1e7b3d5a8f0e6c2b4d9a7f1e3c.r2.cloudflarestorage.com/dealskyvideos/tenants/7c1e2d3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f/videos/static/1760781120000_3f9a2c1d_vorstellung.mp4?X-Amz-Date=20261018T101200Z&X-Amz-Expires=86400&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=2c9e4f1a7b3d5e8c%2F20261018%2Fauto%2Fs3%2Faws4_request&X-Amz-SignedHeaders=content-type%3Bhost&X-Amz-Signature=5d0f3c2a9e8b7a6f5e4d3c2b1a0f9e8d7c6b5a4f3e2d1c0b9a8f7e6d5c4b3a2f",
"upload_method": "PUT",
"upload_headers": {
"Content-Type": "video/mp4"
},
"public_url": "https://cdn.dealskycloud.com/tenants/7c1e2d3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f/videos/static/1760781120000_3f9a2c1d_vorstellung.mp4",
"expires_at": "2026-10-19T10:12:00.000Z",
"max_size_bytes": 1073741824,
"next_step": "POST /v1/media/videos"
},
"meta": {
"request_id": "req_7f3a…"
}
}Hochgeladenes Video in MP4 wandeln und anlegen
/v1/media/videoswrite:assetsRecht: VideosschreibtZweiter Schritt nach POST /v1/media/uploads mit kind=video und dem PUT der Datei. Startet die Umwandlung in MP4 auf dem Server, wie die App es nach jeder Aufnahme tut (Videos müssen MP4 mit Längenangabe sein, sonst scheitern spätere Video-Nachrichten). Ist sie fertig, steht das Video in der Bibliothek (static_video, wie ein Upload in der App) und es gibt eine Benachrichtigung in der Glocke. Kostet keine Credits.
Antwort 202 mit job_id. Den Stand liefert GET /v1/jobs/{id} (kind video_conversion, braucht das Recht outreach); bei succeeded steht die ID des neuen Videos in result.asset_id. Mit nur dem Recht outreach.videos erscheint das fertige Video in GET /v1/media?kind=video. Die Umwandlung dauert meist unter einer Minute, bei großen Dateien länger.
Die Datei wird beim Start nicht geprüft. Fehlt sie (PUT nicht erfolgt oder abgelaufen), endet der Auftrag mit failed. Ist sie kein lesbares Video, endet die Umwandlung mit einem Fehler; wie bei Aufnahmen in der App legt dealsky die Rohdatei dann nach etwa 15 Minuten ungewandelt als Video an. Das Video wird auf höchstens 720p verkleinert. Ein Vorschaubild setzt die API nicht, das geht in der App.
r2_path muss aus einem eigenen Upload stammen, sonst 400. Für dieselbe Datei startet nur ein Auftrag: läuft er noch oder ist er fertig, kommt 409 mit details.job_id; nach failed ist ein neuer Versuch möglich.
Mit Test-Key wird alles geprüft, aber nichts gestartet.
Body
r2_pathstringPflichtmind. 10 Zeichenmax. 300 Zeichenr2_path aus POST /v1/media/uploads
namestringPflichtmax. 200 ZeichenAnzeigename in der Bibliothek
Mögliche Fehler
curl -X POST "https://api.dealsky.io/functions/v1/api/v1/media/videos" \
-H "X-API-Key: $DEALSKY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"r2_path": "tenants/7c1e2d3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f/videos/static/1760781120000_3f9a2c1d_vorstellung.mp4",
"name": "Vorstellung Geschäftsführung"
}'const res = await fetch("https://api.dealsky.io/functions/v1/api/v1/media/videos", {
method: "POST",
headers: {
"X-API-Key": process.env.DEALSKY_API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({
"r2_path": "tenants/7c1e2d3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f/videos/static/1760781120000_3f9a2c1d_vorstellung.mp4",
"name": "Vorstellung Geschäftsführung"
}),
});
const { ok, data, error } = await res.json();import os, requests
res = requests.request(
"POST",
"https://api.dealsky.io/functions/v1/api/v1/media/videos",
headers={"X-API-Key": os.environ["DEALSKY_API_KEY"]},
json={
"r2_path": "tenants/7c1e2d3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f/videos/static/1760781120000_3f9a2c1d_vorstellung.mp4",
"name": "Vorstellung Geschäftsführung"
},
)
print(res.json()){
"ok": true,
"data": {
"job_id": "e1f2a3b4-c5d6-4e7f-8a9b-0c1d2e3f4a5b",
"kind": "video_conversion",
"status": "running",
"name": "Vorstellung Geschäftsführung",
"r2_path": "tenants/7c1e2d3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f/videos/static/1760781120000_3f9a2c1d_vorstellung.mp4"
},
"meta": {
"request_id": "req_7f3a…"
}
}Hochgeladene Sprachnachricht anlegen
/v1/media/audiowrite:assetsRecht: Outreach PlattformschreibtZweiter Schritt nach POST /v1/media/uploads mit kind=audio und dem PUT der Datei. Legt die Sprachnachricht in der Bibliothek an, wie das Hochladen unter Assets, Sprachnachrichten in der App. Sie ist sofort in Kampagnen und im Postfach auswählbar. Kostet keine Credits.
r2_path muss aus einem eigenen Audio-Upload stammen (.m4a oder .mp4), sonst 400. Ob die Datei wirklich hochgeladen wurde, prüft die API nicht; bitte erst nach erfolgreichem PUT aufrufen. Dieselbe Datei lässt sich nur einmal anlegen (409 mit details.id).
duration_seconds (Länge, wie die App sie bei Aufnahmen speichert) und size_bytes (füllt size_mb) sind freiwillig. Recht wie die Seite Sprachnachrichten: outreach.
Mit Test-Key wird alles geprüft, aber nichts angelegt.
Body
r2_pathstringPflichtmind. 10 Zeichenmax. 300 Zeichenr2_path aus POST /v1/media/uploads
namestringPflichtmax. 200 ZeichenAnzeigename in der Bibliothek
duration_secondsnumberab 0bis 3600Länge in Sekunden
size_bytesintegerab 1bis 20971520Größe der Datei in Byte, wie beim Hochladen angegeben
Mögliche Fehler
curl -X POST "https://api.dealsky.io/functions/v1/api/v1/media/audio" \
-H "X-API-Key: $DEALSKY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"r2_path": "tenants/7c1e2d3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f/documents/audio/1760781240000_8b2e7d40_begruessung.m4a",
"name": "Begrüßung Herbst",
"duration_seconds": 23,
"size_bytes": 389120
}'const res = await fetch("https://api.dealsky.io/functions/v1/api/v1/media/audio", {
method: "POST",
headers: {
"X-API-Key": process.env.DEALSKY_API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({
"r2_path": "tenants/7c1e2d3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f/documents/audio/1760781240000_8b2e7d40_begruessung.m4a",
"name": "Begrüßung Herbst",
"duration_seconds": 23,
"size_bytes": 389120
}),
});
const { ok, data, error } = await res.json();import os, requests
res = requests.request(
"POST",
"https://api.dealsky.io/functions/v1/api/v1/media/audio",
headers={"X-API-Key": os.environ["DEALSKY_API_KEY"]},
json={
"r2_path": "tenants/7c1e2d3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f/documents/audio/1760781240000_8b2e7d40_begruessung.m4a",
"name": "Begrüßung Herbst",
"duration_seconds": 23,
"size_bytes": 389120
},
)
print(res.json()){
"ok": true,
"data": {
"id": "7b8c9d0e-1f2a-4b3c-9d4e-5f6a7b8c9d0e",
"name": "Begrüßung Herbst",
"type": "audio",
"kind": "audio",
"url": "https://cdn.dealskycloud.com/tenants/7c1e2d3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f/documents/audio/1760781240000_8b2e7d40_begruessung.m4a",
"thumbnail_url": null,
"description": null,
"duration_seconds": 23,
"size_mb": 0.37,
"is_default": false,
"created_at": "2026-10-18T10:14:00.000Z"
},
"meta": {
"request_id": "req_7f3a…"
}
}