# API de Presets

Un [preset de push](/es/product/content/push-presets/) es una plantilla de notificación push reutilizable — el mismo objeto que construyes en el editor de push del Panel de Control. Esta API gestiona solo los presets de push; los presets de SMS, WhatsApp, Kakao, LINE y Viber tienen cada uno su propio servicio de presets dedicado, no cubierto aquí.

Usa el `código` de un preset para enviarlo a través de [`Notify`](/es/developer/api-reference/messaging-api-v2/notify/) (payload `preset`) o un [punto de envío de push](/es/developer/api-reference/customer-journey-api/point-reference/#messaging-points) de Customer Journey.

## URL base

```
https://rpc-api.svc-nue.pushwoosh.com
```

Todos los endpoints se sirven sobre HTTPS. Las solicitudes y respuestas usan `application/json` a menos que se indique lo contrario.

## Autenticación

Cada solicitud debe incluir un encabezado `Authorization` con tu [token de API del servidor](/es/developer/api-reference/api-access-token/#server-api-token):

```
Authorization: Api YOUR_API_TOKEN
```

## Convenciones

*   **Nomenclatura de campos:** los cuerpos de las solicitudes y los parámetros de consulta/ruta aceptan `lowerCamelCase` (por ejemplo, `sendType`, `localizedProperties`, `searchByName`) — el servidor deserializa cualquiera de las dos formas. Las respuestas siempre se serializan usando los nombres de campo de proto, en `snake_case` (`localized_properties`, `platform_properties`, `per_page`, y así sucesivamente). Los ejemplos de respuesta y la referencia del [Objeto Preset](#preset-object) a continuación usan esa forma.
*   **`code`:** cada respuesta de preset lleva su propio código, generado en `Create`. Pasa este código a `Get`, `Update`, `UpdatePartial`, `Delete`, `Clone`, y a las APIs de mensajería/journey mencionadas anteriormente.
*   **Claves de plataforma:** los mapas `platforms` y `open_actions` tienen como clave el [código de tipo de dispositivo](/es/developer/api-reference/api-identifiers/#device-type) numérico (`1` para iOS, `3` para Android, etc.). `platform_properties` tiene como clave el nombre del enum de la plataforma en su lugar (`IOS`, `ANDROID`, `HUAWEI_ANDROID`, `OSX` — las únicas cuatro plataformas que cubre).
*   **Campos no poblados:** las respuestas de `Get`, `Create` y `Clone` incluyen cada campo del [Objeto Preset](#preset-object), incluso cuando están vacíos o con valor cero. `List` devuelve un conjunto de campos reducido — ver [Listar](#list) a continuación. `Update` y `UpdatePartial` no devuelven ningún campo de preset en absoluto — ver la [precaución](#update) en sus secciones.

### Respuestas de error

| Estado HTTP | Significado |
| :---- | :---- |
| `400 Bad Request` | Argumento inválido — falta un campo requerido o está mal formado, o una precondición falló (por ejemplo, clonar sin un `name`). |
| `401 Unauthorized` | Encabezado `Authorization` faltante o inválido. |
| `403 Forbidden` | La aplicación o el preset no pertenecen a la cuenta del solicitante. |
| `404 Not Found` | El preset o la aplicación no se encontraron. |
| `500 Internal Server Error` | Falla inesperada del lado del servidor. |

`Delete` en un preset que todavía está siendo utilizado por un punto de envío de push de un journey en ejecución o pausado también devuelve `400 Bad Request` (un `FailedPrecondition` en la comunicación) — no `409`. Elimina primero el preset del journey.

`Create`, `Update` y `UpdatePartial` también devuelven `400 Bad Request` por un [token de personalización](#personalization-tokens) no resoluble — ver a continuación.

## Tokens de personalización

`Create`, `Update` y `UpdatePartial` validan cada [token de personalización](/es/product/personalization/dynamic-content/) (`{name|modifier|default}`) en `localizedTitle`, `localizedSubtitle` y `localizedContent` (para cada idioma en la solicitud), y en los campos de contenido enriquecido por plataforma en los que el remitente sustituye (título, contenido, banner, icono, URL, parámetros de deep-link, etc., para cada plataforma). Los campos fuera de ese conjunto, como `richmedia`, `campaignCode`, `deeplink` o `filterCode`, mantienen un token exactamente como está escrito — Pushwoosh no analiza la sintaxis de personalización allí.

Un token necesita un modificador que Pushwoosh reconozca, porque uno sin modificar o mal escrito no se puede formatear y, de lo contrario, llegaría a los usuarios como llaves literales. Un token con un modificador faltante o desconocido (`{Tag|}`, `{Tag|typo}`) falla la llamada con `InvalidArgument`:

```json
{
  "code": 3,
  "message": "personalization token {Tag|} has no known modifier, so it would be delivered as text; expected one of [capitalizefirst capitalizeallfirst uppercase lowercase regular base64 cent dollar comma euro jpy lira M-d-y m-d-y M d y M d Y l M d H:i m-d-y H:i]"
}
```

<Aside type="caution">
En `UpdatePartial`, esta verificación se ejecuta contra el conjunto completo de campos de contenido sustituidos guardados del preset, no solo los campos en la solicitud actual — un preset que ya tiene un token roto en un campo no modificado falla cada llamada `UpdatePartial` subsiguiente hasta que se corrija ese token. `localizedTitle`, `localizedSubtitle` y `localizedContent` son la excepción: se verifican solo cuando la misma llamada los incluye.
</Aside>

### Modificadores aceptados

El selector de personalización del Panel de Control ya ofrece todos los modificadores a continuación para los tags `INTEGER`/`PRICE` (incluidos los formatos de fecha) y para los tags de cadena, excepto `base64` — ese solo es accesible a través de la API. `gitlab.corp.pushwoosh.com/channels/sdk/pkg/dynamiccontent` es la fuente de verdad contra la que validan tanto el Panel de Control como esta API.

| Modificador | Tipo de Tag | Notas |
| :---- | :---- | :---- |
| `capitalizefirst` | cadena | No distingue mayúsculas de minúsculas |
| `capitalizeallfirst` | cadena | No distingue mayúsculas de minúsculas |
| `uppercase` | cadena | No distingue mayúsculas de minúsculas |
| `lowercase` | cadena | No distingue mayúsculas de minúsculas |
| `regular` | cadena o entero | No distingue mayúsculas de minúsculas, no se aplica formato |
| `base64` | cadena | No distingue mayúsculas de minúsculas, solo API — no ofrecido por el selector del CP |
| `cent` / `dollar` / `comma` / `euro` / `jpy` / `lira` | entero | No distingue mayúsculas de minúsculas |
| `M-d-y`, `m-d-y`, `M d y`, `M d Y`, `l`, `M d`, `H:i`, `m-d-y H:i` | entero | Modificadores de formato de fecha, se comparan exactamente como están escritos, incluyendo mayúsculas y minúsculas |

## Endpoints

| Método | Ruta | Descripción |
| :---- | :---- | :---- |
| `POST` | `/api/presets` | Crear un nuevo preset de push |
| `GET` | `/api/presets` | Listar los presets de push de una aplicación |
| `GET` | `/api/presets/{code}` | Obtener un único preset de push |
| `PUT` | `/api/presets/{code}` | Actualizar un preset de push (sobrescritura completa) |
| `PUT` | `/api/presets/{code}:partial` | Actualizar un preset de push (parcial) |
| `POST` | `/api/presets/{code}:clone` | Clonar un preset de push |
| `DELETE` | `/api/presets/{code}` | Eliminar un preset de push |

## Crear

Crea un nuevo preset de push en una aplicación y lo devuelve con su código generado.

`POST` `/api/presets`

### Cuerpo de la solicitud

| Parámetro | Tipo | Requerido | Descripción |
| :---- | :---- | :---- | :---- |
| `application` | cadena | Sí | El [código de aplicación](/es/developer/api-reference/api-identifiers/#application-code) en el que crear el preset. |
| `name` | cadena | Sí | Nombre del preset. |
| `sendType` | cadena | No | Canal del preset (por ejemplo, `push`). |
| `isV2` | booleano | No | Fija la bandera de origen del preset. Omitir para que por defecto sea `true` (v2); establecer en `false` solo al reproducir un preset v1 heredado. |

Todos los demás campos — contenido localizado, plataformas, deep link, inbox, categorías, etc. — se comparten con `Update` y se documentan una vez en la referencia del [Objeto Preset](#preset-object) a continuación.

##### Ejemplo de solicitud

```json
{
  "application": "XXXXX-XXXXX",
  "name": "20% discount",
  "platforms": { "1": true, "3": true },
  "localizedContent": {
    "default": "Get your 20% discount right now",
    "es": "Consigue tu 20% de descuento ahora mismo"
  },
  "localizedTitle": { "default": "Hi there" },
  "openAction": { "link": { "url": "https://example.com" } },
  "categories": ["promo"]
}
```

### Respuesta

Devuelve `{ "preset": { ... } }`, el [Objeto Preset](#preset-object) creado.

## Listar

Lista los presets de push de una aplicación — un conjunto de campos reducido, no el objeto completo — con paginación, ordenamiento y filtrado por nombre o categoría.

`GET` `/api/presets`

### Parámetros de consulta

| Parámetro | Tipo | Requerido | Descripción |
| :---- | :---- | :---- | :---- |
| `application` | cadena | Sí | El código de la aplicación para la cual listar los presets. |
| `orderBy` | cadena | No | `NAME` (predeterminado), `CREATED` o `UPDATED`. |
| `orderDirection` | cadena | No | `ASC` (predeterminado) o `DESC`. |
| `page` | entero | No | Índice de página basado en cero. |
| `perPage` | entero | No | Tamaño de la página. Por defecto es `100` cuando se omite o es `0`. |
| `searchByName` | cadena | No | Coincidencia de subcadena sin distinción de mayúsculas y minúsculas en el nombre **o** código del preset (`ILIKE %value%`). |
| `searchByCategory` | array de cadenas | No | Repite el parámetro para filtrar por cualquiera de varias categorías, ej. `?searchByCategory=promo&searchByCategory=lifecycle`. |
| `showHidden` | booleano | No | Incluir presets marcados como `hidden`. |

<Aside type="note">
`isDefault` es un filtro obsoleto que se mantiene solo para el formulario de envío de push heredado en el Panel de Control — no confíes en él.
</Aside>

### Respuesta

Cada elemento contiene solo: `name`, `code`, `platforms`, `localized_content` (texto plano por localización — **no** `localized_properties`), `localized_title`, `localized_subtitle`, `banner`, `icon`, `categories`, `journey_uuid`, `custom_data`, `is_v2`, `created`, `updated`. Todos los demás campos del [Objeto Preset](#preset-object) — `localized_properties`, `platform_properties`, `deeplink`, `richmedia`, `url`, etc. — se omiten, incluso si están establecidos en el preset.

| Campo | Tipo | Descripción |
| :---- | :---- | :---- |
| `presets` | array de objetos | La página actual de presets, en la forma reducida descrita anteriormente. |
| `page` | entero | El índice de página devuelto. |
| `per_page` | entero | El tamaño de página utilizado para esta respuesta. |
| `total` | entero | Número total de presets que coinciden con los filtros, en todas las páginas. |

##### Ejemplo de respuesta

```json
{
  "presets": [
    { "name": "20% discount", "code": "AAAAA-BBBBB", "platforms": { "1": true, "3": true }, "categories": ["promo"] }
  ],
  "page": 0,
  "per_page": 100,
  "total": 1
}
```

## Obtener

Devuelve un único preset de push por su código, con todos los campos del [Objeto Preset](#preset-object) poblados.

`GET` `/api/presets/{code}`

### Parámetros de ruta

| Parámetro | Tipo | Descripción |
| :---- | :---- | :---- |
| `code` | cadena | El código del preset. |

### Respuesta

Devuelve `{ "preset": { ... } }`, el [Objeto Preset](#preset-object) completo.

## Actualizar

Sobrescribe un preset de push existente por código con los campos proporcionados.

`PUT` `/api/presets/{code}`

### Parámetros de ruta

| Parámetro | Tipo | Descripción |
| :---- | :---- | :---- |
| `code` | cadena | El código del preset a sobrescribir. |

### Cuerpo de la solicitud

Mismos campos que [Crear](#create) (menos `application`), más el resto de los campos del [Objeto Preset](#preset-object). `sendType` se acepta pero se ignora — el canal de un preset no se puede cambiar después de la creación.

<Aside type="caution" title="Omitir un campo no siempre significa 'dejar sin cambios'">
`Update` reconstruye las propiedades de contenido del preset desde cero en cada llamada: `localizedProperties`, `platformProperties`, `openAction`/`openActions`, `deeplink`, `deeplinkParams`, `richmedia`, `url`, `campaignCode`, `filterCode`, `geoZones`, `sendRate`, `cappingCount`/`cappingDays`, los tres campos `notification*Url`, `remotePage`, `wnsContent`, `originalUrl`, las cuatro banderas `*Silent`, `inboxImage`/`inboxIcon`/`inboxDays`/`inboxDate`, `banner`, `icon`, `customData` y `isV2` — omite cualquiera de estos y se borrará (o, para `isV2`, se restablecerá a `true`).

`name`, `platforms`, `categories`, `localizedTitle`, `localizedSubtitle` y `localizedContent` son la excepción: cada uno solo se modifica cuando lo envías, y se deja sin cambios cuando se omite.

Usa [UpdatePartial](#updatepartial) si quieres que el primer grupo también se deje sin cambios cuando se omita.
</Aside>

<Aside type="caution" title="La respuesta no tiene campo de preset">
`Update` devuelve `{}` — un objeto vacío. El mensaje de respuesta define técnicamente un campo `preset`, pero el servidor nunca lo puebla. Llama a `Get` después si necesitas el objeto actualizado de vuelta.
</Aside>

### Respuesta

Un objeto vacío en caso de éxito: `{}`.

## UpdatePartial

Actualiza solo los campos proporcionados de un preset de push existente por código, dejando los campos no establecidos sin cambios.

`PUT` `/api/presets/{code}:partial`

### Parámetros de ruta

| Parámetro | Tipo | Descripción |
| :---- | :---- | :---- |
| `code` | cadena | El código del preset a parchear. |

### Cuerpo de la solicitud

Mismos campos que [Actualizar](#update), menos `application`. A diferencia de `Update`, cada campo aquí — incluyendo `localizedProperties`, `platformProperties`, `categories`, y el resto del grupo de propiedades de contenido listado en la [precaución de Actualizar](#update) — se deja sin cambios cuando se omite, y solo se modifica cuando lo envías (un campo de mapa/array que envíes todavía reemplaza completamente el valor existente para ese campo, simplemente no afecta a nada que no hayas incluido). `sendType` también se acepta pero se ignora.

<Aside type="note">
`isV2` es la única excepción incluso aquí: se reescribe en cada llamada `UpdatePartial`, por defecto a `true` cuando se omite. Envía `isV2: false` explícitamente si el preset debe permanecer como un preset de estilo v1.
</Aside>

##### Ejemplo de solicitud

```json
{
  "sendRate": 500,
  "cappingCount": 3,
  "cappingDays": 7
}
```

### Respuesta

También un objeto vacío — ver la [precaución anterior](#update).

## Clonar

Duplica un preset de push existente, con un nuevo nombre, en la **misma** aplicación.

`POST` `/api/presets/{code}:clone`

<Aside type="note">
A diferencia del `Clone` de la API de Plantillas de Correo Electrónico, este endpoint no tiene un parámetro `application` — siempre clona dentro de la propia aplicación del preset de origen. El clon siempre se crea con `hidden: false`, independientemente del origen.
</Aside>

### Cuerpo de la solicitud

| Parámetro | Tipo | Requerido | Descripción |
| :---- | :---- | :---- | :---- |
| `code` | cadena | Sí | Código del preset de origen a duplicar. |
| `name` | cadena | Sí | Nombre para el nuevo preset. |

##### Ejemplo de solicitud

```json
{ "code": "AAAAA-BBBBB", "name": "20% discount (copy)" }
```

### Respuesta

Devuelve `{ "preset": { ... } }`, el nuevo [Objeto Preset](#preset-object).

## Eliminar

Elimina permanentemente un preset de push por código.

`DELETE` `/api/presets/{code}`

<Aside type="caution">
Falla si el preset todavía es utilizado por un punto `send_push` en un journey en ejecución o pausado — elimínalo primero del journey. Esto no se puede deshacer.
</Aside>

### Parámetros de ruta

| Parámetro | Tipo | Descripción |
| :---- | :---- | :---- |
| `code` | cadena | El código del preset a eliminar. |

### Respuesta

Un objeto vacío en caso de éxito: `{}`.

## Referencia de objetos

Los nombres de los campos a continuación coinciden con lo que `Get`, `Create`, `Update` y `Clone` realmente devuelven — nombres de campo de proto en `snake_case` (ver [Convenciones](#conventions)). La forma `lowerCamelCase` utilizada en los ejemplos de solicitud anteriores funciona de la misma manera en la entrada.

### Objeto Preset

#### Identidad

| Campo | Tipo | Descripción |
| :---- | :---- | :---- |
| `code` | cadena | Generado en `Create`. Identifica este preset en cualquier otro lugar de la API. |
| `name` | cadena | Nombre del preset. |
| `send_type` | cadena | Canal del preset (por ejemplo, `push`). |
| `is_v2` | booleano | `true` para presets creados o migrados al modelo de contenido v2. |
| `system` | booleano | Marca el preset como un preset de sistema/interno. |
| `hidden` | booleano | Oculta el preset de los resultados de `List` (envía `showHidden: true` para incluirlo). |
| `created` | cadena (RFC 3339) | Marca de tiempo de creación. |
| `updated` | cadena (RFC 3339) | Marca de tiempo de la última actualización. |

#### Segmentación y contenido

| Campo | Tipo | Descripción |
| :---- | :---- | :---- |
| `platforms` | map&lt;string, boolean&gt; | A qué plataformas se dirige el preset, con clave por [código de tipo de dispositivo](/es/developer/api-reference/api-identifiers/#device-type) (p. ej., `"1"` para iOS). |
| `localized_properties` | map&lt;string, object&gt; | Localización → contenido enriquecido por plataforma. Misma forma que [`LocalizedContent`](/es/developer/api-reference/messaging-api-v2/payload-reference/#localizedcontent) en el payload de `Notify` — una entrada por bloque de plataforma (`ios`, `android`, etc.). Esta es la forma principal de establecer contenido de push específico de la plataforma. |
| `localized_title` / `localized_subtitle` / `localized_content` | map&lt;string, string&gt; | Localización → texto plano. Una alternativa más simple a `localized_properties` para el título, subtítulo y cuerpo cuando no necesitas sobrescrituras por plataforma. |
| `platform_properties` | map&lt;string, object&gt; | Sobrescrituras heredadas por plataforma, con clave por nombre de enum de la plataforma (`IOS`, `ANDROID`, `HUAWEI_ANDROID`, `OSX`). Ver [Objeto PlatformProperties](#platformproperties-object) a continuación. |
| `open_action` | [`OpenAction`](/es/developer/api-reference/messaging-api-v2/payload-reference/#openaction) | Acción que se activa cuando el usuario abre la notificación, aplicada a todas las plataformas. Mutuamente excluyente con `open_actions` — la respuesta establece exactamente una. |
| `open_actions` | map&lt;string, `OpenAction`&gt; | Sobrescritura por plataforma de `open_action`, con clave por [código de tipo de dispositivo](/es/developer/api-reference/api-identifiers/#device-type). |
| `deeplink` | cadena | Código de [Deep Link](/es/developer/guides/messaging-channels/deep-linking/). |
| `deeplink_params` | map&lt;string, string&gt; | Parámetros pasados al deep link. |
| `richmedia` | cadena | Código de [Rich Media](/es/product/content/rich-media/) abierto por la notificación. |
| `url` | cadena | URL abierta por la notificación, si no se utiliza un deep link o Rich Media. |

#### Inbox

| Campo | Tipo | Descripción |
| :---- | :---- | :---- |
| `inbox_image` | cadena | URL de la imagen que se muestra en la entrada de [Message Inbox](/es/developer/guides/message-inbox/mobile-message-inbox/). |
| `inbox_icon` | cadena | URL del icono que se muestra en la entrada de Message Inbox. |
| `inbox_days` | entero | Días que la entrada permanece en el Message Inbox. |
| `inbox_date` | cadena (RFC 3339) | Fecha de vencimiento explícita para la entrada de Message Inbox, como alternativa a `inbox_days`. |

#### Organización y metadatos

| Campo | Tipo | Descripción |
| :---- | :---- | :---- |
| `categories` | array de cadenas | Nombres de las categorías con las que está etiquetado el preset. |
| `campaign_code` | cadena | [Código de campaña](/es/developer/api-reference/api-identifiers/#campaign-code) al que se atribuye este preset. |
| `filter_code` | cadena | [Código de Segmento / Filtro](/es/developer/api-reference/api-identifiers/#segment--filter-code) al que se dirige este preset por defecto. |
| `geo_zones` | cadena | Segmentación por [Geozona](/es/developer/api-reference/geozones/), si el preset se activa geográficamente. |
| `journey_uuid` | cadena | UUID del Customer Journey propietario de este preset, si fue creado desde un punto de envío de push de un journey. |
| `custom_data` | objeto | JSON de formato libre reenviado al SDK del cliente como el parámetro `u`. |
| `banner` | cadena | URL de la imagen de gran tamaño / adjunto. |
| `icon` | cadena | URL del icono de notificación personalizado. |

#### Límites de entrega

| Campo | Tipo | Descripción |
| :---- | :---- | :---- |
| `send_rate` | entero | Limitación para los envíos que utilizan este preset, en mensajes/segundo — el equivalente a nivel de preset de [`SendRate`](/es/developer/api-reference/messaging-api-v2/notify/#sendrate) de `Notify`. |
| `capping_count` / `capping_days` | entero | Límite de frecuencia por usuario para este preset — el equivalente a nivel de preset de `count` / `days` de [`FrequencyCapping`](/es/developer/api-reference/messaging-api-v2/notify/#frequencycapping) de `Notify`. |

#### Webhooks

| Campo | Tipo | Descripción |
| :---- | :---- | :---- |
| `notification_sent_url` | cadena | URL de callback solicitada cuando se envía una notificación que utiliza este preset. |
| `notification_delivered_url` | cadena | URL de callback solicitada cuando se entrega una notificación que utiliza este preset. |
| `notification_click_url` | cadena | URL de callback solicitada cuando se hace clic en una notificación que utiliza este preset. |

#### Campos heredados

Estos se arrastran del modelo de preset v1. Se pueblan para compatibilidad con el Panel de Control en lugar de para nuevas integraciones.

| Campo | Tipo | Descripción |
| :---- | :---- | :---- |
| `remote_page` | cadena | Referencia a página remota heredada. |
| `wns_content` | cadena | JSON de plantilla de notificación de Windows heredado, como lo aceptan los métodos v1 `createPreset`/`getPreset`. |
| `original_url` | cadena | El valor de `url` antes de acortar, cuando `url` fue reemplazado por un enlace acortado. |
| `ios_silent` / `android_silent` / `huawei_android_silent` | booleano | Banderas de push silencioso (solo datos) por plataforma. |

### Objeto PlatformProperties

Campos disponibles en cada entrada de `platform_properties` (`IOS`, `ANDROID`, `HUAWEI_ANDROID`, `OSX`):

| Campo | Tipo | Descripción |
| :---- | :---- | :---- |
| `badge` | cadena | Sobrescritura del contador de notificaciones. |
| `sound` | cadena | Nombre del archivo de sonido. |
| `sound_off` | booleano | Silenciar el sonido de la notificación. |
| `priority` | cadena | Prioridad en la bandeja de entrada (solo Android/Huawei). |
| `delivery_priority` | cadena | Prioridad de entrega `NORMAL` o `HIGH` (solo Android/Huawei). |
| `ios_interruption_level` | cadena | `passive`, `active`, `time-sensitive`, o `critical` (solo iOS). |

## Relacionado

<CardGrid>
  <LinkCard title="Notify" href="/developer/api-reference/messaging-api-v2/notify/" />
  <LinkCard title="Referencia de Payload" href="/developer/api-reference/messaging-api-v2/payload-reference/" />
  <LinkCard title="Referencia de puntos de Customer Journey" href="/developer/api-reference/customer-journey-api/point-reference/#messaging-points" />
</CardGrid>