对接广告 API 的结构化避坑指南:从认证、资源关系到请求格式

作者:梅琳marlin2026.11.07 02:50浏览量:0

简介:广告投放相关接口往往由多套不同版本、不同路径、不同报文规范的服务组成,直接照搬统一封装很容易触发 403、415 或依赖顺序错误。本文从实际对接流程出发,梳理认证、账号画像、资源层级、两套 Header、专用 Content-Type 以及创建链路,帮助开发者少走弯路,快速形成可维护的集成方案。

广告 API 对接的结构化避坑指南:从认证、资源关系到请求格式

在对接广告投放相关接口时,很多开发者最先遇到的并不是业务复杂度,而是接口体系本身的“不一致性”。这种不一致体现在认证方式、请求路径、请求头、响应结构、资源依赖关系等多个层面。如果按照普通开放平台的统一封装思路去处理,很容易在第一步就踩坑。

本文不围绕某一家具体平台展开,而是以一类常见的广告投放接口形态为对象,系统说明其对接方式、关键约束和工程化建议。内容适用于正在接入搜索广告、商品推广或类似投放能力的开发者与后端工程师。

一、为什么这类接口容易让人“怀疑人生”

很多广告接口并不是单一版本、单一风格的服务,而是由多个子系统组合而成。常见的问题集中在三个方面。

1. 不是一套接口,而是多套接口并存

在广告投放场景中,不同资源层级可能由不同服务承载。例如:

  • 广告活动创建可能走较早版本的接口;
  • 广告组及以下层级,如商品广告、关键词、定向、否定关键词等,走另一套较新版本的接口。

这两套接口通常存在明显差异:

  • URL 路径前缀不同;
  • 鉴权 Header 命名不同;
  • Content-Type 要求不同;
  • 返回结构不同;
  • 错误码语义不完全一致。

因此,开发者不能假设“只要拿到一套鉴权信息,就能用统一风格请求所有资源”。更合理的做法是,按资源类型拆分客户端,并分别维护请求规范。

2. 两套 Header 命名体系

不同接口版本对请求头的要求可能完全不同。例如:

早期接口可能要求:

  1. Authorization: Bearer <token>
  2. Client-Id: <client_id>
  3. Account-Id: <account_id>
  4. Content-Type: application/json

而较新的接口可能要求:

  1. Authorization: Bearer <token>
  2. Advertising-API-Client-Id: <client_id>
  3. Advertising-API-Scope: <profile_id>
  4. Content-Type: application/vnd.spKeyword.v3+json

如果混用,常见结果就是 403 或 401。尤其是当客户端封装层默认注入了一套 Header 后,开发者很容易忽略另一套接口的差异。

3. Content-Type 不是普通的 JSON

在很多广告接口中,尤其是较新版本的资源接口,Content-Type 并不是:

  1. Content-Type: application/json

而是带有资源类型和版本信息的专用媒体类型,例如:

  1. Content-Type: application/vnd.spKeyword.v3+json
  2. Accept: application/vnd.spKeyword.v3+json

这种设计是为了让同一路径下能够演进不同版本,同时明确资源语义。如果仍然使用通用 JSON 类型,可能会得到:

  • 400 Bad Request;
  • 415 Unsupported Media Type;
  • 或者请求被接受但返回非预期结构。

因此,在对接前必须逐个资源确认其专属 Content-Type,而不是全局写死一个值。

二、整体调用链路与资源依赖

广告投放接口通常具有严格的资源创建顺序。我们可以把整个流程抽象为以下依赖关系:

  1. flowchart TD
  2. OAuth[获取访问令牌] --> Profiles[获取账号画像列表]
  3. Profiles --> Portfolio[可选:创建投放组合]
  4. Portfolio --> Campaign[创建广告活动]
  5. Campaign --> AdGroup[创建广告组]
  6. AdGroup --> ProductAds[创建商品广告]
  7. AdGroup --> Keywords[创建关键词]
  8. AdGroup --> Targets[创建投放目标]
  9. AdGroup --> NegKeywords[创建否定关键词]
  10. AdGroup --> NegTargets[创建否定投放目标]
  11. Campaign --> CampNegKw[创建活动级否定关键词]
  12. Campaign --> CampNegTgt[创建活动级否定投放目标]

