Beiträge und Aufträge
Ein Beitrag ist ein Inhalt in einem Workspace: alles, was ein Feed-Element, ein Ereignis eines eigenen Feeds oder ein Beitrag einer Beitragsliste erzeugt, für jeden Kanal, der ihn empfängt. Jeder Kanal eines Beitrags erhält weiterhin sein eigenes Rendering, in seinem eigenen Bildformat und seiner eigenen Sprache, seine eigene Freigabe, wo der Kanal eine verlangt, und seinen eigenen Zustand. Die API nennt einen Kanal eines Beitrags einen Auftrag (Job), weshalb die Pfade /v1/jobs lauten: Ein Auftrag ist das, was Sie beobachten und worauf Sie einwirken (abbrechen, seinen Text ändern, bitten, ihn zu entfernen), und der Beitrag des Kanals darin ist der Nachweis dessen, was auf diesem Kanal geschah.
Reelwire erstellt das Video. Ist ein Beitrag fällig, wird er auf den Wegen übergeben, die sein Kanal eingeschaltet hat, in beliebiger Mischung: per E-Mail oder per Webhook, und wer ihn erhält, veröffentlicht ihn und meldet es dann; oder über den Plattform-Connector des Kanals, der ihn selbst auf der Plattform veröffentlicht und es meldet (Kanäle). Ein Kanal, bei dem jeder Weg ausgeschaltet ist, übergibt seine Beiträge nur an die Syndikationsteilnehmer, deren Gruppe ihn übernimmt. Zum Webhook siehe Webhooks, zur E-Mail und ihrem Beitragspaket, dessen Adressen keinen Schlüssel brauchen und nicht in der Tabelle stehen, siehe unten Per E-Mail übergebene Beiträge.
| Methode | Pfad | Berechtigung |
|---|---|---|
GET | /v1/jobs | posts:read |
POST | /v1/jobs/{id}/cancel | posts:write |
POST | /v1/jobs/{id}/repost | posts:write |
POST | /v1/jobs/{id}/update | posts:write |
POST | /v1/jobs/{id}/resend-email | posts:write |
POST | /v1/jobs/{id}/resend-webhook | posts:write |
POST | /v1/jobs/{id}/resend-connector | posts:write |
POST | /v1/jobs/{id}/resend-participants | posts:write |
POST | /v1/jobs/{id}/retry | posts:write |
POST | /v1/jobs/{id}/retry-render | posts:write |
POST | /v1/jobs/{id}/mark-published | posts:write |
POST | /v1/jobs/{id}/skip | posts:write |
POST | /v1/jobs/{id}/mark-deleted | posts:write |
POST | /v1/jobs/{id}/archive | posts:write |
POST | /v1/jobs/{id}/unarchive | posts:write |
POST | /v1/jobs/{id}/delete | posts:write |
GET | /v1/jobs/{id}/download | posts:read |
GET | /v1/jobs/{id}/reuse | posts:read |
GET | /v1/posts | posts:read |
POST | /v1/posts/{id}/report | posts:write |
GET | /v1/posts/{id}/package | posts:read |
GET | /v1/pipeline | posts:read |
GET | /v1/pipeline/{id} | posts:read |
GET | /v1/overview | posts:read |
GET | /v1/calendar | schedule:read |
GET | /v1/calendar/still | schedule:read |
GET | /v1/calendar/export | schedule:read |
GET | /v1/calendar/export/link | schedule:read |
GET | /v1/approvals | approvals:read |
POST | /v1/approvals/{id} | approvals:write |
Beiträge auflisten
GET /v1/jobs listet die Beiträge: eine Zeile je Beitrag, seine Kanäle darin. Es paginiert, durchsucht und filtert wie jedes Protokoll; siehe Listen und Paginierung. Mit by=channel liefert es stattdessen eine Zeile je Kanal, was die Seite Beiträge zeigt: siehe Filter.
curl "http://localhost:4000/v1/jobs?perPage=1" \
-H "Authorization: Bearer rw_your_key_here"
Dies ist der Beitrag aus dem durchgespielten Beispiel unter Ereignisse senden, für zwei Kanäle: Channel 4 de wurde per Webhook übergeben und als veröffentlicht gemeldet, und Channel 10 en wartet auf einen Prüfer.
{
"jobs": [
{
"id": "01M2SQN507TDA0KNTJJABHBR9A",
"postKey": "01M2SQN507TDA0KNTJJABHBR9A",
"status": "AWAITING_APPROVAL",
"summary": "1 of 2 published",
"progress": 0,
"priority": false,
"createdAt": "2026-09-18T07:45:50.099Z",
"updatedAt": "2026-09-18T07:47:02.316Z",
"origin": "custom",
"details": "Enterprise 2 Stream 1",
"postTitle": null,
"brandName": "Brand 1",
"channelCount": 2,
"channelNames": ["Channel 4 de", "Channel 10 en"],
"caption": "The ten-year settled at 2.41 per cent.",
"title": "Bund yields close at a three-week high",
"email": "off",
"webhook": "partly",
"connector": "off",
"approvalId": "01M2SQPASCPHZ65QRPX9X628GD",
"approval": { "required": true, "state": "PENDING", "login": null, "name": null, "waiting": 1 },
"downloadable": true,
"archived": false,
"channels": [
{
"id": "01M2SQN50JQFC00PZE93M9E33R",
"postId": "01M2SQPANAT1W066PMYNXFTCNZ",
"status": "PUBLISHED",
"state": "PUBLISHED",
"progress": 1,
"createdAt": "2026-09-18T07:45:50.099Z",
"updatedAt": "2026-09-18T07:47:02.316Z",
"origin": "custom",
"details": "Enterprise 2 Stream 1",
"postTitle": null,
"channelId": "01M2985NX4V0WA1GV9MC63DEPJ",
"channelName": "Channel 4 de",
"brandName": "Brand 1",
"platform": "instagram",
"surfaceLabel": "Instagram Reels",
"ratio": "9x16",
"locale": "de",
"caption": "The ten-year settled at 2.41 per cent.",
"title": "Bund yields close at a three-week high",
"publishedAt": "2026-09-18T07:47:02.310Z",
"permalink": "https://www.instagram.com/reel/C9x2Lm4oQpR/",
"scheduledFor": "2026-09-18T07:46:28.711Z",
"error": null,
"templateName": "Big number",
"templateVariant": "Corporate glass",
"templateVersion": "1.0.0",
"renderJobId": "01M2SQN51TGR960ZKWNVKH1HQJ",
"deliverByEmail": false,
"deliverByWebhook": true,
"deliverByConnector": false,
"syndicated": false,
"email": "off",
"webhook": "sent",
"connector": "off",
"handedOver": true,
"deleteRequested": false,
"updatable": true,
"resendable": true,
"retryable": false,
"renderRetryable": false,
"renderRetryCounts": false,
"markable": false,
"skippable": false,
"deletable": true,
"markDeletable": false,
"repostable": true,
"downloadable": true,
"priority": true,
"archived": false,
"approvalId": null,
"approval": { "required": false, "state": null, "login": null, "name": null },
"clip": {
"id": "01M2SQPAJYJR7YB27466FV30SZ",
"mimeType": "video/mp4",
"url": "http://localhost:4000/v1/assets/01M2SQPAJYJR7YB27466FV30SZ/download?exp=...&sig=..."
}
},
{
"id": "01M2SQN50TAP4BXAYDZRC9WMBC",
"postId": "01M2SQPARBQPG1BRENTHBM1W08",
"status": "AWAITING_APPROVAL",
"state": "AWAITING_APPROVAL",
"progress": 1,
"createdAt": "2026-09-18T07:45:50.106Z",
"updatedAt": "2026-09-18T07:46:28.781Z",
"origin": "custom",
"details": "Enterprise 2 Stream 1",
"postTitle": null,
"channelId": "01M2985NXJRXVE5HKCCGKASP8P",
"channelName": "Channel 10 en",
"brandName": "Brand 1",
"platform": "instagram",
"surfaceLabel": "Instagram Reels",
"ratio": "9x16",
"locale": "en",
"caption": "The ten-year settled at 2.41 per cent.",
"title": "Bund yields close at a three-week high",
"publishedAt": null,
"permalink": null,
"scheduledFor": null,
"error": null,
"templateName": "Big number",
"templateVariant": "Corporate glass",
"templateVersion": "1.0.0",
"renderJobId": "01M2SQN51XWQ3D8E0T4B6RZK2M",
"deliverByEmail": false,
"deliverByWebhook": true,
"deliverByConnector": false,
"syndicated": false,
"email": "off",
"webhook": "waiting",
"connector": "off",
"handedOver": false,
"deleteRequested": false,
"updatable": false,
"resendable": false,
"retryable": false,
"renderRetryable": false,
"renderRetryCounts": false,
"markable": false,
"skippable": false,
"deletable": false,
"markDeletable": false,
"repostable": false,
"downloadable": true,
"priority": true,
"archived": false,
"approvalId": "01M2SQPASCPHZ65QRPX9X628GD",
"approval": { "required": true, "state": "PENDING", "login": null, "name": null },
"clip": {
"id": "01M2SQPAPH4YF66ZKK5Y5XA9Y7",
"mimeType": "video/mp4",
"url": "http://localhost:4000/v1/assets/01M2SQPAPH4YF66ZKK5Y5XA9Y7/download?exp=...&sig=..."
}
}
]
}
],
"total": 5,
"all": 5,
"page": 1,
"perPage": 1,
"stages": {
"rendering": 0,
"approval": 1,
"scheduled": 0,
"publishing": 0,
"handedOver": 0,
"published": 4,
"skipped": 0,
"failed": 0,
"rejected": 0,
"cancelled": 0,
"deleted": 0
},
"unstaged": 5,
"facets": {
"stage": ["rendering", "approval", "scheduled", "publishing", "handedOver", "published", "skipped", "failed", "rejected", "cancelled", "deleted"],
"archive": ["archived"],
"approval": ["upcoming", "pending", "approved", "rejected", "none"],
"channelId": ["01M2985NXJRXVE5HKCCGKASP8P", "01M2985NX4V0WA1GV9MC63DEPJ"],
"brandId": ["01M1VFRWE7VHP3H54ESRJQ0SAJ"],
"platform": ["instagram"],
"origin": ["custom"]
},
"labels": {
"channelId": {
"01M2985NXJRXVE5HKCCGKASP8P": "Channel 10 en",
"01M2985NX4V0WA1GV9MC63DEPJ": "Channel 4 de"
},
"brandId": { "01M1VFRWE7VHP3H54ESRJQ0SAJ": "Brand 1" }
}
}
Zwei IDs für zwei Dinge. Die id einer Zeile ist der Beitrag, sein postKey: die ID, die jede Übergabe davon trägt. Die id eines Kanals in channels ist das, was jede Aktion /v1/jobs/{id}/... unten nimmt und was /v1/pipeline/{id} liest. Die postId eines Kanals ist der Beitrag seines Kanals, die ID, unter der ein Webhook-Empfänger zurückmeldet.
Was eine Zeile über den ganzen Beitrag sagt:
statusist der seiner Kanäle, der am dringendsten jemanden braucht. Siehe Der Status eines Beitrags.summarysagt in Worten, wie weit ein Beitrag mit mehreren Kanälen ist: „2 of 3 published“, „1 of 3 handed over“ oder „3 channels“. Bei einem Beitrag mit einem Kanal ist esnull.email,webhookundconnectorsagen, wie jeder Weg nach draußen über seine Kanäle lief:off,waiting(noch nicht übergeben),sending,retrying,sent,failedoderpartly, wo seine Kanäle zu verschiedenen Zeiten gingen, etwa wenn ein Kanal mit einem Prüfer den anderen allein folgt. Ein Kanal trägt dieselben Werte für sich, ohnepartly.approvalIdist die wartende Prüfung, wo genau ein Kanal wartet, undapproval.waiting, wie viele Kanäle warten.captionundtitlesind die seines ersten Kanals,downloadablesagt, ob irgendein Kanal ein Video zu geben hat, undarchivedist true, wo jeder seiner Kanäle archiviert wurde.
Was ein Kanal über sich selbst sagt:
statuswird aus seinem Render und seinem Beitrag berechnet. Siehe Status und Stufen.stateist der gespeicherte Zustand seines Beitrags, wie ihnGET /v1/postshat, odernull, bevor es einen Beitrag gibt.captionundtitlesind der eigene Text seines Beitrags. Wo der Inhalt seinen Text untermetaDatamitbrachte, kommt die Beschreibung in vier Längen,captionTiny(200 Zeichen),captionShort(500),captionMedium(1.500) undcaptionLong(4.000), und der Beitrag jedes Kanals nimmt die längste, für die seine Plattform neben dem eigenen Text der Marke Platz hat; siehe Vorlagen. Ein Kanal auf Keine bestimmte Plattform behält alle vier: Sein Beitragspaket und sein Download zeigen sie je Art von Plattform, und ein Update ändert sie mitcaptions.deliverByEmail,deliverByWebhookunddeliverByConnectorsind die Schalter des Kanals, wie sie jetzt stehen, undemail,webhookundconnector, was jeder Weg für ihn getan hat:off,waiting,sending,retrying,sentoderfailed. Beim Connector bedeutetsentauf der Plattform veröffentlicht.syndicatedist true, solange eine Syndikations-Gruppe mit einem angemeldeten Teilnehmer den Kanal übernimmt: Seine Beiträge gehen dann auch an diese Teilnehmer, was die Schalter auch sagen.handedOverist true, sobald er übergeben wurde, was seither auch darüber gesagt wurde, unddeleteRequested, solange ein Löschen übergeben wurde und niemand gesagt hat, dass der Beitrag weg ist.publishedAtist, wann er übergeben wurde, bis jemand ihn als veröffentlicht meldet (oder der Plattform-Connector ihn veröffentlicht hat); dann ist es, wann das geschah.permalinkist der Link zum Beitrag, wo jemand einen gemeldet hat oder der Connector ihn veröffentlicht hat.approvalsagt, ob er einen Prüfer braucht und wie es damit steht:stateistPENDING,APPROVED,REJECTED,CANCELLED,UPCOMING, solange ein Kanal, der eine Freigabe verlangt, den Clip noch rendert, odernull, wo niemand gefragt wird;loginundnamesagen, wer entschieden hat.kindistpostoderupdatefür eine Änderung an einem bereits veröffentlichten Beitrag, die die verlangtechangeträgt;neededist, wie viele Freigaben es braucht (2, wo ein Enterprise-Kanal zwei Freigebende verlangt),firstwer die erste von zwei gegeben hat, während die zweite aussteht, undrequestedBywer den Beitrag geschrieben oder die Änderung verlangt hat, jeweils alsloginundname.archivedist true, sobald jemand ihn archiviert hat. Siehe Archivieren und wiederherstellen.errorist, warum er gestoppt hat, wo er das tat: der Grund des Renders oder des Beitrags.
Die Flags sagen Ihnen, welche Aktion ein Kanal jetzt annimmt. Lesen Sie sie, statt vom Status zu raten, und Sie müssen keinen 409 behandeln:
| Flag | Aktion | Wahr, solange |
|---|---|---|
updatable | update | Er wurde übergeben (übergeben, veröffentlicht oder übersprungen), und keine Änderung und kein Löschen ist unterwegs. |
resendable | resend-email, resend-webhook, resend-connector, resend-participants | Er ist übergeben, veröffentlicht oder übersprungen, und nichts anderes ist unterwegs; jedes braucht außerdem seinen am Kanal eingeschalteten Weg, und resend-participants eine Syndikationsgruppe mit einem angemeldeten Teilnehmer, die ihn übernimmt (syndicated). |
retryable | retry | Er schlug fehl, nachdem sein Clip erstellt war (POST_FAILED), und der Clip ist noch gespeichert. |
renderRetryable | retry-render | Sein Clip konnte nicht gerendert werden (RENDER_FAILED), und sein Kanal wurde nicht entfernt. renderRetryCounts sagt, ob die Wiederholung ein Video kostet. |
markable | mark-published | Er ist übergeben oder übersprungen, und niemand hat darum gebeten, ihn zu entfernen. Ein fehlgeschlagener Beitrag wird stattdessen mit retry erneut versucht. |
skippable | skip | Er ist übergeben, und noch niemand hat etwas darüber gesagt. |
deletable | delete | Er ist übergeben oder veröffentlicht, und keine Änderung und kein Löschen ist unterwegs. |
markDeletable | mark-deleted | Ein Löschen wurde übergeben, und niemand hat gesagt, dass der Beitrag weg ist; oder kein Weg brachte ein Löschen durch (DELETE_FAILED), bei einem Beitrag, den jemand von Hand entfernt hat. |
repostable | repost | Er wurde einmal übergeben, und sein Kanal ist live mit eingeschaltetem Webhook. |
downloadable | download | Sein Video ist noch gespeichert. |
stage, archive und approval in facets sind die festen Auswahlen. Der Rest von facets und labels wird aus den Zeilen gelesen, die der Workspace tatsächlich hält, nicht aus einer festen Liste, sodass ein Kanal, eine Marke, eine Plattform oder ein Ursprung, der dort erscheint, etwas zurückgeben kann.
Filter
| Parameter | Werte |
|---|---|
stage | rendering, approval, scheduled, publishing, handedOver, published, skipped, failed, rejected, cancelled, deleted |
channelId | Eine Kanal-ID |
brandId | Eine Marken-ID |
platform | Das Format des Kanals: youtube, facebook, instagram, tiktok, linkedin, telegram, discord, slack, threema, x, wechat, signal, pinterest, threads, whatsapp oder download, was Keine bestimmte Plattform ist |
origin | shipped, custom, manual |
approval | upcoming (ein Kanal, der eine Freigabe verlangt, sein Clip wird noch gerendert), pending, approved, rejected, none |
by | channel: eine Zeile je Kanal eines Beitrags statt einer je Beitrag |
archive | archived: nur das, was jemand archiviert hat. Ohne: nur das, was niemand archiviert hat |
Ein Beitrag wird aufgelistet, wenn einer seiner Kanäle passt, und dann mit allen seinen Kanälen.
Mit by=channel ist jeder Kanal eine eigene Zeile: channels enthält diesen einen Kanal, die id der Zeile ist die id des Kanals (die, die jede Aktion unten nimmt), und postKey nennt weiterhin seinen Beitrag. Die Filter, die Suche und die Stufenzählungen zählen dann Kanäle. Wie ein Beitrag übergeben wird, ändert sich nicht: Die Kanäle eines Beitrags, die zusammen gehen, gehen weiterhin in einer E-Mail und einem Webhook-Aufruf.
Status und Stufen
Der status eines Kanals wird berechnet, nicht gespeichert: der Zustand seines Renders, bis der Clip existiert, dann der seines Beitrags, mit einem darübergelegten Update oder Löschen, das unterwegs ist. Eine Stufe ist eine Menge von Status, kein Status:
| Stufe | Kanalstatus |
|---|---|
rendering | ACCEPTED, AWAITING_RENDERING, RENDERING, DOWNLOADING |
approval | AWAITING_APPROVAL |
scheduled | SCHEDULED |
publishing | HANDING_OVER, UPDATING |
handedOver | HANDED_OVER |
published | PUBLISHED |
skipped | SKIPPED |
failed | RENDER_FAILED, POST_FAILED, UPDATE_FAILED, DELETE_FAILED |
rejected | REJECTED |
cancelled | CANCELLED, REPLACED |
deleted | DELETE_REQUESTED, DELETED |

