对象标签 API (Beta)
对象标签可在一个标签中存储有关用户的结构化数据。Object 类型的标签保存一个带有命名字段的对象,例如最近一笔 order 及其 amount 和 status。ObjectList 类型的标签保存此类对象的数组,例如所有 orders。您只需定义一次字段,即可通过标签 API 写入和读取值,并按字段值构建细分。
对象标签的工作原理
Anchor link to对象标签包含架构和值。架构是标签名称和字段列表,每个字段都有自己的标量类型。值存储在字段中,每个用户单独存储。
- 字段。 每个字段都是一个名为
<object>.<field>的标签,例如order.amount。您可以按字段进行细分,也可以通过此名称写入Object标签的字段。 Object值。 每个用户一个对象,例如"order": {"amount": 120, "status": "paid"}。ObjectList值。 具有相同字段的对象数组,例如"orders": [{"amount": 120, "status": "paid"}, {"amount": 50}]。
对象标签始终是 User-specific 标签,即值属于用户而非单个设备,并会复制到该用户的所有设备上。有关常规标签,请参阅 标签 API。
架构规则
Anchor link to在您创建对象标签或添加字段时,Pushwoosh 会检查以下规则:
- 对象名称和字段名称只能包含拉丁字母、数字和
_。 - 完整字段名称
<object>.<field>不超过 64 个字符。 - 一个对象标签有 1 到 20 个字段。字段名称不区分大小写,因此
Amount和amount是同一个字段。 - 字段的类型为以下之一:
INTEGER、STRING、LIST、DATE、BOOLEAN、PRICE、VERSION。不支持时区字段和嵌套对象。 - 字段不能使用其他标签已有的名称。如果标签
order.note已存在,向order添加字段note会失败并返回tag order.note already exists。 - 对象标签不能删除其最后一个字段。请改为删除该对象标签。
- 正在使用的字段或对象标签无法删除。错误信息会列出其使用位置,例如
field is in use: segment Big buyers, in-app Spring sale。引用该标签的细分、In-App、正在运行的 Customer Journey 活动、预设、电子邮件模板及其他项目均计为使用。
管理架构
Anchor link to使用以下 REST 方法创建和更改对象标签。/json/1.3/addTag 仅用于常规标签,因为它无法定义字段。
基础 URL
Anchor link tohttps://rpc-api.svc-nue.pushwoosh.com身份验证
Anchor link to每个请求都必须包含一个 Authorization 标头,其中包含您的 服务器 API 令牌。使用设备 API 令牌会返回 HTTP 403 a device API token cannot call this method, use an account API token。
Authorization: Api YOUR_API_TOKEN以下方法用于管理对象标签的架构:
| 方法 | 路径 | 描述 |
|---|---|---|
POST | /api/tags | 创建对象标签及其字段 |
GET | /api/tags/{name} | 获取对象标签及其字段 |
GET | /api/tags | 列出标签。对象标签会附带其 fields 返回,字段不会作为单独的标签列出 |
POST | /api/tags/{name}/fields | 添加字段 |
DELETE | /api/tags/{name}/fields/{field} | 删除字段 |
DELETE | /api/tags/{name} | 删除对象标签及其所有字段 |
POST /api/tags 和两个字段方法会返回更改后的对象标签,包装在 {"tag": {...}} 中。DELETE /api/tags/{name} 返回 {}。
如果您的账户未启用对象标签,使用对象类型调用 POST /api/tags 以及两个字段方法都会失败并返回 HTTP 403 object tags are not enabled for the account。GET /api/tags/{name} 和 DELETE /api/tags/{name} 返回 HTTP 404 tag not found,GET /api/tags 不会列出对象标签。未启用对象标签时,您无法创建对象标签,因此也就没有可写入值的对象。
创建对象标签
Anchor link toPOST /api/tags
请求正文
Anchor link to| 名称 | 类型 | 描述 |
|---|---|---|
| name* | string | 对象标签的名称。 |
| type* | string | OBJECT 表示单个对象,OBJECT_LIST 表示对象列表。 |
| fields* | array | 对象的字段,1 到 20 个。 |
| fields[].name* | string | 字段名称。该字段会成为标签 <name>.<fields[].name>。 |
| fields[].type* | string | 字段类型:INTEGER、STRING、LIST、DATE、BOOLEAN、PRICE 或 VERSION。 |
{ "name": "orders", "type": "OBJECT_LIST", "fields": [ { "name": "amount", "type": "INTEGER" }, { "name": "status", "type": "STRING" } ]}{ "tag": { "name": "orders", "type": "OBJECT_LIST", "system": false, "user_specific": true, "has_right_ace_modify": true, "fields": [ { "name": "amount", "type": "INTEGER" }, { "name": "status", "type": "STRING" } ] }}无论 user_specific 的值是什么,该标签都会创建为 User-specific 标签。GET /api/tags/{name} 返回相同的对象,但不带 tag 包装。字段按名称排序。
添加字段
Anchor link toPOST /api/tags/{name}/fields
{ "field": { "name": "note", "type": "STRING" }}您可以立即将新字段作为整个标签值的一部分写入。如果对象标签已有 20 个字段,或已存在具有该完整字段名称的标签,添加字段会失败,请参阅 错误。
删除字段
Anchor link toDELETE /api/tags/{name}/fields/{field}
例如,DELETE /api/tags/orders/fields/note 会删除字段 orders.note。您无法删除最后一个字段或正在使用的字段,请参阅 错误。
错误的格式为 {"code": <n>, "message": "...", "details": [...]}。创建对象标签时,400 错误消息以 validate: 开头。
| HTTP 状态 | 消息 | 原因 |
|---|---|---|
| 400 | object tag and field names must contain only letters, digits and underscores | 名称包含其他字符。 |
| 400 | an object tag needs 1 to 20 fields | 创建时没有字段或字段超过 20 个。 |
| 400 | an object tag has at most 20 fields | 对象标签已有 20 个字段。 |
| 400 | field <name> is given twice | 两个字段名称相同(不区分大小写)。 |
| 400 | <object>.<field>: object and field names together cannot be longer than 64 characters | 完整字段名称过长。 |
| 400 | <object>.<field>: field type must be INTEGER, STRING, LIST, DATE, BOOLEAN, PRICE or VERSION | 不支持的字段类型。 |
| 400 | an object tag needs at least one field; delete the object tag instead | 您尝试删除最后一个字段。 |
| 400 | field is in use: ..., tag is in use: ... | 该字段或对象标签正在被细分、In-App、Customer Journey 活动或其他项目使用。 |
| 403 | object tags are not enabled for the account | 该账户未启用对象标签。 |
| 403 | a device API token cannot call this method, use an account API token | 请求使用了设备 API 令牌。 |
| 404 | tag not found | GET 或 DELETE /api/tags/{name}:不存在该标签、该名称是字段,或未启用对象标签。 |
| 404 | object tag not found, field not found | 字段方法:不存在该对象标签或字段。 |
| 409 | tag already exists | 已存在与对象标签同名的标签。 |
| 409 | tag <object>.<field> already exists | 已存在与该字段完整名称同名的标签。 |
使用 /setTags 和 /bulkSetTags 写入对象标签值。这些方法保留各自的身份验证方式:/setTags 在 Authorization: Token 标头中使用设备 API 令牌,/bulkSetTags 在 auth 中使用 API 访问令牌。将 Object 值作为 JSON 对象发送,将 ObjectList 值作为对象数组发送:
{ "request": { "application": "XXXXX-XXXXX", "userId": "user_42", "tags": { "order": { "amount": 120, "status": "paid" }, "orders": [ { "amount": 120, "status": "paid" }, { "amount": 50 } ] } }}如果按 HWID 设置值,该值会存储在该设备所属的用户上。
每个字段接受其类型格式的值:
| 字段类型 | 示例值 |
|---|---|
INTEGER | 120 |
STRING | "paid" |
LIST | ["gift", "express"] |
DATE | "2026-10-02 22:11"(UTC)、"2026-10-02" 或以秒为单位的 Unix 时间戳 |
BOOLEAN | true 或 false |
PRICE | 19.95 |
VERSION | "1.0.0" |
写入会替换整个值
Anchor link to每次写入都会替换对象标签的已存储值:
- 新值中缺少的字段会被删除。以
null发送的字段也会被删除。 null、[]或""会删除整个值。{}会删除Object标签的所有字段。- 不属于该对象字段的键会被跳过。
- 如果某个字段值与字段类型不匹配,则该标签的整个值都会被拒绝,已存储的值保持不变。
/setTags 不会在响应中报告被拒绝的值。请使用 /getTags 检查结果,或使用 /bulkSetTags,它会为每个标签报告结果。
写入 Object 的单个字段
Anchor link to按完整名称写入 Object 标签的单个字段。increment 以及 /setTags 的其他操作都适用于字段:
"tags": { "order.status": "shipped", "order.amount": { "operation": "increment", "value": 5 }}ObjectList 标签的字段无法单独写入,因为无法确定要更改哪个元素。/setTags 会忽略此类值。请改为发送整个列表。
对象标签不会自动创建
Anchor link to如果某个标签不存在,为其传入对象或对象数组的值会被跳过。标签自动创建不会创建对象标签,因此请先使用 POST /api/tags 创建架构。
bulkSetTags 结果
Anchor link to使用 detailed=true 时,除 ok、tag not found 和 wrong value. expect :<type> 外,/bulkSetTags 状态 还会为对象标签返回以下结果之一:
| 结果 | 原因 |
|---|---|
object tags are stored on the user only | 对象标签不是 User-specific 标签。 |
cannot load the fields of the object | Pushwoosh 无法读取对象标签的字段。 |
wrong value. expect an object (a map) or, for a list of objects, an array of maps | 值不适用于该对象标签,或某个字段值与其类型不匹配。 |
a field of a list of objects cannot be set on its own, set the whole list | 值被设置到 ObjectList 标签的字段上。 |
/getTags 将 Object 值作为 JSON 对象返回,将 ObjectList 值作为对象数组返回:
{ "status_code": 200, "status_message": "OK", "response": { "result": { "order": { "amount": 120, "status": "paid" }, "orders": [ { "amount": 120, "status": "paid" }, { "amount": 50 } ] } }}字段值的返回方式与 /getTags 中常规标签值相同:Date 以秒为单位的 Unix 时间戳返回,Price 以字符串形式返回(例如 "120.00"),Boolean 以 1 或 0 返回。
按字段细分
Anchor link to请对字段设置细分条件,而不是对对象标签本身设置。在 细分语言 中,字段是名称中带点的标签,并使用其自身类型的运算符:
AT("XXXXX-XXXXX", "order.amount", gte, 100)对对象标签本身设置的条件会失败并返回 object tag has no value of its own, use one of its fields。
ObjectList 上的条件
Anchor link to当列表中至少有一个元素符合条件时,ObjectList 标签字段上的条件即匹配该用户。用 AND 连接的同一列表字段上的条件必须匹配同一个元素:
AT("XXXXX-XXXXX", "orders.amount", gte, 100) * AT("XXXXX-XXXXX", "orders.status", eq, "paid")此细分包含至少有一笔订单同时满足金额为 100 或以上且已支付的用户。如果用户有一笔未支付的大额订单和一笔已支付的小额订单,则不匹配。用 OR 连接的条件不必匹配同一个元素。两个不同列表上的条件会在各自的列表上分别检查。
某些运算符在 ObjectList 标签的字段上的工作方式不同:
notset。 列表中没有任何元素在此字段中有值。没有该列表的用户也匹配。noteq。 至少有一个元素在此字段中有值,且该值与给定值不同。没有该字段的元素不计入。订单状态为paid和new的用户匹配noteq "paid"。- List 字段上的
notin。 没有任何元素包含任一给定值。 - 其他类型字段上的
notin。 至少有一个元素在此字段中的值不在给定值之中。
notset 和 List 字段上的 notin 不会与用 AND 连接的其他条件绑定到同一个元素。
导出包含对象标签的细分
Anchor link to/exportSegment 会导出对象标签的字段:
- CSV。 每个字段是一个名为
<object>.<field>的单独列,对象标签本身没有列。ObjectList 的字段以 JSON 数组形式保存所有元素中的不同值,与 List 标签相同:["120","50"]。 json和json_each_line。Object标签的字段以名为<object>.<field>的单独标签形式出现。ObjectList标签作为tags中的一个条目出现,其元素位于object_list.items中。每个元素以短名称列出其字段,每个字段的值位于以其类型命名的键下:integer、string、list、date、boolean、price或version。整数值以字符串形式返回:
{ "name": "orders", "object_list": { "items": [ { "fields": [{ "name": "amount", "integer": "120" }, { "name": "status", "string": "paid" }] }, { "fields": [{ "name": "amount", "integer": "50" }] } ] }}如果 tagsList 指定了对象标签,则会导出其所有字段。