跳到内容

功能开关 API

功能开关是一种带有属性的远程开关,SDK 会为每台设备读取这些属性。此 API 管理应用程序的功能开关,其操作与控制面板中 Audience → Feature Flags 的操作相同。要在网站或移动应用中读取功能开关,请使用 Web SDK、Android SDK 或 iOS SDK。

基础 URL

Anchor link to
https://rpc-api.svc-nue.pushwoosh.com

所有端点都通过 HTTPS 提供服务。请求和响应均使用 application/json。

身份验证

Anchor link to

每个请求都必须包含一个 Authorization 标头,其中包含您的 服务器 API 令牌:

Authorization: Api YOUR_API_TOKEN

读取功能开关需要拥有该应用程序的访问权限。创建和更改功能开关需要拥有管理该应用程序的权限。

  • 字段命名: 请求正文接受 lowerCamelCase 或 snake_case。响应使用 snake_case,与 功能开关对象 中一致。
  • 百分比 以基点表示:percent_bp 取值范围为 0 到 10000,其中 2000 表示 20%。
  • 版本: 每个功能开关都带有一个 version。Update、SetRulePercent 和 Reshuffle 接收您上次读取到的版本,如果功能开关在此之后发生了变化,则会失败并返回 VERSION_CONFLICT,因此并发编辑永远不会相互覆盖。请重新读取功能开关并重试。
  • 状态: active、killed 或 archived。Kill、Unkill、Archive 和 Restore 仅更改状态,不接收版本。

每个 REST 端点都有一个参数相同的 MCP 工具:

方法路径描述MCP 工具
GET/api/applications/{application_code}/feature_flags列出应用程序的功能开关list_feature_flags
GET/api/applications/{application_code}/feature_flags/{key}获取单个功能开关get_feature_flag
POST/api/applications/{application_code}/feature_flags创建功能开关create_feature_flag
POST/api/applications/{application_code}/feature_flags/{key}替换名称、描述、属性和规则update_feature_flag
POST/api/applications/{application_code}/feature_flags/{key}/rules/{rule_id}/percent更改单条规则的发布比例set_feature_flag_rule_percent
POST/api/applications/{application_code}/feature_flags/{key}/kill为所有人关闭功能开关kill_feature_flag
POST/api/applications/{application_code}/feature_flags/{key}/unkill重新开启已关闭的功能开关unkill_feature_flag
POST/api/applications/{application_code}/feature_flags/{key}/archive归档功能开关archive_feature_flag
POST/api/applications/{application_code}/feature_flags/{key}/restore恢复已归档的功能开关restore_feature_flag
POST/api/applications/{application_code}/feature_flags/{key}/reshuffle选取新的用户样本reshuffle_feature_flag
GET/api/applications/{application_code}/feature_flags/{key}/history列出功能开关的变更list_feature_flag_history

除 List 和 History 外,每个端点都返回 { "flag": { ... } },即操作完成后的 功能开关对象。

GET /api/applications/{application_code}/feature_flags

请求接收以下参数:

参数位置类型描述
application_codepathstring应用代码。
statusquerystring可选。active、killed 或 archived。省略则列出所有功能开关。

返回 { "flags": [ ... ] },即由 功能开关对象 组成的数组。

GET /api/applications/{application_code}/feature_flags/{key}

返回单个功能开关及其属性、规则和当前 version。

创建一个 active 状态的功能开关。服务器会为每条规则生成 rule_id。

POST /api/applications/{application_code}/feature_flags

请求正文包含以下字段:

