# SosoAPI 发布 API：身份验证、请求和结果

标准 URL： https://sosoapi.ai/zh-hans/docs/publishing-api-reference

以每个目标一份 Scheduled Post 构建服务端发布集成。此参考涵盖于 2026年十月20日 审核的发布 API 契约。示例包含占位符，不会在此页面执行。

## 1. 从服务器进行验证

在「SosoAPI App → 设置 → agent 与 API 访问权限」创建 API key。于服务器环境存储为 SOSOAPI_API_KEY。请求使用 Authorization: Bearer <your-key> 以及 Content-Type: application/json。绝不要将 key 嵌入网站、移动应用包、URL 或公开仓库。

以下所有端点皆使用 POST 与 JSON 主体。Keys 与委派 agent 授权受其能力、允许的 工作区 及所有者当前成员资格限制。读取需要 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 基础 URL。请获取排程帖子详情，以获取当前版本、可用操作与发布结果。

排程帖子端点；所有请求皆为 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。在此读取当前 version。 |

| /studio-api/scheduled-posts/eligibility | workspace_id、targets；可选 include_quota。 | destinations 与可选 quota。唯读预检，不是资源预留。 |

| /studio-api/scheduled-posts/create | workspace_id、确切账号、provider_payload、content、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。过期版本会遭拒绝；destination 不可变更。 |

| /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 说明当前进度与允许的下一步。

status 为 scheduled 或 publishing 的帖子仍待处理。status 为 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。复用该 key 但更改内容会导致冲突。这可防止在 SosoAPI 中重复创建，但不保证平台恰好交付一次。

更新与操作请传入最新详细响应中的 expected_version。如有冲突，请重新获取帖子，并依新版本审核变更。响应遗失时应检查现有状态，不应使用新键另建帖子。

重复内容防护可能会拒绝独立请求，如果其标准化公开内容、账号和临近发布时间相同。如获准读取，请检查现有帖子引用，并在更改请求前询问用户。批量请求会为每个目标返回结果；部分可能成功，其他则失败。

## 7. 错误、速率限制与集成限制

处理程序错误使用包含 error、message、可选 code、retryable、request_id、可选 details 和 retry_after_seconds 的封装。schema 验证 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 不承诺向外发送 webhooks、订阅者 SLA、各平台功能一致或固定发布时间。

HTTP 响应与有用的后续操作

| 状态 | 含义与响应 |

| --- | --- |

| 400 | schema验证可能返回 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/zh-hans/docs/publishing-capabilities)

- [设置你自己的 AI agent](https://sosoapi.ai/zh-hans/docs/quickstart)
