API Feature Flags
Un feature flag est un interrupteur distant doté de propriétés que le SDK lit pour chaque appareil. Cette API gère les flags d’une application : les mêmes opérations que Audience → Feature Flags dans le Panneau de contrôle. Pour lire les flags sur un site web ou dans une application mobile, utilisez le Web SDK, l’Android SDK ou l’iOS SDK.
URL de base
Anchor link tohttps://rpc-api.svc-nue.pushwoosh.comTous les points de terminaison sont servis via HTTPS. Les requêtes et les réponses utilisent application/json.
Authentification
Anchor link toChaque requête doit inclure un en-tête Authorization contenant votre Jeton API Serveur :
Authorization: Api YOUR_API_TOKENLa lecture des flags nécessite l’accès à l’application. Leur création et leur modification nécessitent le droit de la gérer.
Conventions
Anchor link to- Nommage des champs : les corps de requête acceptent
lowerCamelCaseousnake_case. Les réponses utilisentsnake_case, comme dans l’objet Feature flag. - Les pourcentages sont exprimés en points de base :
percent_bpde0à10000, où2000correspond à 20 %. - Versions : chaque flag porte une
version.Update,SetRulePercentetReshuffleprennent la version que vous avez lue en dernier et échouent avecVERSION_CONFLICTsi le flag a changé depuis, de sorte que des modifications simultanées ne s’écrasent jamais. Relisez le flag et réessayez. - Statuts :
active,killedouarchived.Kill,Unkill,ArchiveetRestorene modifient que le statut et ne prennent pas de version.
Points de terminaison
Anchor link toChaque point de terminaison REST dispose d’un outil MCP avec les mêmes paramètres :
| Méthode | Chemin | Description | Outil MCP |
|---|---|---|---|
GET | /api/applications/{application_code}/feature_flags | Lister les flags de l’application | list_feature_flags |
GET | /api/applications/{application_code}/feature_flags/{key} | Obtenir un flag | get_feature_flag |
POST | /api/applications/{application_code}/feature_flags | Créer un flag | create_feature_flag |
POST | /api/applications/{application_code}/feature_flags/{key} | Remplacer le nom, la description, les propriétés et les règles | update_feature_flag |
POST | /api/applications/{application_code}/feature_flags/{key}/rules/{rule_id}/percent | Modifier le déploiement d’une règle | set_feature_flag_rule_percent |
POST | /api/applications/{application_code}/feature_flags/{key}/kill | Désactiver le flag pour tout le monde | kill_feature_flag |
POST | /api/applications/{application_code}/feature_flags/{key}/unkill | Réactiver un flag désactivé | unkill_feature_flag |
POST | /api/applications/{application_code}/feature_flags/{key}/archive | Archiver un flag | archive_feature_flag |
POST | /api/applications/{application_code}/feature_flags/{key}/restore | Restaurer un flag archivé | restore_feature_flag |
POST | /api/applications/{application_code}/feature_flags/{key}/reshuffle | Choisir un nouvel échantillon d’utilisateurs | reshuffle_feature_flag |
GET | /api/applications/{application_code}/feature_flags/{key}/history | Lister les modifications d’un flag | list_feature_flag_history |
Tous les points de terminaison, sauf List et History, renvoient { "flag": { ... } }, l’objet Feature flag après l’opération.
Lister
Anchor link toGET /api/applications/{application_code}/feature_flags
La requête accepte ces paramètres :
| Paramètre | Emplacement | Type | Description |
|---|---|---|---|
application_code | path | string | Le code d’application. |
status | query | string | Facultatif. active, killed ou archived. Omettez-le pour lister tous les flags. |
Renvoie { "flags": [ ... ] }, un tableau d’objets Feature flag.
Obtenir
Anchor link toGET /api/applications/{application_code}/feature_flags/{key}
Renvoie un flag avec ses propriétés, ses règles et sa version actuelle.
Créer
Anchor link toCrée un flag actif. Le serveur génère le rule_id de chaque règle.
POST /api/applications/{application_code}/feature_flags
Le corps de la requête contient ces champs :
| Paramètre | Type | Requis | Description |
|---|---|---|---|
key | string | Oui | Correspond à ^[A-Za-z0-9_.-]{1,58}$. Unique dans l’application, flags archivés compris, comparée sans tenir compte de la casse. Ne peut pas être modifiée ultérieurement. |
name | string | Non | Nom d’affichage, jusqu’à 255 caractères. |
description | string | Non | Description. |
properties | tableau d’objets Property | Non | Jusqu’à 50 propriétés. |
defaults | object | Oui, s’il y a des propriétés | La valeur de chaque propriété pour les appareils pour lesquels le flag est désactivé, indexée par clé de propriété. Chaque valeur doit correspondre au type de la propriété. |
rules | tableau d’objets Rule | Non | Règles ordonnées, jusqu’à 10. La première règle dont le segment correspond à l’appareil décide. |
Exemple de requête
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" } } ]}Mettre à jour
Anchor link toRemplace le nom, la description, les propriétés, les valeurs par défaut et les règles d’un flag. Le statut ne change jamais ici. Envoyez tous les champs, pas seulement ceux qui ont changé.
POST /api/applications/{application_code}/feature_flags/{key}
Prend le même corps que Créer sans key, plus la version de votre dernière lecture. Conservez le rule_id de chaque règle existante. Une règle sans rule_id est créée comme nouvelle. Le type d’une propriété ne peut pas changer après la création de la propriété.
SetRulePercent
Anchor link toModifie le déploiement d’une règle. Les utilisateurs qui ont déjà le flag le conservent lorsque le pourcentage augmente.
POST /api/applications/{application_code}/feature_flags/{key}/rules/{rule_id}/percent
{ "percentBp": 5000, "version": 3 }Kill et Unkill
Anchor link toPOST .../feature_flags/{key}/kill désactive le flag pour tous les appareils, qui reçoivent alors les valeurs par défaut des propriétés. Les règles et les propriétés sont conservées.
POST .../feature_flags/{key}/unkill réactive un flag désactivé avec ses règles telles qu’elles étaient.
Les deux prennent un corps vide {}.
Archiver et restaurer
Anchor link toPOST .../feature_flags/{key}/archive cesse d’envoyer le flag aux appareils. Un flag archivé n’est pas pris en compte dans la limite de flags par application du forfait, et sa clé reste réservée.
POST .../feature_flags/{key}/restore rétablit un flag archivé avec le statut killed, de sorte qu’il ne s’active jamais de lui-même. Appelez unkill pour le déployer à nouveau.
Les deux prennent un corps vide {}.
Redistribuer
Anchor link toPlace chaque utilisateur dans un nouveau bucket, de sorte que les mêmes pourcentages sélectionnent un échantillon d’utilisateurs différent. Certains utilisateurs pour lesquels le flag est activé le perdent, et d’autres l’obtiennent.
POST /api/applications/{application_code}/feature_flags/{key}/reshuffle
{ "confirm": true, "version": 3 }confirm doit valoir true. Sinon, la requête échoue avec CONFIRM_REQUIRED.
Historique
Anchor link toRenvoie les modifications d’un flag, de la plus récente à la plus ancienne : qui a fait chaque modification, quand, et quels champs ont changé. Comme Get, il nécessite l’accès à l’application et renvoie 404 lorsque l’application ou le flag n’existe pas.
GET /api/applications/{application_code}/feature_flags/{key}/history
La requête accepte ces paramètres :
| Paramètre | Emplacement | Type | Description |
|---|---|---|---|
application_code | path | string | Le code d’application. |
key | path | string | La clé du flag. |
page | query | integer | Facultatif. Numéro de page, à partir de 0. |
per_page | query | integer | Facultatif. Entrées par page, 20 par défaut, jusqu’à 100. |
Renvoie { "entries": [ ... ], "total": N }, où total est le nombre d’entrées sur l’ensemble des pages. Chaque entrée contient ces champs :
| Champ | Type | Description |
|---|---|---|
version | integer | La version du flag produite par cette modification. |
action | string | create, update, set_percent, kill, unkill, archive, restore ou reshuffle. |
user_id | string | L’ID de l’utilisateur du Panneau de contrôle qui a fait la modification. 0 pour une modification faite avec un jeton d’API ou par un service Pushwoosh. |
user_email | string | L’e-mail de cet utilisateur. Vide lorsque l’utilisateur a été supprimé ou que user_id vaut 0. |
by_api_token | boolean | true lorsque la modification a été faite avec un jeton d’API. false pour une modification faite par un utilisateur ou par un service Pushwoosh. |
api_token_name | string | Le nom du jeton d’API au moment de la modification. Il est conservé après la suppression du jeton. Vide lorsque le jeton n’a pas de nom ou que by_api_token vaut false. |
created | string | Heure de la modification, RFC 3339. |
flag | Objet Feature flag | Le flag après la modification. |
changes | array | Les champs qui diffèrent de la version précédente. Vide pour create et reshuffle, ainsi que pour l’entrée la plus ancienne d’un flag créé avant l’enregistrement de l’historique, car il n’existe pas de version antérieure avec laquelle la comparer. |
Chaque élément de changes contient field, before et after. before et after contiennent les valeurs encodées sous forme de chaînes JSON : une valeur de type string arrive donc entre guillemets. field prend ces valeurs :
field | Ce qui a changé |
|---|---|
name, description, status | Le champ du flag portant ce nom. |
properties | Les propriétés et leurs valeurs par défaut. |
rules[<rule_id>] | Une règle. Pour une règle ajoutée, before est vide. Pour une règle supprimée, after est vide. |
rules.order | L’ordre des règles. |
Exemple de réponse
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}L’objet flag de l’exemple est abrégé. L’historique est enregistré pour les modifications à partir du 13 octobre 2026. Un flag sans modification enregistrée ne renvoie aucune entrée.
Lire les flags pour un appareil
Anchor link toLes SDK lisent les flags depuis un point de terminaison distinct. Vous ne l’appelez pas lorsque vous utilisez le Web SDK, l’Android SDK ou l’iOS SDK, car ils choisissent l’hôte et mettent la réponse en cache eux-mêmes.
POST https://api.pushwoosh.com/api/v2/device-api/getFeatureFlags
Le corps de la requête contient ces champs :
| Champ | Type | Description |
|---|---|---|
application | string | Le code d’application. |
hwid | string | Le HWID de l’appareil. |
etag | string | Facultatif. L’etag de la dernière réponse dont dispose l’appareil. |
La réponse contient ces champs :
| Champ | Type | Description |
|---|---|---|
flags | object | Les flags, indexés par clé de flag. Chacun contient enabled, rule_id et properties. rule_id vaut default lorsqu’aucune règle ne correspond et est vide pour un flag désactivé. Les flags archivés ne sont pas inclus. |
etag | string | Envoyez-le avec la requête suivante. |
not_modified | boolean | true lorsque l’etag envoyé est à jour. flags est alors omis et l’appareil conserve sa copie. |
partial | boolean | true lorsque les segments de l’appareil n’ont pas été évalués à temps. Ne mettez pas cette réponse en cache. |
Sur un forfait sans feature flags, la réponse est vide.
Objets
Anchor link toObjet Feature flag
Anchor link toChaque point de terminaison renvoie le flag sous cette forme :
| Champ | Type | Description |
|---|---|---|
application_code | string | L’application à laquelle appartient le flag. |
key | string | La clé du flag. |
name | string | Nom d’affichage. |
description | string | Description. |
status | string | active, killed ou archived. |
properties | tableau d’objets Property | Les propriétés du flag. |
defaults | object | La valeur de chaque propriété pour les appareils pour lesquels le flag est désactivé. |
rules | tableau d’objets Rule | Règles ordonnées. |
version | integer | Renvoyez-la avec Update, SetRulePercent et Reshuffle. |
created | string | Heure de création, RFC 3339. |
updated | string | Heure de la dernière modification, RFC 3339. |
last_modified_by_user_id | string | L’utilisateur du Panneau de contrôle qui a modifié le flag en dernier. 0 lorsque la dernière modification a été faite avec un jeton d’API ou par un service Pushwoosh. |
Objet Property
Anchor link toUne propriété décrit une valeur que le SDK lit dans le flag :
| Champ | Type | Description |
|---|---|---|
key | string | Correspond à ^[A-Za-z0-9_]{1,64}$, unique au sein du flag. |
type | string | string, number, boolean ou json. Ne peut pas changer une fois la propriété créée. |
Objet Rule
Anchor link toUne règle décide qui obtient le flag activé et avec quelles valeurs :
| Champ | Type | Description |
|---|---|---|
rule_id | string | Généré par le serveur, r_ suivi de 8 chiffres hexadécimaux, et stable d’une mise à jour à l’autre. Laissez-le vide pour une nouvelle règle. |
name | string | Nom de la règle. |
filter_code | string | Le segment auquel l’appareil doit correspondre. Une valeur vide correspond à tous les appareils. Le segment ne peut contenir que des conditions de tag, de localisation, d’application et de liste. |
percent_bp | integer | Part des utilisateurs correspondants pour lesquels le flag est activé, 0–10000. Un appareil qui correspond au segment s’arrête à cette règle même s’il se trouve en dehors du pourcentage. |
overrides | object | Valeurs de propriétés qui remplacent les valeurs par défaut pour les appareils que cette règle active, indexées par clé de propriété. |
Erreurs
Anchor link toUne requête rejetée renvoie l’un de ces codes de statut HTTP :
| Statut HTTP | Signification |
|---|---|
400 Bad Request | La requête n’est pas valide (field_violations) ou l’état du flag ou le forfait ne l’autorise pas (Type). Consultez les formats de corps et les motifs ci-dessous. |
401 Unauthorized | L’en-tête Authorization est absent ou le jeton n’est pas valide. |
403 Forbidden | Le jeton ne peut pas gérer l’application, ou l’application est une application système. |
404 Not Found | L’application ou le flag n’existe pas. |
409 Conflict | Une autre requête modifie le même flag en ce moment. Réessayez la requête. |
500 Internal Server Error | Défaillance inattendue du serveur. Le corps est {"message": "Sorry, an unexpected error occurred"}. |
Une requête non valide renvoie 400 avec une liste de violations de champs. Chaque violation indique le champ, le motif et les arguments du motif :
{ "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" } } ] } ]}Une requête que l’état du flag ou le forfait n’autorise pas renvoie 400 avec une précondition non remplie. Ses champs Type et Description commencent par une majuscule :
{ "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" } ]}Le reason d’une violation de champ et le Type d’une précondition non remplie prennent ces valeurs :
| Motif | Cause |
|---|---|
KEY_INVALID | La clé ne correspond pas à ^[A-Za-z0-9_.-]{1,58}$. |
KEY_TAKEN | Un autre flag de l’application, archivés compris, porte cette clé. |
TEXT_INVALID | Le nom ou la description est trop long ou contient des caractères interdits. |
PROPERTIES_LIMIT | Plus de 50 propriétés. |
PROPERTY_KEY_INVALID | Une clé de propriété n’est pas valide ou est répétée. |
PROPERTY_TYPE_INVALID | Un type de propriété n’est ni string, ni number, ni boolean, ni json. |
PROPERTY_TYPE_IMMUTABLE | La requête modifie le type d’une propriété existante. |
VALUE_INVALID | Une valeur par défaut ou de remplacement est manquante, ne correspond pas au type de la propriété ou est imbriquée sur plus de 5 niveaux. |
PROPERTIES_TOO_LARGE | Les valeurs des propriétés du flag dépassent 10 000 octets. |
RULES_LIMIT | Plus de 10 règles. |
RULE_NOT_FOUND | Le rule_id ne fait pas partie des règles du flag. |
PERCENT_INVALID | percent_bp est en dehors de 0–10000. |
OVERRIDE_UNKNOWN_PROPERTY | Une valeur de remplacement désigne une propriété que le flag ne possède pas. |
SEGMENT_NOT_FOUND | Le segment de la règle n’existe pas ou appartient à une autre application. |
INVALID_SEGMENT_TYPE | Le segment de la règle contient une condition que les flags ne peuvent pas évaluer : événement, statique, externe, dernière mise à jour ou meilleur moment d’envoi. |
FLAG_DEPENDENCY | Le segment de la règle contient une condition de feature flag, et un flag ne peut pas dépendre d’un autre flag. Renvoyé par Create, Update et Restore, avec le code du segment dans filter_code. |
CONFIRM_REQUIRED | Reshuffle a été envoyé sans confirm: true. |
TAG_CONFLICT | Le compte possède un tag personnalisé nommé PW_FF_ suivi de la clé du flag. |
FEATURE_FLAGS_NOT_ALLOWED | Le forfait du compte n’inclut pas les feature flags. |
FLAGS_LIMIT | L’application compte autant de flags non archivés que le forfait le permet. |
VERSION_CONFLICT | Le flag a changé depuis la version que vous avez envoyée. |
PAYLOAD_TOO_LARGE | Les flags de l’application occuperaient plus de 64 Ko dans la réponse à un appareil. |
STATUS_CONFLICT | Le statut ne permet pas l’opération, par exemple désactiver un flag archivé. |