参数类型必需描述
keystring是须匹配 ^[A-Za-z0-9_.-]{1,58}$。在应用程序内唯一(包括已归档的功能开关),比较时不区分大小写。创建后无法更改。
namestring否显示名称,最多 255 个字符。
descriptionstring否描述。
properties属性对象 数组否最多 50 个属性。
defaultsobject有属性时必需功能开关处于关闭状态的设备所获得的每个属性的值,以属性键为键。每个值都必须与属性类型匹配。
rules规则对象 数组否有序规则,最多 10 条。由第一条细分与设备匹配的规则决定结果。
请求示例
Anchor link to
{
"key": "new_checkout",
"name": "New checkout",
"properties": [
{ "key": "button_color", "type": "string" },
{ "key": "show_apple_pay", "type": "boolean" }
],
"defaults": { "button_color": "blue", "show_apple_pay": false },
"rules": [
{
"name": "Beta testers",
"filter_code": "XXXXX-XXXXX",
"percent_bp": 10000,
"overrides": { "button_color": "green", "show_apple_pay": true }
},
{
"name": "Everyone else",
"filter_code": "",
"percent_bp": 2000,
"overrides": { "button_color": "orange" }
}
]
}

替换功能开关的名称、描述、属性、默认值和规则。此处永远不会更改状态。请发送所有字段,而不仅仅是更改过的字段。

POST /api/applications/{application_code}/feature_flags/{key}

接收与 创建 相同但不含 key 的正文,并加上您上次读取到的 version。保留每条现有规则的 rule_id。没有 rule_id 的规则会作为新规则创建。属性创建后,其类型无法更改。

SetRulePercent

Anchor link to

更改单条规则的发布比例。比例增大时,已经获得该功能开关的用户会保留它。

POST /api/applications/{application_code}/feature_flags/{key}/rules/{rule_id}/percent

{ "percentBp": 5000, "version": 3 }

Kill 和 Unkill

Anchor link to

POST .../feature_flags/{key}/kill 为每台设备关闭功能开关,设备随后会获得默认属性值。规则和属性会被保留。

POST .../feature_flags/{key}/unkill 重新开启已关闭的功能开关,其规则保持原样。

两者都接收空正文 {}。

归档和恢复

Anchor link to

POST .../feature_flags/{key}/archive 停止向设备发送该功能开关。已归档的功能开关不计入套餐中每个应用程序的功能开关数量限制,其键仍保持保留状态。

POST .../feature_flags/{key}/restore 将已归档的功能开关恢复为 killed 状态,因此它永远不会自行开启。调用 unkill 可再次发布它。

两者都接收空正文 {}。

重新洗牌

Anchor link to

将每个用户放入一个新的分桶,使相同的百分比选中不同的用户样本。部分已开启该功能开关的用户会失去它,而其他用户会获得它。

POST /api/applications/{application_code}/feature_flags/{key}/reshuffle

{ "confirm": true, "version": 3 }

confirm 必须为 true。否则请求会失败并返回 CONFIRM_REQUIRED。

历史记录

Anchor link to

返回功能开关的变更,按从新到旧排序:每次变更由谁进行、何时进行以及更改了哪些字段。与 Get 一样,它需要应用程序的访问权限;如果应用程序或功能开关不存在,则返回 404。

GET /api/applications/{application_code}/feature_flags/{key}/history

请求接收以下参数:

参数位置类型描述
application_codepathstring应用代码。
keypathstring功能开关的键。
pagequeryinteger可选。页码,从 0 开始。
per_pagequeryinteger可选。每页条目数,默认为 20,最多 100。

返回 { "entries": [ ... ], "total": N },其中 total 是所有页面的条目总数。每个条目包含以下字段:

字段类型描述
versioninteger此次变更产生的功能开关版本。
actionstringcreate、update、set_percent、kill、unkill、archive、restore 或 reshuffle。
user_idstring进行此次变更的控制面板用户的 ID。如果变更是通过 API 令牌或由 Pushwoosh 服务进行的,则为 0。
user_emailstring该用户的电子邮件地址。如果用户已被删除或 user_id 为 0,则为空。
by_api_tokenboolean如果变更是通过 API 令牌进行的,则为 true。如果变更由用户或 Pushwoosh 服务进行,则为 false。
api_token_namestring变更发生时 API 令牌的名称。删除令牌后该名称仍会保留。如果令牌没有名称或 by_api_token 为 false,则为空。
createdstring变更时间,RFC 3339 格式。
flag功能开关对象变更后的功能开关。
changesarray与上一版本不同的字段。对于 create 和 reshuffle,以及在开始记录历史之前创建的功能开关的最早条目,此数组为空,因为没有更早的版本可供比较。

