# SosoAPI投稿API：認証・リクエスト・結果

正規URL： https://sosoapi.ai/ja/docs/publishing-api-reference

投稿先ごとに一つのScheduled Postを作るサーバー側連携を実装します。2026年十月20日に確認した投稿API契約を扱います。例にはプレースホルダーがあり、このページでは実行されません。

## 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ベースに対する相対パスです。投稿詳細で現在のバージョン、利用可能操作、公開結果を取得してください。

Scheduled Postsのエンドポイント。すべてPOSTです。

| パス | リクエスト | レスポンスと操作範囲 |

| --- | --- | --- |

| /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と一–50件のtargets。各対象に専用のidempotency_key。 | batch_id、successes、failures。1件以上成功で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、プラットフォーム間の同機能、固定公開時刻を保証しません。

HTTPレスポンスと次の対応

| ステータス | 意味と対応 |

| --- | --- |

| 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を保持し、不確かな変更の再試行前に既存状態を確認します。 |

- [プラットフォーム機能一覧](https://sosoapi.ai/ja/docs/publishing-capabilities)

- [自分のAIエージェントを設定](https://sosoapi.ai/ja/docs/quickstart)
