Server-API-Referenz
SosoAPI-Veröffentlichungs-API: Authentifizierung, Anfragen und Ergebnisse
Baue eine serverseitige Veröffentlichungsintegration mit einem Scheduled Post je Ziel. Diese Referenz beschreibt den am 20 Oktober 2026 geprüften Veröffentlichungsvertrag. Beispiele enthalten Platzhalter und werden auf dieser Seite nicht ausgeführt.
Als Markdown lesenVom SosoAPI-Team geprüft ·
1. Serverseitig authentifizieren
Erstelle einen API-Schlüssel unter SosoAPI-App → Einstellungen → Agents & API Access. Speichere ihn serverseitig als SOSOAPI_API_KEY. Anfragen nutzen Authorization: Bearer <your-key> und Content-Type: application/json. Bette den Schlüssel niemals in Website, mobiles App-Bundle, URL oder öffentliches Repository ein.
Alle folgenden Endpunkte nutzen POST mit JSON-Inhalt. Schlüssel und delegierte Agentenberechtigungen sind durch Funktionen, erlaubte Workspaces und aktuelle Eigentümermitgliedschaft begrenzt. Lesen benötigt agent:operate und mindestens viewer-Zugriff; Veröffentlichungsänderungen benötigen agent:publish und mindestens editor. Eine Autorisierung kann Eigentümerrechte nicht erweitern.
Nutze den aktuellen Workspace und die verbundenen Konten der App oder rufe /identity-api/workspace/list und /identity-api/user/social-accounts/list auf, um autorisierte IDs zu finden. Rate niemals die Workspace- oder Konto-ID eines Kunden.
// Node.js 20+; run only on your server.
const apiKey = process.env.SOSOAPI_API_KEY;
if (!apiKey) throw new Error("Set SOSOAPI_API_KEY on your server");
const apiBase = "https://gqeshlawtcexsapabaui.supabase.co/functions/v1";
async function sosoPost(path, body) {
const response = await fetch(apiBase + path, {
method: "POST",
headers: {
Authorization: "Bearer " + apiKey,
"Content-Type": "application/json"
},
body: JSON.stringify(body)
});
const result = await response.json();
if (!response.ok) {
const requestId = result.request_id ?? response.headers.get("x-request-id");
// Handler errors use code/message; schema-validation 400s instead use
// success:false and error:{name:"ZodError",message:...}.
// Preserve status, available code and requestId in server diagnostics.
// Never log the key or an Authorization header.
throw new Error("SosoAPI " + response.status + " (" +
(requestId ?? "no request id") + ")");
}
return result;
}2. Veröffentlichungsendpunkte
Diese Pfade beziehen sich auf die API-Basis des Server-Helpers. Rufe Scheduled-Post-Details für aktuelle Version, verfügbare Aktionen und Veröffentlichungsergebnis ab.
| Pfad | Anfrage | Antwort und Grenze |
|---|---|---|
| /studio-api/scheduled-posts/list | workspace_id; optional project_id, status, Zeitpaar, limit, cursor. | posts, next_cursor, returned_count. Workspace-bezogener Lesezugriff. |
| /studio-api/scheduled-posts/get | id. | post, delivery, actions, attempts, outcomes. Lies hier die aktuelle Version. |
| /studio-api/scheduled-posts/eligibility | workspace_id, targets; optional include_quota. | Ziele und optionales Kontingent. Reine Lesevorprüfung, keine Reservierung. |
| /studio-api/scheduled-posts/create | workspace_id, genaues Konto, provider_payload, Inhalt, scheduled_at, idempotency_key. | post und deduped. 201 für einen neuen Zeitplan; 200 für passende Wiederholung. |
| /studio-api/scheduled-posts/bulk-create | workspace_id und 1–50 targets, jedes mit eigenem idempotency_key. | batch_id, successes, failures. 201, wenn mindestens ein Ziel gelingt; 422, wenn keines gelingt. Prüfe beide Arrays. |
| /studio-api/scheduled-posts/update | id, expected_version, patch; optional passendes provider_payload. | post. Eine veraltete Version wird abgelehnt; das Ziel ist unveränderlich. |
| /studio-api/scheduled-posts/publish-now | id und expected_version. | post. Fordert sofortige Ausführung an; belegt keine Veröffentlichung. |
| /studio-api/scheduled-posts/retry | id, expected_version; optional zukünftiges scheduled_at. | post. Nachweisgestützte Wiederherstellung nur bei Fehlern; niemals blind erneut senden. |
| /studio-api/scheduled-posts/cancel | id und expected_version. | post. Bricht unveröffentlichte Arbeit ab; externer Abbruch kann ausstehend bleiben. |
| /studio-api/scheduled-posts/delete | id und expected_version. | post. Maschinenaufrufer dürfen bereits veröffentlichte Anbieterinhalte nicht löschen. |
| /studio-api/scheduled-posts/withdraw-delete | id und expected_version. | post. Zieht eine gestoppte Instagram-Login-Löschanfrage zurück, die nur der Verifikation dient; behält Anbieterinhalte. |
3. Auflisten und paginieren, ohne den Umfang zu verlieren
limit ist standardmäßig 50 und erlaubt 1–200. Der optionale status ist scheduled, publishing, published, failed, expired, needs_reschedule, cancelled oder deleted. scheduled_from und scheduled_to müssen gemeinsam als ISO-8601-Zeitpunkte mit Offsets angegeben werden; das Ende muss nach dem Anfang liegen.
next_cursor ist null oder ein Objekt mit scheduled_at und id. Sende das gesamte Objekt als cursor mit demselben Workspace und denselben Filtern zurück. Dieser Endpunkt akzeptiert keine Filter page, offset, platform oder social_account_id.
await sosoPost("/studio-api/scheduled-posts/list", {
"workspace_id": "<workspace-uuid>",
"limit": 50
});const first = await sosoPost("/studio-api/scheduled-posts/list", {
workspace_id: "<workspace-uuid>", limit: 50
});
if (first.next_cursor) {
const next = await sosoPost("/studio-api/scheduled-posts/list", {
workspace_id: "<workspace-uuid>", limit: 50, cursor: first.next_cursor
});
// Consume next.posts; continue only while next_cursor is not null.
}4. Einen geprüften Beitrag validieren und erstellen
Ersetze jeden Platzhalter durch Werte aus deinem autorisierten Umfang und einen zukünftigen Zeitpunkt. Dieses Beispiel plant bei der Ausführung einen echten Threads-Textbeitrag. Lass die Person Konto, Inhalt und Zeitpunkt vor dem create-Aufruf bestätigen.
Setze provider_payload.platform und die publish_options dieser Plattform. Der Server prüft die Übereinstimmung mit dem ausgewählten Konto. project_id kann die Beitragsherkunft dokumentieren; das Projekt erteilt weder Veröffentlichungszugriff noch steuert es den Zeitplan.
| Feld | Vertrag |
|---|---|
| workspace_id / social_account_id | Erforderliche UUIDs für den autorisierten Workspace und das genaue Ziel. |
| provider_payload | Erforderlicher Plattform-Diskriminator und plattformspezifische publish_options. |
| scheduled_at / display_timezone | Erforderlicher ISO-8601-Zeitpunkt mit Offset; gültige IANA-Anzeigezeitzone, standardmäßig UTC. |
| idempotency_key | Erforderlicher getrimmter String, 8–160 Zeichen, stabil für diese eine Absicht. |
| caption / hashtags | caption darf null sein, höchstens 5,000 Zeichen; Standard null. hashtags standardmäßig []; höchstens 100 Strings mit je 100 Zeichen. Anbietergrenzen können enger sein. |
| media | Standard []; höchstens 20 registrierte Medienverweise. Jeder enthält kind image/video und kanonische url; ergänze die bereite asset_id. Plattformregeln können enger sein. |
| link_url | Optionale URL oder null. Ziel und Beitragstyp müssen dies unterstützen. |
| local_scheduled_at / schedule_dst_disambiguation | Optionales Paar: Ortszeit ohne Offset und exact/earlier/later. Beide oder keines angeben; sie müssen beabsichtigtem Zeitpunkt und Zeitzone entsprechen. |
| expires_at / automatic_retry_enabled | Optionaler Ablauf nach scheduled_at; null bedeutet kein Ablauf. Automatische Wiederholung ist standardmäßig true und unterliegt weiterhin der Anbietersicherheit. |
| project_id / source_ref | Optionale nullable Project-UUID und Herkunftsobjekt des Aufrufers. Beide ändern keine Befugnisse. |
await sosoPost("/studio-api/scheduled-posts/eligibility", {
"workspace_id": "<workspace-uuid>",
"include_quota": true,
"targets": [
{
"social_account_id": "<threads-account-uuid>",
"media": [],
"provider_payload": {
"platform": "threads",
"publish_options": {
"post_type": "TEXT"
}
},
"draft": {
"caption": "A reviewed update from our team.",
"hashtags": [],
"scheduled_at": "<future-ISO-8601-instant-with-offset>",
"display_timezone": "Asia/Hong_Kong"
}
}
]
});await sosoPost("/studio-api/scheduled-posts/create", {
"workspace_id": "<workspace-uuid>",
"social_account_id": "<threads-account-uuid>",
"caption": "A reviewed update from our team.",
"hashtags": [],
"media": [],
"provider_payload": {
"platform": "threads",
"publish_options": {
"post_type": "TEXT"
}
},
"scheduled_at": "<future-ISO-8601-instant-with-offset>",
"display_timezone": "Asia/Hong_Kong",
"idempotency_key": "<stable-key-for-this-one-intent>"
});5. Ergebnis lesen und sicher abbrechen
Create liefert { post, deduped }. List liefert { posts, next_cursor, returned_count }. Get liefert { post, delivery, actions, attempts, outcomes }. Ein Beitrag enthält id, status, version, destination, schedule und verfügbare Anbieteridentität/Permalink; delivery und actions erklären Fortschritt und erlaubte nächste Schritte.
Beiträge mit status scheduled oder publishing sind noch ausstehend. Ein endgültiges Veröffentlichungsergebnis mit status published bestätigt Veröffentlichung und enthält verfügbare Anbieternachweise; ein Permalink kann fehlen. Lies bei Verbindungsabbruch oder verzögerter Antwort den bestehenden Beitrag vor der Ergebnismeldung.
Rufe vor dem Abbrechen Beitragsdetails ab und übergib die aktuelle numerische version. Während SosoAPI einen Anbieterzeitplan abbricht, kann cancellation_pending zurückkommen. Ein Zeitplanabbruch löscht keinen bereits veröffentlichten Beitrag.
await sosoPost("/studio-api/scheduled-posts/get", {
"id": "<scheduled-post-uuid>"
});const detail = await sosoPost("/studio-api/scheduled-posts/get", {
id: "<scheduled-post-uuid>"
});
// Run only after the person confirms cancelling this unpublished post.
await sosoPost("/studio-api/scheduled-posts/cancel", {
id: detail.post.id, expected_version: detail.post.version
});6. Idempotenz, Konflikte und ungewisse Schreibvorgänge
Verwende bei Wiederholung derselben create-Anfrage denselben idempotency_key. Eine passende Wiederholung liefert den bestehenden Beitrag mit deduped=true zurück. Änderst du bei gleichem Schlüssel den Inhalt, entsteht ein Konflikt. Dies verhindert doppelte Erstellungen in SosoAPI; eine genau einmalige Zustellung durch den Anbieter wird nicht garantiert.
Übergib für Updates und Aktionen expected_version aus der letzten Detailantwort. Bei Konflikten lies erneut und prüfe Änderungen gegen die neue Version. Eine verlorene Antwort verlangt Zustandsprüfung, keinen weiteren Beitrag mit neuem Schlüssel.
Der Schutz vor doppelten Inhalten kann eine separate Anfrage mit demselben normalisierten öffentlichen Inhalt, Konto und einem nahen Veröffentlichungszeitpunkt ablehnen. Prüfe den Verweis auf den bestehenden Beitrag, wenn du Lesezugriff hast, und frage den Nutzer vor Änderungen. Sammelanfragen liefern ein Ergebnis je Ziel; einige können erfolgreich sein, während andere scheitern.
7. Fehler, Ratenbegrenzungen und Integrationsgrenzen
Handler-Fehler verwenden eine Hülle mit error, message, optionalem code, retryable, request_id, optionalen details und retry_after_seconds. Schema-Validierungsfehler mit 400 liefern eine andere Form: { success: false, error: { name: "ZodError", message: "…" } }. Die Validierungsmeldung enthält derzeit die serialisierten Feldprobleme einschließlich ihrer Pfade; gehe nicht davon aus, dass die Felder der Handler-Hülle vorhanden sind.
Bewahre bei Fehlerdiagnose HTTP-Status, Fehlercode und Korrelations-ID aus result.request_id ?? response.headers.get("x-request-id") auf. Nutze Validierungsfeldpfade zur Korrektur. Behebe Authentifizierungs- oder Berechtigungsfehler an Zugangsdaten oder Autorisierung vor Wiederholung.
Das aktuelle studio-api-Limit beträgt 240 Anfragen pro Minute je menschlichem Nutzer und 480 pro Minute im separaten Maschinenzugangsdaten-Kontingent dieses Nutzers. Dies sind Anfragegrenzen, kein Veröffentlichungsdurchsatz oder Tarifkontingent. Andere Endpunkte und Social-Media-Anbieter haben eigene Grenzen. Beachte den aktuellen Retry-After-Header bei 429 oder wiederholbarem 503; keine Endlosschleifen.
Lies den Status in begrenzten Abständen, während der Nutzer den Beitrag verfolgt, oder nutze die Live-Statusansicht der App. Diese API verspricht keine ausgehenden Webhooks, Subscriber-SLA, plattformgleichen Funktionen oder festen Veröffentlichungszeitpunkte.
| Status | Bedeutung und Antwort |
|---|---|
| 400 | Schema-Validierung kann success:false mit ZodError in error statt der Handler-Hülle liefern. Behebe Feldprobleme; nutze x-request-id, falls request_id im Inhalt fehlt. Ungültige oder nicht unterstützte Anfragen auf Handler-Ebene können ebenfalls 400 verwenden. |
| 401 / 403 | Fehlende/abgelaufene Zugangsdaten oder verweigerte Funktion, Rolle, Workspace- oder Kontozugriff. Korrigiere die genaue Berechtigung oder Mitgliedschaft. |
| 404 | Die Ressource ist im autorisierten Umfang nicht verfügbar. Prüfe ihre Identität. |
| 409 | Zustands-/Versions-, Idempotenz-, Duplikatinhalts- oder Eignungskonflikt. Erneut lesen; nicht blind erneut senden. |
| 422 bei bulk-create | Kein Ziel war erfolgreich. Prüfe failures; Teilerfolg verwendet stattdessen 201. |
| 429 | Anfragedrosselung. Beachte Retry-After und behalte dieselbe Absichtsidentität. |
| 503 / andere 5xx | Vorübergehender Dienstausfall oder interner Fehler. Bewahre request_id auf; prüfe bestehenden Zustand vor Wiederholung ungewisser Änderungen. |