Feature Flags API
Este contenido aún no está disponible en su idioma.
A feature flag is a remote switch with properties that the SDK reads for each device. This API manages the flags of an application: the same operations as Audience → Feature Flags in the Control Panel. To read flags on a website, use the Web SDK.
Base URL
Anchor link tohttps://rpc-api.svc-nue.pushwoosh.comAll endpoints are served over HTTPS. Requests and responses use application/json.
Authentication
Anchor link toEvery request must include an Authorization header with your Server API token:
Authorization: Api YOUR_API_TOKENReading flags needs access to the application. Creating and changing them needs the right to manage it.
Conventions
Anchor link to- Field naming: request bodies accept
lowerCamelCaseorsnake_case. Responses usesnake_case, as in the Feature flag object. - Percentages are in basis points:
percent_bpfrom0to10000, where2000is 20%. - Versions: every flag carries a
version.Update,SetRulePercent, andReshuffletake the version you last read and fail withVERSION_CONFLICTwhen the flag changed since, so concurrent edits never overwrite each other. Read the flag again and retry. - Statuses:
active,killed, orarchived.Kill,Unkill,Archive, andRestorechange only the status and take no version.
Endpoints
Anchor link toEach REST endpoint has an MCP tool with the same parameters:
| Method | Path | Description | MCP tool |
|---|---|---|---|
GET | /api/applications/{application_code}/feature_flags | List the application’s flags | list_feature_flags |
GET | /api/applications/{application_code}/feature_flags/{key} | Get one flag | get_feature_flag |
POST | /api/applications/{application_code}/feature_flags | Create a flag | create_feature_flag |
POST | /api/applications/{application_code}/feature_flags/{key} | Replace name, description, properties, and rules | update_feature_flag |
POST | /api/applications/{application_code}/feature_flags/{key}/rules/{rule_id}/percent | Change the rollout of one rule | set_feature_flag_rule_percent |
POST | /api/applications/{application_code}/feature_flags/{key}/kill | Turn the flag off for everyone | kill_feature_flag |
POST | /api/applications/{application_code}/feature_flags/{key}/unkill | Turn a killed flag back on | unkill_feature_flag |
POST | /api/applications/{application_code}/feature_flags/{key}/archive | Archive a flag | archive_feature_flag |
POST | /api/applications/{application_code}/feature_flags/{key}/restore | Restore an archived flag | restore_feature_flag |
POST | /api/applications/{application_code}/feature_flags/{key}/reshuffle | Pick a new sample of users | reshuffle_feature_flag |
Every endpoint except List returns { "flag": { ... } }, the Feature flag object after the operation.
List
Anchor link toGET /api/applications/{application_code}/feature_flags
The request takes these parameters:
| Parameter | In | Type | Description |
|---|---|---|---|
application_code | path | string | The application code. |
status | query | string | Optional. active, killed, or archived. Omit to list all flags. |
Returns { "flags": [ ... ] }, an array of Feature flag objects.
GET /api/applications/{application_code}/feature_flags/{key}
Returns one flag with its properties, rules, and current version.
Create
Anchor link toCreates an active flag. The server generates the rule_id of every rule.
POST /api/applications/{application_code}/feature_flags
The request body has these fields:
| Parameter | Type | Required | Description |
|---|---|---|---|
key | string | Yes | Matches ^[A-Za-z0-9_.-]{1,58}$. Unique in the application, archived flags included, compared case-insensitively. Can’t be changed later. |
name | string | No | Display name, up to 255 characters. |
description | string | No | Description. |
properties | array of Property objects | No | Up to 50 properties. |
defaults | object | Yes, if there are properties | The value of every property for devices the flag is off for, keyed by property key. Each value must match the property type. |
rules | array of Rule objects | No | Ordered rules, up to 10. The first rule whose segment matches the device decides. |
Request example
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" } } ]}Update
Anchor link toReplaces the name, description, properties, defaults, and rules of a flag. The status never changes here. Send all fields, not only the changed ones.
POST /api/applications/{application_code}/feature_flags/{key}
Takes the same body as Create without key, plus version from your last read. Keep the rule_id of every existing rule. A rule without rule_id is created as new. A property’s type can’t change after the property is created.
SetRulePercent
Anchor link toChanges the rollout of one rule. Users who already have the flag keep it when the percentage grows.
POST /api/applications/{application_code}/feature_flags/{key}/rules/{rule_id}/percent
{ "percentBp": 5000, "version": 3 }Kill and Unkill
Anchor link toPOST .../feature_flags/{key}/kill turns the flag off for every device, which then gets the default property values. Rules and properties are kept.
POST .../feature_flags/{key}/unkill turns a killed flag back on with its rules as they were.
Both take an empty body {}.
Archive and Restore
Anchor link toPOST .../feature_flags/{key}/archive stops sending the flag to devices. An archived flag doesn’t count toward the plan’s limit of flags per application, and its key stays reserved.
POST .../feature_flags/{key}/restore brings an archived flag back as killed, so it never turns on by itself. Call unkill to roll it out again.
Both take an empty body {}.
Reshuffle
Anchor link toPlaces every user in a new bucket, so the same percentages select a different sample of users. Some users who have the flag on lose it, and others get it.
POST /api/applications/{application_code}/feature_flags/{key}/reshuffle
{ "confirm": true, "version": 3 }confirm must be true. Otherwise the request fails with CONFIRM_REQUIRED.
Objects
Anchor link toFeature flag object
Anchor link toEvery endpoint returns the flag in this shape:
| Field | Type | Description |
|---|---|---|
application_code | string | The application the flag belongs to. |
key | string | The flag key. |
name | string | Display name. |
description | string | Description. |
status | string | active, killed, or archived. |
properties | array of Property objects | The flag’s properties. |
defaults | object | The value of every property for devices the flag is off for. |
rules | array of Rule objects | Ordered rules. |
version | integer | Send it back with Update, SetRulePercent, and Reshuffle. |
created | string | Creation time, RFC 3339. |
updated | string | Last change time, RFC 3339. |
last_modified_by_user_id | string | The Control Panel user who changed the flag last. |
Property object
Anchor link toA property describes one value the SDK reads from the flag:
| Field | Type | Description |
|---|---|---|
key | string | Matches ^[A-Za-z0-9_]{1,64}$, unique within the flag. |
type | string | string, number, boolean, or json. Can’t change once the property exists. |
Rule object
Anchor link toA rule decides who gets the flag on and with which values:
| Field | Type | Description |
|---|---|---|
rule_id | string | Generated by the server, r_ followed by 8 hex digits, and stable across updates. Leave it empty for a new rule. |
name | string | Rule name. |
filter_code | string | The segment the device must match. Empty matches every device. The segment can hold only tag, location, application, and list conditions. |
percent_bp | integer | Share of matching users the flag is on for, 0–10000. A device that matches the segment stops at this rule even when it falls outside the percentage. |
overrides | object | Property values that replace the defaults for devices this rule turns on, keyed by property key. |
Errors
Anchor link toA rejected request returns one of these HTTP status codes:
| HTTP status | Meaning |
|---|---|
400 Bad Request | The request is invalid (field_violations) or the flag’s state or the plan doesn’t allow it (Type). See the body formats and reasons below. |
401 Unauthorized | The Authorization header is missing or the token is invalid. |
403 Forbidden | The token can’t manage the application, or the application is a system one. |
404 Not Found | The application or the flag doesn’t exist. |
409 Conflict | Another request is changing the same flag at this moment. Retry the request. |
500 Internal Server Error | Unexpected server failure. The body is {"message": "Sorry, an unexpected error occurred"}. |
An invalid request returns 400 with a list of field violations. Each violation names the field, the reason, and the arguments of the reason:
{ "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" } } ] } ]}A request that the flag’s state or the plan doesn’t allow returns 400 with one failed precondition. Its Type and Description fields are capitalized:
{ "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" } ]}The reason of a field violation and the Type of a failed precondition take these values:
| Reason | Cause |
|---|---|
KEY_INVALID | The key doesn’t match ^[A-Za-z0-9_.-]{1,58}$. |
KEY_TAKEN | Another flag of the application, archived ones included, has this key. |
TEXT_INVALID | The name or description is too long or has forbidden characters. |
PROPERTIES_LIMIT | More than 50 properties. |
PROPERTY_KEY_INVALID | A property key is invalid or repeated. |
PROPERTY_TYPE_INVALID | A property type isn’t string, number, boolean, or json. |
PROPERTY_TYPE_IMMUTABLE | The request changes the type of an existing property. |
VALUE_INVALID | A default or override is missing, doesn’t match the property type, or is nested deeper than 5 levels. |
PROPERTIES_TOO_LARGE | The property values of the flag exceed 10,000 bytes. |
RULES_LIMIT | More than 10 rules. |
RULE_NOT_FOUND | The rule_id isn’t one of the flag’s rules. |
PERCENT_INVALID | percent_bp is outside 0–10000. |
OVERRIDE_UNKNOWN_PROPERTY | An override names a property the flag doesn’t have. |
SEGMENT_NOT_FOUND | The rule segment doesn’t exist or belongs to another application. |
INVALID_SEGMENT_TYPE | The rule segment has a condition flags can’t evaluate: event, static, external, last update, or best time to send. |
CONFIRM_REQUIRED | Reshuffle was sent without confirm: true. |
TAG_CONFLICT | The account has a custom tag named PW_FF_ followed by the flag key. |
FEATURE_FLAGS_NOT_ALLOWED | The account’s plan doesn’t include feature flags. |
FLAGS_LIMIT | The application has as many non-archived flags as the plan allows. |
VERSION_CONFLICT | The flag changed since the version you sent. |
PAYLOAD_TOO_LARGE | The flags of the application would take more than 64 KB in one device’s answer. |
STATUS_CONFLICT | The status doesn’t allow the operation, for example killing an archived flag. |