5.4 A/B 测试接口

5.4 A/B 测试接口

A/B 测试管理接口前缀为 /api/v1/ab_tests,均需认证。公开转化反馈接口为 /api/v1/public/ab_test_feedback,不需要登录态或 Bearer Token,写入范围由 _dwz_abt 签名 token 限制。

受保护接口支持工作区上下文请求头:

Authorization: Bearer {token}
X-Workspace-Id: 1

创建 A/B 测试

POST /api/v1/ab_tests
Content-Type: application/json

{
  "short_link_id": 42,
  "name": "落地页颜色测试",
  "description": "比较红色与蓝色落地页的转化效果",
  "traffic_split": "weighted",
  "start_time": "2026-04-15T00:00:00Z",
  "end_time": "2026-04-30T23:59:59Z",
  "variants": [
    {
      "name": "红色",
      "target_url": "https://example.com/red",
      "weight": 60,
      "is_control": true,
      "description": "对照组"
    },
    {
      "name": "蓝色",
      "target_url": "https://example.com/blue",
      "weight": 40,
      "is_control": false,
      "description": "实验组"
    }
  ]
}

traffic_split 支持:equal / weighted / custom。创建时至少需要 2 个变体。

列表

GET /api/v1/ab_tests?page=1&page_size=20&status=running&short_link_id=42

查询参数:

参数 必填 说明
page 页码,默认 1
page_size 每页数量,默认 10,最大 100
short_link_id 按短链接筛选
status 按状态筛选

详情

GET /api/v1/ab_tests/{id}

更新

PUT /api/v1/ab_tests/{id}
Content-Type: application/json

{
  "name": "新的测试名称",
  "description": "更新后的描述",
  "status": "paused",
  "traffic_split": "equal",
  "start_time": "2026-04-15T00:00:00Z",
  "end_time": "2026-04-30T23:59:59Z",
  "is_active": true
}

删除

DELETE /api/v1/ab_tests/{id}

启动

POST /api/v1/ab_tests/{id}/start
Content-Type: application/json

{
  "start_time": "2026-04-15T00:00:00Z"
}

start_time 可选,不传则立即启动。

停止

POST /api/v1/ab_tests/{id}/stop
Content-Type: application/json

{
  "end_time": "2026-04-30T23:59:59Z"
}

end_time 可选,不传则立即停止。停止后实验状态变为 completed

获取 A/B 测试统计

GET /api/v1/ab_tests/{id}/statistics?days=30

查询参数:

参数 必填 说明
days 统计最近天数,默认 7,最大 365

响应示例:

{
  "code": 0,
  "message": "success",
  "data": {
    "ab_test_id": 1,
    "total_clicks": 1000,
    "total_conversions": 138,
    "conversion_value": 2999.5,
    "variant_stats": [
      {
        "variant": {
          "id": 1,
          "ab_test_id": 1,
          "name": "版本A",
          "target_url": "https://example.com/page-a",
          "weight": 50,
          "is_control": true
        },
        "click_count": 480,
        "unique_clicks": 460,
        "conversion_count": 58,
        "conversion_rate": 12.61,
        "conversion_value": 1200,
        "percentage": 48
      },
      {
        "variant": {
          "id": 2,
          "ab_test_id": 1,
          "name": "版本B",
          "target_url": "https://example.com/page-b",
          "weight": 50,
          "is_control": false
        },
        "click_count": 520,
        "unique_clicks": 500,
        "conversion_count": 80,
        "conversion_rate": 16,
        "conversion_value": 1799.5,
        "percentage": 52
      }
    ],
    "daily_stats": [
      {
        "date": "2024-01-15",
        "variants": {
          "1": 45,
          "2": 55
        }
      }
    ],
    "conversion_rate": 14.38,
    "winning_variant": {
      "id": 2,
      "name": "版本B"
    }
  }
}

统计口径:

  • click_count:变体点击次数。
  • unique_clicks:变体唯一会话点击数。
  • conversion_count:通过分流反馈接口写入的业务结果数。
  • 变体 conversion_rateconversion_count / unique_clicks * 100,无唯一点击时为 0
  • 顶层 conversion_ratetotal_conversions / 所有变体 unique_clicks 之和 * 100
  • conversion_value:反馈事件 value 汇总。
  • winning_variant:当前按转化数最高的变体计算。

上报 A/B 测试转化反馈

POST /api/v1/public/ab_test_feedback
Content-Type: application/json

{
  "feedback_token": "<_dwz_abt 参数值>",
  "event_id": "order-202401150001",
  "value": 99.9,
  "currency": "CNY",
  "metadata": {
    "plan": "pro"
  },
  "occurred_at": "2024-01-15T10:30:00Z"
}

A/B 测试跳转到变体目标 URL 时会追加 _dwz_abt 参数。落地页或业务系统在产生注册、下单、购买等结果后,用该 token 回传转化。

参数说明:

参数 必填 说明
feedback_token 短链 A/B 跳转目标 URL 中 _dwz_abt 的值
event_id 业务事件唯一 ID,同一 A/B 测试内幂等,最长 128 字符
value 转化价值,必须大于等于 0
currency 币种,服务端会转为大写,最长 16 字符
metadata 业务附加信息,序列化后最大 4096 字节
occurred_at 业务事件发生时间,ISO 8601 格式;不传则使用服务端当前时间

成功响应:

{
  "code": 0,
  "message": "success",
  "data": {
    "id": 10,
    "duplicate": false,
    "workspace_id": 1,
    "ab_test_id": 1,
    "variant_id": 2,
    "short_link_id": 5,
    "session_id": "ab_1_5_xxx",
    "event_id": "order-202401150001"
  }
}

重复提交相同 event_id 会返回成功,但 duplicatetrue,不会重复计入转化。

错误说明:

HTTP 状态 code 场景
400 40001 缺少 feedback_token、缺少 event_id、字段长度非法、value 为负数
401 40101 token 无效、被篡改、过期,或 token 绑定的实验/变体不存在
500 50001 服务端写入失败

变体级点击统计

GET /api/v1/ab_test_click_statistics/{id}/variants

该接口按变体返回点击时间序列,适合绘图。转化数与转化率以 GET /api/v1/ab_tests/{id}/statistics 为准。

落地页自动回传示例

const token = new URLSearchParams(location.search).get('_dwz_abt');

if (token) {
  await fetch('https://your-domain.com/api/v1/public/ab_test_feedback', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      feedback_token: token,
      event_id: 'order-202401150001',
      value: 99.9,
      currency: 'CNY',
      metadata: {
        order_id: '202401150001',
        plan: 'pro'
      }
    })
  });
}