changes 中的每一项都包含 field、before 和 after。before 和 after 中的值以 JSON 字符串形式编码,因此字符串值会带引号。field 可取以下值:

field变更内容
name, description, status同名的功能开关字段。
properties属性及其默认值。
rules[<rule_id>]一条规则。对于新增的规则,before 为空。对于删除的规则,after 为空。
rules.order规则的顺序。
响应示例
Anchor link to
{
"entries": [
{
"version": 4,
"action": "set_percent",
"user_id": "12345",
"user_email": "owner@example.com",
"by_api_token": false,
"api_token_name": "",
"created": "2026-10-14T09:30:00Z",
"flag": { "key": "new_checkout", "status": "active", "version": 4 },
"changes": [
{
"field": "rules[r_1a2b3c4d]",
"before": "{\"rule_id\":\"r_1a2b3c4d\",\"name\":\"Beta testers\",\"filter_code\":\"XXXXX-XXXXX\",\"percent_bp\":2000,\"overrides\":{\"button_color\":\"green\"}}",
"after": "{\"rule_id\":\"r_1a2b3c4d\",\"name\":\"Beta testers\",\"filter_code\":\"XXXXX-XXXXX\",\"percent_bp\":5000,\"overrides\":{\"button_color\":\"green\"}}"
}
]
}
],
"total": 4
}

示例中的 flag 对象已做简化。历史记录从 2026 年 10 月 13 日起记录变更。没有已记录变更的功能开关不返回任何条目。

读取设备的功能开关

Anchor link to

SDK 通过单独的端点读取功能开关。使用 Web SDK、Android SDK 或 iOS SDK 时无需调用该端点,因为它们会自行选择主机并缓存响应。

POST https://api.pushwoosh.com/api/v2/device-api/getFeatureFlags

请求正文包含以下字段:

字段类型描述
applicationstring应用代码。
hwidstring设备的 HWID。
etagstring可选。设备所持有的最近一次响应的 etag。

响应包含以下字段:

字段类型描述
flagsobject以功能开关键为键的功能开关。每个功能开关都包含 enabled、rule_id 和 properties。如果没有匹配的规则,rule_id 为 default;对于已关闭的功能开关,rule_id 为空。已归档的功能开关不包含在内。
etagstring在下一次请求中发送它。
not_modifiedboolean如果发送的 etag 是最新的,则为 true。此时将省略 flags,设备保留其副本。
partialboolean如果未能及时匹配设备的细分,则为 true。请勿缓存此响应。

在不包含功能开关的套餐中,响应为空。

功能开关对象

Anchor link to

每个端点都以如下结构返回功能开关:

字段类型描述
application_codestring功能开关所属的应用程序。
keystring功能开关的键。
namestring显示名称。
descriptionstring描述。
statusstringactive、killed 或 archived。
properties属性对象 数组功能开关的属性。
defaultsobject功能开关处于关闭状态的设备所获得的每个属性的值。
rules规则对象 数组有序规则。
versioninteger在 Update、SetRulePercent 和 Reshuffle 中将其发回。
createdstring创建时间,RFC 3339 格式。
updatedstring最后更改时间,RFC 3339 格式。
last_modified_by_user_idstring最后更改该功能开关的控制面板用户。如果最后一次更改是通过 API 令牌或由 Pushwoosh 服务进行的,则为 0。

属性对象

Anchor link to

属性描述 SDK 从功能开关中读取的一个值:

字段类型描述
keystring须匹配 ^[A-Za-z0-9_]{1,64}$,在功能开关内唯一。
typestringstring、number、boolean 或 json。属性创建后无法更改。

规则对象

Anchor link to

规则决定谁会开启功能开关以及使用哪些值:

