サーバーAPIリファレンス
SosoAPI投稿API:認証・リクエスト・結果
投稿先ごとに一つのScheduled Postを作るサーバー側連携を実装します。2026年十月20日に確認した投稿API契約を扱います。例にはプレースホルダーがあり、このページでは実行されません。
Markdownで読むSosoAPIチームが確認 ·
1. サーバーで認証する
SosoAPI App → Settings → Agents & API Accessでキーを作り、サーバーのSOSOAPI_API_KEYに保存します。Authorization: Bearer <your-key>とContent-Type: application/jsonを使います。サイト、モバイルアプリ、URL、公開リポジトリに埋め込まないでください。
以下の全エンドポイントはJSON本文でPOSTを使用します。キーと委任認可は、機能権限、許可ワークスペース、所有者の現在の所属に制限されます。読み取りはagent:operateとviewer以上、公開変更はagent:publishとeditor以上が必要です。認可で所有者の権利を広げることはできません。
アプリの現在のワークスペースと接続アカウントを使用するか、/identity-api/workspace/listと/identity-api/user/social-accounts/listを呼び出し、認可されたIDを調べてください。顧客のワークスペースやアカウントIDを推測しないでください。
// 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. 投稿エンドポイント一覧
サーバーヘルパーのAPIベースに対する相対パスです。投稿詳細で現在のバージョン、利用可能操作、公開結果を取得してください。
| パス | リクエスト | レスポンスと操作範囲 |
|---|---|---|
| /studio-api/scheduled-posts/list | workspace_id。任意でproject_id、status、日時の組、limit、cursor。 | posts、next_cursor、returned_count。ワークスペース内の読み取りです。 |
| /studio-api/scheduled-posts/get | id. | post、delivery、actions、attempts、outcomes。現在のバージョンはここで取得します。 |
| /studio-api/scheduled-posts/eligibility | workspace_id、targets。include_quotaは任意。 | 投稿先と任意の利用枠。読み取り専用の事前確認であり、枠の確保ではありません。 |
| /studio-api/scheduled-posts/create | workspace_id、正確なアカウント、provider_payload、内容、scheduled_at、idempotency_key。 | postとdeduped。新規予約は201、一致する再実行は200。 |
| /studio-api/scheduled-posts/bulk-create | workspace_idと1–50件のtargets。各対象に専用のidempotency_key。 | batch_id、successes、failures。一件以上成功で201、全件失敗で422。両配列を確認します。 |
| /studio-api/scheduled-posts/update | id、expected_version、patch。任意で対応するprovider_payload。 | post。古いバージョンは拒否され、投稿先は変更できません。 |
| /studio-api/scheduled-posts/publish-now | id と expected_version. | post。即時実行を要求しますが、公開の証明ではありません。 |
| /studio-api/scheduled-posts/retry | id、expected_version。未来のscheduled_atは任意。 | post。失敗時のみ、証拠に基づき復旧します。無条件の再送はしません。 |
| /studio-api/scheduled-posts/cancel | id と expected_version. | post。未公開作業をキャンセルします。リモート側解除は保留の場合があります。 |
| /studio-api/scheduled-posts/delete | id と expected_version. | post。マシン呼び出し元は公開済みプロバイダーコンテンツを削除できません。 |
| /studio-api/scheduled-posts/withdraw-delete | id と expected_version. | post。停止中の検証専用Instagram Login削除申請を撤回し、プロバイダーのコンテンツを保持します。 |
3. 範囲を維持して一覧とページを取得する
limitの既定値は50で、1–200を指定できます。任意のstatusはscheduled、publishing、published、failed、expired、needs_reschedule、cancelled、deletedです。scheduled_fromとscheduled_toは、オフセット付きISO-8601日時として併せて指定し、終了を開始より後にしてください。
next_cursorはnull、またはscheduled_atとidを持つオブジェクトです。同じワークスペースとフィルターに加え、オブジェクト全体をcursorとして返します。このエンドポイントはpage、offset、platform、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. 確認済み投稿を一件検証して作成する
すべてのプレースホルダーを、認可された範囲の値と未来の日時に置き換えてください。実行すると実際のThreadsテキスト投稿が予約されます。作成を呼び出す前に、本人にアカウント、内容、日時を確認してもらってください。
provider_payload.platformと、そのプラットフォームのpublish_optionsを設定します。サーバーが選択アカウントとの一致を確認します。project_idは出典記録用に指定できますが、公開権限や予約の制御は与えません。
| フィールド | 契約 |
|---|---|
| workspace_id / social_account_id | 認可されたワークスペースと正確な投稿先のUUIDは必須です。 |
| provider_payload | 必須のプラットフォーム識別子と、プラットフォーム別のpublish_options。 |
| scheduled_at / display_timezone | オフセット付きISO-8601日時は必須です。有効なIANA表示タイムゾーンを指定し、既定値はUTCです。 |
| idempotency_key | 必須。前後の空白を除く8–160文字で、一つの意図に安定した同じ値を使用。 |
| caption / hashtags | captionはnullを許可し、最大5,000文字、既定値はnullです。hashtagsの既定値は[]で、最大100件、各100文字です。プロバイダーの制限はより厳しい場合があります。 |
| media | 既定値は[]、登録済みメディア参照は最大20件。各項目はkindがimage/video、正規url、準備済みasset_idを含みます。プラットフォームはさらに制限する場合があります。 |
| link_url | 任意のURLまたはnull。投稿先と投稿種別が対応している必要があります。 |
| local_scheduled_at / schedule_dst_disambiguation | 任意の組:オフセットなし現地時刻とexact/earlier/later。両方か両方なしとし、目的の日時・タイムゾーンに一致させます。 |
| expires_at / automatic_retry_enabled | scheduled_at後の任意の有効期限です。nullは期限なしを意味します。自動再試行の既定値はtrueですが、プロバイダーの安全要件に従います。 |
| project_id / source_ref | 任意のnullを許容するProject UUIDと、呼び出し元の出典オブジェクトです。権限は変わりません。 |
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. 結果を確認し、安全にキャンセルする
作成は{ post, deduped }、一覧は{ posts, next_cursor, returned_count }、取得は{ post, delivery, actions, attempts, outcomes }を返します。投稿にはid、status、version、destination、schedule、取得可能なプロバイダー識別情報とリンクが含まれ、deliveryとactionsで進行と許可された次の操作を説明します。
scheduledとpublishingは保留中です。最終publish結果のpublishedが公開を確認し、取得可能なプロバイダー証拠を含みます。リンクがない場合もあります。切断・遅延時は報告前に既存投稿を取得してください。
キャンセル前に詳細を取得し現在の数値versionを渡します。SosoAPIがプロバイダー側予約を解除中はcancellation_pendingの場合があります。公開済み投稿の削除にはなりません。
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. 冪等性・競合・不確かな書き込み
同じ作成リクエストの再試行には同じidempotency_keyを使用します。一致すれば既存の投稿をdeduped=trueで返します。同じキーで内容を変えると競合します。SosoAPI内の重複作成を防ぎますが、プロバイダー側での厳密に一回の配信は保証しません。
更新・操作には最新詳細のexpected_versionを渡します。競合時は再取得し、新版に対する変更を確認します。応答喪失は既存状態を確認する理由で、新キーで別投稿を作る理由ではありません。
同じ正規化済み公開内容、アカウント、近接した公開時刻の別リクエストは、重複コンテンツ防止機能で拒否される場合があります。閲覧権限があれば既存投稿の参照を確認し、変更前にユーザーへ確認してください。一括リクエストは投稿先ごとに結果を返し、一部だけ成功する場合もあります。
7. エラー、レート制限、連携上の制限
ハンドラーエラーはerror、message、任意のcode、retryable、request_id、任意のdetails、retry_after_secondsを含む形式です。スキーマ検証の400は別形式の{ success: false, error: { name: "ZodError", message: "…" } }を返します。現在の検証メッセージはパスを含むフィールド問題をシリアライズしたものです。ハンドラー形式のフィールドがあるとは限りません。
失敗診断ではHTTPステータス、エラーコード、result.request_id ?? response.headers.get("x-request-id")の関連IDを保持します。検証パスで要求を直し、認証・権限エラーは先に認証情報・認可を修正します。
現在のstudio-api上限は、人のユーザーごとに毎分240リクエスト、同じユーザーのマシン認証情報は別枠で毎分480です。投稿処理能力やプラン枠ではなくリクエスト上限です。他のエンドポイント・プロバイダーは別制限です。429や再試行可能な503では実際のRetry-Afterに従い、連続ループを避けてください。
ユーザーが投稿を追跡している間は間隔を区切って状況を取得するか、アプリのライブ状況を使います。このAPIは送信Webhook、購読者向けSLA、プラットフォーム間の同機能、固定公開時刻を保証しません。
| ステータス | 意味と対応 |
|---|---|
| 400 | スキーマ検証はハンドラー形式ではなくsuccess:falseとerror内のZodErrorを返す場合があります。フィールド問題を修正し、本文にrequest_idがなければx-request-idを使います。無効・非対応の要求もハンドラー側で400になる場合があります。 |
| 401 / 403 | 認証情報の不足・失効、または機能・ロール・ワークスペース・アカウントへのアクセス拒否。該当する認可・所属を修正します。 |
| 404 | 認可範囲でリソースを利用できません。識別情報を確認してください。 |
| 409 | 状態・バージョン、冪等性、重複内容、適格性の競合。再取得し、無条件に再送しないでください。 |
| 一括作成の422 | 成功した投稿先はありません。failuresを確認してください。一部成功の場合は201を使います。 |
| 429 | リクエスト制限。Retry-Afterに従い、同じ意図の識別情報を維持してください。 |
| 503/その他の5xx | 一時障害または内部エラー。request_idを保持し、不確かな変更の再試行前に既存状態を確認します。 |