Social
通过 client.social 管理品牌、连接社交账号,并向 Facebook、Instagram、X、LinkedIn 和 Pinterest 发布或定时发布帖子。
所有 Social 方法都位于 client.social 下,分为 4 个命名空间,另有 1 个顶层调用:
ID、平台和状态
品牌、帖子和连接的 ID 都是普通 UUID 字符串。与地点 ID 不同,这些 ID 从不使用 Base64 编码,SDK 也不会对其进行转换。
平台使用大写枚举值 FACEBOOK、INSTAGRAM、TWITTER(即 X)、LINKEDIN 和 PINTEREST。帖子状态为 DRAFT、PENDING、SCHEDULED、PUBLISHED、FAILED、ARCHIVED 和 REJECTED;各渠道的状态为 SCHEDULED、SUCCESS、ERROR 和 ARCHIVED。
每次写入都会返回 success 标志
Social 写入操作会在 200 响应中通过 success: false 报告验证失败,并在 error 中提供原因。SDK 会在发生传输错误或收到可识别的错误载荷时抛出异常,但您仍应养成自行检查 success 的习惯:
result = client.social.brands.create(profile_name="Jenny Home", timezone=tz)if not result.success: raise RuntimeError(result.error.message)发布操作是异步的
action="PUBLISH" 接收帖子并返回其 id。轮询 social.posts.retrieve() 并读取 connectedChannels[],以获取各渠道的 status、liveLink 和 error;同一次调用中的帖子可能在一个平台上发布成功,而在另一个平台上发布失败。
social.brands.create
创建品牌。只有 profile_name 和 timezone 为必填项。
client.social.brands.create( *, profile_name: str, timezone: dict, business_intent: str | None = None, categories: list[str] | None = None, site_url: str | None = None, logo: str | None = None, country_iso: str | None = None, bio: str | None = None, brand_hashtags: list[str] | None = None, competitor_hashtags: list[str] | None = None, content_preferred_language: str | None = None,) -> APIObjectresult = client.social.brands.create( profile_name="Jenny Home", timezone={ "label": "(GMT-05:00) Eastern Time", "tzCode": "America/New_York", "name": "Eastern Standard Time", "utc": "-05:00", }, business_intent="A family-run home furnishings store selling handmade furniture.", categories=["Furniture Store"], site_url="https://jennyhome.example",)brand_id = result.socialProfile.id # a plain UUID stringAPI 套餐不限制品牌数量,因此此操作不会因数量上限而失败。受配额限制的是连接数,因此应在生成连接链接之前检查 social.limits(),而不是在创建品牌之前检查。
social.brands.list
使用偏移量分页列出品牌。如果您提供筛选条件,其中必须包含 statuses。
client.social.brands.list( *, statuses: list[str] | None = None, profile_name: str | None = None, page: int | None = None, size: int | None = None,) -> APIObjectresult = client.social.brands.list(page=1, size=25)for brand in result.profiles: print(brand.id, brand.profileName, brand.connectedChannelCount)print(result.pageInfo.total, result.pageInfo.hasNextPage)social.brands.retrieve
通过 UUID 获取单个品牌。
client.social.brands.retrieve(brand_id: str) -> APIObjectbrand = client.social.brands.retrieve("6f2c9a41-7b0e-4d55-9a2f-3c8e1d47b902")print(brand.profileName, brand.timezone.tzCode)social.brands.update
更新品牌。只有 profile_id 为必填项;仅发送您要修改的字段。
client.social.brands.update( profile_id: str, *, profile_name: str | None = None, timezone: dict | None = None, business_intent: str | None = None, categories: list[str] | None = None, site_url: str | None = None, logo: str | None = None, country_iso: str | None = None, bio: str | None = None, brand_hashtags: list[str] | None = None, competitor_hashtags: list[str] | None = None, content_preferred_language: str | None = None,) -> APIObject发送 categories、brand_hashtags 和 competitor_hashtags 时,它们会替换已存储的对应列表;传入 [] 会清空该列表。
client.social.brands.update( "6f2c9a41-7b0e-4d55-9a2f-3c8e1d47b902", profile_name="Jenny Home & Co.",)social.brands.archive
归档品牌及其连接。品牌必须已创建至少 90 天。
client.social.brands.archive(social_profile_id: str) -> APIObjectresult = client.social.brands.archive("6f2c9a41-7b0e-4d55-9a2f-3c8e1d47b902")print(result.status) # ARCHIVED or TENURE_NOT_MET对于创建不足 90 天的品牌,调用会返回 success: False 和 status: "TENURE_NOT_MET",且不会做出任何更改。满足存续时间要求后,归档会立即生效:品牌及其关联的所有连接会在同一次调用中归档,并立即停止发布,但这些连接仍会占用连接配额,直到计费周期结束,与手动断开连接的行为完全相同。
social.connections.link
生成一个短期有效的托管页面 URL,引导最终用户将一个平台连接到品牌。将用户重定向到 url。
client.social.connections.link( brand_id: str, *, channel: str, redirect_url: str, error_url: str | None = None, state: str | None = None,) -> APIObjectlink = client.social.connections.link( "6f2c9a41-7b0e-4d55-9a2f-3c8e1d47b902", channel="INSTAGRAM", redirect_url="https://app.example.com/social/connected", error_url="https://app.example.com/social/connect-failed", state="sess_9f2c1e64",)print(link.url, link.expiresIn)用户会返回 redirect_url,URL 中会附加 status、brandId、platform、您提供的 state,以及成功时的 connectedAccountId。连接会在稍后完成创建,因此请持续轮询 social.connections.list() 几秒钟,不要将首次读取结果为空视为失败。Instagram 要求使用已关联 Facebook 主页的企业账号或创作者账号。
social.connections.list
列出关联到品牌的社交账号。
client.social.connections.list(brand_id: str) -> APIObjectresult = client.social.connections.list("6f2c9a41-7b0e-4d55-9a2f-3c8e1d47b902")for channel in result.socialConnected: print(channel.id, channel.platform, channel.displayName)print(result.channelCount)channel.id 是其他所有调用所需的连接 UUID;referenceId 是平台自身的账号标识符,不能作为输入。
social.connections.disconnect
移除连接。此操作不可逆:要恢复连接,必须重新执行 social.connections.link()。
client.social.connections.disconnect(social_profile_connected_channel_id: str) -> APIObjectclient.social.connections.disconnect("b81d5b3c-4a90-4f6a-9c11-71e0dd2fa4a7")面向该渠道的定时帖子不会被取消;它们会在发布时失败,并返回 SY95045。请先使用 social.posts.cancel() 取消这些帖子。
social.posts.create
为一个品牌创建一个帖子,发布到其已连接的多个渠道。
client.social.posts.create( *, social_profile_id: str, name: str, platforms: list[str], content: str, action: str, media_urls: list[str] | None = None, video_urls: list[str] | None = None, link: str | None = None, scheduled_at: str | None = None, schedule_date: str | None = None, schedule_time: str | None = None, connected_channel_ids: list[str] | None = None, client_reference: str | None = None,) -> APIObjectaction="SCHEDULE" 必须且只能使用一种定时参数形式:scheduled_at,或 schedule_date + schedule_time。同时发送两种形式会被拒绝,并返回 SY95046。
result = client.social.posts.create( social_profile_id="6f2c9a41-7b0e-4d55-9a2f-3c8e1d47b902", name="Autumn collection launch", platforms=["INSTAGRAM", "FACEBOOK"], content="Our autumn collection lands today. Solid oak, hand-finished.", media_urls=["https://cdn.example.com/social/autumn.jpg"], action="SCHEDULE", schedule_date="2026-10-02", schedule_time="09:30",)print(result.success, result.socialPostId)social.posts.retrieve
获取单个帖子及其在各渠道的发布状态。创建帖子后轮询此方法。
client.social.posts.retrieve(post_id: str) -> APIObjectpost = client.social.posts.retrieve("c47a1e58-2b93-4f10-a6d7-58e0c9b12345")print(post.status)for channel in post.connectedChannels: print(channel.platform, channel.status, channel.liveLink, channel.error)social.posts.list
使用偏移量分页列出品牌的帖子,支持筛选。
client.social.posts.list( brand_id: str, *, filters: dict | None = None, page: int | None = None, size: int | None = None, fetch_post_content: bool | None = None,) -> APIObjectfilters 接受 name、platforms、status、start_date、end_date、social_connected_channel_id、approval_state、view_mode 和 filter_by_user。
result = client.social.posts.list( "6f2c9a41-7b0e-4d55-9a2f-3c8e1d47b902", filters={"status": ["SCHEDULED"], "startDate": "2026-10-01", "endDate": "2026-10-31"}, page=1, size=50,)for post in result.socialPosts: print(post.socialPostId, post.name, post.status)print(result.pageInfo.total)social.posts.cancel
取消定时帖子或草稿帖子,使其不再发布。
client.social.posts.cancel(social_post_id: str) -> APIObjectclient.social.posts.cancel("c47a1e58-2b93-4f10-a6d7-58e0c9b12345")已发布的帖子无法取消,也不会从任何平台移除;对此类帖子,调用会返回 success: False。
social.posts.insights
获取单个已发布帖子在一个渠道上的互动数据和评论。两个字段均以 JSON 字符串形式返回,包含平台自身的载荷。
client.social.posts.insights( post_id: str, *, social_connected_channel_id: str,) -> APIObjectimport json result = client.social.posts.insights( "c47a1e58-2b93-4f10-a6d7-58e0c9b12345", social_connected_channel_id="b81d5b3c-4a90-4f6a-9c11-71e0dd2fa4a7",)insights = json.loads(result.insights)comments = json.loads(result.comments)print(insights.get("impressions"), len(comments))其中的键由平台定义,各平台之间有所不同;读取时请检查键是否存在以及值是否符合预期。
social.bulk.create
在一次请求中验证最多 500 个帖子并将其加入队列。各行可以指定不同的品牌。
client.social.bulk.create( posts: list[dict], *, name: str | None = None,) -> APIObject每行在 camelCase 中使用与 social.posts.create 相同的字段。如果任何一行无效,则不会创建任何帖子:success 为 False,SY95050 会在 error 中返回,job.results[] 则通过从 0 开始的 index 及其 clientReference 指出每个无效行。
result = client.social.bulk.create([ { "socialProfileId": "6f2c9a41-7b0e-4d55-9a2f-3c8e1d47b902", "name": "Autumn week 1", "platforms": ["INSTAGRAM", "FACEBOOK"], "content": "Week one of the autumn collection.", "mediaUrls": ["https://cdn.example.com/social/autumn-w1.jpg"], "action": "SCHEDULE", "scheduleDate": "2026-10-02", "scheduleTime": "09:30", "clientReference": "campaign-4471-slot-01", },])if not result.success: for row in result.job.results: print(row.index, row.clientReference, row.errors)else: job_id = result.job.idsocial.bulk.retrieve
轮询批量任务,直到其状态变为终态。
client.social.bulk.retrieve(bulk_job_id: str) -> APIObjectjob = client.social.bulk.retrieve("9b3f18d0-7a26-4c51-8e94-1f0d5c6b7a82")print(job.status, job.processedCount, "/", job.totalCount)for row in job.results: print(row.clientReference, row.status, row.socialPostId)status 为 QUEUED、PROCESSING、COMPLETED、COMPLETED_WITH_ERRORS 或 FAILED。某一行达到 CREATED 状态表示帖子已存在,并不表示已发布:将 socialPostId 传入 social.posts.retrieve(),以获取各渠道的结果。
social.limits
在一次调用中获取连接数上限和当前用量。
client.social.limits() -> APIObjectlimits = client.social.limits()print(limits.maxConnections, limits.usage.connections) # pool vs usedprint(limits.brands) # None — brands are unlimitedprint(limits.usage.brands) # brands that exist, uncapped连接配额是整个账号共用的配额池,而非每个品牌各自的配额:Social Launch 提供 20 个,Social Growth 提供 125 个,每个每月 25 美元的连接扩展包额外提供 5 个。在生成连接链接之前检查配额,以便向用户提供升级选项,而不是显示 SY95042。所有 API 套餐中的 limits.brands 均为 None。
另请参阅
- 套餐和附加项:套餐档位、附加项价格、连接池和 90 天期限规则
- Social REST 参考:这些方法封装的原始端点
- 帖子:地点级产品,属于另一项订阅
- 错误处理:类型化异常和
success标志