从图中可以看出:

  1. 必须先完成认证,获取访问令牌;
  2. 通过账号接口获取可操作的账号画像;
  3. 创建一个广告活动;
  4. 在广告活动下创建广告组;
  5. 在广告组下创建商品广告、关键词、定向和否定项;
  6. 某些否定项可以直接挂在广告活动下。

如果跳过某一层级直接创建下级资源,通常会返回资源不存在或父级标识无效的错误。

三、认证与账号画像获取

1. 获取访问令牌

接入广告接口的第一步是获取访问令牌。常见流程包括:

  • 通过授权服务获取授权码;
  • 使用授权码换取访问令牌;
  • 使用刷新令牌维持长期访问。

访问令牌通常通过请求头传递:

  1. Authorization: Bearer <access_token>

令牌有效期有限,需要做好缓存与刷新机制。

2. 获取账号画像

拿到令牌后,需要调用账号相关接口获取可操作的账号画像列表。账号画像通常包含:

  • 账号唯一标识;
  • 账号名称;
  • 区域或站点信息;
  • 账号状态。

后续创建广告活动、广告组等资源时,都需要指定账号画像标识。这个标识在不同接口版本中可能对应不同的 Header 字段。

建议在系统初始化阶段完成账号画像的获取与缓存,并为每个账号维护独立的接口上下文。

四、广告活动创建

广告活动是投放体系的顶层资源。创建广告活动时,通常需要传入:

  • 活动名称;
  • 投放策略;
  • 预算;
  • 开始与结束时间;
  • 定向类型;
  • 出价方式。

广告活动接口可能需要使用较早版本的请求风格。例如:

  1. POST /adsApi/v1/campaigns
  2. Authorization: Bearer <token>
  3. Client-Id: <client_id>
  4. Account-Id: <account_id>
  5. Content-Type: application/json

请求体示例:

  1. {
  2. "name": "2025-03-搜索广告活动",
  3. "budget": 100,
  4. "startDate": "2025-03-01",
  5. "targetingType": "auto",
  6. "bidding": {
  7. "strategy": "fixed",
  8. "amount": 1.5
  9. }
  10. }

创建成功后,需要保存活动 ID,因为后续创建广告组、否定关键词等资源时都要依赖它。

五、广告组及以下资源创建

广告组是广告活动与具体投放单元之间的中间层级。广告组创建通常走较新版本接口,路径前缀和 Header 都可能发生变化。

例如,创建广告组时请求可能如下:

  1. POST /sp/adGroups
  2. Authorization: Bearer <token>
  3. Advertising-API-Client-Id: <client_id>
  4. Advertising-API-Scope: <profile_id>
  5. Content-Type: application/vnd.spAdGroup.v3+json
  6. Accept: application/vnd.spAdGroup.v3+json

请求体示例:

  1. {
  2. "name": "广告组-01",
  3. "campaignId": "<campaign_id>",
  4. "defaultBid": 1.2,
  5. "state": "enabled"
  6. }

可以看到,除了路径变化外,Content-Type 也从普通 JSON 变成了专用类型。

1. 商品广告创建

商品广告关联广告组与具体商品。创建时通常需要:

  • 广告组 ID;
  • 商品标识;
  • 商品类型;
  • 广告状态。

对应 Content-Type 可能是:

  1. Content-Type: application/vnd.spProductAd.v3+json

2. 关键词创建

关键词资源同样需要专用 Content-Type:

  1. Content-Type: application/vnd.spKeyword.v3+json
  2. Accept: application/vnd.spKeyword.v3+json

请求体通常包含:

  • 关键词文本;
  • 匹配类型;
  • 出价;
  • 状态。

匹配类型一般包括:

  • 广泛匹配;
  • 短语匹配;
  • 精确匹配。

不同匹配类型会影响广告展示范围与花费速度。

3. 投放目标创建

投放目标用于在自动投放或手动投放中定义展示条件。创建时可能使用:

  1. Content-Type: application/vnd.spTarget.v3+json

投放目标类型包括:

  • 商品定向;
  • 类目定向;
  • 搜索词定向。

