Passer au contenu

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 to
https://rpc-api.svc-nue.pushwoosh.com

Tous les points de terminaison sont servis via HTTPS. Les requêtes et les réponses utilisent application/json.

Authentification

Anchor link to

Chaque requête doit inclure un en-tête Authorization contenant votre Jeton API Serveur :

Authorization: Api YOUR_API_TOKEN

La 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 lowerCamelCase ou snake_case. Les réponses utilisent snake_case, comme dans l’objet Feature flag.
  • Les pourcentages sont exprimés en points de base : percent_bp de 0 à 10000, où 2000 correspond à 20 %.
  • Versions : chaque flag porte une version. Update, SetRulePercent et Reshuffle prennent la version que vous avez lue en dernier et échouent avec VERSION_CONFLICT si le flag a changé depuis, de sorte que des modifications simultanées ne s’écrasent jamais. Relisez le flag et réessayez.
  • Statuts : active, killed ou archived. Kill, Unkill, Archive et Restore ne modifient que le statut et ne prennent pas de version.

Points de terminaison

Anchor link to

Chaque point de terminaison REST dispose d’un outil MCP avec les mêmes paramètres :

MéthodeCheminDescriptionOutil MCP
GET/api/applications/{application_code}/feature_flagsLister les flags de l’applicationlist_feature_flags
GET/api/applications/{application_code}/feature_flags/{key}Obtenir un flagget_feature_flag
POST/api/applications/{application_code}/feature_flagsCréer un flagcreate_feature_flag
POST/api/applications/{application_code}/feature_flags/{key}Remplacer le nom, la description, les propriétés et les règlesupdate_feature_flag
POST/api/applications/{application_code}/feature_flags/{key}/rules/{rule_id}/percentModifier le déploiement d’une règleset_feature_flag_rule_percent
POST/api/applications/{application_code}/feature_flags/{key}/killDésactiver le flag pour tout le mondekill_feature_flag
POST/api/applications/{application_code}/feature_flags/{key}/unkillRéactiver un flag désactivéunkill_feature_flag
POST/api/applications/{application_code}/feature_flags/{key}/archiveArchiver un flagarchive_feature_flag
POST/api/applications/{application_code}/feature_flags/{key}/restoreRestaurer un flag archivérestore_feature_flag
POST/api/applications/{application_code}/feature_flags/{key}/reshuffleChoisir un nouvel échantillon d’utilisateursreshuffle_feature_flag
GET/api/applications/{application_code}/feature_flags/{key}/historyLister les modifications d’un flaglist_feature_flag_history

Tous les points de terminaison, sauf List et History, renvoient { "flag": { ... } }, l’objet Feature flag après l’opération.

GET /api/applications/{application_code}/feature_flags

La requête accepte ces paramètres :

ParamètreEmplacementTypeDescription
application_codepathstringLe code d’application.
statusquerystringFacultatif. active, killed ou archived. Omettez-le pour lister tous les flags.

Renvoie { "flags": [ ... ] }, un tableau d’objets Feature flag.

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

Renvoie un flag avec ses propriétés, ses règles et sa version actuelle.

