使用時先載入搜尋資料。亦可直接瀏覽下方分類。

伺服器 API 參考

SosoAPI Publishing API:驗證、請求同最終結果

以每個目的帳戶一個 Scheduled Post,建立伺服器發佈整合。以下發佈 API contract 已於 2026 年 10 月 20 日核對。示例包含 placeholders,唔會喺呢個頁面執行。

閱讀 Markdown

SosoAPI 團隊核對 ·

1. 從伺服器進行驗證

喺 SosoAPI App → 設定 → Agents & API Access 建立 API key,並喺伺服器環境存為 SOSOAPI_API_KEY。請求使用 Authorization: Bearer <your-key> 同 Content-Type: application/json。唔好將 key 放入網頁、手機 App bundle、URL 或公開 repository。

以下 endpoints 全部使用 POST 同 JSON body。API key 同 agent 授權受 capabilities、允許嘅 Workspaces 同擁有人目前會籍限制。讀取需要 agent:operate 同至少 viewer 角色;發佈寫入需要 agent:publish 同至少 editor 角色。授權唔會擴大擁有人本身嘅權利。

透過 App 目前嘅 Workspace/已連接帳戶,或者已驗證嘅 /identity-api/workspace/list 同 /identity-api/user/social-accounts/list endpoints,取得獲授權 IDs。唔好猜測客戶嘅 Workspace 或帳戶。

// 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. 發佈 endpoints 一覽

路徑相對於伺服器 helper 嘅 API base。Scheduled Post detail 係目前 version、允許操作同發佈證據嘅來源。

Scheduled Posts endpoints;全部請求使用 POST
路徑請求回應同界線
/studio-api/scheduled-posts/listworkspace_id;可選 project_id、status、成對時間、limit、cursor。posts、next_cursor、returned_count。按 Workspace 限定嘅讀取。
/studio-api/scheduled-posts/getid。post、delivery、actions、attempts、outcomes。喺呢度讀取目前 version。
/studio-api/scheduled-posts/eligibilityworkspace_id、targets;可選 include_quota。destinations 同可選 quota。只讀預檢,唔會預留容量。
/studio-api/scheduled-posts/createworkspace_id、確實帳戶、provider_payload、內容、scheduled_at、idempotency_key。post 同 deduped。新排程回傳 201;相同請求重播回傳 200。
/studio-api/scheduled-posts/bulk-createworkspace_id 同 1–50 個 targets,各自有 idempotency_key。batch_id、successes、failures。至少一個成功回傳 201;全部失敗回傳 422。兩個 arrays 都要檢查。
/studio-api/scheduled-posts/updateid、expected_version、patch;可選相符 provider_payload。post。過期 version 會被拒絕;目的帳戶不可更改。
/studio-api/scheduled-posts/publish-nowid 同 expected_version。post。要求即時執行,唔等於已發佈。
/studio-api/scheduled-posts/retryid、expected_version;可選未來 scheduled_at。post。只限失敗帖子,按證據容許復原;唔可以盲目重發。
/studio-api/scheduled-posts/cancelid 同 expected_version。post。取消未發佈工作;遠端取消可能仍在處理。
/studio-api/scheduled-posts/deleteid 同 expected_version。post。Machine caller 唔可以刪除已發佈嘅平台內容。
/studio-api/scheduled-posts/withdraw-deleteid 同 expected_version。post。撤回已停止、只作核實嘅 Instagram Login 刪除請求,保留平台內容。

3. 按原有範圍讀取同分頁

limit 預設 50,接受 1–200。可選 status 包括 scheduled、publishing、published、failed、expired、needs_reschedule、cancelled、deleted。scheduled_from 同 scheduled_to 必須一齊提供,使用有 offset 嘅 ISO-8601 時間,而且結束必須遲過開始。

next_cursor 係 null,或者包含 scheduled_at 同 id 嘅 object。下一頁要將整個 object 放返入 cursor,並保留相同 Workspace 同 filters。呢個 endpoint 唔接受 page、offset、platform 或 social_account_id filters。

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
  });
  // Read next.posts. Continue only when next_cursor is not null.
}

4. 驗證同建立一個已確認帖子

將每個 placeholder 換成獲授權範圍內嘅值同未來時間。執行以下示例會建立真實 Threads 文字排程。Create 前先由使用者確認帳戶、內容同時間。

provider_payload 包含 platform 同該平台嘅 publish_options。伺服器會核對所選帳戶是否相符。project_id 只係可選來源記錄;Project 唔會授權發佈或控制排程。