部分接口还支持批量更新方式,例如通过 PUT 一次性更新多个目标。

4. 否定关键词与否定投放目标

否定关键词用于排除不相关流量,通常分为:

  • 广告组级否定关键词;
  • 广告活动级否定关键词。

广告组级否定关键词创建示例:

  1. POST /sp/negativeKeywords
  2. Authorization: Bearer <token>
  3. Advertising-API-Client-Id: <client_id>
  4. Advertising-API-Scope: <profile_id>
  5. Content-Type: application/vnd.spNegativeKeyword.v3+json

否定投放目标与否定关键词类似,但作用对象不是搜索词,而是商品、类目或其他投放目标。

六、工程化对接建议

1. 为不同接口版本建立独立客户端

不要试图用一个通用 HTTP 封装覆盖所有接口。建议按接口版本或资源类型拆分为多个客户端类,每个客户端内部维护:

  • Base URL;
  • 默认 Header;
  • Content-Type;
  • 错误处理策略。

例如:

  1. CampaignApiClient
  2. AdGroupApiClient
  3. KeywordApiClient
  4. ProductAdApiClient
  5. NegativeKeywordApiClient

这样可以在保持代码清晰的同时,降低不同接口规范互相干扰的风险。

2. 统一管理认证与账号上下文

虽然接口版本不同,但认证令牌通常是统一的。建议在基础层提供:

  • 令牌获取与刷新;
  • 账号画像缓存;
  • 当前账号上下文管理。

上层客户端只需要读取上下文,不必关心令牌如何获取和刷新。

3. 严格校验 Content-Type 与 Header

在联调前,可以先为每个资源整理一份请求规范表,包含:

  • 资源路径;
  • HTTP 方法;
  • 是否必填账号标识;
  • Header 字段名;
  • Content-Type;
  • Accept;
  • 请求体核心字段;
  • 错误码含义。

这样可以在问题发生时快速定位,而不是反复猜测。

4. 遵循资源创建顺序

建议在代码中显式建模资源依赖。例如:

  1. Campaign -> AdGroup -> ProductAd
  2. Campaign -> AdGroup -> Keyword
  3. Campaign -> AdGroup -> Target
  4. Campaign -> AdGroup -> NegativeKeyword
  5. Campaign -> CampaignNegativeKeyword

服务层可以按顺序调用,并在每一步保存返回的资源 ID。避免因为并发创建或顺序错误导致父资源缺失。

5. 日志与重试

由于多级资源创建是一个串行过程,任何一个环节失败都可能导致后续流程中断。建议为每一步记录关键信息:

  • 请求路径;
  • 请求体摘要;
  • 响应状态码;
  • 返回资源 ID;
  • 失败原因。

对于幂等接口,可以设计安全重试;对于非幂等接口,应避免盲目重试,防止重复创建。

七、常见错误排查

1. 403 或 401

大概率是 Header 使用错误。检查:

  • 是否使用了正确的 Header 字段名;
  • 是否传入了正确的账号画像标识;
  • 令牌是否过期;
  • 是否访问了未授权的接口版本。

2. 415 Unsupported Media Type

几乎可以确定是 Content-Type 不匹配。需要确认资源要求的专用媒体类型,而不是通用 JSON。

3. 400 Bad Request

原因较多,常见包括:

  • 请求体字段名错误;
  • 枚举值不正确;
  • 父级资源 ID 缺失或无效;
  • 媒体类型版本不匹配。

4. 资源不存在

通常是父级资源 ID 缺失或未创建成功。需要检查调用顺序与返回 ID 是否正确保存。

八、总结

广告投放接口对接的复杂度,往往不在于单个接口的调用难度,而在于多版本、多规范、多资源层级的组合。开发者在实际项目中应重点关注以下几点:

  1. 区分不同接口版本,避免统一封装;
  2. 明确每套接口的 Header 与 Content-Type;
  3. 严格按照资源依赖顺序创建;
  4. 为每个资源建立独立的客户端与请求规范;
  5. 做好日志、重试和错误分类。

只有把这些基础工程问题处理清楚,后续的投放策略、数据分析与自动化优化才有稳定可靠的基础。