API de feature flags
Un feature flag es un interruptor remoto con propiedades que el SDK lee para cada dispositivo. Esta API gestiona los flags de una aplicación: las mismas operaciones que Audience → Feature Flags en el Panel de Control. Para leer flags en un sitio web o en una aplicación móvil, use el Web SDK, el Android SDK o el iOS SDK.
URL Base
Anchor link tohttps://rpc-api.svc-nue.pushwoosh.comTodos los endpoints se sirven a través de HTTPS. Las solicitudes y respuestas usan application/json.
Autenticación
Anchor link toCada solicitud debe incluir un encabezado Authorization con su Token de API de servidor:
Authorization: Api YOUR_API_TOKENLeer flags requiere acceso a la aplicación. Crearlos y modificarlos requiere el derecho de gestionarla.
Convenciones
Anchor link to- Nomenclatura de campos: los cuerpos de las solicitudes aceptan
lowerCamelCaseosnake_case. Las respuestas usansnake_case, como en el Objeto feature flag. - Los porcentajes se expresan en puntos básicos:
percent_bpde0a10000, donde2000es el 20 %. - Versiones: cada flag tiene una
version.Update,SetRulePercentyReshufflereciben la versión que leyó por última vez y fallan conVERSION_CONFLICTcuando el flag ha cambiado desde entonces, de modo que las ediciones simultáneas nunca se sobrescriben entre sí. Vuelva a leer el flag y reintente. - Estados:
active,killedoarchived.Kill,Unkill,ArchiveyRestoresolo cambian el estado y no reciben versión.
Endpoints
Anchor link toCada endpoint REST tiene una herramienta MCP con los mismos parámetros:
| Método | Ruta | Descripción | Herramienta MCP |
|---|---|---|---|
GET | /api/applications/{application_code}/feature_flags | Listar los flags de la aplicación | list_feature_flags |
GET | /api/applications/{application_code}/feature_flags/{key} | Obtener un flag | get_feature_flag |
POST | /api/applications/{application_code}/feature_flags | Crear un flag | create_feature_flag |
POST | /api/applications/{application_code}/feature_flags/{key} | Reemplazar nombre, descripción, propiedades y reglas | update_feature_flag |
POST | /api/applications/{application_code}/feature_flags/{key}/rules/{rule_id}/percent | Cambiar el despliegue de una regla | set_feature_flag_rule_percent |
POST | /api/applications/{application_code}/feature_flags/{key}/kill | Desactivar el flag para todos | kill_feature_flag |
POST | /api/applications/{application_code}/feature_flags/{key}/unkill | Volver a activar un flag desactivado | unkill_feature_flag |
POST | /api/applications/{application_code}/feature_flags/{key}/archive | Archivar un flag | archive_feature_flag |
POST | /api/applications/{application_code}/feature_flags/{key}/restore | Restaurar un flag archivado | restore_feature_flag |
POST | /api/applications/{application_code}/feature_flags/{key}/reshuffle | Elegir una nueva muestra de usuarios | reshuffle_feature_flag |
GET | /api/applications/{application_code}/feature_flags/{key}/history | Listar los cambios de un flag | list_feature_flag_history |
Todos los endpoints, excepto List y History, devuelven { "flag": { ... } }, el Objeto feature flag tras la operación.
Listar
Anchor link toGET /api/applications/{application_code}/feature_flags
La solicitud recibe estos parámetros:
| Parámetro | Ubicación | Tipo | Descripción |
|---|---|---|---|
application_code | path | string | El código de aplicación. |
status | query | string | Opcional. active, killed o archived. Omítalo para listar todos los flags. |
Devuelve { "flags": [ ... ] }, un array de Objetos feature flag.
Obtener
Anchor link toGET /api/applications/{application_code}/feature_flags/{key}
Devuelve un flag con sus propiedades, reglas y version actual.
Crear
Anchor link toCrea un flag activo. El servidor genera el rule_id de cada regla.
POST /api/applications/{application_code}/feature_flags
El cuerpo de la solicitud tiene estos campos:
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
key | string | Sí | Coincide con ^[A-Za-z0-9_.-]{1,58}$. Única en la aplicación, incluidos los flags archivados, y comparada sin distinguir mayúsculas de minúsculas. No se puede cambiar después. |
name | string | No | Nombre visible, hasta 255 caracteres. |
description | string | No | Descripción. |
properties | array de Objetos propiedad | No | Hasta 50 propiedades. |
defaults | object | Sí, si hay propiedades | El valor de cada propiedad para los dispositivos en los que el flag está desactivado, indexado por la clave de la propiedad. Cada valor debe coincidir con el tipo de la propiedad. |
rules | array de Objetos regla | No | Reglas ordenadas, hasta 10. Decide la primera regla cuyo segmento coincide con el dispositivo. |
Ejemplo de solicitud
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" } } ]}Actualizar
Anchor link toReemplaza el nombre, la descripción, las propiedades, los valores predeterminados y las reglas de un flag. El estado nunca cambia aquí. Envíe todos los campos, no solo los modificados.
POST /api/applications/{application_code}/feature_flags/{key}
Recibe el mismo cuerpo que Crear sin key, más la version de su última lectura. Conserve el rule_id de cada regla existente. Una regla sin rule_id se crea como nueva. El tipo de una propiedad no puede cambiar después de crear la propiedad.
SetRulePercent
Anchor link toCambia el despliegue de una regla. Los usuarios que ya tienen el flag lo conservan cuando el porcentaje aumenta.
POST /api/applications/{application_code}/feature_flags/{key}/rules/{rule_id}/percent
{ "percentBp": 5000, "version": 3 }Kill y Unkill
Anchor link toPOST .../feature_flags/{key}/kill desactiva el flag para todos los dispositivos, que entonces reciben los valores predeterminados de las propiedades. Las reglas y las propiedades se conservan.
POST .../feature_flags/{key}/unkill vuelve a activar un flag desactivado con sus reglas tal como estaban.
Ambos reciben un cuerpo vacío {}.
Archivar y restaurar
Anchor link toPOST .../feature_flags/{key}/archive deja de enviar el flag a los dispositivos. Un flag archivado no cuenta para el límite de flags por aplicación del plan, y su clave sigue reservada.
POST .../feature_flags/{key}/restore recupera un flag archivado como killed, de modo que nunca se activa por sí solo. Llame a unkill para desplegarlo de nuevo.
Ambos reciben un cuerpo vacío {}.
Redistribuir
Anchor link toColoca a cada usuario en un nuevo bucket, de modo que los mismos porcentajes seleccionan una muestra de usuarios diferente. Algunos usuarios que tienen el flag activado lo pierden y otros lo obtienen.
POST /api/applications/{application_code}/feature_flags/{key}/reshuffle
{ "confirm": true, "version": 3 }confirm debe ser true. De lo contrario, la solicitud falla con CONFIRM_REQUIRED.
Historial
Anchor link toDevuelve los cambios de un flag, del más reciente al más antiguo: quién hizo cada cambio, cuándo y qué campos cambiaron. Al igual que Get, requiere acceso a la aplicación y devuelve 404 cuando la aplicación o el flag no existen.
GET /api/applications/{application_code}/feature_flags/{key}/history
La solicitud recibe estos parámetros:
| Parámetro | Ubicación | Tipo | Descripción |
|---|---|---|---|
application_code | path | string | El código de aplicación. |
key | path | string | La clave del flag. |
page | query | integer | Opcional. Número de página, empezando por 0. |
per_page | query | integer | Opcional. Entradas por página, 20 de forma predeterminada, hasta 100. |
Devuelve { "entries": [ ... ], "total": N }, donde total es el número de entradas en todas las páginas. Cada entrada tiene estos campos:
| Campo | Tipo | Descripción |
|---|---|---|
version | integer | La versión del flag que produjo este cambio. |
action | string | create, update, set_percent, kill, unkill, archive, restore o reshuffle. |
user_id | string | El ID del usuario del Panel de Control que hizo el cambio. 0 para un cambio hecho con un token de API o por un servicio de Pushwoosh. |
user_email | string | El email de ese usuario. Vacío cuando el usuario se eliminó o user_id es 0. |
by_api_token | boolean | true cuando el cambio se hizo con un token de API. false para un cambio hecho por un usuario o por un servicio de Pushwoosh. |
api_token_name | string | El nombre que tenía el token de API en el momento del cambio. Se conserva después de eliminar el token. Vacío cuando el token no tiene nombre o by_api_token es false. |
created | string | Hora del cambio, RFC 3339. |
flag | Objeto feature flag | El flag después del cambio. |
changes | array | Los campos que difieren de la versión anterior. Vacío para create y reshuffle, y para la entrada más antigua de un flag creado antes de que se registrara el historial, porque no hay una versión anterior con la que compararla. |
Cada elemento de changes tiene field, before y after. before y after contienen los valores codificados como cadenas JSON, por lo que un valor de tipo string aparece entre comillas. field toma estos valores:
field | Qué cambió |
|---|---|
name, description, status | El campo del flag con este nombre. |
properties | Las propiedades y sus valores predeterminados. |
rules[<rule_id>] | Una regla. Para una regla añadida, before está vacío. Para una regla eliminada, after está vacío. |
rules.order | El orden de las reglas. |
Ejemplo de respuesta
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}El objeto flag del ejemplo está abreviado. El historial se registra para los cambios a partir del 13 de octubre de 2026. Un flag sin cambios registrados no devuelve entradas.
Leer flags para un dispositivo
Anchor link toLos SDK leen los flags desde un endpoint independiente. No necesita llamarlo cuando usa el Web SDK, el Android SDK o el iOS SDK, porque eligen el host y almacenan la respuesta en caché por sí mismos.
POST https://api.pushwoosh.com/api/v2/device-api/getFeatureFlags
El cuerpo de la solicitud tiene estos campos:
| Campo | Tipo | Descripción |
|---|---|---|
application | string | El código de aplicación. |
hwid | string | El HWID del dispositivo. |
etag | string | Opcional. El etag de la última respuesta que tiene el dispositivo. |
La respuesta tiene estos campos:
| Campo | Tipo | Descripción |
|---|---|---|
flags | object | Flags indexados por clave de flag. Cada uno tiene enabled, rule_id y properties. rule_id es default cuando ninguna regla coincidió y está vacío para un flag desactivado. Los flags archivados no se incluyen. |
etag | string | Envíelo con la siguiente solicitud. |
not_modified | boolean | true cuando el etag enviado está actualizado. En ese caso se omite flags y el dispositivo conserva su copia. |
partial | boolean | true cuando los segmentos del dispositivo no se evaluaron a tiempo. No almacene esta respuesta en caché. |
En un plan sin feature flags, la respuesta está vacía.
Objetos
Anchor link toObjeto feature flag
Anchor link toTodos los endpoints devuelven el flag con esta estructura:
| Campo | Tipo | Descripción |
|---|---|---|
application_code | string | La aplicación a la que pertenece el flag. |
key | string | La clave del flag. |
name | string | Nombre visible. |
description | string | Descripción. |
status | string | active, killed o archived. |
properties | array de Objetos propiedad | Las propiedades del flag. |
defaults | object | El valor de cada propiedad para los dispositivos en los que el flag está desactivado. |
rules | array de Objetos regla | Reglas ordenadas. |
version | integer | Devuélvala con Update, SetRulePercent y Reshuffle. |
created | string | Hora de creación, RFC 3339. |
updated | string | Hora del último cambio, RFC 3339. |
last_modified_by_user_id | string | El usuario del Panel de Control que modificó el flag por última vez. 0 cuando el último cambio se hizo con un token de API o lo hizo un servicio de Pushwoosh. |
Objeto propiedad
Anchor link toUna propiedad describe un valor que el SDK lee del flag:
| Campo | Tipo | Descripción |
|---|---|---|
key | string | Coincide con ^[A-Za-z0-9_]{1,64}$, única dentro del flag. |
type | string | string, number, boolean o json. No puede cambiar una vez que la propiedad existe. |
Objeto regla
Anchor link toUna regla decide quién recibe el flag activado y con qué valores:
| Campo | Tipo | Descripción |
|---|---|---|
rule_id | string | Generado por el servidor, r_ seguido de 8 dígitos hexadecimales, y estable entre actualizaciones. Déjelo vacío para una regla nueva. |
name | string | Nombre de la regla. |
filter_code | string | El segmento con el que debe coincidir el dispositivo. Vacío coincide con todos los dispositivos. El segmento solo puede contener condiciones de etiqueta, ubicación, aplicación y lista. |
percent_bp | integer | Proporción de usuarios coincidentes para los que el flag está activado, 0–10000. Un dispositivo que coincide con el segmento se detiene en esta regla aunque quede fuera del porcentaje. |
overrides | object | Valores de propiedades que reemplazan a los predeterminados para los dispositivos en los que esta regla activa el flag, indexados por la clave de la propiedad. |
Errores
Anchor link toUna solicitud rechazada devuelve uno de estos códigos de estado HTTP:
| Estado HTTP | Significado |
|---|---|
400 Bad Request | La solicitud no es válida (field_violations) o el estado del flag o el plan no la permiten (Type). Consulte los formatos del cuerpo y los motivos a continuación. |
401 Unauthorized | Falta el encabezado Authorization o el token no es válido. |
403 Forbidden | El token no puede gestionar la aplicación, o la aplicación es del sistema. |
404 Not Found | La aplicación o el flag no existe. |
409 Conflict | Otra solicitud está modificando el mismo flag en este momento. Reintente la solicitud. |
500 Internal Server Error | Fallo inesperado del servidor. El cuerpo es {"message": "Sorry, an unexpected error occurred"}. |
Una solicitud no válida devuelve 400 con una lista de infracciones de campo. Cada infracción indica el campo, el motivo y los argumentos del motivo:
{ "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" } } ] } ]}Una solicitud que el estado del flag o el plan no permiten devuelve 400 con una precondición fallida. Sus campos Type y Description van en mayúscula inicial:
{ "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" } ]}El reason de una infracción de campo y el Type de una precondición fallida toman estos valores:
| Motivo | Causa |
|---|---|
KEY_INVALID | La clave no coincide con ^[A-Za-z0-9_.-]{1,58}$. |
KEY_TAKEN | Otro flag de la aplicación, incluidos los archivados, tiene esta clave. |
TEXT_INVALID | El nombre o la descripción son demasiado largos o contienen caracteres prohibidos. |
PROPERTIES_LIMIT | Más de 50 propiedades. |
PROPERTY_KEY_INVALID | Una clave de propiedad no es válida o está repetida. |
PROPERTY_TYPE_INVALID | Un tipo de propiedad no es string, number, boolean ni json. |
PROPERTY_TYPE_IMMUTABLE | La solicitud cambia el tipo de una propiedad existente. |
VALUE_INVALID | Un valor predeterminado o de anulación falta, no coincide con el tipo de la propiedad o está anidado a más de 5 niveles. |
PROPERTIES_TOO_LARGE | Los valores de las propiedades del flag superan los 10 000 bytes. |
RULES_LIMIT | Más de 10 reglas. |
RULE_NOT_FOUND | El rule_id no es una de las reglas del flag. |
PERCENT_INVALID | percent_bp está fuera de 0–10000. |
OVERRIDE_UNKNOWN_PROPERTY | Una anulación nombra una propiedad que el flag no tiene. |
SEGMENT_NOT_FOUND | El segmento de la regla no existe o pertenece a otra aplicación. |
INVALID_SEGMENT_TYPE | El segmento de la regla tiene una condición que los flags no pueden evaluar: evento, estático, externo, última actualización o mejor hora de envío. |
FLAG_DEPENDENCY | El segmento de la regla tiene una condición de feature flag, y un flag no puede depender de otro flag. Lo devuelven Create, Update y Restore, con el código del segmento en filter_code. |
CONFIRM_REQUIRED | Reshuffle se envió sin confirm: true. |
TAG_CONFLICT | La cuenta tiene una etiqueta personalizada llamada PW_FF_ seguida de la clave del flag. |
FEATURE_FLAGS_NOT_ALLOWED | El plan de la cuenta no incluye feature flags. |
FLAGS_LIMIT | La aplicación tiene tantos flags no archivados como permite el plan. |
VERSION_CONFLICT | El flag cambió desde la version que envió. |
PAYLOAD_TOO_LARGE | Los flags de la aplicación ocuparían más de 64 KB en la respuesta a un dispositivo. |
STATUS_CONFLICT | El estado no permite la operación, por ejemplo, desactivar un flag archivado. |