Cré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ètreTypeRequisDescription
keystringOuiCorrespond à ^[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.
namestringNonNom d’affichage, jusqu’à 255 caractères.
descriptionstringNonDescription.
propertiestableau d’objets PropertyNonJusqu’à 50 propriétés.
defaultsobjectOui, s’il y a des propriétésLa 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é.
rulestableau d’objets RuleNonRè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 to

Remplace 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 to

Modifie 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 to

POST .../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 to

POST .../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 to

Place 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 to

Renvoie 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ètreEmplacementTypeDescription
application_codepathstringLe code d’application.
keypathstringLa clé du flag.
pagequeryintegerFacultatif. Numéro de page, à partir de 0.
per_pagequeryintegerFacultatif. 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 :

ChampTypeDescription
versionintegerLa version du flag produite par cette modification.
actionstringcreate, update, set_percent, kill, unkill, archive, restore ou reshuffle.
user_idstringL’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_emailstringL’e-mail de cet utilisateur. Vide lorsque l’utilisateur a été supprimé ou que user_id vaut 0.
by_api_tokenbooleantrue 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_namestringLe 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.
createdstringHeure de la modification, RFC 3339.
flagObjet Feature flagLe flag après la modification.
changesarrayLes 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 :

fieldCe qui a changé
name, description, statusLe champ du flag portant ce nom.
propertiesLes 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.orderL’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 to

Les 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 :

ChampTypeDescription
applicationstringLe code d’application.
hwidstringLe HWID de l’appareil.
etagstringFacultatif. L’etag de la dernière réponse dont dispose l’appareil.

La réponse contient ces champs :

ChampTypeDescription
flagsobjectLes 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.
etagstringEnvoyez-le avec la requête suivante.
not_modifiedbooleantrue lorsque l’etag envoyé est à jour. flags est alors omis et l’appareil conserve sa copie.
partialbooleantrue 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.

Objet Feature flag

Anchor link to

Chaque point de terminaison renvoie le flag sous cette forme :

ChampTypeDescription
application_codestringL’application à laquelle appartient le flag.
keystringLa clé du flag.
namestringNom d’affichage.
descriptionstringDescription.
statusstringactive, killed ou archived.
propertiestableau d’objets PropertyLes propriétés du flag.
defaultsobjectLa valeur de chaque propriété pour les appareils pour lesquels le flag est désactivé.
rulestableau d’objets RuleRègles ordonnées.
versionintegerRenvoyez-la avec Update, SetRulePercent et Reshuffle.
createdstringHeure de création, RFC 3339.
updatedstringHeure de la dernière modification, RFC 3339.
last_modified_by_user_idstringL’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 to

Une propriété décrit une valeur que le SDK lit dans le flag :

ChampTypeDescription
keystringCorrespond à ^[A-Za-z0-9_]{1,64}$, unique au sein du flag.
typestringstring, number, boolean ou json. Ne peut pas changer une fois la propriété créée.

Objet Rule

Anchor link to

Une règle décide qui obtient le flag activé et avec quelles valeurs :

ChampTypeDescription
rule_idstringGé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.
namestringNom de la règle.
filter_codestringLe 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_bpintegerPart 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.
overridesobjectValeurs 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é.

Une requête rejetée renvoie l’un de ces codes de statut HTTP :

Statut HTTPSignification
400 Bad RequestLa 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 UnauthorizedL’en-tête Authorization est absent ou le jeton n’est pas valide.
403 ForbiddenLe jeton ne peut pas gérer l’application, ou l’application est une application système.
404 Not FoundL’application ou le flag n’existe pas.
409 ConflictUne autre requête modifie le même flag en ce moment. Réessayez la requête.
500 Internal Server ErrorDé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 :

MotifCause
KEY_INVALIDLa clé ne correspond pas à ^[A-Za-z0-9_.-]{1,58}$.
KEY_TAKENUn autre flag de l’application, archivés compris, porte cette clé.
TEXT_INVALIDLe nom ou la description est trop long ou contient des caractères interdits.
PROPERTIES_LIMITPlus de 50 propriétés.
PROPERTY_KEY_INVALIDUne clé de propriété n’est pas valide ou est répétée.
PROPERTY_TYPE_INVALIDUn type de propriété n’est ni string, ni number, ni boolean, ni json.
PROPERTY_TYPE_IMMUTABLELa requête modifie le type d’une propriété existante.
VALUE_INVALIDUne 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_LARGELes valeurs des propriétés du flag dépassent 10 000 octets.
RULES_LIMITPlus de 10 règles.
RULE_NOT_FOUNDLe rule_id ne fait pas partie des règles du flag.
PERCENT_INVALIDpercent_bp est en dehors de 0–10000.
OVERRIDE_UNKNOWN_PROPERTYUne valeur de remplacement désigne une propriété que le flag ne possède pas.
SEGMENT_NOT_FOUNDLe segment de la règle n’existe pas ou appartient à une autre application.
INVALID_SEGMENT_TYPELe 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_DEPENDENCYLe 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_REQUIREDReshuffle a été envoyé sans confirm: true.
TAG_CONFLICTLe compte possède un tag personnalisé nommé PW_FF_ suivi de la clé du flag.
FEATURE_FLAGS_NOT_ALLOWEDLe forfait du compte n’inclut pas les feature flags.
FLAGS_LIMITL’application compte autant de flags non archivés que le forfait le permet.
VERSION_CONFLICTLe flag a changé depuis la version que vous avez envoyée.
PAYLOAD_TOO_LARGELes flags de l’application occuperaient plus de 64 Ko dans la réponse à un appareil.
STATUS_CONFLICTLe statut ne permet pas l’opération, par exemple désactiver un flag archivé.