Create 請求欄位同預設值
欄位Contract
workspace_id / social_account_id必填 UUID:已授權 Workspace 同確實目的帳戶。
provider_payload必填 platform discriminator 同平台專用 publish_options。
scheduled_at / display_timezone必填帶 offset 嘅 ISO-8601 時間;有效 IANA 顯示時區,預設 UTC。
idempotency_key必填,trim 後 8–160 字元,同一意圖保持相同。
caption / hashtagsCaption 可為 null,最多 5,000 字元,預設 null。Hashtags 預設 [],最多 100 個、每個 100 字元。平台限制可能更窄。
media預設 [],最多 20 個已登記媒體。每項有 image/video kind 同 canonical url;提供已就緒 asset_id。平台限制可能更窄。
link_url可選 URL 或 null;目的平台同帖子類型必須支援。
local_scheduled_at / schedule_dst_disambiguation可選成對欄位:無 offset 本地時間,加 exact/earlier/later。兩者一齊提供或一齊省略,並須對應所選時間同時區。
expires_at / automatic_retry_enabled可選到期時間,必須遲過 scheduled_at;null 代表無到期限制。自動重試預設 true,仍受平台操作安全規則限制。
project_id / source_ref可選 nullable Project UUID 同來源 object;兩者都唔會改變權限。
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. 讀取結果同安全取消

Create 回傳 { post, deduped };List 回傳 { posts, next_cursor, returned_count };Get 回傳 { post, delivery, actions, attempts, outcomes }。post 包含 id、status、version、destination、排程同可用平台 ID/permalink;delivery 同 actions 解釋進度及允許嘅下一步。

scheduled 或 publishing 唔等於已發佈。publish 最終 outcome 為 published 先有平台發佈證據;permalink 仍可能未有。延遲或斷線嘅 client,要先查現有狀態,先至可以確認結果。

取消前先 Get 最新 detail,再用目前嘅數字 version。原生平台排程可能先進入 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 cancellation.
await sosoPost("/studio-api/scheduled-posts/cancel", {
  id: detail.post.id, expected_version: detail.post.version
});

6. Idempotency、衝突同未確認寫入

完全相同嘅 create 意圖要保留同一個 idempotency_key。相符重播會回傳已有 post 同 deduped=true;用同一 key 改內容會衝突。Create idempotency 唔等於平台提供 exactly-once delivery。

Update 同 actions 使用最新 detail 嘅 expected_version。遇到衝突先重讀狀態,再審閱改動。唔好覆蓋新 version,亦唔好因為收唔到回應就用新 key 再 create。

另一個意圖如果喺相同帳戶、相近發佈時間使用一樣嘅 normalized 公開內容,可能被重複內容檢查拒絕。先查看回傳而且獲授權嘅 existing-post reference,再由使用者決定要點改。Bulk 按目的帳戶分開回報,唔係全部成功或全部回滾。

7. 錯誤、rate limit 同整合界線

Handler 錯誤使用 envelope:error、message、可選 code、retryable、request_id、可選 details 同 retry_after_seconds。Schema-validation 400 使用另一個格式:{ success: false, error: { name: "ZodError", message: "…" } }。目前 validation message 包含序列化嘅欄位 issues 同 paths;唔好假設有 handler envelope 嘅欄位。

診斷時保留 HTTP status、可用 code,同 result.request_id ?? response.headers.get("x-request-id") 取得嘅 correlation ID。按 validation error 嘅欄位 paths 修正請求。驗證/權限失敗需要修復相應 credential 或授權;重複相同請求唔會取得存取權。

目前 studio-api 每位 human user 每分鐘上限 240 次;同一使用者分開嘅 machine credential bucket 為每分鐘 480 次。呢啲係請求上限,唔係發帖速度或方案 quota。其他 endpoints 同社交平台另有上限。429 或可重試 503 要依照實際 Retry-After header 等待,唔好 busy-loop。

採用有上限、由使用者發起嘅狀態讀取,或者 App 已有嘅即時狀態介面。呢份參考唔承諾 outbound webhook delivery、subscriber SLA、所有平台完全一致或固定發佈延遲。

HTTP 回應同對應下一步
Status含義同處理
400Schema validation 可能回傳 success:false 同 error 入面嘅 ZodError,而唔係 handler envelope。修正欄位 issues;body 冇 request_id 時用 x-request-id。Handler 層請求不合規格或 payload 唔支援亦可能用 400。
401 / 403Credential 缺失/過期,或 capability、角色、Workspace/帳戶權限被拒。修復確實授權或會籍。
404喺已授權範圍內搵唔到資源。核對身份。
409狀態/version、idempotency、重複內容或資格衝突。先重讀,唔好盲目重送。
Bulk-create 嘅 422全部目的帳戶失敗。查看 failures;部分成功會用 201。
429請求太密。依照 Retry-After 等待,保留相同意圖 identity。
503 / 其他 5xx暫時服務問題或內部錯誤。保留 request_id;對未確認寫入先查現有狀態,再決定重試。