字段类型描述
rule_idstring由服务器生成,格式为 r_ 后跟 8 位十六进制数字,在更新过程中保持不变。新规则请留空。
namestring规则名称。
filter_codestring设备必须匹配的 细分。为空则匹配所有设备。该细分只能包含标签、位置、应用程序和列表条件。
percent_bpinteger匹配用户中开启功能开关的比例,0–10000。与细分匹配的设备会停在此规则,即使它落在该百分比之外。
overridesobject对于此规则开启的设备,用于替换默认值的属性值,以属性键为键。

被拒绝的请求会返回以下 HTTP 状态码之一:

HTTP 状态含义
400 Bad Request请求无效(field_violations),或功能开关的状态或套餐不允许该请求(Type)。请参阅下面的正文格式和原因。
401 Unauthorized缺少 Authorization 标头或令牌无效。
403 Forbidden该令牌无法管理该应用程序,或该应用程序是系统应用程序。
404 Not Found应用程序或功能开关不存在。
409 Conflict另一个请求此时正在更改同一个功能开关。请重试该请求。
500 Internal Server Error意外的服务器故障。正文为 {"message": "Sorry, an unexpected error occurred"}。

无效请求会返回 400 以及字段违规列表。每个违规都会指明字段、原因以及原因的参数:

{
"code": 3,
"message": "validation failed",
"details": [
{
"@type": "type.googleapis.com/pushwoosh.rpc.errors.v3.BadRequest",
"field_violations": [
{
"field": "key",
"description": "a feature flag with this key already exists in the application",
"reason": "KEY_TAKEN",
"args": { "key": "new_checkout" }
}
]
}
]
}

功能开关的状态或套餐不允许的请求会返回 400 以及一个失败的前置条件。其 Type 和 Description 字段首字母大写:

{
"code": 9,
"message": "precondition failed",
"details": [
{
"@type": "type.googleapis.com/pushwoosh.rpc.errors.v3.FailedPrecondition",
"Type": "VERSION_CONFLICT",
"Description": "feature flag was changed: version 3 was sent, the current one is 4"
}
]
}

字段违规的 reason 和失败前置条件的 Type 取以下值:

原因起因
KEY_INVALID键不匹配 ^[A-Za-z0-9_.-]{1,58}$。
KEY_TAKEN应用程序的另一个功能开关(包括已归档的)已使用此键。
TEXT_INVALID名称或描述过长或包含禁用字符。
PROPERTIES_LIMIT属性超过 50 个。
PROPERTY_KEY_INVALID属性键无效或重复。
PROPERTY_TYPE_INVALID属性类型不是 string、number、boolean 或 json。
PROPERTY_TYPE_IMMUTABLE请求更改了现有属性的类型。
VALUE_INVALID默认值或覆盖值缺失、与属性类型不匹配,或嵌套深度超过 5 层。
PROPERTIES_TOO_LARGE功能开关的属性值超过 10,000 字节。
RULES_LIMIT规则超过 10 条。
RULE_NOT_FOUND该 rule_id 不属于该功能开关的规则。
PERCENT_INVALIDpercent_bp 超出 0–10000 范围。
OVERRIDE_UNKNOWN_PROPERTY覆盖值指定了功能开关中不存在的属性。
SEGMENT_NOT_FOUND规则细分不存在或属于另一个应用程序。
INVALID_SEGMENT_TYPE规则细分包含功能开关无法评估的条件:事件、静态、外部、最后更新或最佳发送时间。
FLAG_DEPENDENCY规则细分包含功能开关条件,而功能开关不能依赖另一个功能开关。由 Create、Update 和 Restore 返回,细分代码位于 filter_code 中。
CONFIRM_REQUIRED发送 Reshuffle 时未带 confirm: true。
TAG_CONFLICT账户中存在名为 PW_FF_ 后跟功能开关键的自定义标签。
FEATURE_FLAGS_NOT_ALLOWED账户的套餐不包含功能开关。
FLAGS_LIMIT应用程序中未归档的功能开关数量已达到套餐允许的上限。
VERSION_CONFLICT自您发送的 version 以来,功能开关已发生变化。
PAYLOAD_TOO_LARGE应用程序的功能开关在单台设备的响应中将超过 64 KB。
STATUS_CONFLICT当前状态不允许该操作,例如关闭已归档的功能开关。