简介:本文面向后端开发者,系统梳理广告投放API对接中的接口版本差异、鉴权头命名冲突与资源MIME类型等高频问题,给出从授权到广告组创建的完整依赖链路与调试要点,帮助读者减少反复试错,构建稳定可维护的对接流程。
在广告投放系统的后端开发中,对接开放 API 往往是”文档看得懂、调通要半天”的典型场景。尤其是当同一业务域被拆分成多套接口版本时,请求头、内容类型、路径风格各自为政,稍有不慎就会收到 403 或 415,而错误信息往往语焉不详。本文按实际对接顺序,梳理从授权到广告组创建的完整链路,并对最容易踩坑的几个环节做重点说明,帮助读者建立一套可复用的调试方法。
很多同学在对接初期会默认”广告 API 是一个整体”,于是用同一套请求头去打所有端点,结果必然受挫。实际情况是,广告投放能力通常被拆分为两个层次:
/adsApi/v1/... 这类版本化前缀。/sp/...。这两套接口在请求头命名、Content-Type 取值、响应结构上都不一致。因此第一件事不是写代码,而是把接口分组,为每组建立独立的 HTTP 客户端配置。工程上建议按”接口族”封装两个基础客户端,各自持有独立的默认请求头与序列化策略,避免在业务代码里到处手动拼 header。
整体创建依赖关系如下(组合/预算组为可选项):
OAuth 授权→ 查询广告账户档案→ 创建组合(可选)→ 创建广告活动(活动管理层接口)→ 创建广告组(投放实体层接口)→ 创建商品广告 / 关键词 / 定向 / 否定词→ 创建活动级否定关键词 / 活动级否定定向
注意依赖方向:广告组必须挂在活动下,商品广告与关键词必须挂在广告组下。任何跨层创建都会因资源 ID 缺失而失败,因此实现上应把这条链路建模为有序任务,而不是并发发起。
所有请求都需要 Bearer 形式的访问令牌,标准流程是 OAuth 2.0 授权码模式:
scope 需包含广告活动管理权限(如 advertising::campaign_management);Authorization 头中携带 Bearer <access_token>;真正的坑在于客户端标识与账户标识的请求头命名:
两组名称相似但字面不同,混用会直接返回 403。实践中建议:
这是第二个高频雷区。投放实体层的多数资源要求使用带资源标识的 vendor MIME 类型,例如关键词资源使用 application/vnd.spKeyword.v3+json 这类形式,而不是笼统的 application/json。写错通常返回 415(不支持的媒体类型)或 400(请求体解析失败)。
应对策略:
一个简化的客户端伪代码如下:
RESOURCE_MIME = {"adGroup": "application/vnd.spAdGroup.v3+json","productAd": "application/vnd.spProductAd.v3+json","keyword": "application/vnd.spKeyword.v3+json","target": "application/vnd.spTarget.v3+json","negativeKeyword": "application/vnd.spNegativeKeyword.v3+json",}def post_resource(client, resource, payload):headers = client.base_headers.copy()headers["Content-Type"] = RESOURCE_MIME[resource]return client.post(f"/sp/{resource}s", json=payload, headers=headers)
第一步,查询账户档案。 授权完成后先调用档案接口获取可投放的账户标识,后续所有请求的账户上下文都来源于此。建议缓存档案信息并设置合理过期时间,避免每次业务请求都重复拉取。
第二步,创建组合(可选)。 若业务需要按预算组管理活动,先创建组合并拿到组合 ID;不需要则跳过,但要在数据模型中预留字段,避免后续迁移。
第三步,创建广告活动。 走活动管理层接口,注意其请求体字段命名与投放实体层不同(例如预算、投放日期的表达方式)。建议为活动创建单独定义 DTO,不要与广告组 DTO 复用。
第四步,创建广告组。 走投放实体层接口,必须携带上一步返回的活动 ID。广告组的默认出价、投放位置等字段会显著影响后续资源的可用性,建议在创建时就明确设置,而非依赖平台默认值。
第五步,批量创建下层资源。 商品广告、关键词、定向、否定关键词、否定定向均挂在广告组下;活动级否定关键词与活动级否定定向挂在活动下。这一层建议:
Content-Type 与请求体,便于在接口调试工具中复现。广告投放 API 对接的难点不在于业务逻辑复杂,而在于多版本接口并存的细节差异。把接口按族分组、把请求头与内容类型下沉到客户端配置、把创建链路建模为有序任务,并在调试阶段保留足够的可观测信息,基本可以覆盖绝大多数踩坑场景。对于更上层的投放策略与数据分析,则可在此基础上逐步叠加,而不必反复纠缠于协议层的细枝末节。