跳到内容

对象标签 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 to
https://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 to

POST /api/tags

请求正文
Anchor link to
名称类型描述
name*string对象标签的名称。
type*stringOBJECT 表示单个对象,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 to

POST /api/tags/{name}/fields

示例:POST /api/tags/orders/fields
{
"field": { "name": "note", "type": "STRING" }
}

您可以立即将新字段作为整个标签值的一部分写入。如果对象标签已有 20 个字段,或已存在具有该完整字段名称的标签,添加字段会失败,请参阅 错误。

删除字段

Anchor link to

DELETE /api/tags/{name}/fields/{field}

例如,DELETE /api/tags/orders/fields/note 会删除字段 orders.note。您无法删除最后一个字段或正在使用的字段,请参阅 错误。

错误的格式为 {"code": <n>, "message": "...", "details": [...]}。创建对象标签时,400 错误消息以 validate: 开头。

HTTP 状态消息原因
400object tag and field names must contain only letters, digits and underscores名称包含其他字符。
400an object tag needs 1 to 20 fields创建时没有字段或字段超过 20 个。
400an object tag has at most 20 fields对象标签已有 20 个字段。
400field <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不支持的字段类型。
400an object tag needs at least one field; delete the object tag instead您尝试删除最后一个字段。
400field is in use: ..., tag is in use: ...该字段或对象标签正在被细分、In-App、Customer Journey 活动或其他项目使用。
403object tags are not enabled for the account该账户未启用对象标签。
403a device API token cannot call this method, use an account API token请求使用了设备 API 令牌。
404tag not foundGET 或 DELETE /api/tags/{name}:不存在该标签、该名称是字段,或未启用对象标签。
404object tag not found, field not found字段方法:不存在该对象标签或字段。
409tag already exists已存在与对象标签同名的标签。
409tag <object>.<field> already exists已存在与该字段完整名称同名的标签。

使用 /setTags 和 /bulkSetTags 写入对象标签值。这些方法保留各自的身份验证方式:/setTags 在 Authorization: Token 标头中使用设备 API 令牌,/bulkSetTags 在 auth 中使用 API 访问令牌。将 Object 值作为 JSON 对象发送,将 ObjectList 值作为对象数组发送:

示例:/json/1.3/setTags
{
"request": {
"application": "XXXXX-XXXXX",
"userId": "user_42",
"tags": {
"order": { "amount": 120, "status": "paid" },
"orders": [
{ "amount": 120, "status": "paid" },
{ "amount": 50 }
]
}
}
}

如果按 HWID 设置值,该值会存储在该设备所属的用户上。

每个字段接受其类型格式的值:

字段类型示例值
INTEGER120
STRING"paid"
LIST["gift", "express"]
DATE"2026-10-02 22:11"(UTC)、"2026-10-02" 或以秒为单位的 Unix 时间戳
BOOLEANtrue 或 false
PRICE19.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 objectPushwoosh 无法读取对象标签的字段。
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 指定了对象标签,则会导出其所有字段。