publishing wird gerade übergeben, und handedOver ist übergeben und noch nicht gemeldet. Die alte Stufe emailed, aus der Zeit, als nur eine E-Mail einen Beitrag übergeben konnte, funktioniert weiterhin und bedeutet handedOver.
HANDED_OVER ist nicht veröffentlicht: Es bedeutet, dass ein Weg nach draußen den Beitrag zugestellt hat und noch niemand gesagt hat, ob er online ging. PUBLISHED kommt nur, wenn jemand es sagt oder wenn der Plattform-Connector des Kanals ihn veröffentlicht hat. SKIPPED ist übergeben und bewusst nicht veröffentlicht. POST_FAILED ist ein Beitrag, der nach allen Versuchen nicht übergeben werden konnte oder von dem der Veröffentlichende meldete, dass er nicht veröffentlicht werden konnte. DELETE_REQUESTED ist ein übergebenes Löschen, das darauf wartet, dass jemand sagt, der Beitrag sei weg, und DELETED ist, sobald sie es getan haben oder der Plattform-Connector ihn entfernt hat.
Ein Beitrag ist in einer Stufe, wenn einer seiner Kanäle es ist, und jede Stufe zählt Beiträge, sodass ein Beitrag in zwei Stufen zählen kann.
Der Zeitraum, in den ein Beitrag fällt, ist, wann ihm etwas geschah, nicht nur, wann sein Inhalt eintraf: since und until passen auf einen Beitrag, der eintraf, gerendert wurde oder bei dem sich einer seiner Kanäle innerhalb des Zeitfensters änderte. Ein Beitrag, der gestern eintraf und vor zehn Minuten veröffentlicht wurde, liegt in der letzten Stunde.
Der Status eines Beitrags
Der status eines Beitrags ist der seiner Kanäle, der am dringendsten jemanden braucht: zuerst ein Fehlschlag; dann der am wenigsten fortgeschrittene der noch laufenden Kanäle, in der Reihenfolge ACCEPTED, AWAITING_RENDERING, RENDERING, DOWNLOADING, AWAITING_APPROVAL, SCHEDULED, HANDING_OVER, UPDATING, DELETE_REQUESTED, HANDED_OVER, womit einer, der auf das Wort von jemandem wartet, zuletzt kommt; dann ein abgeschlossener, veröffentlicht vor übersprungen, gelöscht, abgelehnt und abgebrochen.
Eine Zeile je Kanal
GET /v1/posts ist dasselbe Protokoll auf der Ebene des Beitrags eines Kanals: eine Veröffentlichung auf einem Kanal, in einer Sprache und einem Bildformat. Es filtert nach state und platform.
curl "http://localhost:4000/v1/posts?perPage=1" \
-H "Authorization: Bearer rw_your_key_here"
{
"posts": [
{
"id": "01M2SQPANAT1W066PMYNXFTCNZ",
"postGroupId": "01M2SQN50JQFC00PZE93M9E33R",
"origin": "custom",
"details": "Enterprise 2 Stream 1",
"postTitle": null,
"state": "PUBLISHED",
"platform": "instagram",
"surfaceLabel": "Instagram Reels",
"channelName": "Channel 4 de",
"brandName": "Brand 1",
"locale": "de",
"ratio": "9x16",
"title": "Bund yields close at a three-week high",
"caption": "The ten-year settled at 2.41 per cent.",
"hashtags": ["bunds", "rates"],
"createdAt": "2026-09-18T07:46:28.705Z",
"scheduledFor": "2026-09-18T07:46:28.711Z",
"publishedAt": "2026-09-18T07:47:02.310Z",
"platformPostId": "17912345678901234",
"permalink": "https://www.instagram.com/reel/C9x2Lm4oQpR/",
"failureReason": null,
"connected": true,
"assets": [
{
"assetId": "01M2SQPAJYJR7YB27466FV30SZ",
"url": "http://localhost:4000/v1/assets/01M2SQPAJYJR7YB27466FV30SZ/download?exp=...&sig=...",
"expiresAt": "2026-09-18T08:50:22.000Z"
}
],
"clipStored": true
}
],
"total": 7,
"all": 7,
"page": 1,
"perPage": 1,
"facets": { "state": ["AWAITING_APPROVAL", "PUBLISHED"], "platform": ["instagram"] }
}
id ist der Beitrag des Kanals, die postId, unter der ein Webhook-Empfänger zurückmeldet, und postGroupId ist die id seines Kanals bei GET /v1/jobs, die die Aktionen nehmen. platformPostId und permalink sind das, was der Veröffentlichende zurückgemeldet hat oder was der Plattform-Connector antwortete, als er ihn veröffentlichte, und sie reisen mit einem späteren Update oder Löschen, damit der Beitrag wiedergefunden werden kann. Asset-URLs sind signiert und laufen ab; expiresAt sagt, wann, erzeugen Sie also eine neue, statt die URL zu speichern.
Der state des Beitrags eines Kanals ist einer von DRAFT, PENDING_RENDER, RENDERED, AWAITING_APPROVAL, APPROVED, REJECTED, SCHEDULED, PUBLISHING (wird übergeben), HANDED_OVER (ein Weg nach draußen hat ihn zugestellt, und noch niemand hat gesagt, ob er online ging), PUBLISHED (jemand hat gesagt, dass er online ist, oder der Plattform-Connector hat ihn veröffentlicht), SKIPPED (übergeben und bewusst nicht veröffentlicht), FAILED (er konnte nicht übergeben werden, oder der Veröffentlichende sagte, er könne nicht veröffentlicht werden, und failureReason sagt warum), RECALLED (entfernt, und jemand oder der Plattform-Connector hat es gesagt), REPLACED und CANCELLED (er geht nie hinaus: Jemand hat ihn abgebrochen, oder sein Clip wurde entfernt, um Platz zu schaffen).
clipStored: false bedeutet, dass das Video entfernt wurde, um im Speicherkontingent des Workspaces Platz zu schaffen, oder unter Gerenderte Clips gelöscht wurde. Der Beitrag ist weiterhin ein Nachweis dessen, was hinausging; es gibt keine Datei mehr zum Herunterladen. Bei einem Beitrag, der nie einen Clip hatte, ist es null.
connected sagt, ob ein eigener Weg des Workspaces den Beitrag tragen kann: Sein Kanal hat E-Mail eingeschaltet, oder die Webhook-Adresse des Workspaces ist gesetzt und eingeschaltet.
Einen Beitrag verfolgen, während er läuft
GET /v1/pipeline ist die Live-Ansicht: was gerendert wird, was übergeben wird und was zuletzt fertig wurde. Sie sagt Ihnen, wie oft Sie fragen sollen. since und until schränken sie auf Beiträge ein, die in einem Zeitfenster eintrafen; ohne sie decken die Zählwerte alles ab, was der Workspace hat.
curl http://localhost:4000/v1/pipeline \
-H "Authorization: Bearer rw_your_key_here"
{
"at": "2026-09-18T07:50:22.201Z",
"pollMs": 2000,
"render": { "counts": { "COMPLETED": 7 }, "inFlight": [], "recent": [] },
"posts": {
"counts": { "PUBLISHED": 7 },
"clipCounts": { "PUBLISHED": 7 },
"inFlight": [],
"recent": [
{
"id": "01M2SQN50TAP4BXAYDZRC9WMBC",
"kind": "postGroup",
"state": "PUBLISHED",
"templateId": "tpl_dd7e6b264fb8",
"brand": "Brand 1",
"channelName": "Channel 10 en",
"streamId": "st_30472168d941",
"source": "st_30472168d941",
"title": "Bund yields close at a three-week high",
"createdAt": "2026-09-18T07:46:28.748Z",
"stageSeconds": 4,
"stageSince": "2026-09-18T07:50:18.611Z",
"error": null,
"clips": [
{
"id": "01M2SQPARBQPG1BRENTHBM1W08",
"platform": "instagram",
"locale": "en",
"ratio": "9x16",
"state": "PUBLISHED",
"scheduledFor": "2026-09-18T07:50:17.386Z",
"publishedAt": "2026-09-18T07:50:18.608Z",
"permalink": "https://www.instagram.com/reel/C9x3Nq7pRtS/",
"error": null
}
]
}
]
},
"limit": 12
}
pollMs ist das vom Server vorgeschlagene Intervall. Halten Sie es ein, statt ein eigenes zu wählen. Jede Spur zeigt höchstens limit Kanäle, und counts deckt alle ab, sodass eine Spur „6, 4 gezeigt“ sagen kann.
GET /v1/pipeline/{id} ist alles, was über einen Kanal eines Beitrags bekannt ist, über die id des Kanals: woher seine Daten kamen, die Marke, der Kanal, die Quelle und die Vorlage, die ihn gerendert haben, der Render, die Freigabe und sein Beitrag mit jeder Übergabe, die ihn trug, per E-Mail, per Webhook oder per Plattform-Connector. Es trägt auch, was das Beitragspaket gibt: die Texte zum Kopieren, die Video- und Cover-Links und einen prompt für einen KI-Assistenten, solange das Video noch gespeichert ist.
GET /v1/overview ist die Zählung von allem, nützlich als Gesundheitsanzeige:
{
"brands": 3,
"channels": 15,
"subscriptions": 57,
"templates": { "mirrored": 14 },
"ingest": { "total": 1, "last24h": 1 },
"renderJobs": { "COMPLETED": 7 },
"assets": 7,
"posts": { "AWAITING_APPROVAL": 1, "PUBLISHED": 6 },
"attention": { "pendingApprovals": 1, "deadDeliveries": 0 }
}
Beobachten Sie attention, statt es selbst zu berechnen: Eine tote Zustellung ist eine Übergabe, die nie durchkam, und eine ausstehende Freigabe ist ein Beitrag, der auf eine Person wartet.
Freigaben
Ein Kanal kann so eingestellt werden, dass er jeden Beitrag für einen Prüfer anhält. Diese Beiträge liegen in AWAITING_APPROVAL, gerendert und bereit, bis jemand entscheidet. Ebenso ein Update eines bereits veröffentlichten Beitrags auf einem solchen Kanal (siehe Einen übergebenen Beitrag aktualisieren). Die Freigabe gehört zu Small business und Enterprise: In den darunterliegenden Tarifen kann ein Kanal nicht darauf eingestellt werden (ein 409), und einem Schlüssel wird die Berechtigung Posts - Approvals nicht angeboten.
curl "http://localhost:4000/v1/approvals?perPage=3" \
-H "Authorization: Bearer rw_your_key_here"
{
"approvals": [
{
"id": "01M2SQPASCPHZ65QRPX9X628GD",
"requestedAt": "2026-09-18T07:46:28.781Z",
"channelName": "Channel 10 en",
"templateId": "tpl_dd7e6b264fb8",
"templateVersion": null,
"posts": [
{
"id": "01M2SQPARBQPG1BRENTHBM1W08",
"platform": "instagram",
"locale": "en",
"ratio": "9x16",
"caption": "The ten-year settled at 2.41 per cent.",
"state": "AWAITING_APPROVAL",
"assets": [
{
"assetId": "01M2SQPAPH4YF66ZKK5Y5XA9Y7",
"url": "http://localhost:4000/v1/assets/01M2SQPAPH4YF66ZKK5Y5XA9Y7/download?exp=...&sig=...",
"expiresAt": "2026-09-18T08:50:12.000Z"
}
]
}
]
}
],
"total": 1,
"all": 1,
"page": 1,
"perPage": 3,
"facets": {}
}
Die Liste enthält, was jetzt wartet, die ältesten zuerst, weil eine Warteschlange von vorn abgearbeitet wird. templateVersion ist null, wo der Kanal dem neuesten Build folgt. Jede Anfrage sagt außerdem:
kind:POST, ein Beitrag, der überhaupt noch auf seine Übergabe wartet, oderUPDATE, eine Änderung an einem bereits veröffentlichten Beitrag. EinUPDATEträgtchange, das Update, wie es verlangt wurde (dieselben Felder wie der Text des Updates), sodass ein Prüfer die Worte selbst freigibt.requestedBy: wer den Beitrag geschrieben oder die Änderung verlangt hat, eine Anmeldeadresse oder die ID eines API-Schlüssels.needed: wie viele Freigaben es braucht,1, oder2, wo der Kanal zwei Freigebende verlangt (Enterprise).firstBynennt, wer die erste von zwei gegeben hat, während sie auf die zweite wartet, und ist sonstnull.
Entscheiden Sie mit POST /v1/approvals/{id}. Der Text nimmt state, das APPROVED oder REJECTED ist und standardmäßig APPROVED, und eine optionale note.
curl http://localhost:4000/v1/approvals/01M2SQPASCPHZ65QRPX9X628GD \
-H "Authorization: Bearer rw_your_key_here" \
-H "Content-Type: application/json" \
-d '{"state":"APPROVED","note":"Figures checked against the agency release."}'
{ "postIds": ["01M2SQPARBQPG1BRENTHBM1W08"], "state": "APPROVED" }
Eine Freigabe, die nicht zu diesem Workspace gehört, ist ein 404, und eine bereits entschiedene ein 409.
Ein UPDATE freizugeben übergibt die Änderung auf den verlangten Wegen, wie es die Person getan hätte, die sie verlangt hat; ihn abzulehnen lässt den Beitrag, wie er hinausging. Wo sich der Beitrag seither so geändert hat, dass die Änderung nicht mehr vorgenommen werden kann, ist das Freigeben ein 409, der sagt warum, und er bleibt wartend.
Bei Enterprise gelten zwei Regeln (dargelegt auf der Seite Compliance). Niemand gibt einen Beitrag oder ein Update frei, das er selbst geschrieben hat: Einen freizugeben, dessen requestedBy Sie sind, ist ein 403. Ein Kanal, der zwei Freigebende verlangt, nimmt zwei verschiedene Personen: Die erste Freigabe antwortet
{ "postIds": [], "state": "PENDING", "approvals": 1, "needed": 2 }
und die Anfrage wartet, mit gesetztem firstBy, auf jemand anderen; dieselbe Person erneut freigeben zu lassen ist ein 403. Das Ablehnen unterliegt keiner der beiden Regeln: Jeder, der freigeben darf, stoppt einen Beitrag, auch sein Autor, in jedem der beiden Schritte. Jede Entscheidung ist ein Eintrag des Compliance-Protokolls.
Ein freigegebener Kanal wird für sich übergeben, sobald er fällig ist: Er wartet nicht auf die anderen Kanäle seines Beitrags, und sie haben nie auf ihn gewartet. Eine Ablehnung ist endgültig: Der Beitrag eines abgelehnten Kanals wird nie übergeben und nie erneut versucht. Das Freigeben braucht approvals:write; es ist absichtlich eine eigene Berechtigung neben posts:write, denn die Person, die einen Beitrag abzeichnet, ist oft nicht die, die ihn bearbeiten darf. Die Verbindung eines KI-Assistenten hält sie nur, wo die verbindende Person das ebenfalls eingeschaltet hat; siehe Die Verbindung eines Assistenten.
Auf einen Kanal einwirken
Jede Aktion nimmt die id eines Kanals, channels[].id bei GET /v1/jobs, und wirkt allein auf den Beitrag dieses Kanals: Die anderen Kanäle des Beitrags bleiben unberührt. Jede antwortet mit dem, was sie getan hat, und einem 409 mit einem Satz, wo der Kanal nicht in einem Zustand ist, der sie annimmt. Eine ID, die keinem Beitrag Ihrer Kanäle gehört, erhält denselben 409 mit einem Satz, der das sagt, außer bei archive, unarchive und reuse, die mit 404 antworten.
Abbrechen
POST /v1/jobs/{id}/cancel stoppt alles, was dem Beitrag eines Kanals noch bevorsteht: einen Render, der nicht fertig ist, eine noch nicht entschiedene Prüfung, eine noch nicht gesendete Übergabe, auch eine, die auf einen neuen Versuch wartet. Die anderen Kanäle des Beitrags gehen ohne ihn weiter. Es kann nicht in die Vergangenheit greifen: Ist der Beitrag einmal übergeben, gibt es nichts mehr abzubrechen.
curl -X POST http://localhost:4000/v1/jobs/01M2SQN50JQFC00PZE93M9E33R/cancel \
-H "Authorization: Bearer rw_your_key_here"
{
"error": {
"type": "https://reelwire.io/errors/conflict",
"code": "conflict",
"message": "There is nothing left to cancel: every post of this job has already finished.",
"requestId": "01M2SR0913DRD5SJWP0TR3JTBD",
"details": []
}
}
Das ist ein 409, und der Status des Kanals ist das, woran Sie es vorher hätten erkennen können. Zwei Momente werden mit der Bitte abgelehnt, es in Kürze erneut zu versuchen: die ein, zwei Sekunden, in denen der Clip vom Renderer zurückkopiert wird, und der Augenblick, in dem seine Übergabe gesendet wird.
Einen übergebenen Beitrag aktualisieren
POST /v1/jobs/{id}/update ändert den Text des Beitrags eines Kanals, nachdem er übergeben wurde, veröffentlicht oder nicht, und optional das Video. Es übergibt die Änderung auf den Wegen, die der Kanal eingeschaltet hat (nie auf einem, der aus ist), oder auf denen davon, die in ways genannt sind. Seine E-Mail geht als „This post changed“ mit einem Beitragspaket, das den neuen Text und, wo ersetzt, das neue Video zeigt, und der Webhook erhält ein signiertes post.update: Wer ihn veröffentlicht hat, ändert ihn dort, wo er ist. Über den Plattform-Connector ändert Reelwire den Text des Beitrags, den der Connector selbst veröffentlicht hat, wo die Plattform einer App das erlaubt; ein Video ersetzt es dort nie, um das Video auf einer solchen Plattform zu ändern, senden Sie also eine Löschanfrage und veröffentlichen Sie ihn erneut. Der Beitrag übernimmt den neuen Text, sobald die Änderung hinausgegangen ist, und liest bis dahin UPDATING. Bei einem Kanal, bei dem jeder Weg ausgeschaltet ist, ist die Änderung sofort die des Beitrags selbst und erreicht trotzdem seine Syndikationsteilnehmer.
curl http://localhost:4000/v1/jobs/01M2SQN50JQFC00PZE93M9E33R/update \
-H "Authorization: Bearer rw_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"description": "The ten-year settled at 2.41 per cent. Corrected: the high is a three-week high, not a three-month one.\n\n#bunds #rates"
}'
{ "ok": true, "queued": 1 }
Der Text:
| Feld | Was es ist | Limit |
|---|---|---|
description | Die ganze Beschreibung, wie sie lauten soll: die eigenen Worte des Beitrags, die Zeile der Marke und die Hashtags in einem Text. | 5000 Zeichen |
caption | Der Beitragstext für sich, wo Sie keine description senden. | 4000 Zeichen |
hashtags | Ein Array von Tags, mit oder ohne #. | 60 Tags, je 60 Zeichen |
title | Wo die Plattform ein eigenes Titelfeld hat. | 400 Zeichen |
disclaimer | Die eigene Zeile der Marke. | 300 Zeichen |
final | true, wenn caption, hashtags und disclaimer bereits alles enthalten, was der Beitrag sagen soll. | |
link | { "url": "...", "label": "..." } oder eine leere URL für keinen Link. Fehlt es, bleibt der Link, den der Beitrag hat. | URL 500 Zeichen, Beschriftung 40 |
mediaFileId | Ein Video aus der Mediathek, das statt des aktuellen veröffentlicht werden soll. Fehlt es, bleibt das Video. Eine Datei, die kein Video ist oder nicht mehr in der Mediathek liegt, ist ein 409. | |
ways | Einige der Wege, die der Kanal eingeschaltet hat: EMAIL, WEBHOOK, CONNECTOR. Fehlt es, sind es alle. Ein Weg, den der Kanal aus hat, ist ein 409, der seinen Schalter nennt; eine leere Liste oder ein anderes Wort ist ein 400. Syndikationsteilnehmer erhalten die Änderung, was auch gewählt wird. | |
captions | Nur bei einem Kanal auf Keine bestimmte Plattform: { "tiny": "...", "short": "...", "medium": "...", "long": "..." }, ein Text je Art von Plattform. Der mittlere ist auch die eigene Beschreibung des Beitrags. | 200, 500, 1500 und 4000 Zeichen |
Text über einem Limit wird abgelehnt, nie gekürzt: Eine auf dem Weg hinaus gekürzte Beschreibung ist eine, die niemand geschrieben hat. Die Ablehnung ist ein 409 mit einem Satz, der das Limit nennt.
description ist der Beitrag, wie er lauten wird, und es wird nichts von der Marke hinzugefügt. Mit caption stattdessen werden die Beschreibung und die Hashtags der Marke so hinzugefügt, wie sie waren, als der Beitrag zuerst hinausging, sofern Sie nicht final: true senden: Dann sind die Felder der Beitrag, wie er lauten wird, und wenn Sie hashtags ohne ein Hashtag senden, das jemand entfernt hat, bleibt es entfernt.
Eine Änderung, die schon unterwegs ist, ist ein 409, bis sie hinausgegangen ist. Ebenso ein Beitrag, der nie übergeben wurde: Es gibt dort noch nichts zu ändern.
Bei einem Kanal, der eine Freigabe verlangt, wartet die Änderung auf einen Prüfer. Sie wird wie oben geprüft, dann auf einer eigenen Freigabeanfrage aufbewahrt, und noch nichts wird übergeben:
{ "ok": true, "queued": 0, "awaitingApproval": true, "approvalId": "01M3B6A2K9W4N8D1F5H7J3Q0RT" }
Die Anfrage steht bei GET /v1/approvals mit kind UPDATE, und die approval des Kanals bei GET /v1/jobs liest kind update. Einmal freigegeben, wird die Änderung auf den hier genannten Wegen übergeben; abgelehnt, bleibt der Beitrag, wie er hinausging. Siehe Freigaben. Ein Update wartet jeweils: Ein weiteres zu verlangen, während eines wartet, ist ein 409. Ein Löschen wird nie angehalten.
Wiederverwenden
GET /v1/jobs/{id}/reuse antwortet mit dem, woraus ein Beitrag gemacht wurde, um ihn mit einer Änderung erneut zu erstellen. Es liest und ändert nichts:
{
"reuse": {
"kind": "post",
"templateId": "tpl_dd7e6b264fb8",
"templateName": "Big number",
"variant": "Corporate glass",
"version": "1.0.0",
"pinnedVersion": null,
"brandId": "01M38Z6Y4T0WTFVAX5XET1S17P",
"ratio": "9x16",
"locale": "en",
"data": { "clipData": { "label": "Points the DAX gained this week", "value": 412 }, "locales": { "de": { "clipData": { "label": "Punkte, die der DAX diese Woche zulegte" } } } },
"title": "Copy of Weekly market wrap",
"queueId": "01M38Z6Y8H5G7M4Q2X8V1R0C9D"
}
}
data ist der Inhalt in der eigenen Form der Vorlage, Bilder als media://-Referenzen und locales für jede weitere Sprache. Ein Beitrag aus einer Beitragsliste antwortet mit dem Inhalt, wie er getippt wurde, seiner pinnedVersion (null ist Latest) und der queueId seiner Liste; ein Beitrag aus einem Feed oder Stream antwortet mit dem Inhalt, wie er gerendert wurde, und den Sprachen, die das Ereignis trug, und seine queueId ist null. Um ihn erneut zu veröffentlichen, senden Sie templateId, variant als templateVariant, pinnedVersion als templateVersion und data an POST /v1/queues/{id}/packages; um nur das Video zu rendern, senden Sie templateId, variant, version, data, brandId, ratio und locale unverändert an POST /v1/direct-export/video. Für einen KI-Assistenten ist es reelwire_reuse, das einen gerenderten Clip oder einen direkten Export auf dieselbe Weise liest.
Erneut veröffentlichen
POST /v1/jobs/{id}/repost übergibt den Beitrag eines Kanals jetzt erneut, als neuen eigenen Beitrag mit demselben Video und demselben Text, wie der Beitrag jetzt lautet. Nichts wird erneut gerendert, und das Original bleibt, wie es ist. Der neue Beitrag geht auf jedem Weg, den der Kanal eingeschaltet hat, den Plattform-Connector eingeschlossen, und die Freigabe des Originals durch einen Prüfer überträgt sich. Die postGroupId der Antwort ist die id des Kanals des neuen Beitrags.
Nur ein Kanal mit eingeschaltetem Webhook kann erneut veröffentlicht werden. Ein Kanal ohne ihn wird stattdessen mit seinem eigenen erneuten Senden noch einmal gesendet (siehe Einen Beitrag erneut senden), und das erneute Veröffentlichen ist dort ein 409, der das sagt. Der Kanal muss aktiv sein: Ein pausierter oder entfernter Kanal ist ebenfalls ein 409, der das sagt.
Löschen
POST /v1/jobs/{id}/delete bittet darum, den Beitrag eines Kanals zu entfernen. Es übergibt die Anfrage auf den Wegen, die der Kanal eingeschaltet hat. Seine E-Mail geht als „Please take this post down“, nennt, wo er veröffentlicht wurde, sofern jemand es sagte, und der Webhook erhält ein signiertes post.delete: Wer ihn veröffentlicht hat, nimmt ihn herunter. Über den Plattform-Connector nimmt Reelwire den Beitrag herunter, den der Connector selbst veröffentlicht hat, wo die Plattform einer App das erlaubt, und meldet ihn als gelöscht; wo die Plattform es nicht erlaubt oder der Connector ihn nie veröffentlicht hat, schlägt dieser Weg mit einem Grund fehl, der sagt, ihn von Hand zu entfernen. Ein Text { "ways": ["WEBHOOK"] } sendet es nur auf einigen dieser Wege, wie ways bei einem Update: EMAIL, WEBHOOK und CONNECTOR, nie einem, den der Kanal aus hat (ein 409); eine leere Liste oder ein anderes Wort ist ein 400. Ohne Text geht es auf jedem Weg, den der Kanal eingeschaltet hat, und Syndikationsteilnehmer, die den Beitrag hatten, erhalten es, was auch gewählt wird.
Der Kanal liest dann DELETE_REQUESTED, bis jemand sagt, dass der Beitrag weg ist: mark-deleted unten, Als gelöscht markieren im Beitragspaket oder auf der Seite Beiträge, der Empfänger, der deleted meldet, oder der Plattform-Connector, der ihn heruntergenommen hat. Dann liest er DELETED. Ein Löschen, das nach allen Versuchen auf keinem Weg durchkam, liest DELETE_FAILED und lässt den Beitrag, wie er war; mark-deleted wird dann weiterhin akzeptiert, für einen Beitrag, den jemand von Hand entfernt hat. Erneut zu fragen, während ein Löschen unterwegs ist, ist ein 409; nachdem es hinausging, sendet erneutes Fragen es noch einmal.
Als veröffentlicht markieren, überspringen und als gelöscht markieren
Was nur eine Person oder ein Empfänger wissen kann, gesagt für einen Kanal:
POST /v1/jobs/{id}/mark-publishedsagt, dass der Beitrag online ist. Der Text ist optional:{ "url": "https://..." }, der Link zum Beitrag, bis zu 2000 Zeichen, der dann auf der Seite Beiträge erscheint und mit jedem späteren Update oder Löschen reist. Akzeptiert von übergeben, übersprungen oder fehlgeschlagen und solange er noch übergeben wird;publishedAtwird zu diesem Moment. Ein Link, der keine Webadresse ist, ist ein 400.POST /v1/jobs/{id}/skipsagt, dass er übergeben wurde und nicht veröffentlicht wird. Akzeptiert von übergeben. Ein übersprungener Beitrag kann später immer noch als veröffentlicht markiert werden.POST /v1/jobs/{id}/mark-deletedsagt, dass er heruntergenommen wurde, meist nachdem ein Löschen übergeben wurde. Akzeptiert von übergeben oder veröffentlicht.
Diese drei sind dieselbe Meldung, die ein Webhook-Empfänger mit POST /v1/posts/{id}/report macht, unter denselben Regeln. Für einen KI-Assistenten sind sie reelwire_report_post, mit dem Status published, skipped oder deleted. Jede Aktion antwortet:
| Aktion | Bei Erfolg |
|---|---|
cancel | { "ok": true, "cancelledPosts": 1, "renderStopped": true } |
repost | { "ok": true, "postGroupId": "01M..." } (der Kanal des neuen Beitrags) |
update | { "ok": true, "queued": 1 } |
delete | { "ok": true, "queued": 1 } |
resend-email | { "ok": true, "count": 1 } |
resend-webhook | { "ok": true, "count": 1 } |
resend-connector | { "ok": true, "count": 1 } |
resend-participants | { "ok": true, "count": 1 } |
retry | { "ok": true, "count": 1 } |
mark-published | { "ok": true, "count": 1, "state": "PUBLISHED" } |
skip | { "ok": true, "count": 1, "state": "SKIPPED" } |
mark-deleted | { "ok": true, "count": 1, "state": "RECALLED" } |
RECALLED ist der gespeicherte Zustand, den der Status des Kanals als DELETED liest.
Archivieren und wiederherstellen
POST /v1/jobs/{id}/archive legt den Beitrag eines Kanals ab: GET /v1/jobs lässt ihn weg, sofern nicht archive=archived verlangt wird, und die Zeile trägt dann "archived": true (bei der Zeile eines Beitrags, wo es jeder seiner Kanäle ist). POST /v1/jobs/{id}/unarchive holt ihn zurück. Keines von beiden ändert sonst etwas: Ein Beitrag, der noch unterwegs ist, läuft weiter und wird übergeben, wie er es sonst worden wäre. Beide antworten mit { "ok": true, "archived": true } oder false und mit einem 404 bei einer ID, die keinem Beitrag Ihrer Kanäle gehört. Für einen KI-Assistenten sind sie reelwire_archive_post, das einen mit archived false zurückholt, und reelwire_list_posts nimmt archive.
Zurückmelden
POST /v1/posts/{id}/report ist der Weg, auf dem ein Webhook-Empfänger, ein Skript oder jeder, der von Hand veröffentlicht, mit einem API-Schlüssel mit posts:write sagt, was mit dem Beitrag eines Kanals geschah:
{ "status": "published", "url": "https://www.instagram.com/reel/C9x2Lm4oQpR/", "platformPostId": "17912345678901234" }
status ist published, skipped, failed (mit einem reason, den die Seite Beiträge zeigt) oder deleted. url ist eine Webadresse von bis zu 2000 Zeichen, platformPostId bis zu 200 und reason bis zu 1000; ein Text, der nicht passt, ist ein 400. Die ID ist der Beitrag des Kanals (postId) oder die id des Kanals aus GET /v1/jobs, und eine, die nicht Ihnen gehört, ist ein 404. Es antwortet mit ok, postId, postGroupId, state und permalink. Dasselbe erneut zu sagen ist in Ordnung und behält den neuesten Link; alles, was der Zustand des Beitrags nicht erlaubt, ist ein 409, der den Zustand nennt. Die ganze Regel, Zustand für Zustand, steht unter Webhooks.
Per E-Mail übergebene Beiträge
Ein Kanal mit eingeschalteter E-Mail übergibt seine Beiträge per E-Mail. Ist ein Beitrag fällig, erhalten der Inhaber des Workspaces und alle mit Betrieb eine E-Mail zur Übergabe, egal wie viele Kanäle darin sind. Ihr Betreff ist „Ready to post:“ und die Namen der Kanäle. Die E-Mail selbst trägt weder das Video noch den Text: Sie sagt, welcher Beitrag für welche Kanäle bereit ist, nennt die Kanäle des Beitrags, die nicht darin sind, und warum, und ihr Button Open the post kit führt zum Beitragspaket. Die E-Mail und das Beitragspaket in vollem Umfang finden Sie unter Ein Video von Hand veröffentlichen.
Das Beitragspaket ist eine Seite unter /v1/kit/{token}, die keine Anmeldung braucht: Das Token in ihrer Adresse ist die Zugangsberechtigung. Für jeden Kanal enthält sie das Video zum Abspielen, Herunterladen oder Teilen von einem Smartphone, sein Titelbild, jeden Text zum Kopieren (den Titel, wo es einen gibt, und den Text, wie er hinausgeht, oder, bei einem Kanal auf Keine bestimmte Plattform, die Beschreibung in jeder ihrer vier Längen, eine je Art von Plattform), die Veröffentlichungseinstellungen des Kanals und Als veröffentlicht markieren, mit dem Link, oder Überspringen (bei der E-Mail eines Löschens stattdessen Als gelöscht markieren); darüber ein Prompt für einen KI-Assistenten, der jeden noch zu veröffentlichenden Kanal abdeckt. Es zeigt den Beitrag, wie er jetzt lautet, sodass ein früheres Paket einem Update folgt. Seine Buttons melden über POST /v1/kit/{token}/{postGroupId}/published, /skip und /deleted zurück, unter denselben Regeln wie Zurückmelden. Als gelöscht markieren gibt es nur im Paket eines Löschens und Als veröffentlicht markieren und Überspringen in jedem anderen Paket: Das falsche ist ein 409. Ein Link funktioniert vierzehn Tage ab der E-Mail, die ihn trug, und jede E-Mail trägt ihren eigenen; danach sagt die Seite, dass er abgelaufen ist (ein 410), und der Beitrag steht weiterhin auf der Seite Beiträge. Mit Accept: application/json angefragt, antwortet dieselbe Adresse mit den Fakten des Pakets als JSON, mit expiresAt, und ein abgelaufener Link antwortet dann mit 403 statt mit der Seite. Jede Adresse darf höchstens 60-mal pro Minute anfragen.
Niemand hier kann wissen, ob oder wo er online ging, daher liest der Beitrag des Kanals HANDED_OVER, bis jemand es sagt. Einen Tag nach der E-Mail, wenn ein Kanal davon noch übergeben ist und niemand etwas gesagt hat, erhalten dieselben Personen eine kurze Erinnerung, „Still to post:“, mit einem eigenen Link zum Beitragspaket.
Auch ein Update und ein Löschen gehen per E-Mail, wo E-Mail eingeschaltet ist: ein Update mit dem Betreff „Changed:“ und der Überschrift „This post changed“, ein Löschen mit „Take down:“ und „Please take this post down“, jeweils mit seinem Beitragspaket.
Einen Beitrag erneut senden
Jeder Weg nach draußen hat sein eigenes erneutes Senden, und die Syndikation ein eigenes, für den Beitrag eines Kanals, der übergeben, veröffentlicht oder übersprungen wurde:
POST /v1/jobs/{id}/resend-emailsendet die E-Mail erneut, mit dem Beitrag, wie er jetzt lautet, unter dem Betreff „Sent again:“. Akzeptiert, solangeresendabletrue ist und der Kanal E-Mail eingeschaltet hat (aus ist aus: sonst ein 409); ebenfalls ein 409, solange ein Update, ein Löschen oder eine frühere erneut gesendete E-Mail noch unterwegs ist. Für einen KI-Assistenten ist esreelwire_resend_postmit dem Wegemail.POST /v1/jobs/{id}/resend-webhooksendet daspost.publishdes Beitrags erneut an die Webhook-Adresse des Workspaces, aufgebaut, wie er jetzt lautet, mit einer neuendeliveryId, sodass ein Empfänger, der die IDs behält, die er verarbeitet hat, erneut danach handelt. Akzeptiert, solangeresendabletrue ist und der Kanal Webhook eingeschaltet hat; ein 409, wenn er aus ist, wenn der Workspace keine Webhook-Adresse hat oder solange ein Webhook-Aufruf für den Beitrag noch unterwegs ist. Der Zustand des Beitrags ändert sich nicht. Für einen KI-Assistenten ist esreelwire_resend_postmit dem Wegwebhook.POST /v1/jobs/{id}/resend-connectorveröffentlicht ihn erneut: Der Plattform-Connector des Kanals veröffentlicht das Video und seinen Text, wie der Beitrag jetzt lautet, erneut auf der Plattform als neuen Beitrag. Der frühere Beitrag bleibt, wo er ist. Sobald der neue online ist, wird der Beitrag mit seinem Link als veröffentlicht gemeldet, und ein späteres Update oder Löschen wirkt auf ihn. Akzeptiert, solangeresendabletrue ist und der Kanal Plattform-Connector eingeschaltet hat; ein 409, wenn er aus ist oder solange der Connector noch an dem Beitrag arbeitet. Für einen KI-Assistenten ist esreelwire_resend_postmit dem Wegconnector.POST /v1/jobs/{id}/resend-participantssendet den Beitrag erneut, wie er jetzt lautet, an jeden Syndikations-Teilnehmer, dessen Gruppe den Kanal übernimmt, auf den Wegen, die jede Gruppe erlaubt. Gedacht für einen Kanal mit ausgeschalteten E-Mail, Webhook und Plattform-Connector, dessen einzige Leser seine Teilnehmer sind (eine Kanalzeile sagtsyndicated, wenn eine Gruppe mit einem angemeldeten Teilnehmer ihn übernimmt); ein 409, wo keine es tut. Der Zustand des Beitrags ändert sich nicht. Für einen KI-Assistenten ist esreelwire_resend_postmit dem Wegparticipants.
Ein Kanal, bei dem jeder Weg ausgeschaltet ist, übergibt seinen Beitrag in dem Moment, in dem er fällig ist: Er ist HANDED_OVER ohne E-Mail, ohne Webhook-Aufruf und ohne Connector-Beitrag des Workspaces selbst (email, webhook und connector lesen off). Ein Update dafür ist sofort die Sache des Beitrags selbst, und ein Löschen liest DELETE_REQUESTED, sobald es verlangt wird, da nichts vom Workspace selbst je zugestellt wird, um eines von beidem wahr zu machen; beide erreichen trotzdem seine Teilnehmer.
Erneutes Veröffentlichen bei einem Kanal ohne eingeschalteten Webhook ist ein 409: Das erneute Senden der E-Mail sendet dasselbe an dieselben Personen, und resend-connector veröffentlicht ihn erneut auf der Plattform.
Einen fehlgeschlagenen Beitrag erneut versuchen
POST /v1/jobs/{id}/retry versucht den Beitrag eines Kanals, der fehlschlug (POST_FAILED: Seine E-Mail, sein Webhook-Aufruf oder sein Plattform-Connector kam nach allen Versuchen nie durch, oder sein Empfänger meldete ihn als failed), erneut. Seine Veröffentlichungsanfrage wird neu übergeben, wie der Beitrag jetzt lautet, als eigene Übergabe: Die E-Mail liest „Ready to post:“, der Webhook-Aufruf ist ein post.publish mit einer neuen deliveryId, und der Plattform-Connector veröffentlicht ihn. Der Beitrag wechselt von FAILED zurück zur Übergabe, dann weiter, wie bei einer ersten Übergabe, zu HANDED_OVER oder PUBLISHED, wo der Connector ihn veröffentlicht hat; schlägt jeder Weg erneut fehl, ist er wieder FAILED mit dem neuesten Grund. Der Text ist optional: { "ways": ["EMAIL", "WEBHOOK", "CONNECTOR"] }, einige der Wege, die der Kanal eingeschaltet hat, bei Weglassen jeder von ihnen; ein Weg, den er aus hat, ist ein 409. Syndikationsteilnehmer erhalten ihn nicht erneut, da die erste Übergabe sie erreichte. Akzeptiert, solange retryable true ist; sonst ein 409, wenn der Kanal jeden Weg aus hat, wenn Webhook gewählt ist und der Workspace keine Webhook-Adresse hat oder solange der Beitrag schon erneut versucht wird. Auf der Seite Beiträge ist es Beitragsanfrage erneut senden bei einem fehlgeschlagenen Beitrag. Für einen KI-Assistenten ist es reelwire_retry_post.
Einen fehlgeschlagenen Clip erneut rendern
POST /v1/jobs/{id}/retry-render rendert den Clip eines Kanals erneut, nachdem sein Rendern fehlgeschlagen ist (RENDER_FAILED: Der Renderer meldete einen Fehler, oder das Rendern wurde nicht rechtzeitig fertig). Er nimmt keinen Body. Derselbe Render-Auftrag stellt sich mit einem um eins höheren attempt wieder an und wird aus Inhalt, Marke und Vorlage des Beitrags in ihrem jetzigen Stand gerendert, sodass eine inzwischen korrigierte Vorlage oder Marke wirkt. Sobald der Clip gespeichert ist, wird der Beitrag daraus erstellt und geht weiter wie beim ersten Mal: AWAITING_APPROVAL, wo der Kanal eine Freigabe verlangt, sonst SCHEDULED, dann wird er übergeben, wenn er fällig ist, als eigene Übergabe, falls die anderen Kanäle des Beitrags ohne ihn übergeben wurden. Die Antwort ist { "ok": true, "renderJobId": "...", "attempt": 2, "counted": false }. Er kostet kein Video, da der fehlgeschlagene Versuch bereits angerechnet wurde, außer wo dieser Versuch abgelehnt wurde, weil keine Videos mehr übrig waren (counted ist dann true, und solange weiterhin keines übrig ist, ist es eine 409). Angenommen, solange renderRetryable beim Kanal true ist; sonst eine 409, ebenso wenn der Kanal pausiert ist (setzen Sie ihn zuerst fort) oder während das Rendern bereits wiederholt wird; eine 404 für einen Beitrag, den es nicht gibt. Auf dem Bildschirm „Beiträge“ ist es „Rendern wiederholen“ unter „Mehr“. Für einen KI-Assistenten ist es reelwire_retry_post mit render true.
Der Veröffentlichungskalender
GET /v1/calendar zeigt, was in einem Zeitfenster voraussichtlich veröffentlicht wird: die Kanäle, ihre geplanten Feeds und die wartenden manuellen Beiträge. from und to sind erforderliche ISO-Zeitpunkte, das Zeitfenster beträgt höchstens 367 Tage (ein Jahr im Voraus ab jetzt passt), und alle Zeiten sind UTC. Es braucht schedule:read, eine eigene Berechtigung, sodass ein Schlüssel, der den Kalender liest, nicht auch auf Beiträge einwirken kann.
curl "http://localhost:4000/v1/calendar?from=2026-09-18T00:00:00Z&to=2026-09-19T00:00:00Z" \
-H "Authorization: Bearer rw_your_key_here"
Übergeben Sie channelIds als kommagetrennte Liste, um einzuschränken. Leer bedeutet jeder Kanal. kind behält nur die fertigen Feeds (BROADCAST) oder nur die Beitragslisten (QUEUE); all ist der Standard. Ein Zeitfenster von mehr als 367 Tagen, to vor from, eines von beiden fehlend oder kein Datum oder ein anderes kind ist ein 400.
Die Antwort ist ein Plan, kein Versprechen: Ein Feed veröffentlicht, wenn seine Daten eintreffen, und dies sind die Momente, zu denen er erwartet wird. channels beschreibt jeden Kanal einmal (Marke, Plattform, Bildformat, Sprache, Freigabe). entries ist eine Zeile je erwartetem Beitrag, jeweils mit seiner channelId, der source und ihrer group, dem Moment at, allDay, wo der Plan eines Feeds einen Tag, aber keine Zeit nennt, und einem scheduleLabel; die Beiträge einer Beitragsliste sind Einträge zu ihren genauen Zeiten, ihre Beschriftung sagt, ob jeder geplant, gesendet oder fehlgeschlagen ist. unscheduled enthält, was ein Kanal empfängt, aber keinen Zeitpunkt für den Kalender hat: ein Feed, der beschrieben statt zeitlich festgelegt ist, oder ein eigener Feed, der veröffentlicht, wann immer Ihr System an ihn sendet. Pausierte Kanäle und pausierte Quellen veröffentlichen nichts und fehlen daher.
Jeder Eintrag sagt außerdem, womit er gerendert wird: templateId, variant und version (null für den neuesten Build), feedId bei dem eines fertigen Feeds und packageId und state bei dem einer Beitragsliste. detail=posts fügt jedem Eintrag templateName hinzu und, bei dem einer Beitragsliste, post: was der Beitrag sagt, wie es die Liste des Zeitplans zeigt.
{
"kind": "QUEUE",
"at": "2026-10-26T15:00:00.000Z",
"templateName": "Text card",
"variant": "Bento grid",
"post": {
"title": "Real ticks and real spreads for MetaTrader 5",
"kicker": "MT5 Tick Data",
"lines": [
{ "label": null, "text": "Real ticks. Real spreads. Real results.", "extras": [{ "label": "Words to mark", "text": "Real spreads." }] },
{ "label": "Attribution", "text": "FEA Trading" }
],
"caption": "Tick history for the MetaTrader 5 Strategy Tester, updated every month.",
"hashtags": ["metatrader5"]
}
}
lines folgen der eigenen Reihenfolge der Vorlage und tragen ihre Beschriftungen; das Aussehen, Bilder und Videos fehlen. caption und hashtags sind das, was der Kanal neben dem Clip veröffentlicht, die Beschreibung in der Länge, die seine Plattform nimmt.
Eine Vorschau eines Beitrags
GET /v1/calendar/still?channelId=...&subscriptionId=...&packageId=... antwortet mit einem PNG: der Beitrag einer Beitragsliste, gerendert mit seinen eigenen Worten in Marke, Bildformat und Sprache seines Kanals, ein Einzelbild aus dem letzten Drittel des Clips. Ohne packageId rendert es für einen eigenen Feed stattdessen den Beispielinhalt der Vorlage, da noch nicht bekannt ist, was Ihr System senden wird. Es zählt nicht gegen Ihre Videos und wird nirgends aufbewahrt; ein unveränderter Beitrag antwortet mit 304 auf das ETag, das Sie schon halten. Ein fertiger Feed wird mit seinen eigenen Clips in der Vorschau gezeigt, GET /v1/feeds/{feedId}/reference/{ratio}.
Der Zeitplan als Seite zum Herunterladen
GET /v1/calendar/export nimmt dieselben from, to, channelIds und kind und antwortet mit einer HTML-Seite mit einer Tabelle jedes Beitrags im Zeitfenster (was jeder Beitrag einer Beitragsliste sagt, die Regel jedes Feeds) und darunter den Quellen ohne genauen Zeitplan, in der Sprache dessen, der fragt, als Anhang. Sie öffnet sich in jedem Browser und lässt sich drucken; nichts darin wird von irgendwoher abgerufen. Mit format=pdf antwortet es stattdessen dasselbe als PDF im Querformat A4 (format=html, der Standard, ist die Seite).
curl -OJ "http://localhost:4000/v1/calendar/export?from=2026-10-24T00:00:00Z&to=2026-11-23T23:59:59Z" \
-H "Authorization: Bearer rw_your_key_here"
curl -OJ "http://localhost:4000/v1/calendar/export?from=2026-10-24T00:00:00Z&to=2026-11-23T23:59:59Z&format=pdf" \
-H "Authorization: Bearer rw_your_key_here"
GET /v1/calendar/export/link antwortet stattdessen mit { url, expiresAt, from, to }: einem Link zu derselben Seite, oder mit format=pdf zum PDF, der fünfzehn Minuten ohne Zugangsberechtigung funktioniert, um ihn einer Person zu geben, was reelwire_calendar des KI-Assistenten mit download tut (und format pdf für das PDF). Das Zeitfenster, die Kanäle, die Art, die Sprache und das Format sind in ihn signiert, sodass ein bearbeiteter Link abgelehnt wird.
Mit Einzelbildern jedes Beitrags
Drei Einzelbilder jedes Beitrags, von seinem Anfang, seiner Mitte und seinem Keyframe, gerendert in der Marke seines Kanals, brauchen je einige Sekunden, daher wird diese Datei als Auftrag erstellt. POST /v1/calendar/export/jobs nimmt from, to, channelIds (eine Liste), kind, format und stills: true und antwortet mit 202 { jobId }. GET /v1/calendar/export/jobs/{jobId} antwortet mit { jobId, state, done, total, ahead, error, format, stills, from, to, kind, channels, askedAt, keptUntil, fileName }, wobei state queued (mit ahead Aufträgen davor), working, done oder failed ist und done von total die bisher gerenderten Einzelbilder; sobald es done ist, ist GET /v1/calendar/export/jobs/{jobId}/file die Datei. Die Aufträge eines Workspaces sind eine Warteschlange, nacheinander erstellt, höchstens fünf wartend oder in Arbeit auf einmal (ein sechster ist ein 409). GET /v1/calendar/export/jobs listet Ihre in der Reihenfolge, in der Sie sie angefordert haben, als { jobs: [...] }, und POST /v1/calendar/export/jobs/{jobId}/cancel bricht einen ab, der wartet oder gerade erstellt wird, oder nimmt einen fertigen aus der Liste. Jede dieser Routen antwortet nur für die Aufträge, die derselbe Schlüssel oder dieselbe Person angefordert hat. Einzelbilder werden für die ersten 100 Beiträge gerendert. Ein fertiger Auftrag wird eine Stunde ab seinem Abschluss aufbewahrt, bis keptUntil, dann vergessen; einer, der wartet oder gerade erstellt wird, wird aufbewahrt, bis er fertig ist. Aufträge werden im Speicher gehalten, ein Neustart der API, auch ein Update, vergisst sie also. GET /v1/calendar/export/link?jobId={jobId} antwortet mit einem Link zur Datei eines fertigen Auftrags, { url, expiresAt, from, to, fileName }, der fünfzehn Minuten ohne Zugangsberechtigung funktioniert, solange der Auftrag aufbewahrt wird; ein Auftrag, der noch erstellt wird, ist ein 409. Für einen KI-Assistenten ist es reelwire_calendar mit download und stills, dann exportJobId, um zu fragen, wie weit es ist, und die Datei zu übergeben.
curl -X POST http://localhost:4000/v1/calendar/export/jobs \
-H "Authorization: Bearer rw_your_key_here" -H "Content-Type: application/json" \
-d '{"from":"2026-10-24T00:00:00Z","to":"2026-11-23T23:59:59Z","format":"pdf","stills":true}'
Einen Beitrag herunterladen
GET /v1/jobs/{id}/download und GET /v1/posts/{id}/package liefern beide ein ZIP, kein JSON:
HTTP/1.1 200 OK
content-type: application/zip
content-disposition: attachment; filename="2026-09-18--07-46-28 - Brand 1 - Channel 10 en - Instagram Reels - 9x16.zip"
content-length: 741635
x-request-id: 01M2SR0G3PCP3E63SZ6DZBZBJ0
Sie sind für verschiedene Leser:
/v1/jobs/{id}/downloadist für eine Person und nimmt dieideines Kanals. Es enthält das Video und eine HTML-Seite, die den Beitrag zeigt wie sein Beitragspaket: Marke, Format, Status und Zeiten, den Clip und jeden Text zum Einfügen unter seiner eigenen Beschriftung mit einem Button Kopieren. Ein Kanal auf Keine bestimmte Plattform erhält den Text für jede Art von Plattform. Die Seite funktioniert offline und lässt sich so weiterleiten, wie sie ist. Wo es kein Video gibt, weil der Render noch läuft, fehlschlug oder der Clip entfernt wurde, um Speicher freizugeben, sagt die Seite dort, wo der Clip wäre, warum./v1/posts/{id}/packageist für eine Maschine und nimmt die Beitrags-ID eines Kanals. Es enthält das Video, eine kleine Seite, die es abspielt, und ein JSON des Beitrags:meta(erstellt, Status, Marke, Kanal, Plattform, Freigabe, veröffentlicht) unddescription(Sprache, Seitenverhältnis, Titel, Beschreibung, Markenbeschreibung, Link, Hashtags undtext, alles zusammen, wie es veröffentlicht wird). Ein Beitrag, dessen Clip nicht mehr gespeichert ist, ist ein 404, weil es nichts zu verpacken gibt.
Übergeben Sie ?tz=Europe/Berlin, um die Zeiten in den Dateinamen und in den Dateien in Ihrer eigenen Zone zu erhalten. Das Video ist das, das der Beitrag jetzt zeigt: ein Ersatz aus der Mediathek, wo ein Update einen einsetzte, sonst der gerenderte Clip.
Häufige Fehler
/v1/jobs in einer engen Schleife abfragen. Verwenden Sie /v1/pipeline und halten Sie pollMs ein, oder nehmen Sie den Webhook und hören Sie auf abzufragen.
Eine Asset-URL speichern. Sie sind signiert und laufen innerhalb der Stunde ab. Behalten Sie die assetId und fragen Sie erneut.
Annehmen, ein Beitrag sei ein Kanal. Ein Beitrag geht an jeden Kanal, der seine Quelle empfängt, und seine Kanäle können in verschiedenen Zuständen sein: einer veröffentlicht, einer wartet auf einen Prüfer.
Auf die ID des Beitrags einwirken. Die Aktionen nehmen die id eines Kanals aus channels, nie die id der Zeile, die der postKey des Beitrags ist.
Eine Aktion aufrufen und den 409 als Fehlerpfad behandeln. updatable, resendable, retryable, markable, skippable, deletable, markDeletable und repostable beim Kanal sagen es vorher.
HANDED_OVER als veröffentlicht lesen. Es bedeutet, dass ein Weg nach draußen ihn einer Person oder einem Empfänger zugestellt hat. PUBLISHED kommt, wenn jemand es sagt oder wenn der Plattform-Connector des Kanals ihn veröffentlicht hat.
Erwarten, dass /v1/posts/{id}/package JSON liefert. Es ist ein ZIP mit einem JSON darin.
stage als Status behandeln. Es ist eine Gruppe von Status. Filtern Sie nach stage, lesen Sie status.