` debe declarar `xmlns:tools="http://schemas.android.com/tools"`.
```xml showLineNumbers title="AndroidManifest.xml"
```
---
# File: android-onboardings
---
---
title: "Onboardings en el SDK de Android"
description: "Aprende a trabajar con onboardings en tu app de Android con el SDK de Adapty."
---
:::warning
**Los onboardings están obsoletos a partir de Adapty SDK v4.** Usa [flows](adapty-flow-builder) en su lugar: a diferencia de los onboardings, que se ejecutan dentro de un WebView, los flows se renderizan de forma nativa en el dispositivo — animaciones más fluidas, una apariencia nativa consistente, tiempos de carga más rápidos y sin dependencia del runtime de WebView.
:::
---
# File: android-get-onboardings
---
---
title: "Obtener onboardings en el SDK de Android"
description: "Aprende cómo recuperar onboardings en Adapty para Android."
---
:::warning
**Los onboardings están obsoletos a partir de Adapty SDK v4.** Usa [flows](adapty-flow-builder) en su lugar: a diferencia de los onboardings, que se ejecutan dentro de un WebView, los flows se renderizan de forma nativa en el dispositivo — animaciones más fluidas, una apariencia nativa consistente, tiempos de carga más rápidos y sin dependencia del runtime de WebView.
:::
Tras [diseñar la parte visual de tu onboarding](design-onboarding) con el builder en el Adapty Dashboard, puedes mostrarlo en tu app de Android. El primer paso es obtener el onboarding asociado al placement y su configuración de vista, como se describe a continuación.
Antes de comenzar, asegúrate de que:
1. Tienes instalado el [SDK de Adapty para Android](sdk-installation-android) versión 3.8.0 o superior.
2. Has [creado un onboarding](create-onboarding).
3. Has añadido el onboarding a un [placement](placements).
## Obtener el onboarding \{#fetch-onboarding\}
Cuando creas un [onboarding](onboardings) con nuestro editor sin código, se almacena como un contenedor con la configuración que tu app necesita obtener y mostrar. Este contenedor gestiona toda la experiencia: qué contenido aparece, cómo se presenta y cómo se procesan las interacciones del usuario (como respuestas a cuestionarios o entradas de formularios). El contenedor también registra automáticamente los eventos de analítica, por lo que no necesitas implementar un seguimiento de vistas por separado.
Para un mejor rendimiento, obtén la configuración del onboarding con antelación para que las imágenes tengan tiempo suficiente de descargarse antes de mostrárselas a los usuarios.
Para obtener un onboarding, utiliza el método `getOnboarding`:
```kotlin showLineNumbers
Adapty.getOnboarding("YOUR_PLACEMENT_ID") { result ->
when (result) {
is AdaptyResult.Success -> {
val onboarding = result.value
// the requested onboarding
}
is AdaptyResult.Error -> {
val error = result.error
// handle the error
}
}
}
```
Parámetros:
| Parámetro | Presencia | Descripción |
|---------|--------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| **placementId** | obligatorio | El identificador del [Placement](placements) deseado. Es el valor que especificaste al crear un placement en el Adapty Dashboard. |
| **locale** | opcional
por defecto: `en`
| El identificador de la localización del onboarding. Se espera que este parámetro sea un código de idioma compuesto por uno o dos subetiquetas separadas por el carácter menos (**-**). La primera subetiqueta corresponde al idioma y la segunda a la región.
Ejemplo: `en` significa inglés, `pt-br` representa el portugués brasileño.
Consulta [Localizaciones y códigos de idioma](localizations-and-locale-codes) para más información sobre los códigos de idioma y cómo recomendamos usarlos.
|
| **fetchPolicy** | por defecto: `.reloadRevalidatingCacheData` | Por defecto, el SDK intentará cargar los datos desde el servidor y devolverá los datos en caché en caso de fallo. Recomendamos esta opción porque garantiza que tus usuarios siempre reciban los datos más actualizados.
Sin embargo, si crees que tus usuarios trabajan con una conexión a internet inestable, considera usar `.returnCacheDataElseLoad` para devolver los datos en caché si existen. En este caso, los usuarios podrían no obtener los datos más recientes, pero experimentarán tiempos de carga más rápidos, independientemente de lo intermitente que sea su conexión. La caché se actualiza con regularidad, por lo que es seguro usarla durante la sesión para evitar peticiones de red.
Ten en cuenta que la caché se mantiene intacta al reiniciar la app y solo se borra cuando se desinstala la app o mediante una limpieza manual.
El SDK de Adapty almacena los onboardings localmente en dos capas: la caché actualizada periódicamente descrita anteriormente y los onboardings de respaldo. También utilizamos CDN para obtener los onboardings más rápido y un servidor de respaldo independiente en caso de que el CDN no esté disponible. Este sistema está diseñado para garantizar que siempre obtengas la última versión de tus onboardings y asegurar la fiabilidad incluso cuando la conexión a internet es escasa.
|
| **loadTimeout** | por defecto: 5 seg | Este valor limita el tiempo de espera para este método. Si se alcanza el tiempo límite, se devolverán los datos en caché o el fallback local.
Ten en cuenta que en casos poco frecuentes este método puede agotar el tiempo de espera ligeramente después del valor especificado en `loadTimeout`, ya que la operación puede consistir en diferentes peticiones internamente.
Para Android: puedes crear un `TimeInterval` con funciones de extensión (como `5.seconds`, donde `.seconds` proviene de `import com.adapty.utils.seconds`), o `TimeInterval.seconds(5)`. Para no establecer ningún límite, usa `TimeInterval.INFINITE`.
|
Parámetros de respuesta:
| Parámetro | Descripción |
|:----------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------|
| Onboarding | Un objeto [`AdaptyOnboarding`](https://android.adapty.io/adapty/com.adapty.models/-adapty-onboarding/) con: el identificador y la configuración del onboarding, Remote Config y otras propiedades. |
## Acelera la obtención del onboarding con el onboarding de audiencia predeterminada \{#speed-up-onboarding-fetching-with-default-audience-onboarding\}
Normalmente, los onboardings se obtienen casi al instante, por lo que no necesitas preocuparte por acelerar este proceso. Sin embargo, cuando tienes muchas audiencias y onboardings, y tus usuarios tienen una conexión a internet lenta, obtener un onboarding puede tardar más de lo deseable. En esas situaciones, puede que quieras mostrar un onboarding predeterminado para garantizar una experiencia fluida en lugar de no mostrar ninguno.
Para solucionar esto, puedes usar el método `getOnboardingForDefaultAudience`, que obtiene el onboarding del placement especificado para la audiencia **All Users**. Sin embargo, es fundamental entender que el enfoque recomendado es obtener el onboarding mediante el método `getOnboarding`, tal como se detalla en la sección [Obtener onboarding](#fetch-onboarding) anterior.
:::warning
Considera usar `getOnboarding` en lugar de `getOnboardingForDefaultAudience`, ya que este último tiene limitaciones importantes:
- **Problemas de compatibilidad**: Puede causar problemas al dar soporte a varias versiones de la app, lo que obliga a diseños retrocompatibles o a asumir que las versiones anteriores podrían mostrarse incorrectamente.
- **Sin personalización**: Solo muestra contenido para la audiencia "All Users", eliminando la segmentación por país, atribución o atributos personalizados.
Si una obtención más rápida compensa estos inconvenientes en tu caso de uso, utiliza `getOnboardingForDefaultAudience` como se muestra a continuación. De lo contrario, usa `getOnboarding` como se describe [más arriba](#fetch-onboarding).
:::
```kotlin
Adapty.getOnboardingForDefaultAudience("YOUR_PLACEMENT_ID") { result ->
when (result) {
is AdaptyResult.Success -> {
val onboarding = result.value
// Handle successful onboarding retrieval
}
is AdaptyResult.Error -> {
val error = result.error
// Handle error case
}
}
}
```
Parámetros:
| Parámetro | Presencia | Descripción |
|---------|--------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| **placementId** | obligatorio | El identificador del [Placement](placements) deseado. Es el valor que especificaste al crear un placement en el Adapty Dashboard. |
| **locale** | opcional
por defecto: `en`
| El identificador de la localización del onboarding. Se espera que este parámetro sea un código de idioma compuesto por uno o dos subetiquetas separadas por el carácter menos (**-**). La primera subetiqueta corresponde al idioma y la segunda a la región.
Ejemplo: `en` significa inglés, `pt-br` representa el portugués de Brasil.
Consulta [Localizaciones y códigos de idioma](localizations-and-locale-codes) para más información sobre los códigos de idioma y cómo recomendamos usarlos.
|
| **fetchPolicy** | por defecto: `.reloadRevalidatingCacheData` | Por defecto, el SDK intentará cargar los datos desde el servidor y devolverá los datos en caché si falla. Recomendamos esta opción porque garantiza que tus usuarios siempre reciban los datos más actualizados.
Sin embargo, si crees que tus usuarios tienen una conexión a internet inestable, considera usar `.returnCacheDataElseLoad` para devolver los datos en caché cuando existan. En ese caso, puede que los usuarios no reciban los datos absolutamente más recientes, pero experimentarán tiempos de carga más rápidos sin importar la calidad de su conexión. La caché se actualiza con regularidad, por lo que es seguro usarla durante la sesión para evitar peticiones de red.
Ten en cuenta que la caché se conserva al reiniciar la app y solo se borra cuando se desinstala la aplicación o mediante una limpieza manual.
El SDK de Adapty almacena los onboardings localmente en dos capas: la caché de actualización periódica descrita anteriormente y los onboardings de respaldo. También usamos CDN para obtener los onboardings más rápido y un servidor de respaldo independiente en caso de que el CDN no esté disponible. Este sistema está diseñado para garantizar que siempre obtengas la última versión de tus onboardings y asegurar la fiabilidad incluso cuando la conexión a internet es limitada.
|
---
# File: android-present-onboardings
---
---
title: "Presentar onboardings en el SDK de Android"
description: "Aprende a presentar onboardings en Android para una interacción efectiva con el usuario."
---
:::warning
**Los onboardings están obsoletos a partir de Adapty SDK v4.** Usa [flows](adapty-flow-builder) en su lugar: a diferencia de los onboardings, que se ejecutan dentro de un WebView, los flows se renderizan de forma nativa en el dispositivo — animaciones más fluidas, una apariencia nativa consistente, tiempos de carga más rápidos y sin dependencia del runtime de WebView.
:::
Antes de comenzar, asegúrate de que:
1. Has instalado el [SDK de Adapty para Android](sdk-installation-android) 3.8.0 o posterior.
2. Has [creado un onboarding](create-onboarding).
3. Has añadido el onboarding a un [placement](placements).
Si has personalizado un onboarding con el Onboarding Builder, no necesitas preocuparte por renderizarlo en el código de tu app para mostrárselo al usuario. Ese onboarding ya contiene tanto qué mostrar como cómo mostrarlo.
Para mostrar el onboarding visual en la pantalla del dispositivo, primero debes configurarlo. Para ello, llama al método `AdaptyUI.getOnboardingView()` o crea el `OnboardingView` directamente:
```kotlin
val onboardingView = AdaptyUI.getOnboardingView(
activity = this,
viewConfig = onboardingConfig,
eventListener = eventListener
)
```
```kotlin
val onboardingView = AdaptyOnboardingView(activity)
onboardingView.show(
viewConfig = onboardingConfig,
delegate = eventListener
)
```
```java
AdaptyOnboardingView onboardingView = AdaptyUI.getOnboardingView(
activity,
onboardingConfig,
eventListener
);
```
```java
AdaptyOnboardingView onboardingView = new AdaptyOnboardingView(activity);
onboardingView.show(onboardingConfig, eventListener);
```
```xml
```
Una vez que la vista se haya creado correctamente, puedes añadirla a la jerarquía de vistas y mostrarla en la pantalla del dispositivo.
Parámetros de la solicitud:
| Parámetro | Presencia | Descripción |
| :-------- | :------- |:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| **viewConfig** | obligatorio | La configuración del onboarding obtenida de `AdaptyUI.getOnboardingConfiguration()` |
| **eventListener** | obligatorio | Una implementación de `AdaptyOnboardingEventListener` para gestionar los eventos del onboarding. Consulta [Gestión de eventos de onboarding](android-handle-onboarding-events) para más detalles. |
## Cambiar el color del indicador de carga \{#change-loading-indicator-color\}
Puedes sobreescribir el color por defecto del indicador de carga de la siguiente manera:
```xml
```
## Agrega transiciones suaves entre la pantalla de inicio y el onboarding \{#add-smooth-transitions-between-the-splash-screen-and-onboarding\}
Por defecto, entre la pantalla de inicio y el onboarding verás la pantalla de carga hasta que el onboarding se haya cargado por completo. Sin embargo, si quieres que la transición sea más suave, puedes personalizarla y ampliar la pantalla de inicio o mostrar otra cosa.
Para ello, crea `adapty_onboarding_placeholder_view.xml` en `res/layout` y define ahí un marcador de posición (lo que se mostrará mientras el onboarding se está cargando).
Si defines un placeholder, el onboarding se cargará en segundo plano y se mostrará automáticamente cuando esté listo.
## Desactivar los márgenes del área segura \{#disable-safe-area-paddings\}
Por defecto, la vista de onboarding aplica automáticamente márgenes del área segura para evitar elementos de la interfaz del sistema como la barra de estado y la barra de navegación. Sin embargo, si quieres desactivar este comportamiento y tener control total sobre el diseño, puedes hacerlo estableciendo el parámetro `safeAreaPaddings` en `false`.
```kotlin
val onboardingView = AdaptyUI.getOnboardingView(
activity = this,
viewConfig = onboardingConfig,
eventListener = eventListener,
safeAreaPaddings = false
)
```
```kotlin
val onboardingView = AdaptyOnboardingView(activity)
onboardingView.show(
viewConfig = onboardingConfig,
delegate = eventListener,
safeAreaPaddings = false
)
```
```java
AdaptyOnboardingView onboardingView = AdaptyUI.getOnboardingView(
activity,
onboardingConfig,
eventListener,
false
);
```
```java
AdaptyOnboardingView onboardingView = new AdaptyOnboardingView(activity);
onboardingView.show(onboardingConfig, eventListener, false);
```
Alternativamente, puedes controlar este comportamiento de forma global añadiendo un recurso booleano a tu app:
```xml
false
```
Cuando `safeAreaPaddings` se establece en `false`, el onboarding se extenderá a pantalla completa sin ajustes automáticos de padding, dándote control total sobre el diseño y permitiendo que el contenido del onboarding ocupe todo el espacio de pantalla.
## Personalizar cómo se abren los enlaces en los onboardings \{#customize-how-links-open-in-onboardings\}
:::important
La personalización de cómo se abren los enlaces en los onboardings está disponible a partir de la versión 3.15.1 del SDK de Adapty.
:::
Por defecto, los enlaces en los onboardings se abren en un navegador integrado en la app. Esto ofrece una experiencia fluida al mostrar las páginas web dentro de tu aplicación, sin que el usuario tenga que cambiar de app.
Si prefieres abrir los enlaces en un navegador externo, puedes personalizar este comportamiento estableciendo el parámetro `externalUrlsPresentation` en `AdaptyWebPresentation.ExternalBrowser`:
```kotlin
val onboardingConfig = AdaptyUI.getOnboardingConfiguration(
onboarding = onboarding,
externalUrlsPresentation = AdaptyWebPresentation.ExternalBrowser // default – InAppBrowser
)
```
```java
AdaptyOnboardingConfiguration onboardingConfig = AdaptyUI.getOnboardingConfiguration(
onboarding,
AdaptyWebPresentation.ExternalBrowser // default – InAppBrowser
);
```
---
# File: android-handle-onboarding-events
---
---
title: "Gestionar eventos de onboarding en el SDK de Android"
description: "Gestiona eventos relacionados con el onboarding en Android usando Adapty."
---
:::warning
**Los onboardings están obsoletos a partir de Adapty SDK v4.** Usa [flows](adapty-flow-builder) en su lugar: a diferencia de los onboardings, que se ejecutan dentro de un WebView, los flows se renderizan de forma nativa en el dispositivo — animaciones más fluidas, una apariencia nativa consistente, tiempos de carga más rápidos y sin dependencia del runtime de WebView.
:::
Antes de empezar, asegúrate de que:
1. Has instalado [Adapty Android SDK](sdk-installation-android) 3.8.0 o posterior.
2. Has [creado un onboarding](create-onboarding).
3. Has añadido el onboarding a un [placement](placements).
Los onboardings configurados con el builder generan eventos a los que tu app puede responder. A continuación aprenderás cómo hacerlo.
Para controlar o monitorizar los procesos que ocurren en la pantalla de onboarding dentro de tu app Android, implementa la interfaz `AdaptyOnboardingEventListener`.
## Acciones personalizadas \{#custom-actions\}
En el builder, puedes añadir una acción **personalizada** a un botón y asignarle un ID. Luego, puedes usar ese ID en tu código y gestionarlo como una acción personalizada.
Por ejemplo, si un usuario pulsa un botón personalizado, como **Login** o **Allow notifications**, el método delegado `onCustomAction` se activará con el ID de acción del builder. Puedes crear tus propios IDs, como "allowNotifications".
```kotlin showLineNumbers
class YourActivity : AppCompatActivity() {
private val eventListener = object : AdaptyOnboardingEventListener {
override fun onCustomAction(action: AdaptyOnboardingCustomAction, context: Context) {
when (action.actionId) {
"allowNotifications" -> {
// Request notification permissions
}
}
}
override fun onError(error: AdaptyOnboardingError, context: Context) {
// Handle errors
}
// ... other required delegate methods
}
}
```
Ejemplo de evento (haz clic para expandir)
```json
{
"actionId": "allowNotifications",
"meta": {
"onboardingId": "onboarding_123",
"screenClientId": "profile_screen",
"screenIndex": 0,
"screensTotal": 3
}
}
```
## Cerrar el onboarding \{#closing-onboarding\}
El onboarding se considera cerrado cuando el usuario pulsa un botón con la acción **Close** asignada. Debes gestionar qué ocurre cuando el usuario cierra el onboarding. Por ejemplo:
:::important
Debes gestionar qué ocurre cuando el usuario cierra el onboarding. Por ejemplo, debes dejar de mostrar el onboarding.
:::
Por ejemplo:
```kotlin
override fun onCloseAction(action: AdaptyOnboardingCloseAction, context: Context) {
// Dismiss the onboarding screen
(context as? Activity)?.onBackPressed()
}
```
Ejemplo de evento (haz clic para expandir)
```json
{
"action_id": "close_button",
"meta": {
"onboarding_id": "onboarding_123",
"screen_cid": "final_screen",
"screen_index": 3,
"total_screens": 4
}
}
```
## Abrir un paywall \{#opening-a-paywall\}
:::tip
Gestiona este evento para abrir un paywall si quieres abrirlo dentro del onboarding. Si quieres abrir un paywall después de que se cierre, hay una forma más directa de hacerlo: gestiona [`AdaptyOnboardingCloseAction`](#closing-onboarding) y abre un paywall sin depender de los datos del evento.
:::
La forma más fluida de trabajar con paywalls en onboardings es hacer que el ID de acción sea igual al ID de placement del paywall. Así, después del evento `AdaptyOnboardingOpenPaywallAction`, puedes usar el ID de placement para obtener y abrir el paywall directamente:
```kotlin
override fun onOpenPaywallAction(action: AdaptyOnboardingOpenPaywallAction, context: Context) {
// Get the paywall using the placement ID from the action
Adapty.getPaywall(placementId = action.actionId) { result ->
when (result) {
is AdaptyResult.Success -> {
val paywall = result.value
// Get the paywall configuration
AdaptyUI.getViewConfiguration(paywall) { result ->
when(result) {
is AdaptyResult.Success -> {
val paywallConfig = result.value
// Create and present the paywall
val paywallView = AdaptyUI.getPaywallView(
activity = this,
viewConfig = paywallConfig,
products,
eventListener = paywallEventListener
)
// Add the paywall view to your layout
binding.container.addView(paywallView)
}
is AdaptyResult.Error -> {
val error = result.error
// handle the error
}
}
}
is AdaptyResult.Error -> {
val error = result.error
// handle the error
}
}
}
}
```
Ejemplo de evento (Haz clic para expandir)
```json
{
"action_id": "premium_offer_1",
"meta": {
"onboarding_id": "onboarding_123",
"screen_cid": "pricing_screen",
"screen_index": 2,
"total_screens": 4
}
}
```
## Finalización de la carga del onboarding \{#finishing-loading-onboarding\}
Cuando el onboarding termina de cargarse, se invocará este método:
```kotlin
override fun onFinishLoading(action: AdaptyOnboardingLoadedAction, context: Context) {
// Handle loading completion
}
```
Ejemplo de evento (haz clic para expandir)
```json
{
"meta": {
"onboarding_id": "onboarding_123",
"screen_cid": "welcome_screen",
"screen_index": 0,
"total_screens": 4
}
}
```
## Eventos de navegación \{#navigation-events\}
El método `onAnalyticsEvent` se llama cuando se producen distintos eventos de analítica durante el flow de onboarding.
El objeto `event` puede ser de uno de los siguientes tipos:
|Tipo | Descripción |
|------------|-------------|
| `OnboardingStarted` | Cuando el onboarding se ha cargado |
| `ScreenPresented` | Cuando se muestra cualquier pantalla |
| `ScreenCompleted` | Cuando se completa una pantalla. Incluye un `elementId` opcional (identificador del elemento completado) y un `reply` opcional (respuesta del usuario). Se activa cuando el usuario realiza cualquier acción para salir de la pantalla. |
| `SecondScreenPresented` | Cuando se muestra la segunda pantalla |
| `UserEmailCollected` | Se activa cuando se recoge el email del usuario a través del campo de entrada |
| `OnboardingCompleted` | Se activa cuando un usuario llega a una pantalla con el ID `final`. Si necesitas este evento, asigna el ID `final` a la última pantalla. |
| `Unknown` | Para cualquier tipo de evento no reconocido. Incluye `name` (el nombre del evento desconocido) y `meta` (metadatos adicionales) |
Cada evento incluye información `meta` con los siguientes campos:
| Campo | Descripción |
|------------|-------------|
| `onboardingId` | Identificador único del flow de onboarding |
| `screenClientId` | Identificador de la pantalla actual |
| `screenIndex` | Posición de la pantalla actual en el flow |
| `totalScreens` | Número total de pantallas en el flow |
A continuación se muestra un ejemplo de cómo usar los eventos de analytics para el seguimiento:
```kotlin
override fun onAnalyticsEvent(event: AdaptyOnboardingAnalyticsEvent, context: Context) {
when (event) {
is AdaptyOnboardingAnalyticsEvent.OnboardingStarted -> {
// Track onboarding start
trackEvent("onboarding_started", event.meta)
}
is AdaptyOnboardingAnalyticsEvent.ScreenPresented -> {
// Track screen presentation
trackEvent("screen_presented", event.meta)
}
is AdaptyOnboardingAnalyticsEvent.ScreenCompleted -> {
// Track screen completion with user response
trackEvent("screen_completed", event.meta, event.elementId, event.reply)
}
is AdaptyOnboardingAnalyticsEvent.OnboardingCompleted -> {
// Track successful onboarding completion
trackEvent("onboarding_completed", event.meta)
}
is AdaptyOnboardingAnalyticsEvent.Unknown -> {
// Handle unknown events
trackEvent(event.name, event.meta)
}
// Handle other cases as needed
}
}
```
Ejemplos de eventos (Haz clic para expandir)
```javascript
// OnboardingStarted
{
"name": "onboarding_started",
"meta": {
"onboarding_id": "onboarding_123",
"screen_cid": "welcome_screen",
"screen_index": 0,
"total_screens": 4
}
}
// ScreenPresented
{
"name": "screen_presented",
"meta": {
"onboarding_id": "onboarding_123",
"screen_cid": "interests_screen",
"screen_index": 2,
"total_screens": 4
}
}
// ScreenCompleted
{
"name": "screen_completed",
"meta": {
"onboarding_id": "onboarding_123",
"screen_cid": "profile_screen",
"screen_index": 1,
"total_screens": 4
},
"params": {
"element_id": "profile_form",
"reply": "success"
}
}
// SecondScreenPresented
{
"name": "second_screen_presented",
"meta": {
"onboarding_id": "onboarding_123",
"screen_cid": "profile_screen",
"screen_index": 1,
"total_screens": 4
}
}
// UserEmailCollected
{
"name": "user_email_collected",
"meta": {
"onboarding_id": "onboarding_123",
"screen_cid": "profile_screen",
"screen_index": 1,
"total_screens": 4
}
}
// OnboardingCompleted
{
"name": "onboarding_completed",
"meta": {
"onboarding_id": "onboarding_123",
"screen_cid": "final_screen",
"screen_index": 3,
"total_screens": 4
}
}
```
---
# File: android-onboarding-input
---
---
title: "Procesar datos de onboardings en el SDK de Android"
description: "Guarda y utiliza datos de onboardings en tu app Android con el SDK de Adapty."
---
:::warning
**Los onboardings están obsoletos a partir de Adapty SDK v4.** Usa [flows](adapty-flow-builder) en su lugar: a diferencia de los onboardings, que se ejecutan dentro de un WebView, los flows se renderizan de forma nativa en el dispositivo — animaciones más fluidas, una apariencia nativa consistente, tiempos de carga más rápidos y sin dependencia del runtime de WebView.
:::
Cuando tus usuarios responden a una pregunta de un cuestionario o introducen datos en un campo de texto, se invocará el método `onStateUpdatedAction`. Puedes guardar o procesar el tipo de campo en tu código.
Por ejemplo:
```kotlin
override fun onStateUpdatedAction(action: AdaptyOnboardingStateUpdatedAction, context: Context) {
// Store user preferences or responses
when (val params = action.params) {
is AdaptyOnboardingStateUpdatedParams.Select -> {
// Handle single selection
}
is AdaptyOnboardingStateUpdatedParams.MultiSelect -> {
// Handle multiple selections
}
is AdaptyOnboardingStateUpdatedParams.Input -> {
// Handle text input
}
is AdaptyOnboardingStateUpdatedParams.DatePicker -> {
// Handle date selection
}
}
}
```
Consulta el formato de acción [aquí](https://android.adapty.io/adapty-ui/com.adapty.ui.onboardings.actions/-adapty-onboarding-state-updated-action/).
Ejemplos de datos guardados (el formato puede variar según tu implementación)
```javascript
// Example of a saved select action
{
"elementId": "preference_selector",
"meta": {
"onboardingId": "onboarding_123",
"screenClientId": "preferences_screen",
"screenIndex": 1,
"screensTotal": 3
},
"params": {
"type": "select",
"value": {
"id": "option_1",
"value": "premium",
"label": "Premium Plan"
}
}
}
// Example of a saved multi-select action
{
"elementId": "interests_selector",
"meta": {
"onboardingId": "onboarding_123",
"screenClientId": "interests_screen",
"screenIndex": 2,
"screensTotal": 3
},
"params": {
"type": "multiSelect",
"value": [
{
"id": "interest_1",
"value": "sports",
"label": "Sports"
},
{
"id": "interest_2",
"value": "music",
"label": "Music"
}
]
}
}
// Example of a saved input action
{
"elementId": "name_input",
"meta": {
"onboardingId": "onboarding_123",
"screenClientId": "profile_screen",
"screenIndex": 0,
"screensTotal": 3
},
"params": {
"type": "input",
"value": {
"type": "text",
"value": "John Doe"
}
}
}
// Example of a saved date picker action
{
"elementId": "birthday_picker",
"meta": {
"onboardingId": "onboarding_123",
"screenClientId": "profile_screen",
"screenIndex": 0,
"screensTotal": 3
},
"params": {
"type": "datePicker",
"value": {
"day": 15,
"month": 6,
"year": 1990
}
}
}
```
## Casos de uso \{#use-cases\}
### Enriquece los perfiles de usuario con datos \{#enrich-user-profiles-with-data\}
Si quieres vincular directamente los datos introducidos con el perfil del usuario y evitar pedirle la misma información dos veces, necesitas [actualizar el perfil de usuario](android-setting-user-attributes) con esos datos al gestionar la acción.
Por ejemplo, pides a los usuarios que introduzcan su nombre en el campo de texto con el ID `name` y quieres establecer el valor de ese campo como el nombre del usuario. También les pides que introduzcan su correo electrónico en el campo `email`. En el código de tu app, podría verse así:
```kotlin showLineNumbers
override fun onStateUpdatedAction(action: AdaptyOnboardingStateUpdatedAction, context: Context) {
// Store user preferences or responses
when (val params = action.params) {
is AdaptyOnboardingStateUpdatedParams.Input -> {
// Handle text input
val builder = AdaptyProfileParameters.Builder()
// Map elementId to appropriate profile field
when (action.elementId) {
"name" -> {
when (val inputParams = params.params) {
is AdaptyOnboardingInputParams.Text -> {
builder.withFirstName(inputParams.value)
}
}
}
"email" -> {
when (val inputParams = params.params) {
is AdaptyOnboardingInputParams.Email -> {
builder.withEmail(inputParams.value)
}
}
}
}
Adapty.updateProfile(builder.build()) { error ->
if (error != null) {
// handle the error
}
}
}
}
}
```
### Personalizar paywalls según las respuestas \{#customize-paywalls-based-on-answers\}
Usando cuestionarios en los onboardings, también puedes personalizar los paywalls que muestras a los usuarios después de que completen el onboarding.
Por ejemplo, puedes preguntarles sobre su experiencia con el deporte y mostrar distintos CTAs y productos a diferentes grupos de usuarios.
1. [Añade un cuestionario](onboarding-quizzes) en el editor de onboarding y asigna IDs significativos a sus opciones.
2. Gestiona las respuestas del cuestionario según sus IDs y [establece atributos personalizados](android-setting-user-attributes) para los usuarios.
```kotlin showLineNumbers
override fun onStateUpdatedAction(action: AdaptyOnboardingStateUpdatedAction, context: Context) {
// Handle quiz responses and set custom attributes
when (val params = action.params) {
is AdaptyOnboardingStateUpdatedParams.Select -> {
// Handle quiz selection
val builder = AdaptyProfileParameters.Builder()
// Map quiz responses to custom attributes
when (action.elementId) {
"experience" -> {
// Set custom attribute 'experience' with the selected value (beginner, amateur, pro)
builder.withCustomAttribute("experience", params.params.value)
}
}
Adapty.updateProfile(builder.build()) { error ->
if (error != null) {
// handle the error
}
}
}
}
}
```
3. [Crea segmentos](segments) para cada valor de atributo personalizado.
4. Crea un [placement](placements) y añade [audiencias](audience) para cada segmento que hayas creado.
5. [Muestra un paywall](android-paywalls) para el placement en el código de tu app. Si tu onboarding tiene un botón que abre un paywall, implementa el código del paywall como [respuesta a la acción de ese botón](android-handle-onboarding-events#opening-a-paywall).
---
# File: android-best-practices
---
---
title: "Mejores prácticas en el SDK de Android"
description: "Patrones de referencia para integrar el SDK de Adapty en Android: orden de llamadas, manejo de errores y otras reglas para entornos de producción."
---
---
# File: android-sdk-call-order
---
---
title: "Orden de llamadas en el SDK de Android"
description: "Evita perder el acceso premium, que falten datos de atribución y errores intermitentes de ADAPTY_NOT_INITIALIZED llamando a los métodos del SDK de Adapty en el orden correcto."
---
`Adapty.activate()` debe completarse antes de llamar a cualquier otro método del SDK de Adapty. Hasta que finalice, el SDK no tiene estado. Cualquier llamada emitida antes o en paralelo con `activate()` falla con [`ADAPTY_NOT_INITIALIZED`](android-sdk-error-handling).
Si tu app autentica usuarios y recoges un ID de usuario personalizado después del lanzamiento, llama a `Adapty.identify()` en ese momento. No llames a métodos de acción de usuario hasta que se ejecute el callback de finalización de `identify`. Las llamadas que compiten con él devuelven un error en su callback, o recaen sobre el perfil anónimo creado en la activación. Cuando esto ocurre, la atribución, los IDs de MMP como `appsflyer_id` y la propiedad de la instalación no siempre se transfieren al perfil identificado. Si tu app no autentica usuarios, omite `identify` y sigue trabajando con el perfil anónimo.
Los SDKs de MMP y analíticas (AppsFlyer, Adjust, Branch, PostHog) siguen la misma regla. Inicialízalos primero y espera sus callbacks de UID antes de llamar a `Adapty.activate`. De lo contrario, el ID del MMP queda en un perfil anónimo temporal y no siempre se transfiere al perfil identificado. Para los detalles específicos de AppsFlyer, consulta [AppsFlyer](appsflyer).
## El orden correcto \{#the-correct-order\}
Tu camino depende de dos cosas: cuándo conoces el ID de usuario personalizado y si usas un SDK de MMP o analíticas.
- **Pasos 2 y 5**: Obligatorios para toda app. Activa el SDK y luego llama a los métodos del SDK.
- **Pasos 1 y 3**: Necesarios solo si integras un SDK de MMP o analíticas (AppsFlyer, Adjust, Branch, PostHog).
- **Paso 4**: Necesario solo si tu app autentica usuarios y recoge el ID de usuario personalizado después del lanzamiento.
Si tienes el ID de usuario personalizado al lanzar la app, pásalo en el `AdaptyConfig.Builder` antes de llamar a `activate()` (paso 2a). Esta ruta nunca crea un perfil anónimo, por lo que el paso 4 no es necesario.
| Paso | Llamada | Cuándo | Notas |
|------|---------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------|
| 1 | Inicializa tu SDK de MMP o analíticas (AppsFlyer, Adjust, PostHog, Branch) | Al arrancar la app, lo primero | Espera el callback de UID del MMP, por ejemplo `getAppsFlyerUID`. |
| 2a | `Adapty.activate(context, AdaptyConfig.Builder("KEY").withCustomerUserId(...).build())` | Al arrancar la app, después del paso 1, si tienes el ID de usuario | Recomendado. No se crea ningún perfil anónimo. |
| 2b | `Adapty.activate(context, AdaptyConfig.Builder("KEY").build())` sin `customerUserId` | Al arrancar la app, después del paso 1, si no tienes el ID de usuario (o nunca lo recoges) | Adapty crea un perfil anónimo. |
| 3 | `Adapty.setIntegrationIdentifier(AdaptyIntegrationIdentifier.appsflyerId(uid)) { error -> ... }` | Después del paso 2, antes de cualquier llamada de acción del usuario | Necesario para que los IDs del MMP se asocien al perfil correcto. Pasa una lista de identificadores para configurar varios MMPs en una sola llamada. |
| 4 | `Adapty.identify("YOUR_USER_ID") { error -> ... }` | Después del paso 3 (o del paso 2 si no hay MMP), antes del paso 5 — solo en el flujo 2b con autenticación | Usa el callback de finalización. Las llamadas concurrentes durante `identify` pueden caer en el perfil anónimo. |
| 5 | `getPaywall`, `getPaywallProducts`, `restorePurchases`, `makePurchase`, `updateExternalAttribution`, `updateProfile` | Después del paso 4 si llamas a `identify`; si no, después del paso 3 (o del paso 2 si no hay MMP) | Estas llamadas necesitan un perfil estable. |
:::important
Saltarse estos pasos provoca pérdida de acceso premium para usuarios que regresan, que falte `appsflyer_id` en los perfiles, y que se devuelvan paywalls para la audiencia equivocada.
:::
## Obtener un placement justo después de `updateProfile` \{#fetching-a-placement-right-after-updateprofile\}
Si llamas a `updateProfile` para establecer atributos personalizados y luego obtienes un placement (`getPaywall`) en la misma sesión, espera a que `updateProfile` termine antes de realizar la obtención. Si se lanzan juntos, el SDK puede calcular el hash del segmento del placement a partir de atributos que aún no han terminado de propagarse, lo que añade un reintento antes de que la obtención se resuelva. Consulta [Gestionar errores en el SDK de Android](android-sdk-error-handling) si el propio reintento falla.
## Instalaciones web2app y de embudo web \{#web2app-and-web-funnel-installs\}
Si los usuarios compran en un checkout web (Stripe, Paddle) y luego instalan la app nativa, el primer `activate()` del dispositivo crea un nuevo perfil anónimo. Este perfil no está vinculado al perfil web. Si puedes resolver el ID de usuario personalizado antes del lanzamiento de la app (desde tu flujo de autenticación o el referrer de instalación), pásalo directamente en el `AdaptyConfig.Builder`. De lo contrario, la compra web será invisible en el dispositivo hasta que llames a `identify("YOUR_USER_ID")` y luego a `restorePurchases`.
Para los metadatos que enviar con cada checkout web, consulta:
- [Stripe](stripe)
- [Paddle](paddle)
---
# File: android-optimize-paywall-fetching
---
---
title: "Optimiza la carga de flows y paywalls en el SDK de Android"
description: "Carga flows y paywalls de Adapty de forma fiable: timing, caché y patrones de respaldo para Android."
---
Una carga fiable de un flow o paywall en Android hace tres cosas: renderiza rápido, devuelve la variación orientada a la audiencia y recurre al respaldo de forma elegante cuando la red es lenta. Las reglas que se describen a continuación cubren los patrones de timing, caché y respaldo para conseguirlo.
:::tip
Las reglas asumen que `Adapty.activate()` y `Adapty.identify()` ya se han resuelto. Consulta [Orden de llamadas en el SDK de Android](android-sdk-call-order).
:::
## Reglas y errores comunes \{#rules-and-pitfalls\}
| Haz esto | No hagas esto | Por qué |
|---|---|---|
| Obtén el placement que vas a mostrar, o precalienta la caché con [`preloadFlows`](#preload-placements) (SDK 4.1+). | Lanza tus propias llamadas concurrentes a `getFlow` al iniciar. | Un burst de prefetch manual bloquea el hilo principal y produce una pantalla en negro. `preloadFlows` está diseñado para esto y ejecuta el lote de forma concurrente. |
| Llama a `getFlow` después de que la atribución haya tenido tiempo de resolverse — por ejemplo, 1–2 segundos después de `activate` o tras el disparo de `setOnProfileUpdatedListener`. | Llama a `getFlow` en `Application.onCreate()`. | La atribución aún no ha llegado. El flow se resuelve contra la audiencia por defecto y omite silenciosamente los segmentos y la personalización de ASA. |
| Configura un `loadTimeout` y un [paywall de respaldo](fallback-paywalls) para cada placement. | Esperes a `getFlow` indefinidamente. | Sin un timeout, los usuarios con mala conectividad ven una pantalla en blanco hasta que la red responde — o cierran la app. |
Consulta [Obtener paywalls y productos personalizados](fetch-paywalls-and-products-android) para la referencia de los parámetros `fetchPolicy` y `loadTimeout`, y [Placements](placements) para elegir el placement adecuado.
## Precargar placements \{#preload-placements\}
:::info
`preloadFlows` y `preloadFlowsForDefaultAudience` están disponibles a partir de la versión 4.1 del SDK.
:::
`preloadFlows` almacena en caché el JSON del flow con antelación — una solicitud por placement. Luego se usa de forma habitual: `getFlow` para el flow y `getFlowConfiguration` para su configuración de vista.
`fetchPolicy` decide qué capa lee primero un `getFlow` posterior, no si puede acceder a la caché en absoluto:
- `ReturnCacheDataElseLoad` lee primero la copia precargada y solo va a la red si no hay nada en caché. `ReturnCacheDataIfNotExpiredElseLoad(maxAgeMillis)` hace lo mismo mientras la copia sea más reciente que `maxAgeMillis`.
- El valor predeterminado, `ReloadRevalidatingCacheData`, va primero a la red y usa la copia precargada como respaldo cuando la petición falla o se agota el tiempo de espera.
Una precarga resulta útil en ambos casos, pero de forma distinta: una política de caché primero elimina la petición, mientras que el valor predeterminado la mantiene y obtiene una copia en caliente como respaldo.
Úsalo cuando sepas qué placements necesitará la sesión pero no quieras mostrarlos todavía — por ejemplo, justo después de que se resuelvan `activate` e `identify`, para el flow detrás de un botón que el usuario aún no ha pulsado.
```kotlin showLineNumbers
...
Adapty.preloadFlows(listOf("onboarding", "main_paywall"), loadTimeout = 5.seconds) { error ->
if (error != null) {
// at least one placement failed to preload
}
}
// Later, when the user reaches the paywall:
Adapty.getFlow(
"main_paywall",
fetchPolicy = AdaptyPlacementFetchPolicy.ReturnCacheDataElseLoad,
) { result ->
// ...
}
```
```java showLineNumbers
...
Adapty.preloadFlows(Arrays.asList("onboarding", "main_paywall"), TimeInterval.seconds(5), error -> {
if (error != null) {
// at least one placement failed to preload
}
});
// Later, when the user reaches the paywall:
Adapty.getFlow("main_paywall", AdaptyPlacementFetchPolicy.ReturnCacheDataElseLoad, result -> {
// ...
});
```
**Parámetros:**
- `placementIds` (obligatorio): los placements a precargar. Los IDs en blanco o duplicados se ignoran.
- `loadTimeout` (opcional): tiempo de espera aplicado a cada placement individualmente, no al lote completo. Por defecto es 5 segundos; los valores inferiores a 1 segundo se elevan a 1 segundo.
**Aspectos importantes del comportamiento:**
- La llamada de retorno se activa solo después de que se hayan intentado todos los placements, e informa los fallos por placement juntos. Un fallo en un placement no detiene los demás.
- Si un placement supera el tiempo de espera, encuentra un error de servidor o falla por un error de red, el SDK recurre a las variaciones de respaldo para ese placement. Los demás fallos se informan tal cual.
- La precarga solo calienta la caché. No devuelve contenido: igualmente debes llamar a `getFlow` para mostrarlo.
### Qué cubre una precarga \{#what-a-preload-covers\}
Un flow llega a la pantalla en capas. Una precarga cubre la primera, exactamente igual que `getFlow`:
| Capa | Obtenida por | Preparada por una precarga |
|---|---|---|
| JSON del flow — la variación elegida, sus IDs de producto y el Remote Config | `getFlow` | Sí |
| Diseño de interfaz — estructura, estilos y textos de la pantalla | `getFlowConfiguration` | No |
| Imágenes, incluido el fotograma estático que reemplaza a un elemento de vídeo | `getFlowConfiguration`, en segundo plano | No |
| Archivos de vídeo | El reproductor del sistema, al renderizar la pantalla | No almacenado en caché por el SDK |
`getFlowConfiguration` espera el layout, por lo que la primera solicitud de un layout determinado implica un viaje de ida y vuelta a la red, incluso después de una precarga. El SDK guarda ese layout en su propio caché de disco, que sobrevive a los reinicios de la app y se lee antes de cualquier llamada a la red, de modo que el coste recae en la primera solicitud y no en cada una. Una vez que el SDK tiene el layout, comienza a cachear las imágenes de forma independiente a la llamada: no bloquea la pantalla, y no hay ningún callback ni error que informe de cuándo termina.
### Identificar qué placement falló \{#find-out-which-placement-failed\}
El callback recibe un `AdaptyPreloadPlacementsError` que cubre todo el lote, con el código `REQUEST_FAILED` (2005). Para ver los fallos individuales, lee su propiedad `preloadErrors` — un mapa con clave por ID de placement:
```kotlin showLineNumbers
Adapty.preloadFlows(listOf("onboarding", "main_paywall")) { error ->
if (error is AdaptyPreloadPlacementsError) {
error.preloadErrors.forEach { (placementId, placementError) ->
// log or retry the individual placement
}
}
}
```
`preloadErrors` existe solo en `AdaptyPreloadPlacementsError`, así que confirma el tipo primero: cualquier otro `AdaptyError` proviene de algo distinto a un fallo por placement.
### Omitir la segmentación de audiencias \{#skip-audience-segmentation\}
Para calentar la caché sin esperar a la segmentación de audiencias, usa la variante de audiencia predeterminada. No recibe `loadTimeout`:
```kotlin showLineNumbers
Adapty.preloadFlowsForDefaultAudience(listOf("main_paywall")) { error -> }
```
## Mostrar el contenido multimedia de la primera pantalla desde el bundle de la app \{#show-first-screen-media-from-the-app-bundle\}
Un flow descarga sus imágenes y vídeos desde Adapty. Para mostrar el contenido multimedia de la primera pantalla de forma instantánea, sírvelo desde el bundle de la app. Es una buena forma de reutilizar recursos que ya incluyes en la app, como los visuales de un onboarding nativo existente.
1. En el Flow & Paywall Builder, asigna un [ID de medio personalizado](custom-media#custom-media-id) a la imagen o el vídeo. El archivo que subas allí será el de respaldo.
2. Añade el archivo a la carpeta `res/raw` o `assets` de tu app.
3. Cuando crees la vista del flow con `getFlowView`, pasa el archivo incluido en el bundle para ese ID en `customAssets`:
```kotlin showLineNumbers
// "welcome_video" is the custom media ID set in the Flow & Paywall Builder
val bundledAssets = AdaptyCustomAssets.of(
"welcome_video" to
AdaptyCustomVideoAsset.file(
FileLocation.fromResId(requireContext(), R.raw.welcome),
preview = AdaptyCustomImageAsset.file(
FileLocation.fromResId(requireContext(), R.drawable.welcome_poster),
),
resolution = AdaptyCustomVideoAsset.Resolution(width = 1080, height = 1920),
),
)
val flowView = AdaptyUI.getFlowView(
activity,
flowConfiguration,
products,
eventListener,
insets,
bundledAssets,
)
```
Los archivos incluidos en el paquete aumentan el tamaño de descarga de tu app, así que incluye solo los archivos multimedia que el usuario ve primero.
Los archivos multimedia que no incluyas en el paquete seguirán apareciendo de inmediato: la configuración de la vista lleva una copia de baja resolución de cada imagen, incluido el fotograma estático de los vídeos, y la muestra hasta que se cargue el archivo completo.
Para la referencia completa de `customAssets`, consulta [Personalizar recursos](android-get-pb-paywalls#customize-assets).
## Ajusta para conectividad deficiente \{#tune-for-poor-connectivity\}
Para mercados con conectividad consistentemente deficiente (zonas rurales, transporte público, regiones con problemas de enrutamiento):
- Establece `fetchPolicy` en `AdaptyPlacementFetchPolicy.ReturnCacheDataElseLoad` en cada solicitud excepto la primera.
- Configura un [paywall de respaldo](fallback-paywalls) para cada placement en el Adapty Dashboard.
- Establece `loadTimeout` entre 3 y 5 segundos y acepta el respaldo cuando se agote el tiempo.
- No condicionales la visualización del flow a `getProfile`. Llama a `getFlow` de forma independiente para que un perfil lento no bloquee la interfaz.
---
# File: android-test
---
---
title: "Prueba y lanzamiento en Android SDK"
description: "Aprende a verificar el estado de suscripción en tu app Android con Adapty."
---
Si ya has implementado el SDK de Adapty en tu app Android, querrás comprobar que todo está configurado correctamente y que las compras funcionan como se espera. Esto implica probar tanto la integración del SDK como el flujo de compra real con el entorno sandbox de Google Play.
## Prueba tu app \{#test-your-app\}
Para realizar pruebas exhaustivas de tus compras in-app, incluyendo pruebas en sandbox y validación en closed track, consulta nuestra [guía de pruebas](testing-on-android).
## Prepárate para el lanzamiento \{#prepare-for-release\}
Antes de enviar tu app al store, sigue la [Lista de verificación para el lanzamiento](release-checklist) para confirmar que:
- La conexión al store y las notificaciones del servidor están configuradas
- Las compras se completan y se reportan a Adapty
- El acceso se desbloquea y se restaura correctamente
- Se cumplen los requisitos de privacidad y revisión
---
# File: android-reference
---
---
title: "Referencia del SDK de Android"
description: "Documentación de referencia para el SDK de Android de Adapty."
---
Esta página contiene documentación de referencia para el SDK de Android de Adapty. Elige el tema que necesites:
- **[Modelos del SDK](https://android.adapty.io)** - Modelos de datos y estructuras usados por el SDK
- **[Gestión de errores](android-sdk-error-handling)** - Gestión de errores y resolución de problemas
---
# File: android-sdk-error-handling
---
---
title: "Gestionar errores en el SDK de Android"
description: "Gestiona los errores del SDK de Android de forma eficaz con la guía de solución de problemas de Adapty."
---
Cada error devuelto por el SDK es de tipo `AdaptyError`.
:::tip
**Activa los logs detallados antes de depurar.** La mayoría de los `AdaptyError` envuelven un error subyacente de Play Billing, de red o del backend. Con los logs detallados activados (`Adapty.logLevel = AdaptyLogLevel.VERBOSE` — consulta [Logging](sdk-installation-android#logging)), ese error envuelto se imprime en la consola, lo que normalmente te indica la causa real.
:::
:::important
Si estas soluciones no resuelven tu problema, consulta [Otros problemas](#other-issues) para ver los pasos que debes seguir antes de contactar con el soporte y así ayudarnos a asistirte de forma más eficiente.
:::
| Error | Solución |
|----------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| UNKNOWN | Este error indica que ocurrió un error desconocido o inesperado. |
| [ITEM_UNAVAILABLE](https://developer.android.com/reference/com/android/billingclient/api/BillingClient.BillingResponseCode#ITEM_UNAVAILABLE()) | Este error ocurre principalmente durante la fase de pruebas. Puede significar que los productos no están en producción o que el usuario no pertenece al grupo de Testers en Google Play. |
| ADAPTY_NOT_INITIALIZED | El SDK de Adapty no está activado.
Se produce habitualmente cuando una splash screen o un hook de UI temprano llama a métodos de Adapty antes de que `Adapty.activate` haya terminado. El síntoma es intermitente y puede no reproducirse en un emulador porque el timing en dispositivos reales es diferente. Espera a que `Adapty.activate` complete antes de programar cualquier otra llamada al SDK. Consulta [Orden de llamadas en el SDK de Android](android-sdk-call-order) para ver la secuencia completa. También debes [configurar el SDK de Adapty](sdk-installation-android#activate-adapty-module-of-adapty-sdk) correctamente usando el método `Adapty.activate`. |
| PROFILE_WAS_CHANGED | El perfil de usuario cambió durante la operación.
Esto ocurre cuando se llama a un método mientras `Adapty.identify` todavía está en curso: la llamada en vuelo aterriza en un perfil que está a punto de ser reemplazado y el SDK la rechaza. Espera a que `Adapty.identify` complete antes de programar otras llamadas al SDK. Consulta [Orden de llamadas en el SDK de Android](android-sdk-call-order). |
| PRODUCT_NOT_FOUND | Este error indica que el producto solicitado para la compra no está disponible en el store. |
| CURRENT_SUBSCRIPTION_TO_UPDATE
\_NOT_FOUND_IN_HISTORY
| La suscripción original que debe reemplazarse no se encuentra entre las suscripciones activas. |
| [BILLING_SERVICE_TIMEOUT](https://developer.android.com/google/play/billing/errors#service_timeout_error_code_-3) | Este error indica que la solicitud alcanzó el tiempo máximo de espera antes de que Google Play pudiera responder. Esto puede deberse, por ejemplo, a un retraso en la ejecución de la acción solicitada por la llamada a la Play Billing Library. |
| [FEATURE_NOT_SUPPORTED](https://developer.android.com/reference/com/android/billingclient/api/BillingClient.BillingResponseCode#FEATURE_NOT_SUPPORTED()) | La función solicitada no es compatible con el Play Store en el dispositivo actual. |
| [BILLING_SERVICE_DISCONNECTED](https://developer.android.com/google/play/billing/errors#service_disconnected_error_code_-1) | Este error indica que la conexión de la app cliente al servicio de Google Play Store mediante `BillingClient` se ha interrumpido. |
| [BILLING_SERVICE_UNAVAILABLE](https://developer.android.com/google/play/billing/errors#service_unavailable_error_code_2) | Este error indica que el servicio de facturación de Google Play no está disponible en este momento. En la mayoría de los casos, significa que hay un problema de conexión de red en algún punto entre el dispositivo cliente y los servicios de facturación de Google Play. |
| [BILLING_UNAVAILABLE](https://developer.android.com/google/play/billing/errors#billing_unavailable_error_code_3) | Este error indica que ocurrió un problema de facturación durante el proceso de compra. Las posibles causas son:
1. La app de Play Store en el dispositivo del usuario falta o está desactualizada.
2. El usuario se encuentra en un país no compatible.
3. El usuario forma parte de una cuenta empresarial donde el administrador ha desactivado las compras.
4. Google Play no pudo cobrar el método de pago del usuario (por ejemplo, una tarjeta de crédito caducada).
5. El usuario no ha iniciado sesión en la app de Play Store.
|
| [DEVELOPER_ERROR](https://developer.android.com/google/play/billing/errors#developer_error) | Este error indica que estás usando una API de forma incorrecta. |
| [BILLING_ERROR](https://developer.android.com/google/play/billing/errors#error_error_code_6) | Este error indica un problema interno con el propio Google Play. |
| [ITEM_ALREADY_OWNED](https://developer.android.com/reference/com/android/billingclient/api/BillingClient.BillingResponseCode#ITEM_ALREADY_OWNED()) | El producto ya ha sido comprado. |
| [ITEM_NOT_OWNED](https://developer.android.com/reference/com/android/billingclient/api/BillingClient.BillingResponseCode#ITEM_NOT_OWNED()) | Este error indica que la acción solicitada sobre el artículo falló porque el usuario no es su propietario. |
| [BILLING_NETWORK_ERROR](https://developer.android.com/google/play/billing/errors#network_error_error_code_12) | Este error indica que hubo un problema con la conexión de red entre el dispositivo y los sistemas de Play. |
| NO_PRODUCT_IDS_FOUND | Este error indica que ninguno de los productos del paywall está disponible en el store.
Si encuentras este error, sigue los pasos a continuación para resolverlo:
- Comprueba que todos los productos se han añadido al Adapty Dashboard.
- Asegúrate de que el **Package name** de tu app coincide con el del Google Play Console.
- Verifica que los identificadores de producto de los stores coinciden con los que has añadido al Dashboard. Ten en cuenta que los identificadores no deben incluir el Bundle ID, a menos que ya esté incluido en el store.
- Confirma que el estado de pago de la app es **Active** en tu configuración fiscal de Google. Asegúrate de que tu información fiscal esté actualizada y que tus certificados sean válidos.
- Comprueba que hay una cuenta bancaria vinculada a la app para que pueda ser apta para monetización.
- Verifica si los productos están disponibles en tu región.
- Asegúrate de que tu app está en alguno de los tracks de prueba. El track **Internal testing** es la opción más sencilla, ya que no requiere revisión y mantiene la app oculta para los usuarios.
|
| NO_PURCHASES_TO_RESTORE | Obsoleto en Adapty Android SDK 3.17.3 y 4.0.2: `restorePurchases()` ya no devuelve este error. Cuando no hay nada que restaurar, el método finaliza correctamente con el perfil actual, por lo que debes comprobar el estado del nivel de acceso en él. En versiones anteriores del SDK, este error indica que Google Play no encontró la compra a restaurar. |
| AUTHENTICATION_ERROR | Debes [configurar el SDK de Adapty](sdk-installation-android#activate-adapty-module-of-adapty-sdk) correctamente mediante el método `Adapty.activate`. |
| BAD_REQUEST | Solicitud incorrecta.
Asegúrate de haber completado todos los pasos necesarios para [integrarte con Google Play](google-play-store-connection-configuration). |
| SERVER_ERROR | Error del servidor. |
| REQUEST_FAILED | Este error indica un problema de red que no se puede definir con precisión. |
| DECODING_FAILED | No se pudo decodificar la respuesta.
Revisa tu código y asegúrate de que los parámetros que envías son válidos. Por ejemplo, este error puede indicar que estás usando una clave de API no válida. |
| ANALYTICS_DISABLED | No podemos gestionar los eventos de analítica porque has [desactivado esta opción](analytics-integration#disabling-external-analytics-for-a-specific-customer). |
| WRONG_PARAMETER | Este error indica que alguno de tus parámetros no es correcto: está en blanco cuando no puede estarlo, es del tipo incorrecto, etc.
El SDK también devuelve este error cuando no puede leer un archivo de [respaldo](fallback-paywalls) local, generalmente porque la versión del archivo no coincide con la versión del SDK. Descarga un archivo nuevo desde el dashboard.
|
| LOGGING_OUT_UNIDENTIFIED_USER | Se llamó a `Adapty.logout()` para un usuario que nunca fue identificado. Llámalo solo después de [`Adapty.identify`](android-identifying-users). |
## Fetches lentas justo después de `updateProfile` \{#slow-fetches-right-after-updateprofile\}
Si estableces atributos personalizados con `updateProfile` y obtienes un placement en la misma sesión, el SDK puede calcular el hash de segmento del placement a partir de atributos que aún no han terminado de propagarse. Reintenta una vez que el hash de segmento se actualiza, por lo que el síntoma es una obtención más lenta en lugar de un error. La obtención falla solo cuando el reintento sigue sin coincidir, lo que significa que la escritura del atributo no se ha completado.
Para evitar el reintento, usa `await` en `updateProfile` antes de obtener el placement. Consulta [Orden de llamadas en el SDK de Android](android-sdk-call-order).
## Errores de renderizado del flow \{#flow-rendering-errors\}
El SDK de Adapty 4.0 y versiones posteriores notifica estos errores a través de `onError` en tu `AdaptyFlowEventListener`, en lugar de devolverlos desde una llamada a un método. Consulta [Gestionar eventos en el SDK de Android](android-handling-events).
| Error | Solución |
|-------|----------|
| WRONG_ASSET_TYPE | Un elemento de imagen en el flow apunta a un recurso que es un relleno de color o degradado, por lo que el SDK muestra un marcador de posición en su lugar. Asigna un recurso de imagen a ese elemento en el [Flow & Paywall Builder](adapty-flow-builder). |
| JS_EXCEPTION | El JavaScript del flow ha lanzado una excepción. Lee el texto de la excepción en el mensaje de error. |
| NAVIGATOR_NOT_FOUND | Una acción de apertura de pantalla hace referencia a un navegador que no existe en la configuración de vistas del flow, y el flow no tiene ningún navegador `default` al que recurrir. Revisa el destino de la acción en el [Flow & Paywall Builder](adapty-flow-builder). |
| INVALID_ACTION_URL | Una acción de apertura de URL hace referencia a un ID de cadena que no se resuelve en una URL válida. Define una URL válida para esa acción en el [Flow & Paywall Builder](adapty-flow-builder). |
## Otros problemas \{#other-issues\}
Si todavía no has encontrado una solución, los siguientes pasos pueden ser:
- **Actualizar el SDK a la última versión**: Siempre recomendamos actualizar a las últimas versiones del SDK, ya que son más estables e incluyen correcciones de problemas conocidos.
- **Contactar al equipo de soporte u obtener ayuda de otros desarrolladores** en el [foro de soporte](https://adapty.featurebase.app/).
- **Contactar al equipo de soporte a través de [support@adapty.io](mailto:support@adapty.io) o por el chat**: Si no puedes actualizar el SDK o la actualización no resolvió el problema, contacta a nuestro equipo de soporte. Ten en cuenta que tu problema se resolverá más rápido si [activas el registro detallado](sdk-installation-android#logging) y compartes los logs con el equipo. También puedes adjuntar fragmentos de código relevantes.
---
# File: android-sdk-migration-guides
---
---
title: "Guías de migración del SDK de Android"
description: "Guías de migración para las versiones del SDK de Android de Adapty."
---
Esta página contiene todas las guías de migración para el SDK de Android de Adapty. Elige la versión a la que quieres migrar para ver las instrucciones detalladas:
- **[Migrar a v4.1](migration-to-android-sdk-41)**
- **[Migrar a v4.0](migration-to-android-sdk-v4)**
- **[Migrar a v3.12](migration-to-android-312)**
- **[Migrar a v3.10](migration-to-android-310)**
- **[Migrar a v3.4](migration-to-android-sdk-34)**
- **[Migrar a v3.3](migration-to-android330)**
- **[Migrar a v3.0](migration-to-android-sdk-v3)**
---
# File: migration-to-android-sdk-41
---
---
title: "Migrar el SDK de Adapty para Android a v4.1"
description: "Migra al SDK de Adapty para Android v4.1: activa Adapty Attribution de forma explícita y adopta las APIs de atribución externa renombradas."
---
El SDK de Adapty para Android 4.1 cambia la forma en que se activa Adapty Attribution y renombra las APIs de atribución externa.
:::warning
Las APIs renombradas son un cambio radical. `AdaptyAttributionSource` se elimina por completo — no está deprecada ni existe un typealias para hacer de puente. El código que compila contra 4.0.x no compilará en 4.1 hasta que renombres todos los puntos de llamada indicados a continuación.
:::
## Referencia rápida \{#quick-reference\}
| v4.0 | v4.1 |
|---|---|
| Adapty Attribution habilitada automáticamente | Adapty Attribution deshabilitada por defecto; actívala con `.withAdaptyAttributionEnabled(true)` |
| `Adapty.updateAttribution(attribution, source)` | `Adapty.updateExternalAttribution(attribution, provider)` |
| `AdaptyAttributionSource` | `AdaptyExternalAttributionProvider`, con un nuevo valor `CUSTOM` |
| `AdaptyProfile.appliedAttributionSources` | `AdaptyProfile.appliedExternalAttributionProviders` |
| Archivo de respaldo descargado para 4.0 | Nuevo formato de archivo de respaldo; descarga el archivo de nuevo |
## Instalación \{#installation\}
Establece la versión de `adapty-bom` en `4.1.0` (o posterior) y sincroniza el proyecto. El BOM resuelve automáticamente las versiones correspondientes de `android-sdk` y `android-ui`. Consulta [Instalar el SDK de Adapty](sdk-installation-android) para ver las declaraciones de dependencias.
:::note
Si actualizas desde 4.0.0 o 4.0.1, también se aplican dos cambios de la versión 4.0.2:
- Adapty trabaja con Google Play Billing Library 8 por defecto, en lugar de 7.0.0.
- `restorePurchases` se completa correctamente cuando no hay nada que restaurar y devuelve el perfil actual, en lugar de fallar con `NO_PURCHASES_TO_RESTORE`. Consulta [Restaurar compras](android-restore-purchase).
:::
## La atribución de Adapty está desactivada por defecto \{#adapty-attribution-is-disabled-by-default\}
En la versión 4.0 y anteriores, el SDK registraba las instalaciones para [Atribución de Adapty](user-acquisition) de forma automática. A partir de la versión 4.1, esto está desactivado por defecto: el SDK no registra instalaciones, el listener configurado con `setOnInstallationDetailsListener` no se dispara nunca, y `getCurrentInstallationStatus` devuelve `AdaptyInstallationStatus.Determined.NotAvailable`.
Si utilizas la atribución de Adapty, actívala al inicializar el SDK:
```diff showLineNumbers
val config = AdaptyConfig.Builder("PUBLIC_SDK_KEY")
+ .withAdaptyAttributionEnabled(true)
.build()
Adapty.activate(applicationContext, config)
```
Si no usas Adapty Attribution, no es necesario hacer ningún cambio.
## APIs de atribución externa renombradas \{#renamed-external-attribution-apis\}
### updateAttribution → updateExternalAttribution
El método que pasa datos de atribución de un proveedor externo (Adjust, AppsFlyer, Branch, Tenjin o uno personalizado) cambia de nombre, y su parámetro `source` pasa a llamarse `provider`:
```diff showLineNumbers
- Adapty.updateAttribution(attribution, AdaptyAttributionSource.ADJUST) { error -> /* handle the error */ }
+ Adapty.updateExternalAttribution(attribution, AdaptyExternalAttributionProvider.ADJUST) { error -> /* handle the error */ }
```
Se conservan ambas sobrecargas: `attribution` puede ser un `Map` o un `String` JSON.
El callback se activa una vez que el backend acepta los datos para su procesamiento asíncrono. Un resultado exitoso no significa que los datos ya se hayan aplicado al perfil.
### AdaptyAttributionSource → AdaptyExternalAttributionProvider
El tipo ha sido renombrado, y los valores predefinidos conservan sus nombres: `APPLE_ADS`, `ADJUST`, `APPSFLYER`, `BRANCH` y `TENJIN`. Para cualquier otro proveedor, constrúyelo a partir de una cadena: `AdaptyExternalAttributionProvider("your_provider")`.
La versión 4.1 también añade un valor predefinido `CUSTOM` para proveedores con los que Adapty no se integra directamente. En la 4.0, ese mismo valor solo estaba disponible como la cadena `"custom"`.
### AdaptyProfile.appliedAttributionSources → appliedExternalAttributionProviders
La propiedad del perfil que lista los proveedores de atribución aplicados al perfil cambia de nombre. El tipo de sus elementos cambia en consecuencia:
```diff showLineNumbers
- if (profile.appliedAttributionSources.contains(AdaptyAttributionSource.APPLE_ADS)) {
+ if (profile.appliedExternalAttributionProviders.contains(AdaptyExternalAttributionProvider.APPLE_ADS)) {
// Apple Ads attribution has been applied
}
```
## Archivos de respaldo \{#fallback-files\}
El formato del [archivo de respaldo](fallback-flows) cambió en la versión 4.1 del SDK. Descarga el archivo de nuevo desde **[Placements](https://app.adapty.io/placements)** > **Fallbacks** e inclúyelo en tu app, aunque ya hayas descargado uno para la versión 4.0.
:::warning
Este paso no genera ningún error de compilación. Si lo omites, se lanzará `WRONG_PARAMETER` en cada llamada de placement que necesite un respaldo — consulta [Gestión de errores en el SDK de Android](android-sdk-error-handling).
:::
---
# File: migration-to-android-sdk-v4
---
---
title: "Migrar Adapty Android SDK a v4.0"
description: "Migra al Adapty Android SDK v4.0 reemplazando las APIs de paywall con APIs de flow, que renderizan flows además de los paywalls del antiguo builder."
---
Adapty Android SDK 4.0 introduce flows y renombra las APIs de paywall en consecuencia. Las nuevas APIs funcionan con flows y siguen siendo compatibles con los paywalls del antiguo builder — no se requieren cambios de configuración en el Adapty Dashboard.
## Referencia rápida \{#quick-reference\}
| v3 | v4 |
|---|---|
| `Adapty.getPaywall(placementId, locale)` | `Adapty.getFlow(placementId)` |
| `Adapty.getPaywallForDefaultAudience(placementId, locale)` | `Adapty.getFlowForDefaultAudience(placementId)` |
| `AdaptyUI.getViewConfiguration(paywall)` | `AdaptyUI.getFlowConfiguration(flow, locale)` |
| `AdaptyUI.LocalizedViewConfiguration` | `AdaptyUI.FlowConfiguration` |
| `Adapty.getPaywallProducts(paywall)` | `Adapty.getPaywallProducts(flow)` |
| `Adapty.logShowPaywall(paywall)` | `Adapty.logShowFlow(flow)` |
| `AdaptyPaywall` | `AdaptyFlow` |
| `AdaptyUI.getPaywallView(...)` | `AdaptyUI.getFlowView(...)` |
| `AdaptyPaywallView` | `AdaptyFlowView` |
| `AdaptyPaywallScreen` (Compose) | `AdaptyFlowScreen` |
| `showPaywall(...)` | `showFlow(...)` |
| `AdaptyPaywallInsets` | `AdaptyFlowInsets` |
| `AdaptyUiEventListener` | `AdaptyFlowEventListener` |
| `AdaptyUiDefaultEventListener` | `AdaptyFlowDefaultEventListener` |
| `onPaywallShown` / `onPaywallClosed` | `onFlowShown` / `onFlowClosed` |
| `onRenderingError` | `onError` |
| `Adapty.updateAttribution(attribution, source)` (`source: String`) | `Adapty.updateAttribution(attribution, source)` (`source: AdaptyAttributionSource`) |
| `Adapty.setIntegrationIdentifier(key, value)` | `Adapty.setIntegrationIdentifier(AdaptyIntegrationIdentifier)` |
`AdaptyPaywallProduct` mantiene su nombre — los productos siguen perteneciendo a un flow, y `getPaywallProducts` ahora recibe un `AdaptyFlow`. Los demás métodos de `AdaptyFlowEventListener` (`onProductSelected`, `onPurchaseStarted`, `onPurchaseFinished`, `onPurchaseFailure`, `onRestoreSuccess`, `onRestoreFailure`, `onActionPerformed`, `onAwaitingPurchaseParams`, `onLoadingProductsFailure`, etc.) mantienen sus nombres y firmas.
## Instalación \{#installation\}
Establece la versión de `adapty-bom` en `4.0.1` (o posterior) y sincroniza el proyecto. El BOM resuelve automáticamente las versiones correspondientes de `android-sdk` y `android-ui`. Consulta [Instalar el SDK de Adapty](sdk-installation-android) para ver las declaraciones de dependencias.
## APIs eliminadas y en desuso \{#removed-and-deprecated-apis\}
- **`Adapty.makePurchase(activity, product, subscriptionUpdateParams, isOfferPersonalized, callback)`** — eliminada. Esta sobrecarga fue marcada como obsoleta en la v3. Pasa las mismas opciones a través de `AdaptyPurchaseParameters` en su lugar:
```diff showLineNumbers
- Adapty.makePurchase(activity, product, subscriptionUpdateParams, isOfferPersonalized) { result -> /* ... */ }
+ val params = AdaptyPurchaseParameters.Builder()
+ .withSubscriptionUpdateParams(subscriptionUpdateParams)
+ .withOfferPersonalized(isOfferPersonalized)
+ .build()
+ Adapty.makePurchase(activity, product, params) { result -> /* ... */ }
```
- **Los onboardings están obsoletos.** `AdaptyUI.getOnboardingView` y `AdaptyUI.getOnboardingConfiguration` están marcados como `@Deprecated` en la versión 4.0 — migra los onboardings a flows creados en el [Flow & Paywall Builder](adapty-flow-builder).
## Obtener flows \{#fetching-flows\}
### getPaywall + getViewConfiguration → getFlow + getFlowConfiguration
El tipo de retorno del fetch cambia de `AdaptyPaywall` a `AdaptyFlow`, y el cargador de configuración pasa de llamarse `AdaptyUI.getViewConfiguration` a `AdaptyUI.getFlowConfiguration` (devolviendo `AdaptyUI.FlowConfiguration` en lugar de `AdaptyUI.LocalizedViewConfiguration`). El parámetro `locale` sale de la llamada al fetch y pasa a `getFlowConfiguration`: `AdaptyFlow` también expone `paywalls` — las variaciones de paywall del flow, como valores `AdaptyFlowPaywall`. Los métodos de paywall web reciben uno de estos valores.
```diff showLineNumbers
- Adapty.getPaywall("YOUR_PLACEMENT_ID", locale = "en") { result ->
+ Adapty.getFlow("YOUR_PLACEMENT_ID") { result ->
if (result is AdaptyResult.Success) {
- val paywall = result.value
- if (!paywall.hasViewConfiguration) return@getPaywall
- AdaptyUI.getViewConfiguration(paywall) { configResult ->
+ val flow = result.value
+ if (!flow.hasViewConfiguration) return@getFlow
+ AdaptyUI.getFlowConfiguration(flow, locale = "en") { configResult ->
if (configResult is AdaptyResult.Success) {
val flowConfiguration = configResult.value
}
}
}
}
```
`locale` es opcional en `getFlowConfiguration`: si lo omites, la vista se renderiza en `en`, o en la localización predeterminada del flow cuando este no tiene `en`. Consulta [Localizaciones y códigos de idioma](android-localizations-and-locale-codes).
### getPaywallProducts(paywall) → getPaywallProducts(flow)
`getPaywallProducts` ahora recibe un `AdaptyFlow` devuelto por `Adapty.getFlow`:
```diff showLineNumbers
- Adapty.getPaywallProducts(paywall) { result -> /* products */ }
+ Adapty.getPaywallProducts(flow) { result -> /* products */ }
```
### Archivos de respaldo \{#fallback-files\}
El formato del archivo de respaldo [cambió en el SDK v4](fallback-flows). Descarga el nuevo archivo desde **[Placements](https://app.adapty.io/placements)** > **Fallbacks** y agrégalo a tu app.
## Seguimiento de vistas de flows \{#tracking-flow-views\}
### logShowPaywall → logShowFlow
`logShowPaywall` pasa a llamarse `logShowFlow` y ahora recibe un `AdaptyFlow` en lugar de un `AdaptyPaywall`. El evento se sigue registrando en la misma variación, por lo que las métricas de funnel y pruebas A/B existentes seguirán funcionando sin cambios en el dashboard.
```diff showLineNumbers
- Adapty.logShowPaywall(paywall)
+ Adapty.logShowFlow(flow)
```
Al igual que en v3, no es necesario llamar a este método cuando se muestran flows o paywalls renderizados por Adapty — Adapty registra esas vistas automáticamente.
## Mostrar flows \{#displaying-flows\}
### getPaywallView / AdaptyPaywallView → getFlowView / AdaptyFlowView
Renombra el método de fábrica y el tipo de vista, y pasa la `AdaptyUI.FlowConfiguration`:
```diff showLineNumbers
- val paywallView = AdaptyUI.getPaywallView(
- activity,
- viewConfiguration,
- products,
- eventListener,
- )
+ val flowView = AdaptyUI.getFlowView(
+ activity,
+ flowConfiguration,
+ products,
+ eventListener,
+ )
```
Si creas la vista directamente, el método show también cambia de nombre:
```diff showLineNumbers
- val paywallView = AdaptyPaywallView(activity)
- paywallView.showPaywall(viewConfiguration, products, eventListener)
+ val flowView = AdaptyFlowView(activity)
+ flowView.showFlow(flowConfiguration, products, eventListener)
```
En los layouts XML, actualiza el tag de la vista:
```diff showLineNumbers
-
+
```
El parámetro opcional `personalizedOfferResolver` se ha eliminado de `getFlowView` / `showFlow` / `AdaptyFlowScreen`. Para indicar precios personalizados, configúralo por producto a través de `onAwaitingPurchaseParams` (`AdaptyPurchaseParameters.Builder().withOfferPersonalized(true)`). Un nuevo parámetro opcional `customAssets` te permite sobreescribir imágenes y vídeos en tiempo de ejecución — consulta [Personalizar assets](android-get-pb-paywalls#customize-assets).
### AdaptyPaywallScreen → AdaptyFlowScreen
En Jetpack Compose, renombra el composable y actualiza el parámetro de configuración:
```diff showLineNumbers
- AdaptyPaywallScreen(
- viewConfiguration,
+ AdaptyFlowScreen(
+ flowConfiguration,
products,
eventListener,
)
```
## Manejo de eventos \{#handling-events\}
El listener de eventos se renombra de `AdaptyUiEventListener` a `AdaptyFlowEventListener` (y `AdaptyUiDefaultEventListener` a `AdaptyFlowDefaultEventListener`). La mayoría de los nombres de métodos no cambian; los callbacks de ciclo de vida y renderizado se renombran:
```diff showLineNumbers
- class YourListener : AdaptyUiDefaultEventListener() {
+ class YourListener : AdaptyFlowDefaultEventListener() {
- override fun onPaywallShown(context: Context) {}
- override fun onPaywallClosed() {}
+ override fun onFlowShown(context: Context) {}
+ override fun onFlowClosed() {}
- override fun onRenderingError(error: AdaptyError, context: Context) {}
+ override fun onError(error: AdaptyError, context: Context) {}
}
```
Los cuerpos de los handlers existentes no necesitan cambios en el código — solo renombra el tipo y los overrides. `onError` se activa para los mismos errores de renderizado que `onRenderingError`, más otros errores de ejecución no relacionados con compras. Consulta [Gestionar eventos de flow y paywall](android-handling-events) para ver la lista completa de callbacks.
v4 también añade un callback `onBackPressed(context): Boolean`, y su comportamiento predeterminado cambia cómo funciona el botón atrás del sistema. Anteriormente, el botón atrás (o el gesto de retroceso) se propagaba a tu actividad o fragmento, lo que normalmente cerraba el paywall. En v4, la implementación predeterminada consume la pulsación, por lo que **el botón atrás del sistema ya no cierra un flow por sí solo** — igual que en iOS, donde un flow no se puede cerrar con un gesto del sistema. Ofrece a los usuarios una salida explícita (un botón **Close** o una acción `on_device_back`), o sobrescribe `onBackPressed` para que devuelva `false` y restaurar el comportamiento anterior. Consulta [Botón atrás del sistema](android-handling-events#system-back-button) para más detalles.
El manejador de compras predeterminado también deja de cerrar la pantalla. En v3, el `onPurchaseFinished` predeterminado cerraba el paywall tras cualquier compra finalizada que no fuera una cancelación del usuario (una compra exitosa o pendiente). En v4 no hace nada, por lo que **un flow permanece abierto después de una compra hasta que lo cierres manualmente**, lo que coincide con el comportamiento en iOS. Si dependías de ese cierre automático, cierra la pantalla tú mismo una vez que la compra finalice. Consulta [Compra exitosa, cancelada o pendiente](android-handling-events#successful-canceled-or-pending-purchase) para ver un ejemplo.
## Identificadores de atribución e integración \{#attribution-and-integration-identifiers\}
### updateAttribution
El parámetro `source` cambia de `String` al nuevo tipo `AdaptyAttributionSource`, y `attribution` ahora es un `Map` (también hay una sobrecarga con `String` JSON disponible). Usa una de las fuentes predefinidas:
```diff showLineNumbers
- Adapty.updateAttribution(attribution, "appsflyer") { error -> /* handle the error */ }
+ Adapty.updateAttribution(attribution, AdaptyAttributionSource.APPSFLYER) { error -> /* handle the error */ }
```
Fuentes predefinidas: `AdaptyAttributionSource.APPLE_ADS`, `.ADJUST`, `.APPSFLYER`, `.BRANCH`, `.TENJIN`. Para cualquier otra fuente, constrúyela a partir de una cadena: `AdaptyAttributionSource("your_source")`.
:::note
SDK 4.1 renombra este método a `updateExternalAttribution` y el tipo a `AdaptyExternalAttributionProvider`. Los nombres anteriores se eliminan en la versión 4.1 sin haber sido marcados como obsoletos. Si migras directamente a la versión 4.1, consulta [Migrar a v4.1](migration-to-android-sdk-41).
:::
### setIntegrationIdentifier
`setIntegrationIdentifier(key, value)` se reemplaza por un método que acepta uno o más valores `AdaptyIntegrationIdentifier`. Construye cada identificador con un método de conveniencia en lugar de pasar una clave de cadena sin formato:
```diff showLineNumbers
- Adapty.setIntegrationIdentifier("appsflyer_id", appsFlyerId) { error -> /* handle the error */ }
+ Adapty.setIntegrationIdentifier(AdaptyIntegrationIdentifier.appsflyerId(appsFlyerId)) { error -> /* handle the error */ }
```
Puedes establecer varios identificadores en una sola llamada:
```kotlin showLineNumbers
Adapty.setIntegrationIdentifier(
listOf(
AdaptyIntegrationIdentifier.appsflyerId(appsFlyerId),
AdaptyIntegrationIdentifier.adjustDeviceId(adjustDeviceId),
)
) { error -> /* handle the error */ }
```
Reemplaza cada cadena de clave antigua por su método de conveniencia correspondiente:
| Clave v3 | Método `AdaptyIntegrationIdentifier` de v4 |
|---|---|
| `"adjust_device_id"` | `adjustDeviceId(value)` |
| `"airbridge_device_id"` | `airbridgeDeviceId(value)` |
| `"amplitude_user_id"` | `amplitudeUserId(value)` |
| `"amplitude_device_id"` | `amplitudeDeviceId(value)` |
| `"appmetrica_device_id"` | `appmetricaDeviceId(value)` |
| `"appmetrica_profile_id"` | `appmetricaProfileId(value)` |
| `"appsflyer_id"` | `appsflyerId(value)` |
| `"branch_id"` | `branchId(value)` |
| `"facebook_anonymous_id"` | `facebookAnonymousId(value)` |
| `"firebase_app_instance_id"` | `firebaseAppInstanceId(value)` |
| `"mixpanel_user_id"` | `mixpanelUserId(value)` |
| `"one_signal_subscription_id"` | `oneSignalSubscriptionId(value)` |
| `"one_signal_player_id"` | `oneSignalPlayerId(value)` |
| `"posthog_distinct_user_id"` | `posthogDistinctUserId(value)` |
| `"pushwoosh_hwid"` | `pushwooshHWID(value)` |
| `"tenjin_analytics_installation_id"` | `tenjinAnalyticsInstallationId(value)` |
Para una clave que no esté en esta lista, construye el identificador directamente a partir de una `Key` personalizada: `AdaptyIntegrationIdentifier(AdaptyIntegrationIdentifier.Key("custom"), customValue)`.
---
# File: migration-to-android-312
---
---
title: "Migrar el SDK de Adapty para Android a v3.12"
description: "Migra al SDK de Adapty para Android v3.12 para obtener mejor rendimiento y nuevas funciones de monetización."
---
En Adapty SDK 3.12.0, hemos eliminado el método `logShowOnboarding` del SDK.
Si has estado usando este método, no estará disponible cuando actualices el SDK a la versión 3.12 o posterior.
En su lugar, puedes [crear onboardings en el creador de onboardings sin código de Adapty](onboardings). Los análisis de estos onboardings se registran automáticamente y dispones de muchas opciones de personalización.
---
# File: migration-to-android-310
---
---
title: "Guía de migración al SDK de Adapty para Android 3.10.0"
description: ""
---
El SDK de Adapty 3.10.0 es una versión mayor que introduce mejoras que pueden requerir algunos pasos de migración de tu parte:
1. `AdaptyUiPersonalizedOfferResolver` ha sido eliminado. Si lo estás usando, pásalo en el callback `onAwaitingPurchaseParams`.
2. Actualiza la firma del método `onAwaitingSubscriptionUpdateParams` para los paywalls del Paywall Builder.
## Actualizar el callback de parámetros de compra \{#update-purchase-parameters-callback\}
El método `onAwaitingSubscriptionUpdateParams` ha sido renombrado a `onAwaitingPurchaseParams` y ahora usa `AdaptyPurchaseParameters` en lugar de `AdaptySubscriptionUpdateParameters`. Esto te permite especificar parámetros de reemplazo de suscripción (crossgrade) e indicar si el precio es personalizado ([más información](https://developer.android.com/google/play/billing/integrate#personalized-price)), junto con otros parámetros de compra.
```diff showLineNumbers
- override fun onAwaitingSubscriptionUpdateParams(
- product: AdaptyPaywallProduct,
- context: Context,
- onSubscriptionUpdateParamsReceived: SubscriptionUpdateParamsCallback,
- ) {
- onSubscriptionUpdateParamsReceived(AdaptySubscriptionUpdateParameters(...))
- }
+ override fun onAwaitingPurchaseParams(
+ product: AdaptyPaywallProduct,
+ context: Context,
+ onPurchaseParamsReceived: AdaptyUiEventListener.PurchaseParamsCallback,
+ ): AdaptyUiEventListener.PurchaseParamsCallback.IveBeenInvoked {
+ onPurchaseParamsReceived(
+ AdaptyPurchaseParameters.Builder()
+ .withSubscriptionUpdateParams(AdaptySubscriptionUpdateParameters(...))
+ .withOfferPersonalized(true)
+ .build()
+ )
+ return AdaptyUiEventListener.PurchaseParamsCallback.IveBeenInvoked
+ }
```
Si no se necesitan parámetros adicionales, puedes usar simplemente:
```kotlin showLineNumbers
+ override fun onAwaitingPurchaseParams(
product: AdaptyPaywallProduct,
context: Context,
onPurchaseParamsReceived: AdaptyUiEventListener.PurchaseParamsCallback,
): AdaptyUiEventListener.PurchaseParamsCallback.IveBeenInvoked {
onPurchaseParamsReceived(AdaptyPurchaseParameters.Empty)
return AdaptyUiEventListener.PurchaseParamsCallback.IveBeenInvoked
}
```
---
# File: migration-to-android-sdk-34
---
---
title: "Migrar el SDK de Adapty para Android a la versión 3.4"
description: "Migra al SDK de Adapty para Android v3.4 para obtener mejor rendimiento y nuevas funciones de monetización."
---
El SDK de Adapty 3.4.0 es una versión principal que introduce mejoras que requieren pasos de migración por tu parte.
## Actualizar los archivos de paywall de respaldo \{#update-fallback-paywall-files\}
Actualiza los archivos de paywall de respaldo para garantizar la compatibilidad con la nueva versión del SDK:
1. [Descarga los archivos de paywall de respaldo actualizados](fallback-paywalls) desde el Adapty Dashboard.
2. [Reemplaza los paywalls de respaldo existentes en tu app](android-use-fallback-paywalls) con los nuevos archivos.
## Actualizar la implementación del modo Observer \{#update-implementation-of-observer-mode\}
Si usas el modo Observer, asegúrate de actualizar su implementación.
En versiones anteriores, tenías que restaurar las compras para que Adapty reconociera las transacciones realizadas a través de tu propia infraestructura, ya que Adapty no tenía acceso directo a ellas en el modo Observer. Si usabas paywalls, también tenías que asociar manualmente cada transacción con el paywall que la había iniciado.
En la nueva versión, debes reportar explícitamente cada transacción para que Adapty la reconozca. Si usas paywalls, también tienes que pasar el ID de variación para vincular la transacción al paywall utilizado.
:::warning
**¡No omitas el reporte de transacciones!**
Si no llamas a `reportTransaction`, Adapty no reconocerá la transacción, no aparecerá en los análisis y no se enviará a las integraciones.
:::
```diff showLineNumbers
- Adapty.restorePurchases { result ->
- if (result is AdaptyResult.Success) {
- // success
- }
- }
-
- Adapty.setVariationId(transactionId, variationId) { error ->
- if (error == null) {
- // success
- }
- }
+ val transactionInfo = TransactionInfo.fromPurchase(purchase)
+
+ Adapty.reportTransaction(transactionInfo, variationId) { result ->
+ if (result is AdaptyResult.Success) {
+ // success
+ }
+ }
```
```diff showLineNumbers
- Adapty.restorePurchases(result -> {
- if (result instanceof AdaptyResult.Success) {
- // success
- }
- });
-
- Adapty.setVariationId(transactionId, variationId, error -> {
- if (error == null) {
- // success
- }
- });
+ TransactionInfo transactionInfo = TransactionInfo.fromPurchase(purchase);
+
+ Adapty.reportTransaction(transactionInfo, variationId, result -> {
+ if (result instanceof AdaptyResult.Success) {
+ // success
+ }
+ });
```
---
# File: migration-to-android330
---
---
title: "Migrar el SDK de Adapty para Android a v3.3"
description: "Migra al SDK de Adapty para Android v3.3 para mejorar el rendimiento y acceder a nuevas funciones de monetización."
---
Adapty SDK 3.3.0 es una versión principal que incorpora algunas mejoras que, sin embargo, pueden requerir ciertos pasos de migración de tu parte.
1. Actualiza la forma en que gestionas las compras en paywalls no creadas con Paywall Builder. Deja de procesar los códigos de error `USER_CANCELED` y `PENDING_PURCHASE`. Una compra cancelada ya no se considera un error y ahora aparecerá en los resultados de compra sin error.
2. Reemplaza los eventos `onPurchaseCanceled` y `onPurchaseSuccess` por el nuevo evento `onPurchaseFinished` para paywalls creadas con Paywall Builder. Este cambio se debe a la misma razón: las compras canceladas ya no se tratan como errores y se incluirán en los resultados de compra sin error.
3. Cambia la firma del método `onAwaitingSubscriptionUpdateParams` para paywalls de Paywall Builder.
4. Actualiza el método utilizado para proporcionar paywalls de respaldo si pasas el URI de archivo directamente.
5. Actualiza las configuraciones de integración para Adjust, AirBridge, Amplitude, AppMetrica, Appsflyer, Branch, Facebook Ads, Firebase y Google Analytics, Mixpanel, OneSignal, Pushwoosh.
## Actualizar la compra \{#update-making-purchase\}
Las compras canceladas y pendientes anteriormente se consideraban errores y devolvían los códigos `USER_CANCELED` y `PENDING_PURCHASE`, respectivamente.
Ahora se usa una nueva clase `AdaptyPurchaseResult` para indicar compras canceladas, exitosas y pendientes. Actualiza el código de compra de la siguiente manera:
~~~diff
Adapty.makePurchase(activity, product) { result ->
when (result) {
is AdaptyResult.Success -> {
- val info = result.value
- val profile = info?.profile
-
- if (profile?.accessLevels?.get("YOUR_ACCESS_LEVEL")?.isActive == true) {
- // Grant access to the paid features
- }
+ when (val purchaseResult = result.value) {
+ is AdaptyPurchaseResult.Success -> {
+ val profile = purchaseResult.profile
+ if (profile.accessLevels["YOUR_ACCESS_LEVEL"]?.isActive == true) {
+ // Grant access to the paid features
+ }
+ }
+
+ is AdaptyPurchaseResult.UserCanceled -> {
+ // Handle the case where the user canceled the purchase
+ }
+
+ is AdaptyPurchaseResult.Pending -> {
+ // Handle deferred purchases (e.g., the user will pay offline with cash
+ }
+ }
}
is AdaptyResult.Error -> {
val error = result.error
// Handle the error
}
}
}
~~~
Para ver el ejemplo de código completo, consulta la página [Realizar compras en la app móvil](android-making-purchases#make-purchase).
## Modificar eventos de compra del Paywall Builder \{#modify-paywall-builder-purchase-events\}
1. Añade el evento `onPurchaseFinished`:
```diff showLineNumbers
+ public override fun onPurchaseFinished(
+ purchaseResult: AdaptyPurchaseResult,
+ product: AdaptyPaywallProduct,
+ context: Context,
+ ) {
+ when (purchaseResult) {
+ is AdaptyPurchaseResult.Success -> {
+ // Grant access to the paid features
+ }
+ is AdaptyPurchaseResult.UserCanceled -> {
+ // Handle the case where the user canceled the purchase
+ }
+ is AdaptyPurchaseResult.Pending -> {
+ // Handle deferred purchases (e.g., the user will pay offline with cash)
+ }
+ }
+ }
```
Para ver el ejemplo de código completo, consulta [Compra exitosa, cancelada o pendiente](android-handling-events#successful-canceled-or-pending-purchase) y la descripción del evento.
2. Elimina el procesamiento del evento `onPurchaseCancelled`:
```diff showLineNumbers
- public override fun onPurchaseCanceled(
- product: AdaptyPaywallProduct,
- context: Context,
- ) {}
```
3. Elimina `onPurchaseSuccess`:
```diff showLineNumbers
- public override fun onPurchaseSuccess(
- profile: AdaptyProfile?,
- product: AdaptyPaywallProduct,
- context: Context,
- ) {
- // Your logic on successful purchase
- }
```
## Cambiar la firma del método onAwaitingSubscriptionUpdateParams \{#change-the-signature-of-on-awaiting-subscription-update-params-method\}
Ahora, si se compra una nueva suscripción mientras otra sigue activa, llama a `onSubscriptionUpdateParamsReceived(AdaptySubscriptionUpdateParameters...))` si la nueva suscripción debe reemplazar a la actualmente activa, o a `onSubscriptionUpdateParamsReceived(null)` si la suscripción activa debe permanecer y la nueva debe añadirse por separado:
```diff showLineNumbers
- public override fun onAwaitingSubscriptionUpdateParams(
- product: AdaptyPaywallProduct,
- context: Context,
- ): AdaptySubscriptionUpdateParameters? {
- return AdaptySubscriptionUpdateParameters(...)
- }
+ public override fun onAwaitingSubscriptionUpdateParams(
+ product: AdaptyPaywallProduct,
+ context: Context,
+ onSubscriptionUpdateParamsReceived: SubscriptionUpdateParamsCallback,
+ ) {
+ onSubscriptionUpdateParamsReceived(AdaptySubscriptionUpdateParameters(...))
+ }
```
Consulta la sección de documentación [Actualización de suscripción](android-handling-events#upgrade-subscription) para ver el ejemplo de código final.
## Actualización para proporcionar paywalls de respaldo \{#update-providing-fallback-paywalls\}
Si pasas una URI de archivo para proporcionar paywalls de respaldo, actualiza la forma en que lo haces así:
```diff showLineNumbers
val fileUri: Uri = // Get the URI for the file with fallback paywalls
- Adapty.setFallbackPaywalls(fileUri, callback)
+ Adapty.setFallbackPaywalls(FileLocation.fromFileUri(fileUri), callback)
```
```diff showLineNumbers
Uri fileUri = // Get the URI for the file with fallback paywalls
- Adapty.setFallbackPaywalls(fileUri, callback);
+ Adapty.setFallbackPaywalls(FileLocation.fromFileUri(fileUri), callback);
```
## Actualizar la configuración del SDK de integraciones de terceros \{#update-third-party-integration-sdk-configuration\}
Para garantizar que las integraciones funcionen correctamente con el SDK de Android de Adapty 3.3.0 y versiones posteriores, actualiza las configuraciones del SDK para las siguientes integraciones tal como se describe en las secciones a continuación.
### Adjust
Actualiza el código de tu app móvil como se muestra a continuación. Para ver el ejemplo de código completo, consulta la [configuración del SDK para la integración con Adjust](adjust#connect-your-app-to-adjust).
```diff showLineNumbers
- Adjust.getAttribution { attribution ->
- if (attribution == null) return@getAttribution
-
- Adjust.getAdid { adid ->
- if (adid == null) return@getAdid
-
- Adapty.updateAttribution(attribution, AdaptyAttributionSource.ADJUST, adid) { error ->
- // Handle the error
- }
- }
- }
+ Adjust.getAdid { adid ->
+ if (adid == null) return@getAdid
+
+ Adapty.setIntegrationIdentifier("adjust_device_id", adid) { error ->
+ if (error != null) {
+ // Handle the error
+ }
+ }
+ }
+
+ Adjust.getAttribution { attribution ->
+ if (attribution == null) return@getAttribution
+
+ Adapty.updateAttribution(attribution, "adjust") { error ->
+ if (error != null) {
+ // Handle the error
+ }
+ }
+ }
```
```diff showLineNumbers
val config = AdjustConfig(context, adjustAppToken, environment)
config.setOnAttributionChangedListener { attribution ->
attribution?.let { attribution ->
- Adapty.updateAttribution(attribution, AdaptyAttributionSource.ADJUST) { error ->
+ Adapty.updateAttribution(attribution, "adjust") { error ->
if (error != null) {
// Handle the error
}
}
}
}
Adjust.onCreate(config)
```
### AirBridge
Actualiza el código de tu aplicación móvil como se muestra a continuación. Para ver el ejemplo de código completo, consulta la [configuración del SDK para la integración con AirBridge](airbridge#connect-your-app-to-airbridge).
```diff showLineNumbers
Airbridge.getDeviceInfo().getUUID(object: AirbridgeCallback.SimpleCallback() {
override fun onSuccess(result: String) {
- val params = AdaptyProfileParameters.Builder()
- .withAirbridgeDeviceId(result)
- .build()
- Adapty.updateProfile(params) { error ->
- if (error != null) {
- // Handle the error
- }
- }
+ Adapty.setIntegrationIdentifier("airbridge_device_id", result) { error ->
+ if (error != null) {
+ // Handle the error
+ }
+ }
}
override fun onFailure(throwable: Throwable) {
}
})
```
### Amplitude
Actualiza el código de tu app móvil como se muestra a continuación. Para ver el ejemplo de código completo, consulta la [configuración del SDK para la integración con Amplitude](amplitude#sdk-configuration).
```diff showLineNumbers
// For Amplitude maintenance SDK (obsolete)
val amplitude = Amplitude.getInstance()
val amplitudeDeviceId = amplitude.getDeviceId()
val amplitudeUserId = amplitude.getUserId()
//for actual Amplitude Kotlin SDK
val amplitude = Amplitude(
Configuration(
apiKey = AMPLITUDE_API_KEY,
context = applicationContext
)
)
val amplitudeDeviceId = amplitude.store.deviceId
val amplitudeUserId = amplitude.store.userId
//
- val params = AdaptyProfileParameters.Builder()
- .withAmplitudeDeviceId(amplitudeDeviceId)
- .withAmplitudeUserId(amplitudeUserId)
- .build()
- Adapty.updateProfile(params) { error ->
- if (error != null) {
- // Handle the error
- }
- }
+ Adapty.setIntegrationIdentifier("amplitude_user_id", amplitudeUserId) { error ->
+ if (error != null) {
+ // Handle the error
+ }
+ }
+ Adapty.setIntegrationIdentifier("amplitude_device_id", amplitudeDeviceId) { error ->
+ if (error != null) {
+ // Handle the error
+ }
+ }
```
### AppMetrica
Actualiza el código de tu aplicación como se muestra a continuación. Para ver el ejemplo de código completo, consulta la [configuración del SDK para la integración con AppMetrica](appmetrica#sdk-configuration).
```diff showLineNumbers
val startupParamsCallback = object: StartupParamsCallback {
override fun onReceive(result: StartupParamsCallback.Result?) {
val deviceId = result?.deviceId ?: return
- val params = AdaptyProfileParameters.Builder()
- .withAppmetricaDeviceId(deviceId)
- .withAppmetricaProfileId("YOUR_ADAPTY_CUSTOMER_USER_ID")
- .build()
- Adapty.updateProfile(params) { error ->
- if (error != null) {
- // Handle the error
- }
- }
+ Adapty.setIntegrationIdentifier("appmetrica_device_id", deviceId) { error ->
+ if (error != null) {
+ // Handle the error
+ }
+ }
+
+ Adapty.setIntegrationIdentifier("appmetrica_profile_id", "YOUR_ADAPTY_CUSTOMER_USER_ID") { error ->
+ if (error != null) {
+ // Handle the error
+ }
+ }
}
override fun onRequestError(
reason: StartupParamsCallback.Reason,
result: StartupParamsCallback.Result?
) {
// Handle the error
}
}
AppMetrica.requestStartupParams(context, startupParamsCallback, listOf(StartupParamsCallback.APPMETRICA_DEVICE_ID))
```
### AppsFlyer
Actualiza el código de tu aplicación móvil como se muestra a continuación. Para ver el ejemplo de código completo, consulta la [configuración del SDK para la integración con AppsFlyer](appsflyer#configure-your-app-code).
```diff showLineNumbers
val conversionListener: AppsFlyerConversionListener = object : AppsFlyerConversionListener {
override fun onConversionDataSuccess(conversionData: Map) {
- Adapty.updateAttribution(
- conversionData,
- AdaptyAttributionSource.APPSFLYER,
- AppsFlyerLib.getInstance().getAppsFlyerUID(context)
- ) { error ->
- if (error != null) {
- // Handle the error
- }
- }
+ val uid = AppsFlyerLib.getInstance().getAppsFlyerUID(context)
+ Adapty.setIntegrationIdentifier("appsflyer_id", uid) { error ->
+ if (error != null) {
+ // Handle the error
+ }
+ }
+ Adapty.updateAttribution(conversionData, "appsflyer") { error ->
+ if (error != null) {
+ // Handle the error
+ }
+ }
}
}
```
### Branch
Actualiza el código de tu aplicación móvil como se muestra a continuación. Para ver el ejemplo de código completo, consulta la [configuración del SDK para la integración con Branch](branch#connect-your-app-to-branch).
```diff showLineNumbers
// Login and update attribution
Branch.getAutoInstance(this)
.setIdentity("YOUR_USER_ID") { referringParams, error ->
referringParams?.let { data ->
- Adapty.updateAttribution(data, AdaptyAttributionSource.BRANCH) { error ->
- if (error != null) {
- // Handle the error
- }
- }
+ Adapty.updateAttribution(data, "branch") { error ->
+ if (error != null) {
+ // Handle the error
+ }
+ }
}
}
// Logout
Branch.getAutoInstance(context).logout()
```
### Facebook Ads
Actualiza el código de tu aplicación móvil como se muestra a continuación. Para ver el ejemplo de código completo, consulta la [configuración del SDK para la integración con Facebook Ads](facebook-ads#connect-your-app-to-facebook-ads).
```diff showLineNumbers
- val builder = AdaptyProfileParameters.Builder()
- .withFacebookAnonymousId(AppEventsLogger.getAnonymousAppDeviceGUID(context))
-
- Adapty.updateProfile(builder.build()) { error ->
- if (error != null) {
- // Handle the error
- }
- }
+ Adapty.setIntegrationIdentifier(
+ "facebook_anonymous_id",
+ AppEventsLogger.getAnonymousAppDeviceGUID(context)
+ ) { error ->
+ if (error != null) {
+ // Handle the error
+ }
+ }
```
### Firebase y Google Analytics \{#firebase-and-google-analytics\}
Actualiza el código de tu aplicación móvil como se muestra a continuación. Para ver el ejemplo de código completo, consulta la [configuración del SDK para la integración de Firebase y Google Analytics](firebase-and-google-analytics).
```diff showLineNumbers
// After Adapty.activate()
FirebaseAnalytics.getInstance(context).appInstanceId.addOnSuccessListener { appInstanceId ->
- Adapty.updateProfile(
- AdaptyProfileParameters.Builder()
- .withFirebaseAppInstanceId(appInstanceId)
- .build()
- ) { error ->
- if (error != null) {
- // Handle the error
- }
- }
+ Adapty.setIntegrationIdentifier("firebase_app_instance_id", appInstanceId) { error ->
+ if (error != null) {
+ // Handle the error
+ }
+ }
}
```
```diff showLineNumbers
// After Adapty.activate()
- FirebaseAnalytics.getInstance(context).getAppInstanceId().addOnSuccessListener(appInstanceId -> {
- AdaptyProfileParameters params = new AdaptyProfileParameters.Builder()
- .withFirebaseAppInstanceId(appInstanceId)
- .build();
-
- Adapty.updateProfile(params, error -> {
- if (error != null) {
- // Handle the error
- }
- });
- });
+ FirebaseAnalytics.getInstance(context).getAppInstanceId().addOnSuccessListener(appInstanceId -> {
+ Adapty.setIntegrationIdentifier("firebase_app_instance_id", appInstanceId, error -> {
+ if (error != null) {
+ // Handle the error
+ }
+ });
+ });
```
### Mixpanel
Actualiza el código de tu aplicación móvil como se muestra a continuación. Para ver el ejemplo de código completo, consulta la [configuración del SDK para la integración con Mixpanel](mixpanel#sdk-configuration).
```diff showLineNumbers
- val params = AdaptyProfileParameters.Builder()
- .withMixpanelUserId(mixpanelAPI.distinctId)
- .build()
-
- Adapty.updateProfile(params) { error ->
- if (error != null) {
- // Handle the error
- }
- }
+ Adapty.setIntegrationIdentifier("mixpanel_user_id", mixpanelAPI.distinctId) { error ->
+ if (error != null) {
+ // Handle the error
+ }
+ }
```
### OneSignal
Actualiza el código de tu aplicación móvil como se muestra a continuación. Para ver el ejemplo de código completo, consulta la [configuración del SDK para la integración con OneSignal](onesignal#sdk-configuration).
```diff showLineNumbers
// SubscriptionID
val oneSignalSubscriptionObserver = object: IPushSubscriptionObserver {
override fun onPushSubscriptionChange(state: PushSubscriptionChangedState) {
- val params = AdaptyProfileParameters.Builder()
- .withOneSignalSubscriptionId(state.current.id)
- .build()
-
- Adapty.updateProfile(params) { error ->
+ Adapty.setIntegrationIdentifier("one_signal_subscription_id", state.current.id) { error ->
if (error != null) {
// Handle the error
}
}
}
}
```
```diff showLineNumbers
// SubscriptionID
IPushSubscriptionObserver oneSignalSubscriptionObserver = state -> {
- AdaptyProfileParameters params = new AdaptyProfileParameters.Builder()
- .withOneSignalSubscriptionId(state.getCurrent().getId())
- .build();
- Adapty.updateProfile(params, error -> {
+ Adapty.setIntegrationIdentifier("one_signal_subscription_id", state.getCurrent().getId(), error -> {
if (error != null) {
// Handle the error
}
});
};
```
```diff showLineNumbers
// PlayerID
val osSubscriptionObserver = OSSubscriptionObserver { stateChanges ->
stateChanges?.to?.userId?.let { playerId ->
- val params = AdaptyProfileParameters.Builder()
- .withOneSignalPlayerId(playerId)
- .build()
-
- Adapty.updateProfile(params) { error ->
+ Adapty.setIntegrationIdentifier("one_signal_player_id", playerId) { error ->
if (error != null) {
// Handle the error
}
- }
}
}
```
```diff showLineNumbers
// PlayerID
OSSubscriptionObserver osSubscriptionObserver = stateChanges -> {
OSSubscriptionState to = stateChanges != null ? stateChanges.getTo() : null;
String playerId = to != null ? to.getUserId() : null;
if (playerId != null) {
- AdaptyProfileParameters params1 = new AdaptyProfileParameters.Builder()
- .withOneSignalPlayerId(playerId)
- .build();
-
- Adapty.updateProfile(params1, error -> {
+ Adapty.setIntegrationIdentifier("one_signal_player_id", playerId, error -> {
if (error != null) {
// Handle the error
}
- });
}
};
```
### Pushwoosh
Actualiza el código de tu aplicación móvil como se muestra a continuación. Para ver el ejemplo de código completo, consulta la [configuración del SDK para la integración con Pushwoosh](pushwoosh#sdk-configuration).
```diff showLineNumbers
- val params = AdaptyProfileParameters.Builder()
- .withPushwooshHwid(Pushwoosh.getInstance().hwid)
- .build()
- Adapty.updateProfile(params) { error ->
+ Adapty.setIntegrationIdentifier("pushwoosh_hwid", Pushwoosh.getInstance().hwid) { error ->
if (error != null) {
// Handle the error
}
}
```
```diff showLineNumbers
- AdaptyProfileParameters params = new AdaptyProfileParameters.Builder()
- .withPushwooshHwid(Pushwoosh.getInstance().getHwid())
- .build();
-
- Adapty.updateProfile(params, error -> {
+ Adapty.setIntegrationIdentifier("pushwoosh_hwid", Pushwoosh.getInstance().getHwid(), error -> {
if (error != null) {
// Handle the error
}
});
```
---
# File: migration-to-android-sdk-v3
---
---
title: "Migrar el SDK de Android de Adapty a la versión 3.0"
description: "Migra al SDK de Android de Adapty v3.0 para obtener mejor rendimiento y nuevas funciones de monetización."
---
Adapty SDK v3.0 introduces significant changes. This document outlines the key modifications to help you upgrade from v2.x to v3.0. We've made every effort to ensure backward compatibility, but some changes may require updates to your codebase.
## Renaming Paywalls to Placements
In v3.0, we've renamed "paywalls" to "placements" throughout the SDK. This change reflects the concept that a "placement" is a specific location in your app where a paywall can be displayed. Here's a summary of the renaming:
| Before (v2.x) | After (v3.0) |
|---|---|
| `getPaywalls()` | `getPlacements()` |
| `Paywall` | `Placement` |
| `paywallId` | `placementId` |
| `paywallVariationId` | `placementVariationId` |
## Changes to `AdaptyPaywall`
`AdaptyPaywall` in v3.0 contains the following properties:
| Property | Type | Description |
|---|---|---|
| `placementId` | `String` | The ID of the placement in Adapty |
| `variationId` | `String` | The ID of the variation in the A/B test |
| `revision` | `Int` | The revision of the paywall |
| `onboardingScreens` | `List` | The onboarding screens for the paywall |
| `remoteConfig` | `AdaptyRemoteConfig?` | The remote config for the paywall |
| `products` | `List` | The products associated with the paywall |
## Start Using Adapty Android SDK v3.0
Starting with v3.0, we recommend initializing the Adapty Android SDK in the `Application.onCreate()` method. This ensures the SDK is ready to use when your app launches.
To migrate to Adapty Android SDK v3.0:
1. [Install Adapty Android SDK v3.x](sdk-installation-android).
2. Make the changes listed in the sections below.
## Changes to Adapty configuration
### Configuration builder changes
The configuration builder was updated to allow for a more flexible setup. The new builder accepts an `appKey` parameter, which is your Adapty API key. The old builder accepted a `apiKey` parameter.
```kotlin title="App.kt"
override fun onCreate() {
super.onCreate()
Adapty.activate(
applicationContext,
AdaptyConfig.Builder("PUBLIC_SDK_KEY")
.withObserverMode(false)
.withCustomerUserId(customerUserId)
.withIpAddressCollectionDisabled(false)
.withIpAddressCollectionDisabled(false)
.build()
)
}
```
```kotlin title="App.kt"
override fun onCreate() {
super.onCreate()
Adapty.activate(
applicationContext,
AdaptyConfig.Builder("PUBLIC_SDK_KEY")
.withObserverMode(false)
.withCustomerUserId(customerUserId)
.withIpAddressCollectionDisabled(false)
.build()
)
}
```
## Changes to paywalls
### Retrieving paywalls
```kotlin title="kotlin"
Adapty.getPaywall(placementId, locale, loadTimeout) { result ->
when (result) {
is AdaptyResult.Success -> {
val paywall = result.value
// use paywall
}
is AdaptyResult.Error -> {
val error = result.error
// handle the error
}
}
}
```
```kotlin title="kotlin"
Adapty.getPaywall(id, locale, fetchPolicy, loadTimeout) { result ->
when (result) {
is AdaptyResult.Success -> {
val paywall = result.value
// use paywall
}
is AdaptyResult.Error -> {
val error = result.error
// handle the error
}
}
}
```
The `fetchPolicy` parameter has been removed from `getPaywall`. This parameter previously controlled whether the SDK fetched fresh data from the server or used a cached version. You can now control this via the configuration builder.
### Retrieving paywall products
```kotlin title="kotlin"
Adapty.getPaywallProducts(paywall) { result ->
when (result) {
is AdaptyResult.Success -> {
val products = result.value
// use the products
}
is AdaptyResult.Error -> {
val error = result.error
// handle the error
}
}
}
```
```kotlin title="kotlin"
Adapty.getPaywallProducts(paywall) { result ->
when (result) {
is AdaptyResult.Success -> {
val products = result.value
// use the products
}
is AdaptyResult.Error -> {
val error = result.error
// handle the error
}
}
}
```
### Logging paywall display
```kotlin title="kotlin"
Adapty.logShowPaywall(paywall)
```
```kotlin title="kotlin"
Adapty.logShowPaywall(paywall)
```
## Changes to `AdaptyProfile`
In v3.0, we've updated `AdaptyProfile`. The `customAttributes` property is now included in the `AdaptyProfile.CustomerUser` object rather than directly in the profile.
```kotlin title="kotlin"
val profile: AdaptyProfile
val customAttributes = profile.customerUser?.customAttributes
```
```kotlin title="kotlin"
val profile: AdaptyProfile
val customAttributes = profile.customAttributes
```
## Changes to `AdaptyPaywallProduct`
In v3.0, we've updated `AdaptyPaywallProduct`. The `variationId` property has been removed and the `paywallVariationId` property has been renamed to `variationId`.
```kotlin title="kotlin"
val product: AdaptyPaywallProduct
val variationId = product.variationId
```
```kotlin title="kotlin"
val product: AdaptyPaywallProduct
val variationId = product.paywallVariationId
```
## Changes to `AdaptySubscriptionUpdateParameters`
In v3.0, we've updated `AdaptySubscriptionUpdateParameters`. The `replacementMode` property has been renamed to `prorationMode`.
```kotlin title="kotlin"
val params = AdaptySubscriptionUpdateParameters(
oldSubVendorProductId,
prorationMode
)
```
```kotlin title="kotlin"
val params = AdaptySubscriptionUpdateParameters(
oldSubVendorProductId,
replacementMode
)
```
## Changes to `AdaptyPurchasedInfo`
In v3.0, we've updated `AdaptyPurchasedInfo`. The response now includes the `profile` and, optionally, the `purchase` property.
```kotlin title="kotlin"
Adapty.makePurchase(activity, product, subscriptionUpdateParams, isOfferPersonalized) { result ->
when (result) {
is AdaptyResult.Success -> {
val profile = result.value.profile
val purchase = result.value.purchase
}
is AdaptyResult.Error -> {
val error = result.error
// handle the error
}
}
}
```
```kotlin title="kotlin"
Adapty.makePurchase(activity, product, subscriptionUpdateParams, isOfferPersonalized) { result ->
when (result) {
is AdaptyResult.Success -> {
val profile = result.value.profile
}
is AdaptyResult.Error -> {
val error = result.error
// handle the error
}
}
}
```
Adapty SDK v3.0 trae soporte para el nuevo e innovador [Adapty Paywall Builder](adapty-paywall-builder), la nueva versión de la herramienta no-code y fácil de usar para crear paywalls. Con su máxima flexibilidad y ricas capacidades de diseño, tus paywalls serán más efectivos y rentables.
Los SDKs de Adapty se distribuyen como un BoM (Bill of Materials), lo que garantiza que las versiones del SDK de Adapty y del SDK de AdaptyUI en tu app sean siempre consistentes.
Para migrar a v3.0, actualiza tu código de la siguiente manera:
```diff showLineNumbers
dependencies {
...
- implementation 'io.adapty:android-sdk:2.11.5'
- implementation 'io.adapty:android-ui:2.11.3'
+ implementation platform('io.adapty:adapty-bom:3.0.4')
+ implementation 'io.adapty:android-sdk'
+ implementation 'io.adapty:android-ui'
}
```
```diff showLineNumbers
dependencies {
...
- implementation("io.adapty:android-sdk:2.11.5")
- implementation("io.adapty:android-ui:2.11.3")
+ implementation(platform("io.adapty:adapty-bom:3.0.4"))
+ implementation("io.adapty:android-sdk")
+ implementation("io.adapty:android-ui")
}
```
```diff showLineNumbers
//libs.versions.toml
[versions]
..
- adapty = "2.11.5"
- adaptyUi = "2.11.3"
+ adaptyBom = "3.0.4"
[libraries]
..
- adapty = { group = "io.adapty", name = "android-sdk", version.ref = "adapty" }
- adapty-ui = { group = "io.adapty", name = "android-ui", version.ref = "adaptyUi" }
+ adapty-bom = { module = "io.adapty:adapty-bom", version.ref = "adaptyBom" }
+ adapty = { module = "io.adapty:android-sdk" }
+ adapty-ui = { module = "io.adapty:android-ui" }
//module-level build.gradle.kts
dependencies {
...
+ implementation(libs.adapty.bom)
implementation(libs.adapty)
implementation(libs.adapty.ui)
}
```
---
# End of Documentation
_Generated on: 2026-10-30T13:00:39.455Z_
_Successfully processed: 54/54 files_
# API - Adapty Documentation (Full Content)
This file contains the complete content of all documentation pages for this platform.
Locale: es
Generated on: 2026-10-30T13:00:39.458Z
Total files: 32
---
# File: developer-cli
---
---
title: "CLI para desarrolladores"
description: "Descripción general del CLI para desarrolladores de Adapty."
---
La **Adapty Developer CLI** es una herramienta de línea de comandos para gestionar tu cuenta de Adapty sin necesidad de abrir el Dashboard. Ofrece las principales funciones de configuración, accesibles desde tu terminal o entornos automatizados.
**Qué puedes hacer con la CLI:**
- Crea y configura apps de iOS y Android en tu cuenta de Adapty
- Define niveles de acceso — los niveles de suscripción que tu app comprueba en tiempo de ejecución
- Configura productos y asígnalos a los IDs de las stores de App Store y Google Play
- Vincula ofertas de la store, incluidas las pruebas gratuitas de Google Play, a productos — consulta [Ofertas de productos](developer-cli-products#product-offers) en la referencia de comandos
- Crea paywalls y asígnales productos
- Crea flows, escribe sus configuraciones de builder y publícalos — consulta [Flows](developer-cli-flows) en la referencia de comandos
- Configura placements para obtener paywalls o flows a través del SDK
- Lee los análisis de tu app — ingresos, MRR, conversiones, el embudo, retención, LTV y cohortes — a través de [Analytics](developer-cli-analytics)
- Crea, inicia, detén y reemplaza pruebas A/B de paywalls y flows a través de [A/B tests](developer-cli-ab-tests)
- Gestiona campañas de Apple Ads, palabras clave y reglas de automatización a través de [Ads Manager](developer-cli-ads-manager)
- Lee los informes de atribución de Adapty — gasto, instalaciones, ingresos y ROAS por canal y campaña — a través de [Attribution](developer-cli-attribution)
- Migra un proyecto de RevenueCat — su catálogo, diseños de paywalls, código de la app e historial de transacciones — consulta [Migración desde RevenueCat](migration-from-revenuecat)
- Instala los skills de Adapty en tus agentes de programación con `adapty skills install` — consulta [Skills](developer-cli-reference#skills) en la referencia de comandos
---
# File: developer-cli-quickstart
---
---
title: "Guía de inicio rápido para el CLI para desarrolladores de Adapty"
description: "Configura tu cuenta de Adapty de principio a fin usando el CLI para desarrolladores — desde la creación de la app hasta un placement activo, en unos pocos comandos."
---
El CLI de Adapty te permite configurar tu app completamente desde la línea de comandos. Úsalo como alternativa al [inicio rápido del dashboard](integrate-payments) si prefieres herramientas de terminal o [clientes MCP](https://github.com/adaptyteam/adapty-cli/tree/main/skills/adapty-cli).
:::note
Conectar Adapty con App Store Connect y Google Play todavía requiere una configuración puntual en el dashboard — esto se explica en el paso 3.
:::
Al terminar, tu app, nivel de acceso, producto, flow o paywall y placement estarán visibles en el [Adapty Dashboard](https://app.adapty.io).
Si ejecutas la CLI en la aplicación Claude (anteriormente Claude Cowork), configúrala primero en Claude — consulta [Configurar la CLI de Adapty en la aplicación Claude](developer-cli-cowork).
## 1. Instala el CLI \{#1-install-the-cli\}
Requiere [Node.js](https://nodejs.org/en/download) 18 o posterior.
Para instalar el CLI, ejecuta el comando:
```bash
npm install -g adapty
```
O directamente:
```bash
npx adapty auth login
```
## 2. Autentícate \{#2-authenticate\}
Ejecuta el comando de inicio de sesión para conectar el CLI con tu cuenta de Adapty.
```bash
adapty auth login
```
El CLI abre una pestaña del navegador. Verifica que el código que aparece en la terminal coincida con el del navegador y haz clic en **Authorize**. La terminal confirmará cuando la autenticación se haya completado.
## 3. Crea tu app \{#3-create-your-app\}
Una app en Adapty representa tu aplicación móvil. Una misma app de Adapty se conecta tanto a App Store como a Google Play, por lo que solo necesitas crear una, independientemente de en cuántos stores publiques.
```bash
adapty apps create --title "My App" --platform ios --platform android --apple-bundle-id com.example.app --google-bundle-id com.example.app
```
```bash
adapty apps create --title "My App" --platform ios --apple-bundle-id com.example.app
```
```bash
adapty apps create --title "My App" --platform android --google-bundle-id com.example.app
```
El comando devuelve un ``. Usa este ID en todos los comandos siguientes.
:::important
Antes de continuar, conecta tu app a App Store Connect y Google Play en el Adapty Dashboard. Los IDs de producto de ambos stores son necesarios en el paso 5.
- [Conectar App Store Connect](app-store-connection-configuration)
- [Conectar Google Play](google-play-store-connection-configuration)
:::
## 4. Crea un nivel de acceso (opcional) \{#4-create-an-access-level-optional\}
Los [niveles de acceso](access-level) controlan a qué puede acceder el usuario tras una compra. En lugar de comprobar si un usuario compró un producto concreto, tu app verifica si el usuario tiene un determinado nivel de acceso. Esto desacopla la lógica de tu app de los IDs de producto específicos.
Con cada nueva app se crea automáticamente un nivel de acceso `premium`. **Para la mayoría de las apps puedes saltarte este paso.** Usa `premium` como ID de nivel de acceso en el paso 5.
Solo ejecuta este comando si distintos productos desbloquean distintas funciones para diferentes grupos de usuarios; por ejemplo, si un suscriptor "Basic" y uno "Pro" tienen acceso a partes diferentes de la app.
```bash
adapty access-levels create --app --sdk-id "pro" --title "Pro"
```
- `--sdk-id` es el identificador que usarás en el código de tu app para comprobar si una función debe estar disponible para el usuario (por ejemplo, `if user.hasAccessLevel("pro")`). Si te saltas este paso y usas el nivel de acceso por defecto, su `--sdk-id` es `premium`.
- `--title` es una etiqueta de visualización para tu referencia en el Adapty Dashboard.
El comando devuelve un ``.
## 5. Crea un producto \{#5-create-a-product\}
En Adapty, un [producto](product) representa cualquier cosa que tu app vende: una suscripción o una compra única. Los elementos de App Store Connect y Google Play se pueden agrupar en un único producto de Adapty y gestionarse desde un solo lugar.
Necesitarás los IDs de producto de cada store: el Apple product ID de App Store Connect, y el Android product ID y el base plan ID de Google Play Console. Consulta [Productos](quickstart-products) para saber dónde encontrarlos.
Si omitiste el paso 4, usa el `default_access_level.id` que devolvió el comando `apps create` en el paso 3 como tu ``.
:::important
Los IDs de productos del store que vincules aquí no se pueden cambiar una vez creados. Para usar IDs de productos del store diferentes, crea un nuevo producto.
:::
```bash
adapty products create --app --title "My Product" --access-level-id --period monthly --ios-product-id --android-product-id --android-base-plan-id
```
```bash
adapty products create --app --title "My Product" --access-level-id --period monthly --ios-product-id
```
```bash
adapty products create --app --title "My Product" --access-level-id --period monthly --android-product-id --android-base-plan-id
```
El comando devuelve un ``.
Si también vendes este producto en la web a través de Stripe o Paddle, añade esos IDs al mismo comando. Consulta [products create](developer-cli-products#adapty-products-create) en la referencia de comandos.
Si el producto tiene prueba gratuita o descuento en Google Play, o una oferta promocional o de recuperación en App Store, vincula la oferta al producto para que Adapty pueda aplicarla. Consulta [product-offers create](developer-cli-products#adapty-product-offers-create) en la referencia de comandos.
## 6. Crea un flow o un paywall \{#6-create-a-flow-or-paywall\}
Todo producto debe estar dentro de un flow o un paywall antes de poder aparecer en tu app. Elige una opción:
- Un **flow** es una pantalla, o una secuencia de pantallas, que diseñas en el [Flow & Paywall Builder](adapty-flow-builder) sin código y el SDK de Adapty renderiza de forma nativa: una pantalla de paywall, un onboarding, un cuestionario. Elige un flow cuando quieras que Adapty se encargue de renderizar la pantalla de compra. Los flows requieren el SDK de Adapty 4.0 o posterior.
- Un **paywall** es un conjunto de productos sin diseño asociado. Elige un paywall cuando renderices la pantalla de compra en el código de tu propia app y solo necesites que Adapty entregue los productos, opcionalmente con un [Remote Config](customize-paywall-with-remote-config).
Un placement sirve un único tipo de contenido, así que decide antes del paso 7.
### 6a. Crear un flow \{#6a-create-a-flow\}
El CLI crea el registro del flow. Sus pantallas viven en una configuración de builder, un documento JSON que el CLI no genera. Para crear la configuración desde el terminal, usa la [skill flow-generator](flow-generator-skill), que maneja el CLI por ti.
Crea el flow:
```bash
adapty flows create --app --name "Onboarding"
```
El comando devuelve un ``.
Crea sus pantallas con la [skill flow-generator](flow-generator-skill) o en el [Flow & Paywall Builder](adapty-flow-builder). En cualquier caso, el resultado es un borrador guardado que tus usuarios aún no ven.
Publica el flow:
```bash
adapty flows publish --app
```
El comando pide confirmación. La publicación se ejecuta en segundo plano, así que comprueba el estado con `adapty flows get --app ` hasta que aparezca `published`. Si aparece `publication_failed`, [`flows config get`](developer-cli-flows#adapty-flows-config-get) indica el motivo. Un placement solo acepta un flow publicado.
### 6b. Crea un paywall \{#6b-create-a-paywall\}
Un [paywall](paywalls) es el contenedor que agrupa tus productos.
:::important
Una vez que un paywall está vinculado a un placement, sus productos no se pueden modificar. Para usar productos distintos, crea un nuevo paywall y actualiza el placement para que apunte a él.
:::
```bash
adapty paywalls create --app --title "My Paywall" --product-id
```
```bash
adapty paywalls create --app --title "My Paywall" --product-id --product-id
```
El comando devuelve un ``.
## 7. Crea un placement \{#7-create-a-placement\}
Un [placement](placements) es el punto de tu app donde muestras un flow o paywall. Lo único que escribes directamente en el código de tu app es el ID del placement. Todo lo demás — qué flow o paywall mostrar y a qué usuarios — se gestiona desde el dashboard sin necesidad de publicar una nueva versión de la app.
`--developer-id` es la cadena que usarás más adelante en el código de tu app cuando le preguntes a Adapty qué mostrar en ese punto. Elige algo que describa la ubicación, como `"main"`, `"onboarding"` o `"settings"`.
```bash
adapty placements create --app --title "Onboarding" --developer-id "onboarding" --audiences '[{"content_type":"flow","segment_ids":[],"flow_id":"","priority":0}]'
```
```bash
adapty placements create --app --title "Main" --developer-id "main" --audiences '[{"content_type":"paywall","segment_ids":[],"paywall_id":"","priority":0}]'
```
La bandera `--audiences` controla qué flow o paywall se muestra a cada usuario. Los ejemplos anteriores definen una única audiencia por defecto: todos los usuarios en este placement ven el mismo contenido. Un placement sirve un solo tipo de contenido: un placement de paywall admite entradas de tipo `paywall` y un placement de flow admite entradas de tipo `flow`. Para segmentar por segmento, consulta [Forma de audiences](developer-cli-placements#audiences-shape) en la referencia de comandos.
## ¿Qué hacer a continuación? \{#whats-next\}
Todas las entidades ya son visibles en el [Adapty Dashboard](https://app.adapty.io). A continuación:
- Cambia un flow más adelante — describe el cambio al [skill flow-generator](flow-generator-skill), o abre el flow en el [Flow & Paywall Builder](adapty-flow-builder).
- Renderiza un paywall en tu app — [obtén el paywall y sus productos](fetch-paywalls-and-products) con el SDK y construye la pantalla con tu propio código.
- [Integra el SDK de Adapty](quickstart-sdk) — añade el SDK a tu app para obtener y mostrar el placement.
- Dirige distintos [segmentos](segments) de usuarios a diferentes flows o paywalls — consulta [`placements update`](developer-cli-placements#adapty-placements-update) y [`segments list`](developer-cli-placements#adapty-segments-list) en la referencia de comandos.
---
# File: developer-cli-authentication
---
---
title: "Autenticación en el Adapty Developer CLI"
description: "Cómo autenticarse con el Adapty Developer CLI."
---
El CLI requiere autenticación para llamar a la API de Adapty.
Un solo inicio de sesión cubre todo el CLI. Los [comandos del Ads Manager](developer-cli-ads-manager) acceden a un servicio diferente, pero utilizan el mismo token almacenado — no hay un segundo paso de inicio de sesión.
## Iniciar sesión \{#log-in\}
Para iniciar sesión:
1. En tu terminal, ejecuta:
```bash
adapty auth login
```
2. El CLI muestra un código de verificación en formato `XXXX-XXXX` y abre el Adapty Dashboard en tu navegador.
3. En la página de autorización, confirma que el código coincide con lo que aparece en tu terminal.
4. Haz clic en **Authorize**. El navegador mostrará "CLI authorized! You can close this tab."
5. De vuelta en la terminal, el CLI confirma que estás autenticado.
Si el código expira antes de que autorices, o si haces clic en **Deny**, ejecuta el siguiente comando de nuevo para reiniciar el proceso:
```bash
adapty auth login
```
## Gestionar la autenticación \{#manage-authentication\}
### Comprobar el estado de autenticación \{#check-authentication-status\}
Para ver tu estado de autenticación actual, ejecuta:
```bash
adapty auth status
```
Cuando estás autenticado, la salida muestra tu nombre, un prefijo de token enmascarado y la ruta al archivo de configuración local:
```
User: Jane Doe
Token: abcd1234****
Config: ~/.config/adapty/config.json
```
A partir de la CLI 0.9.1, al iniciar sesión se almacena tu nombre pero no tu correo electrónico. La línea `Email:` solo aparece en sesiones guardadas por una versión anterior. En scripts que lean `adapty auth status --json`, usa el campo `name` para identificar al usuario.
Cuando no estás autenticado:
```
Not authenticated. Run `adapty auth login`.
```
### Verificar tu token \{#verify-your-token\}
Para confirmar que tu token es válido y ver los detalles de tu cuenta, ejecuta:
```bash
adapty auth whoami
```
A diferencia de `adapty auth status`, este comando realiza una solicitud en tiempo real al servidor para verificar el token.
### Cerrar sesión \{#log-out\}
Para borrar tus credenciales almacenadas localmente, ejecuta:
```bash
adapty auth logout
```
Esto elimina `~/.config/adapty/config.json` y la migración guardada por `adapty migrations create` o `adapty migrations use`. El token sigue siendo válido en el servidor hasta que expire; si necesitas invalidarlo de inmediato, usa `adapty auth revoke` en su lugar.
### Revocar tu token \{#revoke-your-token\}
Para invalidar el token en el servidor y borrarlo localmente, ejecuta:
```bash
adapty auth revoke
```
Si el token tiene una migración guardada, el CLI también la elimina, pero solo después de que el servidor confirme la revocación. Usa esto cuando quieras invalidar completamente un token — por ejemplo, si tus credenciales pudieran haber sido comprometidas. Tras revocar, ejecuta `adapty auth login` para autenticarte de nuevo.
## Errores de token \{#token-errors\}
Si un token se revoca o deja de ser válido, los comandos del CLI devuelven un error 401. Para volver a autenticarte, ejecuta:
```bash
adapty auth login
```
---
# File: developer-cli-reference
---
---
title: "Referencia de comandos del Adapty Developer CLI"
description: "Índice de los comandos del Adapty Developer CLI organizados por tema, con las opciones globales, opciones de paginación y el comando para instalar los skills de Adapty."
---
El CLI de Adapty agrupa sus comandos por tema, como `products` o `placements`. Cada tema tiene su propia página con sus comandos, argumentos, flags y valores aceptados. Esta página lista los temas, los flags que acepta cualquier comando y el comando para instalar los skills de Adapty.
| Tema | Comandos | Qué hacen |
|---|---|---|
| [Apps y niveles de acceso](developer-cli-apps) | `apps`, `access-levels` | Crear y configurar apps y los niveles de suscripción que comprueba tu app |
| [Productos y ofertas](developer-cli-products) | `products`, `product-offers` | Configurar productos, mapearlos a los IDs de producto de App Store y Google Play, y vincular ofertas de la store a ellos |
| [Paywalls](developer-cli-paywalls) | `paywalls` | Crear paywalls y asignarles productos |
| [Flows](developer-cli-flows) | `flows` | Crear flows, escribir y validar sus configuraciones del builder, publicarlos y leer sus métricas |
| [Placements y segmentos](developer-cli-placements) | `placements`, `segments` | Configurar placements, sus audiencias y los segmentos a los que se dirigen las audiencias. Leer las métricas de los placements de flows |
| [Analytics](developer-cli-analytics) | `analytics` | Leer gráficos, conversiones, el embudo, retención, LTV y cohortes |
| [Pruebas A/B](developer-cli-ab-tests) | `ab-tests` | Crear, iniciar, detener, reemplazar y archivar pruebas A/B de paywalls y flows |
| [Atribución](developer-cli-attribution) | `attribution` | Leer gasto, instalaciones, ingresos y ROAS por canal y campaña |
| [Ads Manager](developer-cli-ads-manager-reference) | `asa` | Gestionar campañas, palabras clave y reglas de automatización de Apple Ads |
| [Migraciones](developer-cli-migrations) | `migrations` | Mover un proyecto de RevenueCat a Adapty |
| [Autenticación](developer-cli-authentication) | `auth` | Iniciar sesión, comprobar y revocar tu sesión de CLI |
## Indicadores globales \{#global-flags\}
Estos indicadores están disponibles en todos los comandos.
| Indicador | Descripción |
|---|---|
| `--json` | Devuelve la salida en JSON en lugar de texto formateado |
| `--help` | Muestra la ayuda del comando |
Todos los comandos `list` excepto `adapty product-offers list` también aceptan indicadores de paginación:
| Indicador | Valor por defecto | Descripción |
|---|---|---|
| `--page` | `1` | Número de página |
| `--page-size` | `20` | Elementos por página (máx.: 100) |
## Skills \{#skills\}
### adapty skills install
Instala los skills de Adapty en los agentes de codificación de esta máquina.
```bash
adapty skills install
```
| Flag | Requerido | Descripción |
|---|---|---|
| `--agent` | No | Agente en el que instalar: `claude-code`, `codex` o `gemini-cli`. Repite la flag para varios agentes. |
| `-y`, `--yes` | No | Instala en todos los agentes encontrados sin preguntar. Obligatorio cuando el CLI encuentra varios agentes y no puede preguntar, por ejemplo con `--json`. |
La CLI busca Claude Code, Codex y Gemini CLI en el `PATH`. Si no encuentra ninguno, pregunta si ejecutar `npx skills@1.7.0 add adaptyteam/adapty-skills --all --global`, que cubre otros agentes. Reinicia el agente para cargar los skills.
Claude Code no actualiza el plugin por su cuenta. Para obtener nuevos skills a medida que se publican, en Claude Code ejecuta `/plugin`, abre **Marketplaces**, selecciona `adapty` y elige **Enable auto-update**. Para activarlo sin usar el menú, añade `"autoUpdate": true` a la entrada `adapty` en `~/.claude/settings.json`:
```json title="~/.claude/settings.json"
{
"extraKnownMarketplaces": {
"adapty": {
"source": { "source": "github", "repo": "adaptyteam/adapty-skills" },
"autoUpdate": true
}
}
}
```
Los skills instalados a través del CLI de skills se actualizan con `npx skills update`. Para Codex, consulta el [README del plugin](https://github.com/adaptyteam/adapty-skills/blob/main/plugin/README.md#codex).
---
# File: developer-cli-apps
---
---
title: "Comandos de apps y niveles de acceso"
description: "Comandos de la CLI de Adapty para listar, leer, crear y actualizar apps y niveles de acceso."
---
Estos comandos de la CLI de Adapty gestionan tus apps y sus [niveles de acceso](access-level): los niveles de suscripción que tu app comprueba en tiempo de ejecución.
## Apps \{#apps\}
Administra las apps de tu cuenta de Adapty. Para la configuración desde el dashboard, consulta [Configuración de la app](general).
### adapty apps list
Lista todas las apps de tu cuenta de Adapty.
```bash
adapty apps list
```
Acepta [flags de paginación](developer-cli-reference#global-flags).
### adapty apps get
Obtén los detalles de una app específica.
```bash
adapty apps get
```
| Argumento | Descripción |
|---|---|
| `app-id` | ID de la app (UUID) |
### adapty apps create
Crea una nueva app.
```bash
adapty apps create --title "My App" --platform ios --apple-bundle-id com.example.app
```
| Flag | Requerido | Descripción |
|---|---|---|
| `--title` | Sí | Título de la app |
| `--platform` | Sí | Plataforma: `ios` o `android`. Repite para ambas: `--platform ios --platform android` |
| `--apple-bundle-id` | Requerido con `--platform ios` | Apple bundle ID |
| `--google-bundle-id` | Requerido con `--platform android` | Google bundle ID |
### adapty apps update
Actualiza una app existente.
```bash
adapty apps update --title "New Name"
```
| Argument | Description |
|---|---|
| `app-id` | App ID (UUID) |
| Flag | Description |
|---|---|
| `--title` | Nuevo título de la app |
| `--apple-bundle-id` | Nuevo Apple bundle ID |
| `--google-bundle-id` | Nuevo Google bundle ID |
Se requiere al menos un flag. `--platform` no se puede cambiar después de la creación.
## Niveles de acceso \{#access-levels\}
### adapty access-levels list
Lista todos los [niveles de acceso](access-level) de una aplicación.
```bash
adapty access-levels list --app
```
| Flag | Required | Description |
|---|---|---|
| `--app` | Yes | App ID (UUID) |
Acepta [flags de paginación](developer-cli-reference#global-flags).
### adapty access-levels get
Obtén los detalles de un [nivel de acceso](access-level) específico.
```bash
adapty access-levels get --app
```
| Argumento | Descripción |
|---|---|
| `access-level-id` | ID del nivel de acceso (UUID) |
| Flag | Requerido | Descripción |
|---|---|---|
| `--app` | Sí | ID de la app (UUID) |
### adapty access-levels create
Crea un nuevo [nivel de acceso](access-level).
```bash
adapty access-levels create --app --sdk-id "pro" --title "Pro"
```
| Flag | Obligatorio | Descripción |
|---|---|---|
| `--app` | Sí | ID de la app (UUID) |
| `--sdk-id` | Sí | Identificador usado en el código de la app para comprobar el acceso (por ejemplo, `"pro"` o `"premium"`) |
| `--title` | Sí | Etiqueta de visualización en el Adapty Dashboard |
### adapty access-levels update
Actualiza un [nivel de acceso](access-level) existente.
```bash
adapty access-levels update --app --title "Pro Access"
```
| Argumento | Descripción |
|---|---|
| `access-level-id` | ID del nivel de acceso (UUID) |
| Flag | Requerido | Descripción |
|---|---|---|
| `--app` | Sí | ID de la app (UUID) |
| `--title` | Sí | Nueva etiqueta de visualización |
`--sdk-id` no se puede cambiar después de la creación.
## ¿Qué sigue? \{#whats-next\}
- [Referencia de comandos](developer-cli-reference) — todos los temas del CLI, los flags globales y los flags de paginación.
---
# File: developer-cli-products
---
---
title: "Comandos de productos y ofertas de productos"
description: "Comandos de la CLI de Adapty para listar, leer, crear y actualizar productos, asignarles IDs de App Store y Google Play, y vincular ofertas de la store."
---
Estos comandos de la CLI de Adapty gestionan [productos](product), los asignan a sus IDs de producto en App Store y Google Play, y vinculan ofertas de la store a ellos.
## Productos \{#products\}
### Lista de productos de Adapty \{#adapty-products-list\}
Lista todos los [productos](product) de una app.
```bash
adapty products list --app
```
| Flag | Requerido | Descripción |
|---|---|---|
| `--app` | Sí | ID de la app (UUID) |
Acepta [flags de paginación](developer-cli-reference#global-flags).
### adapty products get
Obtén los detalles de un [producto](product) específico.
```bash
adapty products get --app
```
| Argumento | Descripción |
|---|---|
| `product-id` | ID del producto (UUID) |
| Flag | Requerido | Descripción |
|---|---|---|
| `--app` | Sí | ID de la app (UUID) |
### adapty products create
Crea un nuevo [producto](product).
:::important
Los IDs de producto de la store y los IDs de precio no se pueden cambiar después de la creación. Para usar IDs de store diferentes, crea un nuevo producto.
:::
```bash
adapty products create --app --title "Monthly" --access-level-id --period monthly --ios-product-id com.example.monthly
```
| Flag | Requerido | Descripción |
|---|---|---|
| `--app` | Sí | ID de la app (UUID) |
| `--title` | Sí | Título del producto |
| `--access-level-id` | Sí | ID (UUID) del [nivel de acceso](access-level) que desbloquea este producto |
| `--period` | Sí | Período de suscripción: `weekly`, `monthly`, `two_months`, `trimonthly`, `semiannual`, `annual`, `lifetime` |
| `--ios-product-id` | Al menos un store requerido | ID del producto en App Store Connect |
| `--android-product-id` | Al menos un store requerido | ID del producto en Google Play Console |
| `--android-base-plan-id` | Requerido con `--android-product-id` salvo que se use `--period lifetime` | ID del plan base en Google Play Console |
| `--stripe-product-id` | Al menos un store requerido | ID del producto en Stripe |
| `--stripe-price-id` | Requerido con `--stripe-product-id` | ID del precio en Stripe |
| `--paddle-product-id` | Al menos un store requerido | ID del producto en Paddle |
| `--paddle-price-id` | Requerido con `--paddle-product-id` | ID del precio en Paddle |
Cada producto necesita al menos un store: `--ios-product-id`, `--android-product-id`, `--stripe-product-id`, o `--paddle-product-id`. Un mismo producto puede llevar IDs de varios stores a la vez.
Para vender un producto en la web a través de Stripe o Paddle, primero conecta el proveedor de pago con Adapty: consulta [Stripe](stripe) y [Paddle](paddle). Para cada uno de estos stores, pasa el ID del producto y el ID del precio juntos. El comando falla si solo pasas uno de los dos.
```bash
adapty products create --app --title "Monthly" --access-level-id --period monthly --stripe-product-id prod_xxx --stripe-price-id price_xxx
```
Un producto solo para web es válido: puedes crear un producto con IDs de Stripe o Paddle sin IDs de App Store o Google Play.
### adapty products update
Actualiza un [producto](product) existente.
Los IDs de producto y precio del store no se pueden cambiar después de la creación y no están disponibles en este comando. Para usar IDs de store diferentes, crea un nuevo producto.
```bash
adapty products update --app --title "Monthly" --access-level-id
```
| Argumento | Descripción |
|---|---|
| `product-id` | ID del producto (UUID) |
| Indicador | Obligatorio | Descripción |
|---|---|---|
| `--app` | Sí | ID de la app (UUID) |
| `--title` | No | Título del producto |
| `--access-level-id` | No | ID (UUID) del [nivel de acceso](access-level) que desbloquea este producto |
## Ofertas de producto \{#product-offers\}
Vincula las ofertas que creaste en App Store Connect o Google Play Console con un producto de Adapty para que Adapty pueda aplicarlas. Para saber qué hace cada tipo de oferta y cómo crearla en el store, consulta [Añadir ofertas a Adapty](create-offer).
Añade estas ofertas:
- Ofertas promocionales y de recuperación de App Store.
- Todas las ofertas de Google Play, incluidas las pruebas gratuitas. Google Play no tiene un tipo de oferta introductoria, por lo que una prueba es una oferta sobre un plan base y solo se aplica después de vincularla en Adapty.
No añadas ofertas introductorias de App Store: se aplican automáticamente a los usuarios que cumplan los requisitos.
Una oferta vinculada aún tiene que seleccionarse para el producto en un flow o un paywall antes de que los usuarios la vean. Para seleccionarla en un paywall, usa el Adapty Dashboard: consulta [Mostrar oferta](create-offer#2-display-offer).
`adapty products list` y `adapty products get` muestran cuántas ofertas están vinculadas a cada producto en `offers_count`. El recuento incluye solo las ofertas vinculadas en Adapty, no las que existen en los stores.
### adapty product-offers list
Lista todas las ofertas vinculadas a un [producto](product).
```bash
adapty product-offers list --app --product
```
| Flag | Obligatorio | Descripción |
|---|---|---|
| `--app` | Sí | ID de la app (UUID) |
| `--product` | Sí | ID del producto (UUID) |
Devuelve todas las ofertas en una sola página y no acepta [flags de paginación](developer-cli-reference#global-flags).
### adapty product-offers get
Obtén los detalles de una oferta específica.
```bash
adapty product-offers get --app
```
| Argumento | Descripción |
|---|---|
| `offer-id` | ID de la oferta (UUID) |
| Flag | Obligatorio | Descripción |
|---|---|---|
| `--app` | Sí | ID de la app (UUID) |
### adapty product-offers create
Vincula una oferta de store a un [producto](product).
```bash
adapty product-offers create --app --product --title "Spring" --type promotional --ios-offer-id spring_ios --android-offer-id spring-android
```
| Flag | Obligatorio | Descripción |
|---|---|---|
| `--app` | Sí | ID de la app (UUID) |
| `--product` | Sí | ID del producto (UUID) |
| `--title` | Sí | Nombre de la oferta, visible solo en el Adapty Dashboard |
| `--type` | Sí | Tipo de oferta: `promotional` o `win_back` |
| `--ios-offer-id` | Al menos un store obligatorio | ID de oferta de App Store Connect |
| `--android-offer-id` | Al menos un store obligatorio | ID de oferta de Google Play Console |
Las ofertas de recuperación son exclusivas de App Store, por lo que `--type win_back` solo acepta `--ios-offer-id`. Para cualquier oferta de Google Play, incluida la prueba gratuita, usa `--type promotional`.
```bash
adapty product-offers create --app --product --title "Come back" --type win_back --ios-offer-id winback_ios
```
### adapty product-offers update
Actualiza una oferta existente.
```bash
adapty product-offers update --app --title "Spring 2"
```
| Argument | Description |
|---|---|
| `offer-id` | ID de la oferta (UUID) |
| Indicador | Obligatorio | Descripción |
|---|---|---|
| `--app` | Sí | ID de la app (UUID) |
| `--title` | No | Nombre de la oferta |
| `--type` | No | Tipo de oferta: `promotional` o `win_back`. Para cambiar una oferta a `win_back`, elimina también su parte de Google Play con `--clear-android-offer-id` |
| `--ios-offer-id` | No | Nuevo ID de oferta de App Store |
| `--android-offer-id` | No | Nuevo ID de oferta de Google Play |
| `--clear-ios-offer-id` | No | Elimina la parte de App Store de la oferta |
| `--clear-android-offer-id` | No | Elimina la parte de Google Play de la oferta |
Se requiere al menos una opción además de `--app`. Los campos que omitas conservan sus valores actuales. Cada oferta mantiene al menos un ID de oferta de store, por lo que el comando falla si intenta eliminar el último.
:::warning
El comando lee la oferta y la guarda completa. Si alguien edita la misma oferta en el Adapty Dashboard entre esa lectura y el guardado, su cambio se sobreescribe.
:::
Las ofertas introductorias no se pueden actualizar. Una oferta que tenga un store distinto de App Store o Google Play tampoco se puede actualizar desde la CLI: edítala en el Adapty Dashboard.
Para eliminar una oferta, utiliza el Adapty Dashboard. La CLI no tiene comando de eliminación.
## ¿Qué sigue? \{#whats-next\}
- [Referencia de comandos](developer-cli-reference) — todos los temas de la CLI, los flags globales y los flags de paginación.
---
# File: developer-cli-paywalls
---
---
title: "Comandos de paywalls"
description: "Comandos de la CLI de Adapty para listar, leer, crear y actualizar paywalls, y listar los placements que muestran un paywall."
---
Estos comandos de la CLI de Adapty gestionan los [paywalls](paywalls) y los productos que vende cada paywall.
## adapty paywalls list
Lista todos los [paywalls](paywalls) de una app.
```bash
adapty paywalls list --app
```
| Flag | Obligatorio | Descripción |
|---|---|---|
| `--app` | Sí | ID de la app (UUID) |
Acepta [flags de paginación](developer-cli-reference#global-flags).
## adapty paywalls get
Obtén los detalles de un [paywall](paywalls) específico.
```bash
adapty paywalls get --app
```
| Argumento | Descripción |
|---|---|
| `paywall-id` | ID del paywall (UUID) |
| Flag | Obligatorio | Descripción |
|---|---|---|
| `--app` | Sí | ID de la app (UUID) |
## adapty paywalls create
Crea un nuevo [paywall](paywalls).
```bash
adapty paywalls create --app --title "Default Paywall" --product-id
```
| Flag | Obligatorio | Descripción |
|---|---|---|
| `--app` | Sí | ID de la app (UUID) |
| `--title` | Sí | Título del paywall |
| `--product-id` | Sí | ID del [producto](product) (UUID). Repite para varios productos: `--product-id --product-id ` |
## adapty paywalls update
Reemplaza todos los campos de un [paywall](paywalls) existente.
:::important
Una vez que un paywall está vinculado a un placement, sus productos no pueden modificarse. Para usar productos distintos en un paywall activo, crea un nuevo paywall y actualiza el placement para que apunte a él.
:::
```bash
adapty paywalls update --app --title "Default Paywall" --product-id
```
Este comando reemplaza todos los campos del paywall, incluida la lista completa de productos.
| Argumento | Descripción |
|---|---|
| `paywall-id` | ID del paywall (UUID) |
| Flag | Required | Description |
|---|---|---|
| `--app` | Yes | ID de la app (UUID) |
| `--title` | Yes | Título del paywall |
| `--product-id` | Yes | ID del [producto](product) (UUID). Repite para varios productos: `--product-id --product-id ` |
## adapty paywalls placements
Lista todos los [placements](placements) que actualmente usan un [paywall](paywalls) determinado.
```bash
adapty paywalls placements --app
```
| Argumento | Descripción |
|---|---|
| `paywall-id` | ID del paywall (UUID) |
| Flag | Requerido | Descripción |
|---|---|---|
| `--app` | Sí | ID de la app (UUID) |
Usa este comando antes de intercambiar un paywall para ver qué placements se verían afectados.
Los elementos de esta lista no incluyen el campo `is_active`. Para consultar el estado de activación de un placement, usa [`placements list`](developer-cli-placements#adapty-placements-list) o [`placements get`](developer-cli-placements#adapty-placements-get).
## ¿Qué sigue? \{#whats-next\}
- [Referencia de comandos](developer-cli-reference) — todos los temas del CLI, los flags globales y los flags de paginación.
---
# File: developer-cli-flows
---
---
title: "Comandos de flows"
description: "Comandos de la CLI de Adapty para crear flows, leer y escribir sus configuraciones del builder, validarlos y previsualizarlos, subir archivos multimedia, publicarlos y leer sus métricas."
---
Los [flows](adapty-flow-builder) son los paywalls y onboardings que construyes en el Flow & Paywall Builder. El CLI gestiona el registro del flow, su configuración del builder y la publicación. Una configuración del builder es un documento JSON extenso que normalmente genera el Flow & Paywall Builder; el CLI no la genera por sí solo. Para crear o editar una configuración desde la terminal, usa el [skill flow-generator](flow-generator-skill), que ejecuta estos comandos por ti. Antes de publicar, el [skill flow-audit](flow-audit-skill) comprueba si el flow está listo para producción. Los comandos `flows metrics` leen los datos de la página de [métricas de flows](flow-metrics) y requieren la versión 0.15.0 o posterior del CLI. Los comandos se incluyen aquí como referencia.
## adapty flows list \{#adapty-flows-list\}
Lista todos los flows de una aplicación.
```bash
adapty flows list --app
```
| Flag | Required | Description |
|---|---|---|
| `--app` | Yes | App ID (UUID) |
Acepta [flags de paginación](developer-cli-reference#global-flags).
## adapty flows get
Obtén los detalles de un flow específico.
```bash
adapty flows get --app
```
| Argument | Description |
|---|---|
| `flow-id` | Flow ID (UUID) |
| Flag | Required | Description |
|---|---|---|
| `--app` | Yes | App ID (UUID) |
La respuesta contiene `id`, `name`, `status` y `updated_at`. El status es uno de los siguientes:
| Estado | Significado |
|---|---|
| `draft` | El flow nunca ha sido publicado |
| `published` | La versión actual está activa |
| `dirty` | El flow fue publicado anteriormente y la versión actual tiene cambios sin publicar. Los usuarios siguen viendo la última versión publicada |
| `publishing` | La publicación está en curso |
| `publication_failed` | La última publicación falló. Corrige la configuración y vuelve a publicar |
| `archived` | El flow está archivado |
## adapty flows create
Crea un flow. El nuevo flow tiene un nombre y sin configuración. Para añadir una configuración, usa [`flows config update`](#adapty-flows-config-update).
```bash
adapty flows create --app --name "Onboarding"
```
| Flag | Obligatorio | Descripción |
|---|---|---|
| `--app` | Sí | ID de la app (UUID) |
| `--name` | Sí | Nombre del flow |
## adapty flows update
Renombra un flow.
```bash
adapty flows update --app --name "Onboarding v2"
```
| Argument | Description |
|---|---|
| `flow-id` | ID del flow (UUID) |
| Flag | Required | Description |
|---|---|---|
| `--app` | Yes | ID de la app (UUID) |
| `--name` | Yes | Nuevo nombre del flow |
## adapty flows publish
Publica la versión actual de un flow para tus usuarios.
```bash
adapty flows publish --app
```
| Argumento | Descripción |
|---|---|
| `flow-id` | ID del flow (UUID) |
| Flag | Obligatorio | Descripción |
|---|---|---|
| `--app` | Sí | ID de la app (UUID) |
| `--yes`, `-y` | No | Publica sin pedir confirmación. Obligatorio cuando la salida se redirige o se usa `--json` |
Dado que publicar cambia lo que ven tus usuarios, el comando muestra el nombre del flow y pide confirmación. Cualquier respuesta distinta de `y` cancela el comando con código de salida 1. Con `--json` o en una tubería, el comando rechaza con código de salida 2 en lugar de esperar una respuesta, así que usa `--yes` en scripts y sesiones de agentes.
La publicación es asíncrona: la respuesta devuelve `status: publishing` y el flow aún no está activo. Consulta [`flows get`](#adapty-flows-get) hasta que el estado pase a `published` o `publication_failed`. Si ocurre `publication_failed`, [`flows config get`](#adapty-flows-config-get) indica el motivo.
La publicación falla con HTTP 400 cuando el flow no tiene configuración, cuando la configuración no es publicable o cuando la versión actual ya está activa. Para validar una configuración antes de publicarla, usa [`flows config validate`](#adapty-flows-config-validate).
## adapty flows config get
Lee la configuración del builder de un flow.
```bash
adapty flows config get --app
```
| Argument | Description |
|---|---|
| `flow-id` | Flow ID (UUID) |
| Flag | Required | Description |
|---|---|---|
| `--app` | Yes | App ID (UUID) |
La respuesta contiene `config`, `remote_configs`, `status` y `updated_at`. `updated_at` es una marca de tiempo en milisegundos del último cambio de configuración. Pásala a [`flows config update`](#adapty-flows-config-update) como `--expected-updated-at` para evitar sobreescribir una edición concurrente. Un flow cuya configuración nunca se ha escrito devuelve 404.
Tras un intento de publicación, la respuesta también incluye tres campos que describen cómo fue. Léelos cuando [`flows get`](#adapty-flows-get) indique `publication_failed`:
| Campo | Descripción |
|---|---|
| `publication_status` | El estado de publicación de esta versión del flow: `transforming`, `transformed`, `uploading`, `uploaded`, `published` o `failed` |
| `transform_error` | El error de transformación sin procesar: puede ser un payload JSON con los problemas o una cadena de resumen |
| `publication_error` | Un mensaje legible para una publicación fallida |
## adapty flows config update
Escribe la configuración del builder de un flow.
```bash
adapty flows config update --app --config-file config.json
```
| Argument | Description |
|---|---|
| `flow-id` | ID del flow (UUID) |
| Indicador | Requerido | Descripción |
|---|---|---|
| `--app` | Sí | ID de la app (UUID) |
| `--config` | Uno de los dos | Configuración del Builder como cadena JSON |
| `--config-file` | Uno de los dos | Ruta a un archivo JSON con la configuración del Builder, o `-` para leer desde stdin |
| `--remote-configs` | No | Array JSON de entradas `{locale, data}`, donde `data` es el Remote Config como cadena |
| `--expected-updated-at` | No | El valor `updated_at` de un `flows config get` anterior. Si la configuración cambió después de esa lectura, el comando falla en lugar de sobrescribir el cambio. Omítelo para sobrescribir sin condiciones |
Al escribir la configuración se guarda un borrador sin publicarlo. En un flow publicado, la escritura crea una nueva versión: el estado del flow pasa a `dirty`, y los usuarios siguen viendo la versión publicada hasta que ejecutes [`flows publish`](#adapty-flows-publish).
## adapty flows config validate
Comprueba si una configuración del builder es publicable, sin guardarla.
```bash
adapty flows config validate --app --config-file config.json
```
| Argumento | Descripción |
|---|---|
| `flow-id` | ID del flow (UUID) |
| Flag | Requerido | Descripción |
|---|---|---|
| `--app` | Sí | ID de la app (UUID) |
| `--config` | Una de las dos | Configuración del builder como cadena JSON |
| `--config-file` | Una de las dos | Ruta a un archivo JSON con la configuración del builder, o `-` para leer desde stdin |
La respuesta contiene `valid` y una lista de `issues`. Cuando la configuración no es publicable, el comando termina con el código 1, por lo que los scripts pueden usarlo como condición de bloqueo.
## adapty flows config preview
Renderiza un archivo de configuración local en el navegador. Este comando no realiza ninguna llamada a la API y no acepta el flag `--app`.
```bash
adapty flows config preview ./config.json --screen --device iphone-14 --orientation portrait
```
| Argumento | Descripción |
|---|---|
| `config-file` | Ruta a un archivo JSON de configuración del builder local |
| Flag | Por defecto | Descripción |
|---|---|---|
| `--screen` | La primera pantalla del flow | ID de pantalla a renderizar |
| `--device` | `iphone-14` | Marco de dispositivo en el que renderizar |
| `--orientation` | `portrait` | `portrait` o `landscape` |
En la terminal, el comando abre la vista previa en tu navegador. Cuando se usa con pipes o con `--json`, imprime la URL en su lugar. La URL contiene toda la configuración y es larga: pásala por un pipe a una herramienta de capturas de pantalla en lugar de imprimirla. Las configuraciones de más de 32 KB aproximadamente se renderizan lentamente.
## adapty flows media upload
Sube una imagen para usarla en la configuración de un flow.
```bash
adapty flows media upload --app ./hero.png
```
| Argumento | Descripción |
|---|---|
| `file` | Ruta al archivo de imagen |
| Flag | Obligatorio | Descripción |
|---|---|---|
| `--app` | Sí | ID de la app (UUID) |
Formatos aceptados: GIF, HEIC, JPEG, PNG, SVG y WebP. La respuesta contiene el `id`, el `name` y la `url` del CDN de la imagen para referenciarla desde la configuración.
## adapty flows metrics list \{#adapty-flows-metrics-list\}
Muestra las métricas de por vida de varios flows, una línea por cada flow. Estos son los datos de la tabla de flows en el dashboard.
```bash
adapty flows metrics list --app --ids ,
```
| Flag | Obligatorio | Descripción |
|---|---|---|
| `--app` | Sí | ID de la app (UUID) |
| `--ids` | Sí | IDs de los flows (UUIDs). Sepáralos con comas o repite el flag |
| `--csv` | No | Imprime CSV: una fila por cada flow, con el ID del flow y las 27 métricas. No se puede usar con `--json` |
Cada línea muestra el ID del flow con sus visualizaciones, compras, pruebas y revenue. `--json` y `--csv` incluyen las 27 métricas de la página de [métricas de flow](flow-metrics#metrics-definitions), como `unique_profiles_views`, `net_revenue` y `conversion_rate_purchases`. Una métrica sin datos es `0`, nunca `null`.
## Valores de métricas de flows de Adapty \{#adapty-flows-metrics-values\}
Lista las claves y valores de filtro de un flow: lo que acepta [`flows metrics get --filter`](#filter-the-metrics).
```bash
adapty flows metrics values --app
```
| Argumento | Descripción |
|---|---|
| `flow-id` | ID del flow (UUID) |
| Flag | Requerido | Descripción |
|---|---|---|
| `--app` | Sí | ID de la app (UUID) |
Cada línea muestra una etiqueta y, entre paréntesis, el valor a pasar. Los valores están anidados tal como los filtros del dashboard los anidan:
```text
Country (country)
Americas (Americas)
United States (US)
Europe (Europe)
Germany (DE)
Store (store)
App Store (app_store)
Google Play (play_store)
```
El valor superior de cada grupo es la clave del filtro, y los valores más internos son los que acepta esa clave. En el ejemplo, `--filter country=US` mantiene Estados Unidos, y `--filter store=play_store` mantiene Google Play.
## adapty flows metrics get \{#adapty-flows-metrics-get\}
Muestra las métricas de un flow para un período, como el árbol de la página de [métricas de flow](flow-metrics).
```bash
adapty flows metrics get --app --date-from 2026-09-01 --date-to 2026-10-21 --date-type purchase_date --based-on placement
```
| Argumento | Descripción |
|---|---|
| `flow-id` | ID del flow (UUID) |
| Flag | Requerido | Descripción |
|---|---|---|
| `--app` | Sí | ID de la app (UUID) |
| `--based-on` | Sí | Por qué se divide el primer nivel del árbol: `placement` o `audience`. Corresponden a las vistas basadas en placement y en audiencia de la página de [métricas de flow](flow-metrics#view-options-for-metrics-data) |
| `--date-type` | Sí | A qué fecha se aplica el período: `purchase_date` o `profile_install_date` para [filtrar por fecha de instalación](flow-metrics#filter-metrics-by-install-date) |
| `--date-from` | No | Primer día del período, inclusive (`YYYY-MM-DD`). Úsalo junto con `--date-to` |
| `--date-to` | No | Último día del período, inclusive (`YYYY-MM-DD`). Úsalo junto con `--date-from` |
| `--granularity` | No | Divide el período en puntos: `day`, `week`, `month`, `quarter` o `year` |
| `--filter` | No | Muestra solo los datos con estos valores de una clave de filtro. Se puede repetir. Ver [Filtrar las métricas](#filter-the-metrics) |
| `--timezone` | No | Zona horaria IANA de los puntos del período, por ejemplo `Europe/Berlin`. Sin este parámetro, Adapty usa la zona horaria de la app |
| `--depth` | No | Cuántos niveles del árbol se muestran bajo `Total`. Por defecto: `1` |
| `--csv` | No | Imprime CSV: una fila por cada nodo del árbol completo. No se puede usar con `--json` |
El CLI termina con código 2 y no envía ninguna solicitud cuando falta `--based-on` o `--date-type`, o cuando solo se proporciona un extremo del período. Adapty valida los valores de `--based-on`, `--date-type` y `--granularity`: un valor incorrecto termina con código 4, y el error lista los valores aceptados.
### Lee el resultado \{#read-the-output\}
El comando imprime una línea `Total` y, a continuación, el primer nivel del árbol. Cada línea muestra vistas, compras, trials y revenue. Con `--granularity`, los puntos del período aparecen justo debajo de su nodo:
```text
Total views 19 purchases 7 trials 4 revenue 241.93
Onboarding views 10 purchases 7 trials 0 revenue 241.93
2026-09-01 views 0 purchases 0 trials 0 revenue 0.00
2026-10-01 views 10 purchases 0 trials 0 revenue 241.93
Settings views 0 purchases 0 trials 0 revenue 0.00
```
Los niveles del árbol son los niveles del dashboard: placement, audiencia, prueba A/B, variante de flow, pantalla y producto. Con `--based-on audience`, el nivel de placement se omite. Para mostrar más niveles, usa `--depth`, por ejemplo `--depth 3`.
Para el árbol completo con las 27 métricas, utiliza uno de estos flags:
- `--json` imprime la respuesta del servidor sin modificaciones.
- `--csv` imprime una fila por cada nodo, incluidos los puntos de período. Las columnas son `path` (los títulos desde `Total` hasta el nodo, separados por ` > `), `level`, `title` y luego las métricas.
### Filtrar las métricas \{#filter-the-metrics\}
Escribe cada `--filter` como `key=value`, con las claves y valores que lista [`flows metrics values`](#adapty-flows-metrics-values). Para conservar varios valores a la vez, sepáralos con comas o repite el flag con la misma clave. Los filtros con claves distintas se combinan, por lo que los datos deben cumplir todos ellos:
```bash
adapty flows metrics get --app --date-from 2026-09-01 --date-to 2026-10-21 \
--date-type purchase_date --based-on placement --filter country=US,DE --filter store=app_store
```
La CLI envía cada valor exactamente como está escrito. Para incluir una coma dentro de un valor, escribe `\,`. Un valor vacío también es un valor: `attribution_channel=` conserva los datos sin canal, que `flows metrics values` muestra como **No Data**.
## ¿Qué viene ahora? \{#whats-next\}
- [Referencia de comandos](developer-cli-reference) — todos los temas de la CLI, los flags globales y los flags de paginación.
---
# File: developer-cli-placements
---
---
title: "Comandos de placements y segmentos"
description: "Comandos de la CLI de Adapty que crean y actualizan placements y sus audiencias, leen las métricas de los placements de flow y crean los segmentos a los que se dirigen esas audiencias."
---
Estos comandos de la CLI de Adapty gestionan los [placements](placements), las audiencias en ellos y los [segmentos](segments) a los que se dirigen esas audiencias.
## Placements \{#placements\}
Los [placements](placements) son los puntos donde tus flows, paywalls y onboardings llegan a los usuarios. El tipo de contenido de un placement se fija en el momento de su creación, por lo que migrar una app de paywalls a flows implica crear nuevos placements en lugar de actualizar los existentes — el [skill migrate-placements](migrate-placements-skill) ejecuta estos comandos en bloque.
### Lista de placements de Adapty \{#adapty-placements-list\}
Lista todos los [placements](placements) de una aplicación.
```bash
adapty placements list --app
```
| Flag | Requerido | Descripción |
|---|---|---|
| `--app` | Sí | ID de la app (UUID) |
| `--type` | No | Lista solo los placements de este tipo: `paywall`, `flow` u `onboarding` |
Acepta [flags de paginación](developer-cli-reference#global-flags).
Cada elemento contiene `id`, `developer_id`, `title`, `is_active` y `type`. `is_active` es `true` para un placement activo y `false` para uno inactivo. `type` es el tipo de contenido del placement: `paywall`, `flow` u `onboarding`. En `--json`, un placement sin tipo tiene `type: null`. El flag `--type` y el campo `type` requieren la versión 0.15.0 o posterior de la CLI.
### adapty placements get
Obtén los detalles de un [placement](placements) específico.
```bash
adapty placements get --app
```
| Argumento | Descripción |
|---|---|
| `placement-id` | ID del placement (UUID) |
| Flag | Obligatorio | Descripción |
|---|---|---|
| `--app` | Sí | ID de la app (UUID) |
La respuesta contiene `id`, `developer_id`, `title`, `is_active`, `type` y un array `audiences`. `is_active` es `true` para un placement activo y `false` para uno inactivo. Cada entrada de audiencia incluye `content_type`, `segment_ids`, `priority` y el ID de su contenido: `paywall_id` para `paywall`, `flow_id` para `flow`, o `ab_test_id` y `ab_test_title` para una audiencia que ejecuta una [prueba A/B](ab-tests). La audiencia predeterminada tiene `segment_ids: []` y el valor de prioridad más alto (la última en evaluarse). Consulta [Formato de audiencias](#audiences-shape).
### adapty placements create
Crea un nuevo [placement](placements).
```bash
adapty placements create --app --title "Main" --developer-id "main" --audiences '[{"content_type":"paywall","segment_ids":[],"paywall_id":"","priority":0}]'
```
| Indicador | Obligatorio | Descripción |
|---|---|---|
| `--app` | Sí | ID de la app (UUID) |
| `--title` | Sí | Título del placement |
| `--developer-id` | Sí | Identificador de cadena usado en el código de la app para solicitar este [placement](placements) |
| `--audiences` | Uno de los dos | Array JSON de entradas de audiencia, cada una con un `content_type` explícito. Ver [Formato de audiencias](#audiences-shape) |
| `--paywall-id` | Uno de los dos | **Obsoleto.** ID del [paywall](paywalls) (UUID). Se envuelve en el lado del cliente en una única audiencia predeterminada |
Pasa exactamente uno de `--audiences` o `--paywall-id`. Pasar ambos o ninguno devuelve un error.
:::warning
`--paywall-id` está en desuso y será eliminado. Al utilizarlo, la CLI muestra una advertencia en stderr y convierte el valor en una audiencia predeterminada. Usa `--audiences` para nueva automatización.
:::
### adapty placements update
Reemplaza todos los campos de un [placement](placements) existente.
```bash
adapty placements update --app --title "Main" --developer-id "main" --audiences '[{"content_type":"paywall","segment_ids":[],"paywall_id":"","priority":0}]'
```
Este comando reemplaza todos los campos del placement, incluida la lista completa de audiencias.
| Argumento | Descripción |
|---|---|
| `placement-id` | ID del placement (UUID) |
| Flag | Obligatorio | Descripción |
|---|---|---|
| `--app` | Sí | ID de la app (UUID) |
| `--title` | Sí | Título del placement |
| `--developer-id` | Sí | Identificador de cadena utilizado en el código de la app para solicitar este [placement](placements) |
| `--audiences` | Uno de los dos | Array JSON de entradas de audiencia, cada una con un `content_type` explícito. Ver [Forma de audiencias](#audiences-shape) |
| `--paywall-id` | Uno de los dos | **Obsoleto.** ID del [paywall](paywalls) (UUID). Reemplaza todas las audiencias con una única audiencia predeterminada |
:::warning
Pasar `--paywall-id` reescribe todas las audiencias del placement. Las audiencias específicas de segmento se eliminan. Para conservarlas, usa `--audiences` e incluye todas las entradas que quieras mantener.
:::
#### Estructura de audiences \{#audiences-shape\}
El flag `--audiences` acepta un array JSON. Cada entrada tiene:
| Campo | Tipo | Descripción |
|---|---|---|
| `content_type` | `string` | Obligatorio en cada entrada. `"paywall"`, `"flow"`, `"ab_test"` (prueba A/B de paywall), `"flow_ab_test"` (prueba A/B de flow), `"cross_ab_test"` o `"flow_cross_ab_test"` (prueba A/B de placement cruzado). Usa `paywall`, `ab_test` y `cross_ab_test` en un placement de paywall, y `flow`, `flow_ab_test` y `flow_cross_ab_test` en un placement de flow |
| `segment_ids` | `string[]` | IDs de [segmento](segments) a los que se dirige esta audiencia. Longitud 0 o 1. Un array vacío indica la **audiencia predeterminada** — el fallback para usuarios que no coinciden con ningún otro segmento |
| `paywall_id` | `string` | ID (UUID) del [paywall](paywalls) que se muestra a los usuarios de esta audiencia. Obligatorio cuando `content_type` es `"paywall"` |
| `flow_id` | `string` | ID (UUID) del [flow](adapty-flow-builder) que se muestra a los usuarios de esta audiencia. Obligatorio cuando `content_type` es `"flow"` |
| `ab_test_id` | `string` | ID de la [prueba A/B](ab-tests) que se ejecuta para los usuarios de esta audiencia. Obligatorio en los cuatro tipos de contenido de prueba A/B |
| `ab_test_title` | `string` | Título de la prueba A/B. Solo lectura: la API lo ignora al escribir |
| `priority` | `number` | Basado en 0, único dentro del placement. Las audiencias se evalúan de menor a mayor; la audiencia predeterminada debe tener el valor más alto |
Un placement debe tener exactamente una audiencia predeterminada.
:::warning
`placements update` reemplaza la lista completa de audiencias, incluidas las que tienen una prueba A/B en curso. Para mantener una prueba activa, copia su entrada desde `placements get` a `--audiences` sin modificarla, con el mismo `ab_test_id` y los mismos `segment_ids`. Una escritura que elimine o reemplace esa entrada detiene la prueba sin ganador. Una escritura que mueva la entrada a otros segmentos reinicia la prueba, y un `ab_test_id` en otra audiencia la inicia allí. Una escritura que solo cambie las prioridades mantiene la prueba en curso. La CLI no avisa sobre ninguno de estos casos.
:::
Las entradas de prueba A/B entre placements (`cross_ab_test`, `flow_cross_ab_test`) son de solo lectura. La API las ignora al escribir y conserva las almacenadas.
El tipo de contenido de un placement se fija al crearlo, por lo que `placements update` no puede cambiar un placement de paywall a un flow ni viceversa. Sirve el flow desde un placement propio; consulta [Crear un nuevo placement para tu flow](migrate-to-flows#create-a-new-placement-for-your-flow).
El CLI verifica cada entrada antes de enviar la solicitud. Una entrada con un `content_type` faltante o desconocido, o sin el ID que su `content_type` requiere, termina con código 2 y no se envía nada. Para un `content_type` que no reconoce, el CLI imprime `this CLI does not know this audience kind; update the CLI`. Si la entrada proviene de `placements get`, actualiza el CLI en lugar de eliminar la entrada: puede ser una prueba A/B en ejecución.
Un flow solo puede vincularse después de haber sido publicado. El servidor rechaza un flow en estado `draft` o cuya primera publicación aún está en curso; el CLI reconoce ese rechazo y sale con el código 2, imprimiendo el comando `flows publish` para ese flow. Para publicar un flow, usa [`flows publish`](developer-cli-flows#adapty-flows-publish) o el [Flow & Paywall Builder](builder-save-publish) y espera a que su estado sea `published`.
Ejemplo con una audiencia específica y una predeterminada:
```bash
adapty placements update --app --title "Main" --developer-id "main" \
--audiences '[{"content_type":"paywall","segment_ids":[""],"paywall_id":"","priority":0},{"content_type":"paywall","segment_ids":[],"paywall_id":"","priority":1}]'
```
Ejemplo de un placement que sirve un flow publicado a todos los usuarios:
```bash
adapty placements create --app --title "Onboarding" --developer-id "onboarding" \
--audiences '[{"content_type":"flow","segment_ids":[],"flow_id":"","priority":0}]'
```
Para intercambiar un paywall en varios placements sin perder el enrutamiento específico por segmento:
1. Encuentra los placements afectados:
```bash
adapty paywalls placements --app
```
2. Para cada uno, lee el array completo de `audiences`:
```bash
adapty placements get --app --json
```
3. Reemplaza los valores `paywall_id` coincidentes en el cliente. Deja todas las demás entradas sin cambios, incluidas las entradas de pruebas A/B.
4. Escribe el payload modificado de nuevo:
```bash
adapty placements update --app --title "" --developer-id "" --audiences ''
```
### Lista de métricas de placements de adapty
Muestra las métricas de por vida de varios placements de flow, una línea por cada placement. Estos son los datos de la tabla de placements en el dashboard.
```bash
adapty placements metrics list --app --type flow --ids ,
```
| Indicador | Obligatorio | Descripción |
|---|---|---|
| `--app` | Sí | ID de la app (UUID) |
| `--type` | Sí | Tipo de placement, tal como lo muestra [`placements list`](#adapty-placements-list): `flow` |
| `--ids` | Sí | IDs de placements (UUIDs). Sepáralos con comas o repite el indicador |
| `--csv` | No | Imprime CSV: una fila por placement, con el ID del placement y las 27 métricas. No se puede usar con `--json` |
Los comandos `placements metrics` leen los números de la página de [métricas de placement](placement-metrics) para placements de flow, y requieren la versión 0.15.0 o posterior de la CLI. `--type` debe coincidir con el tipo de placement: Adapty rechaza un placement de otro tipo.
Cada línea muestra el ID del placement con sus visualizaciones, compras, pruebas e ingresos. `--json` y `--csv` incluyen las 27 métricas.
### adapty placements metrics values
Lista las claves y valores de filtro de un placement de tipo flow: lo que acepta `placements metrics get --filter`.
```bash
adapty placements metrics values --app --type flow
```
| Argumento | Descripción |
|---|---|
| `placement-id` | ID del placement (UUID) |
| Flag | Requerido | Descripción |
|---|---|---|
| `--app` | Sí | ID de la app (UUID) |
| `--type` | Sí | Tipo de placement: `flow` |
El resultado tiene la misma forma que [`flows metrics values`](developer-cli-flows#adapty-flows-metrics-values): el valor superior de cada grupo es la clave de filtro, y los valores más internos son lo que toma la clave.
### adapty placements metrics get
Muestra las métricas de un placement de flow como el árbol de la página de [métricas de placement](placement-metrics), para toda su vida útil o para un período.
```bash
adapty placements metrics get --app --type flow --based-on flow
```
| Argumento | Descripción |
|---|---|
| `placement-id` | ID del placement (UUID) |
| Flag | Obligatorio | Descripción |
|---|---|---|
| `--app` | Sí | ID de la app (UUID) |
| `--type` | Sí | Tipo de placement: `flow` |
| `--based-on` | Sí | Por qué divide el primer nivel del árbol: `audience`, `flow` o `placement` |
| `--group-by` | No | Divide cada audiencia por `country` o `store` |
| `--date-from` | No | Primer día del período, inclusive (`YYYY-MM-DD`). Pásalo junto con `--date-to` y `--date-type` |
| `--date-to` | No | Último día del período, inclusive (`YYYY-MM-DD`). Pásalo junto con `--date-from` y `--date-type` |
| `--date-type` | No | A qué fecha se aplica el período: `purchase_date` o `profile_install_date`. Pásalo junto con `--date-from` y `--date-to` |
| `--granularity` | No | Divide el período en puntos: `day`, `week`, `month`, `quarter` o `year` |
| `--filter` | No | Muestra solo los datos con estos valores de una clave de filtro. Repetible. Ver [Filtrar las métricas](developer-cli-flows#filter-the-metrics) |
| `--timezone` | No | Zona horaria IANA de los puntos del período, por ejemplo `Europe/Berlin`. Sin ella, Adapty usa la zona horaria de la app |
| `--depth` | No | Cuántos niveles del árbol se muestran bajo `Total`. Por defecto: `1` |
| `--csv` | No | Imprime CSV: una fila por cada nodo de todo el árbol. No se puede usar con `--json` |
Sin `--date-from`, `--date-to` y `--date-type`, el comando devuelve las métricas de por vida. Para un período, pasa los tres: un período sin `--date-type` termina con el código 4.
La salida, `--depth`, `--json`, `--csv` y `--filter` funcionan igual que en [`flows metrics get`](developer-cli-flows#read-the-output). Por ejemplo, para comparar las audiencias de un placement por store:
```bash
adapty placements metrics get --app --type flow --based-on audience --group-by store \
--date-from 2026-09-01 --date-to 2026-10-21 --date-type purchase_date --depth 2
```
## Segmentos \{#segments\}
Los [segmentos](segments) agrupan usuarios según los atributos de su perfil. Usa estos comandos para crear segmentos y buscar IDs de segmento al componer [audiencias de placement](#audiences-shape). Para crear un segmento a partir de campañas, grupos de anuncios o palabras clave de Apple Ads, usa [`adapty asa segments create`](developer-cli-ads-manager-reference#segments) en su lugar: busca automáticamente los IDs de Apple y asigna al segmento el nombre que usa Ads Manager.
### Lista de segmentos de Adapty \{#adapty-segments-list\}
Lista todos los [segmentos](segments) de una app.
```bash
adapty segments list --app
```
| Flag | Obligatorio | Descripción |
|---|---|---|
| `--app` | Sí | ID de la app (UUID) |
Acepta [flags de paginación](developer-cli-reference#global-flags).
### adapty segments get
Obtén los detalles de un [segmento](segments) específico.
```bash
adapty segments get --app
```
| Argumento | Descripción |
|---|---|
| `segment-id` | ID del segmento (UUID) |
| Flag | Obligatorio | Descripción |
|---|---|---|
| `--app` | Sí | ID de la app (UUID) |
La respuesta contiene `id`, `title`, `description`, `filters`, `profile_count`, `refresh_in_progress`, `created_at` y `updated_at`. `list` devuelve únicamente `id`, `title` y `description`.
### adapty segments create
Crea un [segmento](segments) a partir de uno o más filtros.
```bash
adapty segments create --app --title "US installs" --filter ip_country:IN:US --filter install_date:>=:2026-01-01
```
| Flag | Obligatorio | Descripción |
|---|---|---|
| `--app` | Sí | ID de la app (UUID) |
| `--title` | Sí | Título del segmento |
| `--filter` | Sí | Regla de filtro. Repetible. Ver [Sintaxis de filtros](#filter-syntax) |
| `--description` | No | Descripción del segmento |
Un usuario pertenece al segmento solo cuando cumple todos los filtros. La respuesta tiene los mismos campos que `segments get`. `profile_count` empieza en `0`, y Adapty lo recalcula después de que se crea el segmento.
### adapty segments update
Reemplaza el título, la descripción y los filtros de un [segmento](segments) existente.
```bash
adapty segments update --app --title "US installs" --filter ip_country:IN:US,CA
```
| Argumento | Descripción |
|---|---|
| `segment-id` | ID del segmento (UUID) |
| Flag | Obligatorio | Descripción |
|---|---|---|
| `--app` | Sí | ID de la app (UUID) |
| `--title` | Sí | Título del segmento |
| `--filter` | Sí | Regla de filtro. Repetible. Ver [Sintaxis de filtros](#filter-syntax) |
| `--description` | No | Descripción del segmento |
:::warning
`segments update` reemplaza el segmento completo. Pasa todos los filtros que quieras conservar, no solo el que modificas. Para leer los filtros actuales, ejecuta `adapty segments get --app --json`.
:::
#### Sintaxis de filtros \{#filter-syntax\}
Escribe cada `--filter` como `field:OPERATOR:value`. Para coincidir con varios valores, sepáralos con comas: `ip_country:IN:US,CA`.
| Operador | Valores | Ejemplo |
|---|---|---|
| `IN`, `NOT IN` | Uno o más | `ip_country:NOT IN:US,CA` |
| `>`, `>=`, `<`, `<=` | Uno | `age:>:18` |
| `BETWEEN` | Dos | `total_revenue_usd:BETWEEN:10,100` |
| `IS NULL`, `IS NOT NULL` | Ninguno | `age:IS NULL` |
Pasa los números como valores simples, por ejemplo `age:>:18`. Adapty los convierte para campos numéricos como `age`, `total_revenue_usd` y atributos personalizados de tipo float.
Para un valor que esta forma abreviada no pueda expresar, pasa el filtro como un objeto JSON:
```bash
adapty segments create --app --title "Adults" --filter '{"field_name":"age","operator":">","value_list":[18]}'
```
Adapty valida los nombres de campo, los operadores y los tipos de valor, y reporta un error por cada filtro inválido. Para ver los nombres de campo y los formatos de valor de los filtros existentes, ejecuta `adapty segments get --app --json` en un segmento creado en el dashboard.
## ¿Qué sigue? \{#whats-next\}
- [Referencia de comandos](developer-cli-reference) — todos los temas de la CLI, los flags globales y los flags de paginación.
---
# File: developer-cli-analytics
---
---
title: "Consultar Analytics desde la CLI"
description: "Lee Adapty Analytics desde la terminal: gráficos como ingresos y MRR, conversiones, el embudo, retención, LTV y cohortes de instalación, en formato tabla, JSON o CSV."
---
El CLI de Adapty lee [Adapty Analytics](analytics) desde el terminal, bajo el tema `adapty analytics`. Devuelve los números que muestra el dashboard de Analytics para una app: [gráficos](charts) como ingresos y MRR, [conversiones](analytics-conversion), el [embudo](analytics-funnels), [retención](analytics-retention), [LTV](ltv) y [cohortes de instalación](analytics-cohorts).
Úsalo para dar a un agente de IA acceso en tiempo real a los números de tu app, para extraer un gráfico a un script o una hoja de cálculo, o para responder una pregunta puntual sin abrir el dashboard.
Cada comando `analytics` es de solo lectura y actúa sobre una sola app.
## Antes de empezar \{#before-you-start\}
El tema `analytics` usa la misma instalación e inicio de sesión que el resto de la CLI. Si aún no lo has configurado, sigue los pasos 1 y 2 de la [guía de inicio rápido](developer-cli-quickstart). El tema requiere la versión 0.10.0 o posterior de la CLI. Para ver tu versión, ejecuta `adapty --version`.
A diferencia de la [API de exportación de analytics](export-analytics-api), la CLI no necesita ninguna clave de API secreta. Con tu inicio de sesión en la CLI tienes acceso a todas las apps a las que tu usuario de Adapty puede acceder.
Todos los comandos reciben el UUID de la app en `--app`. Para encontrarlo, ejecuta:
```bash
adapty apps list
```
## Crea una consulta \{#build-a-query\}
Crea cada consulta en el mismo orden: busca los nombres en el catálogo, consulta los valores de los filtros y luego ejecuta un comando de datos.
1. **Muestra qué puede responder el análisis de la app**. El catálogo lista todos los gráficos con su unidad, cada conversión, las agrupaciones y filtros que acepta cada comando, y los valores aceptados y predeterminados de cada opción:
```bash
adapty analytics catalog --app
```
Los nombres de gráficos y conversiones, como `revenue`, `mrr` o `trial-paid`, provienen de esta lista. El CLI no mantiene su propia lista, por lo que un gráfico que Adapty añada más adelante funcionará sin necesidad de actualizar el CLI.
2. **Busca los valores de los filtros**. Omite este paso si no vas a filtrar. Por ejemplo, para listar los países por los que puedes filtrar:
```bash
adapty analytics values --app --dimension country
```
3. **Ejecuta el comando de datos**:
```bash
adapty analytics chart --app --chart revenue \
--date-from 2026-07-01 --date-to 2026-09-30 --group-by country
```
La respuesta tiene una fila para el total y luego una fila por cada grupo.
### Ejemplos
MRR de este trimestre, comparado con el trimestre anterior:
```bash
adapty analytics chart --app --chart mrr \
--date-from 2026-07-01 --date-to 2026-09-30 \
--compare-from 2026-04-01 --compare-to 2026-06-30
```
Conversión mensual de prueba a pago en dos países:
```bash
adapty analytics conversion --app --conversion trial-paid \
--date-from 2026-04-01 --date-to 2026-09-30 --granularity month --filter country=US,GB
```
Retención por país, contada desde la prueba:
```bash
adapty analytics retention --app --date-from 2026-07-01 --date-to 2026-09-30 \
--group-by country --use-trial
```
LTV a los 7, 30 y 90 días, sobre ingresos después de comisiones e impuestos, guardado como archivo CSV:
```bash
adapty analytics ltv --app --date-from 2026-07-01 --date-to 2026-09-30 \
--revenue-basis net --period-type days --renewal-days 7,30,90 --csv > ltv.csv
```
Cohortes de instalación semanales sobre ingresos después de la comisión del store:
```bash
adapty analytics cohort --app --date-from 2026-07-01 --date-to 2026-09-30 \
--granularity week --revenue-basis proceeds
```
## Elige el formato de salida \{#choose-the-output\}
Cada comando de datos se imprime en uno de tres formatos:
| Salida | Flag | Para qué usarla |
|---|---|---|
| Tabla | Ninguna | Lectura en la terminal. Cada tabla empieza con un encabezado que indica el gráfico, el período, la zona horaria y los filtros. Los importes tienen 2 decimales. Algunos campos se omiten, como los motivos de abandono del funnel y las predicciones de cohorte, y una línea debajo de la tabla lo indica. |
| JSON | `--json` | Scripts y agentes de IA. La respuesta de la API sin modificar, con todos los campos. |
| CSV | `--csv` | Hojas de cálculo. Una fila por grupo, con todos los campos de la respuesta. Un período comparado se incluye en las columnas `compare.*` de la misma fila. |
No puedes usar `--csv` y `--json` a la vez.
En JSON, el total es la primera entrada de `data.segments`, y `data.value` es el número para todo el período. `meta.query` muestra la consulta que se ejecutó, con todos los valores predeterminados completados y la zona horaria aplicada.
## Leer los resultados \{#read-the-results\}
- **Fechas**: `--date-from` y `--date-to` son días inclusivos en la [zona horaria de informes](general) de la app. Para leer los días en otra zona horaria, pasa un nombre IANA en `--timezone`, como `Europe/Berlin`. `meta.query.timezone` muestra la zona horaria en uso.
- **Ingresos**: `--revenue-basis` establece qué valores monetarios se usan: `gross` (el predeterminado), `proceeds` (tras la comisión del store) o `net` (tras la comisión e impuestos). Funciona con `ltv`, `cohort` y los gráficos que muestran dinero. El catálogo marca esos gráficos con `takes revenue_basis`.
- **Valores vacíos**: Un valor vacío significa que Adapty no tiene ningún valor, nunca cero. Un período de LTV que una cohorte aún no ha alcanzado está vacío, al igual que una cohorte que no se puede predecir. En la salida `--json` estos valores son `null`. La tabla imprime `—` y el CSV deja la celda vacía.
- **La fila de totales**: Encuentra el total mediante `is_total`, no por una `key` vacía. La `key` de un grupo también puede estar vacía, por ejemplo el grupo de usuarios sin país.
- **Claves de grupo**: La `key` de un grupo no siempre es un valor que `--filter` acepta. Para filtrar, toma los valores de `analytics values`.
- **Períodos comparados**: Solo `chart` y `conversion` aceptan `--compare-from` y `--compare-to`. El período comparado tiene su propio total y grupos, y la tabla lo imprime como una segunda tabla.
- **Números de atribución**: No sumes estos números a los números de [Atribución](developer-cli-attribution). Adapty los calcula de forma diferente.
El CLI devuelve los números del dashboard, con dos excepciones:
- `funnel` aplica el filtro `cancellation_reason`, que el funnel del dashboard ignora. Con ese filtro, ambos números pueden diferir.
- `retention` ofrece una lista de agrupaciones diferente a la del dashboard. Consulta la lista en el catálogo.
## Límites \{#limits\}
Cada comando de análisis acepta como máximo 2 solicitudes por segundo por aplicación y 360 solicitudes por minuto en total. El CLI nunca reintenta una solicitud. Si envías solicitudes demasiado rápido, el comando termina con el código 4. Con `--json`, el error incluye `retry_after_seconds`: espera ese tiempo y vuelve a ejecutar el comando.
## Errores \{#errors\}
Cada error sale con un código que indica qué debes corregir:
| Código de salida | Causa | Qué hacer |
|---|---|---|
| 2 | La CLI rechazó la entrada antes de enviarla: un UUID de app no válido, un rango de fechas mal formado o invertido, un período de comparación con un extremo faltante, `--renewal-days` sin `--period-type days`, un `--filter` sin `=`, o `--csv` con `--json`. | Corrige el flag que indica el mensaje. |
| 3 | No has iniciado sesión, o tu usuario de Adapty no tiene acceso a la app. | Inicia sesión con `adapty auth login`. Si ya has iniciado sesión, encuentra el ID de la app en `adapty apps list`, que solo muestra las apps a las que tienes acceso de lectura. |
| 4 | Adapty rechazó la solicitud: un gráfico, conversión, agrupación, filtro o zona horaria desconocidos; `--revenue-basis` en un gráfico que no muestra dinero; o demasiadas solicitudes. | Corrige el nombre desde `adapty analytics catalog`. Con `--json`, el error incluye el código de error de la API. Para el caso de demasiadas solicitudes, consulta [Límites](#limits). |
## Referencia de comandos \{#command-reference\}
Cada comando de datos acepta estos flags:
| Flag | Obligatorio | Descripción |
|---|---|---|
| `--app` | Sí | UUID de la app, obtenido con `adapty apps list`. |
| `--date-from` | Sí | Primer día del período, inclusive, en formato `YYYY-MM-DD`. |
| `--date-to` | Sí | Último día del período, inclusive. No puede ser anterior a `--date-from`. |
| `--filter` | No | `dimension=value[,value]`. Filtra los datos donde la dimensión tenga uno de los valores indicados. Repite el flag para filtrar por varias dimensiones. Usa `\,` para incluir una coma dentro de un valor. Un valor vacío es un valor válido: `country=` mantiene los datos sin país. |
| `--timezone` | No | Zona horaria IANA de los días, por ejemplo `Europe/Berlin`. Si se omite, se usa la zona horaria de la app. |
| `--csv` | No | Muestra una tabla CSV en lugar de la tabla legible. No puede usarse con `--json`. |
Cada comando añade sus propios flags a estos.
### `analytics catalog`
Lista lo que los análisis de la aplicación pueden responder: cada comando con sus opciones, agrupaciones y filtros; cada gráfico con su unidad; cada conversión; y cada dimensión de filtro.
| Flag | Obligatorio | Descripción |
|---|---|---|
| `--app` | Sí | UUID de la aplicación, obtenido con `adapty apps list`. |
### `analytics values`
Lista los valores que toma una dimensión de filtro para la app. Cada `value` es exactamente lo que acepta `--filter =`.
| Flag | Required | Description |
|---|---|---|
| `--app` | Yes | App UUID, from `adapty apps list`. |
| `--dimension` | Yes | A filter dimension from `adapty analytics catalog`. |
### `analytics chart`
Lee un [gráfico](charts): el número del período completo, sus puntos y sus grupos.
| Flag | Obligatorio | Descripción |
|---|---|---|
| `--chart` | Sí | Nombre de un gráfico de `adapty analytics catalog`, como `revenue` o `mrr`. |
| `--group-by` | No | Una agrupación de este gráfico, del catálogo. |
| `--granularity` | No | Duración de un punto: `day`, `week`, `month` (por defecto), `quarter` o `year`. |
| `--revenue-basis` | No | `gross` (por defecto), `proceeds` o `net`. Solo para gráficos que muestran dinero. |
| `--compare-from` | No | Primer día de un período con el que comparar. Requiere `--compare-to`. |
| `--compare-to` | No | Último día de un período con el que comparar. Requiere `--compare-from`. |
### `analytics conversion`
Lee una [conversión](analytics-conversion): la tasa en porcentaje, con los dos recuentos que la dividen, para cada punto y grupo.
| Indicador | Requerido | Descripción |
|---|---|---|
| `--conversion` | Sí | Nombre de una conversión de `adapty analytics catalog`, como `trial-paid` o `install-paid`. |
| `--group-by` | No | Una agrupación del catálogo. |
| `--granularity` | No | Duración de un punto: `day` (por defecto), `week`, `month`, `quarter` o `year`. |
| `--compare-from` | No | Primer día de un período con el que comparar. Requiere `--compare-to`. |
| `--compare-to` | No | Último día de un período con el que comparar. Requiere `--compare-from`. |
When the period has no conversions, `meta.recommended_period` in the `--json` output can name a period that has some.
### `analytics funnel`
Lee el [embudo](analytics-funnels): el recuento en cada paso desde la instalación hasta las renovaciones.
| Indicador | Obligatorio | Descripción |
|---|---|---|
| `--group-by` | No | Una agrupación del catálogo. |
### `analytics retention`
Lee la [retención](analytics-retention): los suscriptores que permanecen en cada período.
| Flag | Required | Description |
|---|---|---|
| `--group-by` | No | Una agrupación del catálogo. |
| `--use-trial` | No | Contar desde la prueba, no desde el primer período de pago. |
### `analytics ltv`
Lee el [LTV](ltv): los ingresos por usuario de pago después de cada renovación o día.
| Bandera | Requerido | Descripción |
|---|---|---|
| `--group-by` | No | Una agrupación del catálogo. |
| `--revenue-basis` | No | `gross` (por defecto), `proceeds` o `net`. |
| `--period-type` | No | `renewals` (por defecto) cuenta por renovación. `days` cuenta por día desde la instalación. |
| `--renewal-days` | No | Días a contar con `--period-type days`, separados por comas, en orden ascendente, como `7,30,90`. Solo con `--period-type days`. |
### `analytics cohort`
Lee [cohortes de instalación](analytics-cohorts): los ingresos, suscriptores, promedios y predicciones de cada cohorte por renovación o día. Cada cohorte es una fila, y su fecha de inicio es su `key`. Las cohortes no se pueden agrupar.
| Indicador | Requerido | Descripción |
|---|---|---|
| `--granularity` | No | Duración de una cohorte: `day`, `week`, `month` (por defecto), `quarter` o `year`. |
| `--revenue-basis` | No | `gross` (por defecto), `proceeds` o `net`. |
| `--period-type` | No | `renewals` (por defecto) cuenta por renovación. `days` cuenta por día desde la instalación. |
| `--renewal-days` | No | Días a contar con `--period-type days`, separados por comas, en orden ascendente. Solo con `--period-type days`. |
## Qué sigue \{#whats-next\}
- [Cómo funciona Adapty Analytics](how-adapty-analytics-works) — de dónde vienen los números.
- [Controles, filtros y agrupación](controls-filters-grouping-compare-proceeds) — qué significan los filtros y las opciones de ingresos en el dashboard.
- [Consultar atribución desde la CLI](developer-cli-attribution) — gasto, instalaciones y ROAS por canal y campaña.
---
# File: developer-cli-ab-tests
---
---
title: "Ejecutar pruebas A/B desde la CLI"
description: "Crea, inicia, detiene, reemplaza y archiva pruebas A/B de paywalls y flows desde el terminal con la CLI de Adapty, y visualiza el efecto exacto antes de cada paso que no se puede deshacer."
---
La CLI de Adapty ejecuta [pruebas A/B](ab-tests) de paywalls o flows directamente desde el terminal, bajo el tema `adapty ab-tests`. Puedes crear una prueba como borrador, iniciarla en un placement para una audiencia, detenerla con un ganador, reemplazar una prueba activa con una modificada y archivar las pruebas antiguas.
Úsalo para que un agente de IA ejecute tus pruebas, para crear un script de prueba en varias aplicaciones, o para iniciar o detener una prueba sin abrir el dashboard.
Una prueba regular divide los usuarios de una audiencia en un placement entre dos o más paywalls, o entre dos o más flows. Para ejecutar una prueba en varios placements, usa una [prueba crossplacement](ab-test-types) en el dashboard. Los comandos `ab-tests` no devuelven resultados de la prueba. Para ver los resultados, como la probabilidad de ser el mejor, usa el dashboard: [Resultados y métricas de pruebas A/B](results-and-metrics). Para leer el análisis de los usuarios de una prueba, filtra los [comandos de análisis](developer-cli-analytics) por la dimensión **A/B tests** de `adapty analytics catalog`.
## Antes de empezar \{#before-you-start\}
El tema `ab-tests` utiliza la misma instalación e inicio de sesión que el resto de la CLI. Si aún no lo has configurado, sigue los pasos 1 y 2 de la [guía de inicio rápido](developer-cli-quickstart). El tema requiere la versión 0.14.0 o posterior de la CLI. Para ver tu versión, ejecuta `adapty --version`.
Cada comando requiere el UUID de la app en `--app`. Para encontrarlo, ejecuta:
```bash
adapty apps list
```
Una prueba usa contenido que ya existe:
- **Flows**: Un flow se une a una prueba solo cuando está publicado. Un flow en borrador, o con cambios sin publicar, no es aceptado. Para publicar un flow, ejecuta `adapty flows publish`.
- **Paywalls**: Para crear un paywall con productos que ya están en Adapty, ejecuta `adapty paywalls create`. Para darle un nuevo diseño a un paywall, usa el [Paywall Builder](adapty-paywall-builder).
- **Placements**: Una prueba de paywall se ejecuta en un placement de paywall, y una prueba de flow en un placement de flow. Para crear un placement, ejecuta `adapty placements create`. Tu app no mostrará nada de un nuevo placement hasta que su código obtenga ese placement.
- **Segments**: Para ejecutar una prueba solo para algunos usuarios, crea primero un [segmento](segments) con `adapty segments create`.
For these commands, see the [command reference](developer-cli-reference).
## Listar y consultar pruebas \{#list-and-read-tests\}
`list` muestra pruebas A/B de flows a menos que pases `--type paywall`. Para ver todas las pruebas de una app, ejecútalo una vez por cada tipo:
```bash
adapty ab-tests list --app --type flow --page-size 100
```
```bash
adapty ab-tests list --app --type paywall --page-size 100
```
Una prueba puede estar en uno de estos estados: `draft`, `live`, `completed`, `inactive` o `archived`.
Para consultar una prueba concreta con sus variantes, ejecuta:
```bash
adapty ab-tests get --app
```
En `get --json`, `segment_ids` es la audiencia de la prueba: `[]` corresponde a Todos los usuarios y `null` significa que aún no se ha planificado ninguna audiencia. Cada variante tiene su `weight` y el ID del paywall o flow. Para identificar una variante, usa `paywall_title` o `flow_name`. El `title` de la variante está vacío a menos que lo hayas establecido.
## Crear una prueba \{#create-a-test\}
Una prueba nueva es un borrador. Ningún usuario ve un borrador, así que puedes crear uno y modificarlo en cualquier momento.
1. **Encuentra los IDs** del contenido que quieres probar, con `adapty paywalls list` o `adapty flows list`.
2. **Crea el borrador** con dos o más variantes. Cada variante es un paywall o flow con un peso. El peso es el porcentaje de usuarios que ven esa variante, y los pesos deben sumar 100:
```bash
adapty ab-tests create --app --title "Annual vs monthly" \
--goal "More revenue per user" --placement \
--paywalls '[{"paywall_id":"","weight":50},{"paywall_id":"","weight":50}]'
```
`--placement` es obligatorio. Una prueba de paywall necesita un placement de paywall, y una prueba de flow necesita un placement de flow. Para una prueba de flow, usa `--flows` con `flow_id` en cada variante. Una variante también puede tener un `title`, como `"title":"A"`.
3. **Revisa el borrador** con `ab-tests get`.
La ubicación de un borrador es solo provisional. `create` también puede aceptar una audiencia provisional, con `--segment` o `--all-users`. Estos valores provisionales no tienen ningún efecto sobre los usuarios. Cuando inicies la prueba, vuelve a pasar el placement y la audiencia a `start`.
## Iniciar una prueba \{#start-a-test\}
:::warning
No puedes deshacer un inicio. Desde el momento en que la prueba comienza, los usuarios de la audiencia que indiques dejan de ver su paywall o flow actual.
:::
Para iniciar un borrador, indica el placement y una audiencia: `--all-users`, o `--segment` con un ID de segmento:
```bash
adapty ab-tests start --app --placement --segment
```
El CLI muestra lo que hará el inicio y pregunta `Apply? [y/N]` antes de enviar nada. El lugar donde se ejecuta la prueba depende de las audiencias del placement:
- **El placement tiene una audiencia para este segmento** (o para todos los usuarios): La prueba se ejecuta en esa audiencia. Una prueba que esté activa en ese momento se detiene y pasa al estado `completed`.
- **El placement no tiene audiencia para este segmento**: `start` añade una nueva audiencia con la máxima prioridad en el placement. Los usuarios de este segmento que actualmente coincidan con otra audiencia pasan a la prueba.
Para dar a la prueba una prioridad menor que otra audiencia, primero añade el segmento como audiencia con esa prioridad. Asígnale el paywall o flow que esos usuarios ven ahora y luego inicia la prueba en esa audiencia. Consulta [Cambiar la prioridad de la audiencia](change-audience-priority).
Un cambio en una audiencia de segmento puede tardar hasta 20 minutos en llegar a todos los usuarios.
Solo se inicia una prueba en borrador. Para ejecutar una prueba de nuevo, crea una nueva: lee la prueba antigua con `get` y luego crea una prueba con los mismos grupos usando `create`.
## Cambiar una prueba \{#change-a-test\}
`update` envía la prueba completa de nuevo. Incluye todos los parámetros cada vez, incluyendo el obligatorio `--placement`. Si omites un parámetro, Adapty borra su valor: por ejemplo, el objetivo o la audiencia planificada.
```bash
adapty ab-tests update --app --title "Annual vs monthly, Q4" \
--goal "More revenue per user" --placement \
--paywalls '[{"paywall_id":"","weight":70},{"paywall_id":"","weight":30}]'
```
En una prueba en vivo, `update` solo cambia el título y el objetivo. Pasa los brazos, el placement y la audiencia exactamente como los devuelve `get`; se rechazarán otros brazos u otro placement. La prueba mantiene su hora de inicio y los usuarios conservan sus brazos. No puedes modificar una prueba completada o archivada.
Para cambiar los brazos o los pesos de una prueba en vivo, reemplázala. `replace` es la acción **Modify** del dashboard:
```bash
adapty ab-tests replace --app --title "Annual vs monthly v2" \
--placement \
--paywalls '[{"paywall_id":"","weight":80},{"paywall_id":"","weight":20}]'
```
La prueba activa se detiene y pasa al estado `completed`, y sus resultados se conservan con su ID. Una nueva prueba con un nuevo ID comienza en la misma audiencia, y Adapty asigna de nuevo a cada usuario de la audiencia a un grupo. Si indicas un placement diferente en `--placement`, Adapty mueve la audiencia a ese placement. No puedes mover una prueba de todos los usuarios.
## Detener una prueba \{#stop-a-test\}
`stop` finaliza la prueba. Tú decides qué ven los usuarios de su audiencia a partir de ese momento. Indica exactamente uno de estos flags:
| Flag | Después de detener |
|---|---|
| `--winner ` | Toda la audiencia ve uno de los grupos de la prueba. Indica el ID del paywall o el ID del flow de ese grupo. |
| `--other ` | Toda la audiencia ve un paywall o flow que no formaba parte de la prueba, del mismo tipo que la prueba. |
| `--no-content` | La audiencia abandona el placement y sus usuarios pasan a la siguiente audiencia que les corresponda. No está disponible para pruebas con audiencia de todos los usuarios. |
```bash
adapty ab-tests stop --app --winner
```
La prueba pasa al estado `completed`. Para volver a probar los mismos grupos, crea una nueva prueba como se describe en [Iniciar una prueba](#start-a-test). Para elegir al ganador, consulta [Resultados y métricas de la prueba A/B](results-and-metrics).
## Archivar una prueba \{#archive-a-test\}
Puedes archivar cualquier prueba que no esté activa. Para archivar una prueba activa, primero detenla. No puedes restaurar una prueba archivada.
```bash
adapty ab-tests archive --app
```
## Confirmación en scripts y agentes \{#confirmation-in-scripts-and-agents\}
`start`, `stop`, `replace`, y `archive` no se pueden deshacer, por lo que cada uno muestra su efecto antes de enviar nada. La forma en que solicita confirmación depende de cómo se ejecute el comando:
| Cómo se ejecuta el comando | Qué ocurre |
|---|---|
| En un terminal | La CLI imprime el efecto y pregunta `Apply? [y/N]`. Si respondes `y` o `yes`, la CLI envía la solicitud. Para cualquier otra respuesta, la CLI termina con código 1 y no envía nada. |
| Con `--yes` | La CLI envía la solicitud sin preguntar. |
| Con `--json`, en una tubería o sin terminal | La CLI no envía nada y termina con código 6. El mensaje de error describe el efecto. |
De este modo, un script o un agente puede leer el efecto de un comando antes de ejecutarlo: lanzarlo sin `--yes`, leer el mensaje y volver a ejecutarlo con `--yes` solo después de que alguien haya aprobado dicho efecto.
## Errores \{#errors\}
| Código de salida | Causa | Qué hacer |
|---|---|---|
| 1 | Respondiste algo distinto a `y` en el prompt. No se envió nada. | Vuelve a ejecutar el comando si era tu intención. |
| 2 | La CLI rechazó la entrada antes de enviarla: un UUID inválido, arms que no son un array JSON, un arm sin ID o sin peso entero, `--paywalls` y `--flows` ambos o ninguno, o dos opciones de stop. | Corrige el flag que indica el mensaje. |
| 3 | No has iniciado sesión, o tu usuario de Adapty no tiene acceso a la app. | Inicia sesión con `adapty auth login` y encuentra el ID de la app en `adapty apps list`. |
| 4 | Adapty rechazó la solicitud. El mensaje indica el motivo. | Consulta [Mensajes de Adapty](#messages-from-adapty). |
| 5 | La CLI no pudo conectar con Adapty. | Asegúrate de tener conexión y vuelve a ejecutar el comando. |
| 6 | Un comando que no se puede deshacer se ejecutó sin `--yes` y sin nadie que respondiera. No se envió nada. | Lee el efecto en el mensaje y vuelve a ejecutar el comando con `--yes`. |
| 130 | Pulsaste Ctrl+C en el prompt. No se envió nada. | — |
### Mensajes de Adapty
| Mensaje | Qué hacer |
|---|---|
| `The sum of the weights must equal 100, but has N.` | Cambia los pesos para que sumen 100. |
| `Flow() must be published before adding to AB test.` | Publica el flow y vuelve a ejecutar el comando. |
| `Paywalls cannot be changed in non-draft ab tests.` o `Placement cannot be changed in non-draft ab tests.` | Pasa los arms y el placement tal como los devuelve `get`, o usa `replace`. |
| `AB Test from default audience can not be stopped.` | Una prueba A/B para todos los usuarios necesita un paywall o flow tras detenerla: usa `--winner` o `--other`. |
| `AB Test to stop must be live.` | Solo se puede detener o reemplazar una prueba en curso. |
| `Live Ab Test can not be deleted.` | Detén la prueba antes de archivarla. |
## Referencia de comandos \{#command-reference\}
Todos los comandos requieren `--app`, el UUID de la app obtenido con `adapty apps list`. Todos los comandos excepto `list` necesitan el ID de la prueba como argumento.
### `ab-tests list`
| Flag | Required | Description |
|---|---|---|
| `--type` | No | `flow` (predeterminado) o `paywall`. |
| `--state` | No | `live`, `draft`, `completed`, `inactive` o `archived`. |
| `--placement` | No | Solo las pruebas de este placement (ID). Repite el flag para varios placements. |
| `--segment` | No | Solo las pruebas que se ejecutan para exactamente este segmento (ID). Repite el flag para varios segmentos. |
| `--search` | No | Solo las pruebas cuyo título contenga este texto. |
| `--page` | No | Número de página. Predeterminado: 1. |
| `--page-size` | No | Pruebas por página, hasta 100. Predeterminado: 20. |
### `ab-tests get`
Devuelve el test con sus ramas. No acepta otros flags.
### `ab-tests create`
| Indicador | Obligatorio | Descripción |
|---|---|---|
| `--title` | Sí | Título de la prueba. |
| `--paywalls` | Uno de los dos | Variantes de una prueba A/B de paywall, en JSON: `[{"paywall_id":"","weight":50,"title":"A"}, …]`. `title` es opcional. |
| `--flows` | Uno de los dos | Variantes de una prueba A/B de flow, en JSON, con `flow_id` en lugar de `paywall_id`. |
| `--goal` | No | Lo que la prueba pretende demostrar. |
| `--placement` | Sí | Placement para el que se planifica la prueba (ID). Una prueba de paywall necesita un placement de paywall, y una prueba de flow necesita un placement de flow. |
| `--segment` | No | Planifica la prueba para un segmento (ID). No se puede usar junto con `--all-users`. |
| `--all-users` | No | Planifica la prueba para todos los usuarios. |
### `ab-tests update`
Acepta los mismos flags que `create`, y `--placement` es obligatorio. Un flag que omitas se borrará. En una prueba en curso, solo se pueden cambiar `--title` y `--goal`. Pasa de nuevo el mismo placement y audiencia.
### `ab-tests start`
| Flag | Obligatorio | Descripción |
|---|---|---|
| `--placement` | Sí | Placement donde ejecutar la prueba (ID). |
| `--segment` | Una de las dos | Ejecutar la prueba para un segmento (ID). |
| `--all-users` | Una de las dos | Ejecutar la prueba para todos los usuarios. |
| `--yes`, `-y` | No | Iniciar sin confirmación. Obligatorio con `--json` o en un pipe. |
### `ab-tests stop`
| Indicador | Requerido | Descripción |
|---|---|---|
| `--winner` | Uno de los tres | Muestra el paywall o flow de este arm (ID) a toda la audiencia. |
| `--other` | Uno de los tres | Muestra un paywall o flow que no estaba en la prueba (ID). |
| `--no-content` | Uno de los tres | Elimina la audiencia del placement. No está permitido para una prueba de todos los usuarios. |
| `--yes`, `-y` | No | Detiene sin confirmar. Requerido con `--json` o en una tubería. |
### `ab-tests replace`
| Flag | Requerido | Descripción |
|---|---|---|
| `--title` | Sí | Título de la nueva prueba. |
| `--placement` | Sí | Placement de la nueva prueba (ID). Un placement diferente mueve la audiencia a ese placement. |
| `--paywalls` o `--flows` | Sí | Variantes de la nueva prueba, como en `create`. |
| `--goal` | No | Lo que la nueva prueba pretende demostrar. |
| `--yes`, `-y` | No | Reemplazar sin confirmación. Obligatorio con `--json` o en un pipe. |
La nueva prueba toma la audiencia de la prueba que reemplaza, por lo que `replace` no admite ningún flag de audiencia.
### `ab-tests archive`
| Flag | Required | Description |
|---|---|---|
| `--yes`, `-y` | No | Archivar sin confirmación. Obligatorio con `--json` o en una tubería. |
## ¿Qué viene después? \{#whats-next\}
- [Skill de agente para pruebas A/B](ab-tests-skill) — permite que tu agente planifique, inicie y detenga pruebas, con tu confirmación antes de cada paso que no se puede deshacer.
- [Crear, ejecutar y detener una prueba A/B](run_stop_ab_tests) — los mismos pasos en el dashboard.
- [Resultados y métricas de pruebas A/B](results-and-metrics) — cómo interpretar los resultados y elegir un ganador.
---
# File: developer-cli-migrations
---
---
title: "Comandos de migraciones"
description: "Comandos de Adapty CLI para mover un proyecto de RevenueCat a Adapty: crear una migración, ejecutar sus pasos, comprobar su estado y cerrarla."
---
Mueve un proyecto de RevenueCat a Adapty: su catálogo y, opcionalmente, sus eventos del store e historial de transacciones. Adapty ejecuta cada migración como una secuencia de pasos e indica qué acciones puedes ejecutar a continuación, así que consulta `status` antes de cada acción. Para ver el procedimiento completo, consulta [Migración desde RevenueCat](migration-from-revenuecat).
Todos los comandos excepto `list`, `create`, `use`, `current` y `unuse` aceptan el flag de migración:
| Flag | Requerido | Descripción |
|---|---|---|
| `-m`, `--migration` | No | ID de migración. Sin él, la CLI usa la variable de entorno `ADAPTY_MIGRATION`, y después la migración guardada por `create` o `use`. |
## adapty migrations list
Lista tus migraciones y los flows de migración que puedes iniciar, agrupados por aplicación.
```bash
adapty migrations list
```
## adapty migrations create
Inicia una migración y guárdala como la actual.
```bash
adapty migrations create --name
adapty migrations create --flow --app
```
| Indicador | Requerido | Descripción |
|---|---|---|
| `--name` | Uno de `--name` o `--flow` | Nombre de la nueva app de Adapty. Inicia la migración del catálogo. No se puede combinar con `--flow` ni con `--app`. |
| `--flow` | Uno de `--name` o `--flow` | Flow a iniciar en una app existente, tal como lo muestra `adapty migrations list`. Requiere `--app`. |
| `--app` | Con `--flow` | ID de la app (UUID) |
| `--no-select` | No | Crea la migración sin guardarla como la actual |
Los flows disponibles para una app existente después de su migración de catálogo:
| Flow | Descripción |
|---|---|
| `transactions` | Importa el historial de transacciones desde una exportación Cloud Export diaria de RevenueCat |
| `transactions_support` | Importa el historial de transacciones a través del soporte de RevenueCat y el soporte de Adapty, para planes de RevenueCat sin Cloud Export |
| `apple_events` | Reenvía las notificaciones de App Store a Adapty mientras RevenueCat continúa recibiéndolas |
| `google_events` | Suscribe a Adapty al tema Pub/Sub que RevenueCat utiliza para las notificaciones de Google Play |
| `code` | Hace que tu agente de codificación reemplace el SDK de RevenueCat en una base de código de la app |
| `integrations` | Hace que tu agente de codificación encuentre las herramientas de analítica, atribución y mensajería en el código de la app para configurarlas en Adapty |
| `paywall_design` | Hace que tu agente de codificación reconstruya los diseños de paywall de RevenueCat en los flows creados por la migración del catálogo |
## adapty migrations use
Guarda una migración como la actual, para que los demás comandos no necesiten `-m`.
```bash
adapty migrations use
```
| Argumento | Descripción |
|---|---|
| `migration-id` | ID de migración obtenido de `adapty migrations list` |
La CLI verifica que puedes acceder a la migración antes de guardar el ID. La migración guardada pertenece al token actual y se aplica en cualquier terminal.
## adapty migrations current
Muestra la migración actual y su procedencia: la variable de entorno `ADAPTY_MIGRATION` o la selección guardada.
```bash
adapty migrations current
```
## adapty migrations unuse
Borra la migración guardada. Un valor de `ADAPTY_MIGRATION` establecido en tu shell permanece activo hasta que lo elimines.
```bash
adapty migrations unuse
```
## adapty migrations status
Muestra el estado de una migración, sus problemas y las acciones disponibles a continuación.
```bash
adapty migrations status
```
| Flag | Obligatorio | Descripción |
|---|---|---|
| `--wait` | No | Realiza polling hasta que la migración cambie y devuelve el estado más reciente |
| `--timeout` | No | Tiempo de polling para `--wait`: de 1 a 600 segundos, 120 por defecto. Acepta `300`, `300s` o `5m`. Requiere `--wait`. |
Con `--json`, `next_actions` y `available_actions` muestran el ID de cada acción, los recursos que lee, su `input_schema` y el texto de `confirm`.
El código de salida `0` significa que la solicitud fue exitosa, no que la migración lo haya sido. Comprueba `migration.state` en la respuesta.
## Pasos de migraciones de Adapty \{#adapty-migrations-steps\}
Muestra el checklist de migración y el estado de cada paso.
```bash
adapty migrations steps
```
## adapty migrations show
Lista los recursos que puedes leer en este momento, o lee uno en concreto.
```bash
adapty migrations show [resource]
```
| Argument | Description |
|---|---|
| `resource` | Nombre del recurso, por ejemplo `apps`, `mapping`, `report` o `export-config`. Omítelo para ver la lista de recursos disponibles en el paso actual. |
## adapty migrations run
Ejecuta una acción de `adapty migrations status`.
```bash
adapty migrations run
```
| Argumento | Descripción |
|---|---|
| `action-id` | ID de acción de `next_actions` o `available_actions` en `adapty migrations status` |
| Flag | Obligatorio | Descripción |
|---|---|---|
| `--input` | No | Entrada de la acción como objeto JSON que coincide con el `input_schema` de la acción. Sin entrada, la CLI envía `{}`. |
| `--input-file` | No | Ruta a un archivo con la entrada de la acción, o `-` para leerla desde stdin. No se puede combinar con `--input`. |
| `-y`, `--yes` | Para acciones con texto `confirm` | Confirma la acción tras leer su texto `confirm`. No hay ningún prompt interactivo. |
| `--open` | No | Abre el enlace de la acción incluso con una tubería o `--json` |
| `--no-browser` | No | Muestra el enlace de la acción sin abrir un navegador |
Las acciones existen en tres tipos:
- **Las acciones de entrada** envían tus datos a Adapty, por ejemplo las apps de RevenueCat a migrar o tus decisiones de mapeo.
- **Las acciones externas** abren una página en el Adapty Dashboard, por ejemplo para pegar la clave API secreta de RevenueCat. Completa la página y luego comprueba `status`.
- **Las acciones del agente**, por ejemplo `migrate_code`, son tareas para tu agente de codificación. Ejecútalas desde el repositorio git de la app: la CLI guarda los datos de la migración en `.git/adapty//` e imprime las instrucciones para el agente. El agente reporta el resultado ejecutando la acción de nuevo con `--input`.
## adapty migrations close
Finaliza o cancela una migración. No puedes reabrirla después.
```bash
adapty migrations close --outcome finish --yes
```
| Flag | Required | Description |
|---|---|---|
| `--outcome` | Yes | `finish` marca la migración como completada; `cancel` la abandona |
| `-y`, `--yes` | Yes | Confirma el cierre |
## Qué hacer a continuación \{#whats-next\}
- [Referencia de comandos](developer-cli-reference) — todos los temas de la CLI, los flags globales y los flags de paginación.
---
# File: developer-cli-ads-manager
---
---
title: "Gestionar Ads Manager desde la CLI"
description: "Ejecuta campañas de Apple Ads, palabras clave y reglas de automatización desde el terminal con la CLI para desarrolladores de Adapty."
---
La CLI de Adapty puede gestionar tu cuenta de [Ads Manager](adapty-ads-manager) desde el terminal, bajo el tema `adapty asa`. Cubre campañas, grupos de anuncios, palabras clave, anuncios, páginas de producto, reglas de automatización, métricas e investigación de la competencia.
Úsalo para las tareas que el navegador ralentiza: dar a un agente de IA acceso en vivo al rendimiento de tus anuncios, añadir varios cientos de palabras clave desde un archivo o aplicar la misma configuración en varias campañas. Para todo lo demás, el [dashboard](https://app.adapty.io) sigue siendo más rápido.
:::warning
La CLI no puede eliminar nada. Las campañas, anuncios y reglas de automatización se pueden crear, actualizar y pausar desde el terminal, pero eliminarlos solo es posible desde el dashboard.
:::
## Antes de comenzar \{#before-you-start\}
Los comandos de Ads Manager usan la misma instalación e inicio de sesión que el resto de la CLI. Si aún no lo has configurado, sigue los pasos 1 y 2 de la [guía de inicio rápido](developer-cli-quickstart).
### Requisitos previos \{#prerequisites\}
Dos condiciones adicionales se aplican a todos los comandos `adapty asa`:
- **Una cuenta de Apple Ads conectada**: conéctala con `adapty asa connect`, o desde el dashboard como se describe en [Comenzar con Adapty Ads Manager](adapty-ads-manager-get-started).
- **Una suscripción activa de Ads Manager**: sin ella, todos los comandos fallan con `402 ads_manager_subscription_required`.
Un comando muestra ambas a la vez:
```bash
adapty asa whoami
```
### Diferencias con el resto de la CLI
- **No existe el flag `--app`**: El alcance es la empresa a la que pertenece tu token. `--app` solo existe en algunos comandos `list` como filtro. Los comandos `asa segments` son la excepción: escriben en una app de Adapty, por lo que `--app` indica esa app.
- **Las escrituras llegan directamente a Apple**: Cada comando que modifica tu cuenta imprime el cuerpo de la solicitud y pide confirmación antes de enviarla. No hay paso de staging.
- **Las lecturas son baratas, las escrituras no**: Usa los comandos `list` y `--dry-run` con libertad. Trata todo lo demás como irreversible.
Para omitir el mensaje de confirmación en un script, usa `--yes`. Con `--json` o en una tubería, un comando de escritura rechaza la operación en lugar de esperar una respuesta que nunca llegará, por lo que `--yes` es obligatorio en esos casos.
## Encuentra los IDs que necesitas \{#find-the-ids-you-need\}
Cada comando requiere UUIDs, y cada UUID proviene de un comando `list`. Trabaja siguiendo la jerarquía:
```bash
adapty asa orgs list
adapty asa campaigns list --campaign-group
adapty asa ad-groups list --campaign
```
Delimita cada lectura con un filtro. Los filtros acotan la consulta en lugar de la página impresa, así que una lectura delimitada es económica mientras que una sin delimitar pagina por toda la cuenta. `adapty asa keywords list` sin `--ad-group` es la lectura más amplia del tema.
Estas listas devuelven solo metadatos. Los datos de rendimiento vienen de [`asa metrics`](#query-metrics-from-agents-and-scripts).
## Obtener recomendaciones de palabras clave \{#get-keyword-recommendations\}
Para crear una lista de palabras clave sin investigación previa, obtén un conjunto predefinido para tu app. Pasa el `adam_id` de la app obtenido con `adapty asa apps list` y el tipo de conjunto — `brand`, `generic` o `competitor`:
```bash
adapty asa keywords recommend --adam-id --type generic --country US
```
El pool no tiene pujas ni tipos de concordancia. Elige los tuyos y añade las palabras clave como se describe en [Añadir palabras clave en bloque](#add-keywords-in-bulk). Si el resultado muestra `status: building`, vuelve a intentarlo en aproximadamente un minuto. Consulta los [comandos de Ads Manager](developer-cli-ads-manager-reference#adapty-asa-keywords-recommend) para ver los tipos de pool y los límites.
## Añadir palabras clave en lote \{#add-keywords-in-bulk\}
Añadir palabras clave una a una es el principal motivo para salir del dashboard. Escribe una palabra clave por línea en un archivo de texto:
```bash
adapty asa keywords add --ad-group --from-file keywords.txt --bid 1.20 --match-type EXACT
```
Las palabras clave se aplican en lotes de 100 como máximo por llamada. Divide las listas más grandes en varias llamadas.
Pueden producirse dos tipos de error y se comportan de manera distinta. Un ID no válido hace que todo el lote falle antes de llamar a Apple, por lo que no se aplica nada. Apple también puede rechazar palabras clave individuales: el resto se añaden igualmente, y cada rechazo se notifica con su motivo. Comprueba la línea de resumen en lugar de fijarte solo en el código de salida.
Empieza con unas pocas palabras clave y revisa el resultado antes de enviar un archivo completo.
## Crear una campaña de máximas conversiones \{#max-conversions\}
Una campaña que puja con `MAX_CONVERSIONS` solo se sirve cuando tiene un grupo de anuncios automatizado, así que crea ambos a la vez:
```bash
adapty asa campaigns create --org --name "Max Conv" --adam-id 123456 --country US --daily-budget 50 --bidding-strategy MAX_CONVERSIONS
adapty asa ad-groups create --campaign --name "Automated Max Conv" --automated
```
Hasta que ese grupo de anuncios exista, la campaña reporta `serving_status: NOT_RUNNING` con `AUTOMATED_KEYWORDS_REQUIRED_AD_GROUP_MISSING` entre sus `serving_state_reasons`, y `campaigns create` muestra tanto el motivo como el comando que lo resuelve.
`--automated` es lo que satisface el requisito — un grupo de anuncios normal con `--automated-keywords` no lo hace. Apple programa y ejecuta el grupo de anuncios automatizado por sí mismo, por lo que no requiere `--start-time`, `--default-bid` es opcional y permanece habilitado: para detener el gasto, pausa la campaña.
En la campaña, mantén `--target-cpa` por debajo de `--daily-budget`.
## Configurar opciones de facturación para una línea de crédito \{#invoicing-options\}
Apple requiere opciones de facturación en cada campaña de una organización que factura por línea de crédito. `adapty asa orgs list` muestra el `payment_model` de cada organización — `LOC` significa que los cinco indicadores `--invoice-*` son aplicables:
```bash
adapty asa campaigns create --org --name "LOC push" --adam-id 123456 --country US --daily-budget 50 --invoice-advertiser "Acme Inc" --invoice-order-number PO-42 --invoice-contact-name "Jane Doe" --invoice-contact-email jane@acme.com --invoice-billing-email billing@acme.com
```
Pass all five in one call — a partial set is rejected before the request reaches Apple. Without them, the campaign is created but reports `serving_status: NOT_RUNNING` with `MISSING_BO_OR_INVOICING_FIELDS`.
Los mismos cinco flags en `adapty asa campaigns update` configuran las Invoicing Options en una campaña que ya existe. Reemplazan el conjunto almacenado por completo, así que pasa los cinco incluso si solo quieres cambiar uno.
## Crear una estructura de campaña en una sola operación \{#create-a-campaign-structure-in-one-operation\}
`campaigns bulk-create` reemplaza un script que itera sobre `campaigns create` y `ad-groups create`. Envía toda la estructura de una campaña — campañas con sus grupos de anuncios, palabras clave, palabras clave negativas y anuncios — como una sola operación:
```bash
adapty asa campaigns bulk-create --file structure.json
```
La entrada es una descripción JSON de la estructura — consulta [el formato de la estructura](developer-cli-ads-manager-reference#adapty-asa-campaigns-bulk-create) para ver los campos. JSON es el camino natural para un agente de IA: genera la estructura y la pasa directamente:
```bash
cat structure.json | adapty asa campaigns bulk-create --file -
```
Una [plantilla de Apple Ads en bloque](https://ads.apple.com/app-store/help/campaigns/0089-make-edits-in-bulk) también funciona como entrada — el servidor convierte `Campaign_And_Adgroup_Template.xlsx` o un [`.csv` de palabras clave](https://ads.apple.com/app-store/help/keywords/0014-add-and-manage-keywords) en una estructura. `--org-id` acepta el `org_id` numérico de `adapty asa orgs list`. Para revisar la conversión antes de que se cree nada, añade `--preview`:
```bash
adapty asa campaigns bulk-create --from-file Campaign_And_Adgroup_Template.xlsx --org-id 1234567 --preview
```
Los problemas de conversión se notifican con su hoja, fila y columna. Cuando la estructura impresa tenga buen aspecto, elimina `--preview` para enviarla.
La salida de `--preview` es también la forma más rápida de obtener un archivo de estructura inicial: guárdalo, edítalo y envíalo con `--file` — del mismo modo que [`automations get`](#run-automation-rules) proporciona una plantilla de regla.
La estructura completa se valida antes de crear nada, y un rechazo lista todos los nodos inválidos. Una vez aceptada, los objetos se crean en el servidor mientras el comando informa el progreso. El informe final es `success`, `partial` o `failed` — un resultado `partial` lista cada objeto que no se creó, con el error de Apple.
Para una estructura grande, usa `--no-wait` para obtener el ID de operación de inmediato y consultar el progreso más tarde:
```bash
adapty asa campaigns bulk-status
```
## Consulta métricas desde agentes y scripts \{#query-metrics-from-agents-and-scripts\}
`asa metrics` genera informes sobre cualquier nivel de la cuenta para un rango de fechas. Añade `--json` para que un agente de IA o un script pueda consumir el resultado directamente:
```bash
adapty asa metrics --entity campaign --date-from 2026-07-01 --date-to 2026-07-31 --metric spend --metric roas --json
```
`--metric` es obligatorio y repetible, y acepta los nombres que Ads Manager registra. Consulta [Métricas](adapty-ads-manager-metrics) para ver la lista completa. Cada métrica que indiques se calcula en todo el nivel de entidad antes de paginar, así que solicita solo las columnas que vayas a leer en lugar del catálogo completo.
`--app`, `--campaign` y `--ad-group` acotan el informe, y acotarlo es la forma más económica de acelerar una llamada, porque el coste depende del número de entidades agregadas y no del tamaño de la página. Cuatro métricas cuentan perfiles únicos por entidad — `subscribers`, `paid_subscribers`, `arppu` y `arpas` — y estas requieren un filtro de campaña o grupo de anuncios en cualquier nivel de entidad:
```bash
adapty asa metrics --entity keyword --date-from 2026-07-01 --date-to 2026-07-31 --metric arpas --campaign --json
```
Las métricas de cohorte funcionan de manera diferente al resto. No existe la métrica `ltv`, porque el valor de vida se lee en una ventana de renovación en lugar de en una fecha. Solicita la ventana en su lugar:
```bash
adapty asa metrics --entity campaign --date-from 2026-07-01 --date-to 2026-07-31 --metric roas --by-days 7 --by-days 90 --order-by-day 90
```
Esto devuelve tus campañas clasificadas por ROAS al día 90. En una sola llamada caben hasta 16 ventanas.
Cada fila es una entidad, ya agregada y ordenada en el servidor. Una pregunta del tipo "las cinco campañas con mayor gasto" es, por tanto, una sola llamada, no un recorrido por todas las páginas:
```bash
adapty asa metrics --entity campaign --date-from 2026-07-01 --date-to 2026-07-31 --order-by spend --page-size 5
```
Las métricas y la lista de términos de búsqueda comparten un único presupuesto de analytics por empresa: 5 llamadas por minuto y un máximo de 2 en cualquier intervalo de 10 segundos. Formula una pregunta concreta en lugar de hacer consultas repetidas.
Dos límites se aplican a un informe. El período de generación de informes está limitado por el nivel de agrupación que elijas: 28 días con `--group-by day`, 90 días sin agrupación por período, 180 por semana, 365 por mes. Además, cada página está limitada a 5000 filas de desglose, contando una fila por entidad × país × período. Por eso, para ampliar un informe conviene usar una agrupación más amplia en `--group-by`, no dividirlo en más llamadas.
## Consulta palabras clave de la competencia \{#check-competitor-keywords\}
Un solo comando devuelve las palabras clave por las que pujan las apps de la competencia, para hasta cinco apps de la App Store a la vez:
```bash
adapty asa competitors summary --app-ids 1668337467,6503873027 --json
```
El período y los países están fijados en el servidor —el último mes completo, en todos los países— así que el comando no tiene más flags que los IDs de las apps. La primera llamada para un conjunto de apps puede tardar decenas de segundos.
Utiliza esto para extraer datos de palabras clave de la competencia en un informe de forma programada. Para filtrar los resultados, comparar países en paralelo o añadir directamente las palabras clave que encuentres a una campaña, usa [Market Intelligence](ads-manager-market-intelligence) en el dashboard.
## Crear un segmento para cada campaña \{#create-a-segment-for-each-campaign\}
Para mostrar a los usuarios de una campaña específica su propio paywall, crea un [segmento](segments) para esa campaña y úsalo como [audiencia](audience) en un placement. Primero, verifica que la campaña no tenga ya un segmento:
```bash
adapty asa segments list --app --campaign
```
Si el resultado está vacío, crea el segmento:
```bash
adapty asa segments create --app --campaign --yes
```
`--app` es el ID de la app de Adapty que se obtiene con `adapty apps list`. La CLI nombra el segmento `[ASA] Campaign: `, igual que Ads Manager, para que Ads Manager lo reconozca como propio. Para crear un segmento a partir de grupos de anuncios o palabras clave, consulta [Segments](developer-cli-ads-manager-reference#segments) en la referencia de comandos.
## Encuentra quién modificó tus campañas \{#find-who-changed-your-campaigns\}
Para saber quién pausó una campaña o cambió una puja, y cuándo, consulta el historial de cambios de la organización. Llega en tiempo real desde Apple, por lo que también incluye los cambios realizados directamente en Apple Ads o mediante otras herramientas:
```bash
adapty asa change-history list --campaign-group --entity-type Campaign --event-type UPDATE
```
Para ver el valor anterior y el nuevo de cada campo modificado, añade `--fields`. Para consultar un cambio en detalle, pasa su `detail_id` a `change-history get`:
```bash
adapty asa change-history get --campaign-group
```
Cada llamada lee una organización y hasta 14 días, dentro de los 6 meses que Apple conserva. Los filtros `--campaign` y `--ad-group` de este comando aceptan los IDs numéricos de Apple, no UUIDs. Consulta [Historial de cambios](developer-cli-ads-manager-reference#change-history) para ver todos los flags.
Para ver los mismos cambios en el Adapty Dashboard, usa la [página de Historial de cambios](ads-manager-change-history).
## Ejecutar reglas de automatización \{#run-automation-rules\}
La CLI almacena el JSON que le proporciones, por lo que la forma más rápida de obtener un archivo de [regla de automatización](ads-manager-automations) válido es crear una regla en el dashboard y luego leerla de vuelta:
```bash
adapty asa automations get --json > rule.json
```
Edita ese archivo y úsalo como plantilla para nuevas reglas:
```bash
adapty asa automations create --file rule.json
```
Un archivo de regla contiene exactamente una condición y exactamente una acción, que es lo que la API almacena por regla. Cuando pases un archivo a `automations update`, elimina primero el campo `internal_id` — la actualización se rechaza si está presente.
### Crea una acción de añadir como palabra clave a partir de flags \{#build-an-add-as-keyword-action-from-flags\}
Una acción es la excepción al JSON escrito a mano. **Add as keyword**, que promueve un término de búsqueda o copia una palabra clave en otro grupo de anuncios, toma sus grupos de anuncios de destino, puja y tipo de concordancia de los flags:
```bash
adapty asa automations create --file rule.json --target-ad-group --match-type EXACT --cpt-bid-type search_term_current_cpt --negate ad-group
```
:::warning
Obtén los `params` de esta acción a partir de los flags, nunca de una regla que lleve una acción diferente. La API resuelve `params` por forma y no por nombre de variante, por lo que una clave perteneciente a otra acción hace que elija esa acción y descarte el resto, respondiendo con `200` y almacenando una regla que no añade palabras clave a ningún grupo de anuncios.
:::
Los mismos flags en `automations update` reparan una regla ya almacenada con la forma incorrecta. El CLI lee la regla, reconstruye la acción desde cero y la vuelve a escribir, conservando solo los ajustes almacenados que encajan en una acción **Add as keyword**:
```bash
adapty asa automations update --target-ad-group --match-type EXACT --cpt-bid-type search_term_current_cpt
```
Lo que faltaba en la regla incorrecta debe venir de un flag. Consulta [los comandos de Ads Manager](developer-cli-ads-manager-reference#add-keyword-flags) para ver el conjunto completo.
Prueba una regla antes de dejarla modificar pujas:
```bash
adapty asa automations run --dry-run
```
Una dry run evalúa las condiciones y registra lo que haría la regla sin tocar Apple Ads. Las ejecuciones se ponen en cola en lugar de realizarse de inmediato, por lo que el comando muestra un ID de ejecución y el resultado aparece en `adapty asa automations runs`.
## Volver a ejecutar scripts de forma segura \{#re-run-scripts-safely\}
Cada escritura envía una clave de idempotencia. La CLI genera una por invocación y reintenta una vez tras un error de red, de modo que una solicitud que falló en tránsito nunca se aplica dos veces.
En un script, fija la clave tú mismo para que toda la pipeline pueda volver a ejecutarse:
```bash
adapty asa campaigns create --org --name "Winter push" --adam-id 123456 --country US --daily-budget 50 --idempotency-key winter-push-2026 --yes
```
Re-ejecutar el mismo comando en menos de 24 horas devuelve el resultado almacenado e imprime `Already applied earlier` en lugar de crear una segunda campaña. La misma clave con un cuerpo distinto falla con `422`, lo que detecta un script editado que reutiliza una clave por error.
## Próximos pasos \{#whats-next\}
- [Gestiona Apple Ads con una herramienta de codificación con IA](developer-cli-ads-manager-skill) — instala el plugin de Apple Ads para que Claude Code, Copilot CLI, Codex o Gemini CLI puedan ejecutar estos comandos por ti.
- [Comandos de Ads Manager](developer-cli-ads-manager-reference) — todos los comandos con sus argumentos, flags y valores aceptados.
- [Automatizaciones](ads-manager-automations) — qué hace cada tipo de regla y qué acciones puede ejecutar.
- [Métricas](adapty-ads-manager-metrics) — los nombres de métrica aceptados por `--metric` y cómo se calcula cada una.
---
# File: developer-cli-ads-manager-reference
---
---
title: "Comandos de Ads Manager para el CLI de Adapty Developer"
description: "Referencia de todos los comandos adapty asa: campañas, grupos de anuncios, palabras clave, anuncios, segmentos, automatizaciones, métricas e historial de cambios."
---
Este artículo lista todos los comandos de [Ads Manager](adapty-ads-manager) en el CLI de Adapty, con sus argumentos, flags y valores aceptados. Los comandos de Ads Manager se encuentran bajo el topic `adapty asa`.
:::link
Para conocer los requisitos previos, las prácticas de escritura segura y ejemplos basados en tareas, consulta [Gestionar Ads Manager desde la CLI](developer-cli-ads-manager).
:::
Estos comandos requieren una cuenta de Apple Ads conectada y una suscripción activa de Ads Manager. Ejecuta [`adapty asa whoami`](#adapty-asa-whoami) para verificar ambas. Para el resto de la CLI, consulta la [referencia de comandos](developer-cli-reference).
## Flags globales \{#global-flags\}
Estos flags están disponibles en todos los comandos de Ads Manager.
| Flag | Descripción |
|---|---|
| `--json` | Salida en formato JSON en lugar de texto formateado |
| `--help` | Muestra la ayuda del comando |
Todos los comandos `list` también aceptan flags de paginación:
| Flag | Por defecto | Descripción |
|---|---|---|
| `--page` | `1` | Número de página |
| `--page-size` | `100` | Elementos por página (máx.: 1000) |
Las páginas de Ads Manager son más grandes que en el resto de la CLI. Es preferible usar una página grande en lugar de un bucle de páginas pequeñas.
Todos los comandos que modifican tu cuenta aceptan estos flags:
| Indicador | Descripción |
|---|---|
| `--yes`, `-y` | Aplica sin pedir confirmación. Es obligatorio cuando la salida se redirige por pipe o se usa `--json` |
| `--idempotency-key` | Clave fija para esta escritura. Una repetición con la misma clave y cuerpo en 24 horas devuelve el resultado almacenado en lugar de aplicar el cambio de nuevo |
Los comandos de Ads Manager no aceptan el indicador `--app`. El ámbito es la empresa a la que pertenece tu token. `--app` existe en algunos comandos `list` solo como filtro. Los comandos de [segmentos](#segments) son la excepción: allí, `--app` es la app de Adapty a la que pertenece el segmento.
## Filtros de lista \{#list-filters\}
Los filtros acotan la consulta en sí, no la página mostrada. Una `keywords list` sin filtros recorre todas las palabras clave de la cuenta, así que limita cada lectura al nivel que necesites.
| Filtro | Aceptado por |
|---|---|
| `--campaign-group` | `campaigns`, `ad-groups`, `keywords`, `negative-keywords`, `search-terms`, `ads`, `creatives`, `product-pages` |
| `--app` | `campaigns`, `ad-groups`, `keywords`, `negative-keywords`, `search-terms`, `creatives`, `product-pages` |
| `--campaign` | `ad-groups`, `keywords`, `negative-keywords`, `search-terms`, `ads` |
| `--ad-group` | `keywords`, `negative-keywords`, `search-terms`, `ads` |
| `--status` | `campaigns`, `ad-groups`, `ads` (`ENABLED` o `PAUSED`), `keywords` (`ACTIVE` o `PAUSED`) |
| `--search` | `campaigns`, `ad-groups`, `keywords`, `negative-keywords`, `search-terms`, `ads`. Coincidencia de subcadena sin distinción entre mayúsculas y minúsculas en el nombre |
`adapty asa apps list`, `orgs list`, `automations list` y `automations runs` no admiten filtros. Solo aceptan flags de paginación.
`--campaign-group`, `--app`, `--campaign` y `--ad-group` reciben los UUIDs que imprime el comando `list` correspondiente, y cada uno es repetible:
```bash
adapty asa keywords list --ad-group --ad-group
```
Un ID que pertenece a otra empresa no devuelve ningún resultado, por lo que la página aparece vacía en lugar de mostrar un error.
## Cuenta \{#account\}
### adapty asa whoami
Muestra la empresa, cómo se concedió el acceso a Ads Manager y si Apple Ads está conectado.
```bash
adapty asa whoami
```
Ejecuta este comando primero. Informa de si se cumplen los dos requisitos previos para todos los demás comandos.
### adapty asa connect
Vincula una cuenta de Apple Ads a Adapty.
```bash
adapty asa connect
```
El comando imprime un enlace de autorización de Apple y espera hasta que Apple notifique que la cuenta está conectada.
| Flag | Por defecto | Descripción |
|---|---|---|
| `--wait` / `--no-wait` | `--wait` | Espera hasta que Apple Ads notifique que está conectado. `--no-wait` devuelve el control inmediatamente |
| `--timeout` | `300` | Segundos de espera para el paso del navegador |
### adapty asa orgs list
Lista los grupos de campañas (organizaciones de Apple Ads) disponibles para tu empresa.
```bash
adapty asa orgs list
```
Cada fila contiene dos identificadores que no son intercambiables:
| Campo | Se usa como |
|---|---|
| `internal_id` | El UUID que `--org` acepta en [`campaigns create`](#adapty-asa-campaigns-create), y que `--campaign-group` acepta como [filtro de lista](#list-filters) |
| `org_id` | El ID numérico de organización de Apple, que acepta `--org-id` en [`campaigns bulk-create`](#adapty-asa-campaigns-bulk-create). `--org` y `--campaign-group` lo rechazan |
`--org` solo existe en `campaigns create`. Ningún comando de lista lo acepta.
Cada fila también incluye un `payment_model`. Cuando es `LOC`, la organización factura por línea de crédito, y cada campaña en ella necesita los [indicadores `--invoice-*`](#adapty-asa-campaigns-create).
Acepta [indicadores de paginación](#global-flags).
### adapty asa apps list
Lista las apps promocionadas en Apple Ads.
```bash
adapty asa apps list
```
Cada fila contiene dos identificadores que no son intercambiables:
| Campo | Se usa como |
|---|---|
| `internal_id` | El UUID que `--app` acepta como [filtro de lista](#list-filters) |
| `adam_id` | El ID numérico de App Store de Apple, que usa `--adam-id` en [`campaigns create`](#adapty-asa-campaigns-create) y [`product-pages sync`](#adapty-asa-product-pages-sync) |
Acepta [flags de paginación](#global-flags).
## Campañas \{#campaigns\}
### adapty asa campaigns list
Lista [campañas](ads-manager-create-campaign). Devuelve solo metadatos — consulta los datos de rendimiento con [`asa metrics`](#adapty-asa-metrics).
```bash
adapty asa campaigns list --app --status PAUSED
```
Acepta [indicadores de paginación](#global-flags) y los [filtros de lista](#list-filters) `--campaign-group`, `--app`, `--search` y `--status`.
### adapty asa campaigns get
Obtén detalles de una campaña específica.
```bash
adapty asa campaigns get
```
| Argument | Description |
|---|---|
| `campaign-id` | Campaign ID (UUID) |
### adapty asa campaigns create
Crea una campaña.
```bash
adapty asa campaigns create --org --name "Winter push" --adam-id 123456 --country US --daily-budget 50
```
| Indicador | Obligatorio | Descripción |
|---|---|---|
| `--org` | Sí | ID del grupo de campañas (UUID). Ver [`orgs list`](#adapty-asa-orgs-list) |
| `--name` | Sí | Nombre de la campaña |
| `--adam-id` | Sí | ID de la app en el App Store (`adam_id`) |
| `--country` | Sí | Código de país o región. Repite para varios: `--country US --country CA` |
| `--daily-budget` | Sí | Presupuesto diario como cantidad simple, por ejemplo `50` o `12.50` |
| `--budget` | No | Presupuesto total |
| `--target-cpa` | No | Coste objetivo por adquisición. Debe ser inferior a `--daily-budget` |
| `--currency` | No | Código de moneda para los importes de esta llamada. Valor predeterminado: `USD` |
| `--bidding-strategy` | No | `MANUAL_CPT` o `MAX_CONVERSIONS`. Apple usa `MANUAL_CPT` por defecto |
| `--ad-channel-type` | No | `SEARCH` o `DISPLAY`. Valor predeterminado: `SEARCH` |
| `--billing-event` | No | `TAPS` o `IMPRESSIONS`. Valor predeterminado: `TAPS` |
| `--supply-source` | No | Fuente de suministro, repetible. Valor predeterminado: `APPSTORE_SEARCH_RESULTS` |
| `--status` | No | Estado inicial: `ENABLED` o `PAUSED` |
| `--invoice-advertiser` | Línea de crédito | Opciones de facturación: nombre del anunciante |
| `--invoice-order-number` | Línea de crédito | Opciones de facturación: número de pedido |
| `--invoice-contact-name` | Línea de crédito | Opciones de facturación: nombre del contacto de compra |
| `--invoice-contact-email` | Línea de crédito | Opciones de facturación: email del contacto de compra |
| `--invoice-billing-email` | Línea de crédito | Opciones de facturación: email del contacto de facturación |
Una organización cuyo `payment_model` es `LOC` factura mediante línea de crédito, y Apple requiere opciones de facturación en cada una de sus campañas. Pasa los cinco flags `--invoice-*` en una sola llamada — un conjunto parcial se rechaza antes de enviar la solicitud. Consulta [Configurar opciones de facturación para una línea de crédito](developer-cli-ads-manager#invoicing-options).
La respuesta incluye `serving_status` y `serving_state_reasons`. Es posible crear una campaña y que aún así no sirva anuncios: una campaña de tipo `MAX_CONVERSIONS` espera a que se cree un [grupo de anuncios automatizado](#adapty-asa-ad-groups-create), y una campaña con línea de crédito espera a que se configuren sus Opciones de Facturación. En ambos casos, el comando muestra el motivo y el comando que lo resuelve.
### adapty asa campaigns update
Actualiza una campaña existente.
```bash
adapty asa campaigns update --daily-budget 80 --status PAUSED
```
| Argumento | Descripción |
|---|---|
| `campaign-id` | ID de campaña (UUID) |
| Flag | Descripción |
|---|---|
| `--name` | Nuevo nombre de campaña |
| `--status` | `ENABLED` o `PAUSED` |
| `--country` | Reemplaza la lista de países. Repite para varios |
| `--daily-budget` | Nuevo presupuesto diario |
| `--budget` | Nuevo presupuesto total |
| `--target-cpa` | Nuevo coste objetivo por adquisición |
| `--bidding-strategy` | `MANUAL_CPT` o `MAX_CONVERSIONS` |
| `--currency` | Código de moneda para los importes de esta llamada. Por defecto: `USD` |
| `--invoice-advertiser` | Opciones de facturación: nombre del anunciante |
| `--invoice-order-number` | Opciones de facturación: número de pedido |
| `--invoice-contact-name` | Opciones de facturación: nombre del contacto del comprador |
| `--invoice-contact-email` | Opciones de facturación: email del contacto del comprador |
| `--invoice-billing-email` | Opciones de facturación: email del contacto de facturación |
Al menos un flag es obligatorio.
Los cinco flags `--invoice-*` van juntos y reemplazan las Opciones de Facturación almacenadas como un conjunto, así que pasa los cinco aunque solo quieras cambiar uno. Un conjunto parcial se rechaza antes de enviar la solicitud.
### adapty asa campaigns bulk-create
Crea toda una estructura de campaña — campañas con grupos de anuncios anidados, palabras clave, palabras clave negativas y anuncios — en una sola operación.
```bash
adapty asa campaigns bulk-create --file structure.json
```
Convierte una plantilla bulk nativa de Apple Ads en lugar de escribir el JSON:
```bash
adapty asa campaigns bulk-create --from-file Campaign_And_Adgroup_Template.xlsx --org-id 1234567
```
| Flag | Predeterminado | Descripción |
|---|---|---|
| `--file` | — | Archivo JSON con la estructura de la campaña, o `-` para leer desde la entrada estándar |
| `--from-file` | — | Plantilla en bloque de Apple Ads para convertir en el servidor: [`Campaign_And_Adgroup_Template.xlsx`](https://ads.apple.com/app-store/help/campaigns/0089-make-edits-in-bulk) o un [`.csv` de palabras clave](https://ads.apple.com/app-store/help/keywords/0014-add-and-manage-keywords) |
| `--org-id` | — | ID numérico de organización de Apple (`org_id`). Ver [`orgs list`](#adapty-asa-orgs-list). Obligatorio con `--from-file` |
| `--preview` | — | Con `--from-file`: muestra la estructura convertida y se detiene. No se crea nada |
| `--wait` / `--no-wait` | `--wait` | Consulta el estado de la operación hasta que finaliza. `--no-wait` imprime el ID de la operación y termina |
| `--poll-interval` | `5` | Segundos entre consultas de progreso |
| `--timeout` | `900` | Segundos máximos para esperar a que finalice la operación |
Exactamente uno de `--file` y `--from-file` es obligatorio.
La estructura nombra el grupo de campaña en el nivel superior y anida todo lo demás:
```json title="structure.json"
{
"campaign_group_id": 555777,
"campaigns": [
{
"payload": {
"name": "US Search",
"adam_id": 123456,
"countries_or_regions": ["US"],
"daily_budget_amount": { "amount": "100", "currency": "USD" },
"status": "ENABLED",
"ad_channel_type": "SEARCH",
"billing_event": "TAPS",
"supply_sources": ["APPSTORE_SEARCH_RESULTS"]
},
"ad_groups": [
{
"payload": { "name": "Brand", "start_time": "2026-08-01T00:00:00Z", "status": "ENABLED" },
"keywords": [{ "text": "meditation app", "match_type": "BROAD" }]
}
]
}
]
}
```
`campaign_group_id` acepta el ID numérico de la organización de Apple; usa `campaign_group_internal_id` para pasar el UUID en su lugar. Un nodo con `payload` crea una entidad nueva. Un nodo que referencia una entidad existente por su `id` es un ancla — úsalo para añadir grupos de anuncios a una campaña existente, y añade `update_payload` para modificar la entidad en la misma operación. Cada campaña anida `ad_groups`, y cada grupo de anuncios anida `keywords`, `negative_keywords` y `ads`. Una campaña también acepta `negative_keywords` directamente para las palabras clave a nivel de campaña.
Toda la estructura se valida antes de crear nada, y si hay un rechazo se listan todos los nodos inválidos. Con `--from-file`, los problemas de conversión se notifican con su hoja, fila y columna; los avisos de conversión no detienen el envío, pero los errores de conversión lo abortan. Antes de enviar, el comando informa de cuántas campañas, grupos de anuncios, palabras clave, palabras clave negativas y anuncios contiene la estructura, y pide confirmación.
A continuación, el comando sondea la operación e imprime el progreso hasta que se alcanza uno de los tres estados finales:
| Estado | Significado |
|---|---|
| `success` | Todos los objetos fueron creados |
| `partial` | Algunos objetos no se crearon. Cada error se muestra con el error de Apple |
| `failed` | La operación falló y el comando termina con código distinto de cero |
Si la operación no ha finalizado tras `--timeout` segundos, el comando devuelve e imprime la llamada [`bulk-status`](#adapty-asa-campaigns-bulk-status) para ejecutar más tarde.
### adapty asa campaigns bulk-status
Muestra el progreso de una operación masiva: el estado, el recuento de objetos y el registro por objeto.
```bash
adapty asa campaigns bulk-status
```
| Argumento | Descripción |
|---|---|
| `operation-id` | ID de operación (UUID) que imprime [`campaigns bulk-create`](#adapty-asa-campaigns-bulk-create) |
El campo `status` puede ser `pending`, `running`, `success`, `partial` o `failed`. El bloque `counts` indica cuántos objetos se han aplicado, fallado y están pendientes del total.
Acepta [flags de paginación](#global-flags).
## Grupos de anuncios \{#ad-groups\}
### adapty asa ad-groups list
Lista los [grupos de anuncios](ads-manager-create-ad-group). Devuelve solo metadatos — consulta el rendimiento con [`asa metrics`](#adapty-asa-metrics).
```bash
adapty asa ad-groups list --campaign
```
Acepta [flags de paginación](#global-flags) y los [filtros de lista](#list-filters) `--campaign-group`, `--app`, `--campaign`, `--search` y `--status`.
### adapty asa ad-groups get
Obtén los detalles de un grupo de anuncios específico.
```bash
adapty asa ad-groups get
```
| Argument | Description |
|---|---|
| `ad-group-id` | ID del grupo de anuncios (UUID) |
### adapty asa ad-groups create
Crea un grupo de anuncios en una campaña.
```bash
adapty asa ad-groups create --campaign --name "Brand terms" --default-bid 1.20
```
| Flag | Obligatorio | Descripción |
|---|---|---|
| `--campaign` | Sí | ID de campaña (UUID) |
| `--name` | Sí | Nombre del grupo de anuncios |
| `--default-bid` | Salvo `--automated` | Puja predeterminada como importe simple, por ejemplo `1.20` |
| `--cpa-goal` | No | Objetivo de coste por adquisición |
| `--pricing-model` | No | `CPC` o `CPM`. Apple exige uno en cada grupo de anuncios. Valor predeterminado: `CPC` |
| `--start-time` | No | Inicio de programación (`YYYY-MM-DD`). Por defecto, hoy |
| `--end-time` | No | Fin de programación (`YYYY-MM-DD`) |
| `--automated-keywords` / `--no-automated-keywords` | No | Permite que Apple añada palabras clave automáticamente |
| `--automated` | No | Crea el grupo de anuncios automatizado que necesita una campaña `MAX_CONVERSIONS` |
| `--currency` | No | Código de divisa para los importes de esta llamada. Valor predeterminado: `USD` |
| `--status` | No | Estado inicial: `ENABLED` o `PAUSED` |
`--automated` inscribe al grupo de anuncios en palabras clave automatizadas, por lo que no puede combinarse con `--automated-keywords`. Apple programa el grupo de anuncios automatizado por su cuenta y lo mantiene activo, por lo que `--start-time` y `--status PAUSED` no están permitidos — pausa la campaña en su lugar. Consulta [Crear una campaña de Conversiones Máximas](developer-cli-ads-manager#max-conversions).
### adapty asa ad-groups update
Actualiza un grupo de anuncios existente.
```bash
adapty asa ad-groups update --default-bid 1.50 --status PAUSED
```
| Argumento | Descripción |
|---|---|
| `ad-group-id` | ID del grupo de anuncios (UUID) |
| Flag | Descripción |
|---|---|
| `--name` | Nuevo nombre del grupo de anuncios |
| `--status` | `ENABLED` o `PAUSED` |
| `--default-bid` | Nueva puja predeterminada |
| `--cpa-goal` | Nuevo objetivo de coste por adquisición |
| `--start-time` | Inicio de la programación (`YYYY-MM-DD`) |
| `--end-time` | Fin de la programación (`YYYY-MM-DD`) |
| `--automated-keywords` / `--no-automated-keywords` | Permitir que Apple añada palabras clave automáticamente |
| `--currency` | Código de divisa para los importes de esta llamada. Por defecto: `USD` |
Se requiere al menos un flag. La campaña padre se resuelve en el servidor y nunca se pasa directamente.
## Palabras clave \{#keywords\}
Los comandos de palabras clave se aplican en lotes de un máximo de 100 elementos por llamada. Consulta [Gestionar palabras clave](ads-manager-manage-keywords) para conocer el equivalente en el dashboard.
### adapty asa keywords list
Lista las palabras clave de targeting. Devuelve solo metadatos — consulta las métricas de rendimiento con [`asa metrics`](#adapty-asa-metrics).
```bash
adapty asa keywords list --ad-group --status ACTIVE
```
Acepta [flags de paginación](#global-flags) y los [filtros de lista](#list-filters) `--campaign-group`, `--app`, `--campaign`, `--ad-group`, `--search` y `--status`. Filtra por `--ad-group` — sin filtro, esta es la lectura más amplia del tema.
### adapty asa keywords recommend
Obtén un banco de palabras clave listo para usar para una de tus aplicaciones. Estos son los mismos bancos que utiliza Ads Manager cuando configuras una campaña en el dashboard.
```bash
adapty asa keywords recommend --adam-id --type generic --country US
```
| Flag | Requerido | Descripción |
|---|---|---|
| `--adam-id` | Sí | ID de tu app en el App Store de Apple (`adam_id`), obtenido desde [`asa apps list`](#adapty-asa-apps-list) |
| `--type` | Sí | `brand`, `generic` o `competitor` |
| `--country` | No | Código de país ISO de dos letras. Repite para añadir varios. Por defecto: todos los países del banco |
El flag `--type` selecciona el pool:
| Tipo | Palabras clave |
|---|---|
| `brand` | Los términos de marca de tu app, sus variantes ortográficas y los términos orgánicos que contienen la marca. El resultado también incluye los propios términos de marca |
| `generic` | Términos no relacionados con ninguna marca por los que tu app y sus principales competidores orgánicos aparecen en resultados, con todos los términos de marca conocidos eliminados. `relevance_tier: top_organic` marca los términos donde tu app ya aparece en el top 10 orgánico |
| `competitor` | Los términos de marca de cada competidor seleccionado para la app en [AI Growth Advisor](autopilot-analysis#select-competitors), un grupo por competidor. Está vacío hasta que selecciones competidores |
Cada keyword incluye su país, popularidad, puntuación y rango orgánico medio. Las keywords no tienen pujas ni tipos de concordancia. Elige los que consideres oportunos y luego añade las keywords con [`asa keywords add`](#adapty-asa-keywords-add).
Comprueba el `status` del pool antes de usar sus keywords:
| Estado | Significado |
|---|---|
| `ready` | El pool está listo |
| `building` | El pool se está construyendo. Vuelve a intentarlo en un minuto |
| `empty` | El pool se ha construido y no contiene keywords |
| `failed` | La construcción falló. Inténtalo más tarde |
La primera llamada de `brand` o `generic` para una app construye el pool durante la solicitud y puede tardar decenas de segundos. El comando tiene un límite de 10 llamadas por minuto por empresa, y solo se ejecuta una construcción de `brand` o `generic` a la vez por empresa. Una segunda construcción durante ese tiempo devuelve `429 cli_analytics_busy` con `Retry-After: 5`.
### adapty asa keywords add
Añade palabras clave de segmentación a un grupo de anuncios.
```bash
adapty asa keywords add --ad-group --text "running shoes" --text "trail shoes" --bid 1.20
```
Lee las palabras clave desde un archivo, una por línea:
```bash
adapty asa keywords add --ad-group --from-file keywords.txt
```
| Indicador | Obligatorio | Descripción |
|---|---|---|
| `--ad-group` | Sí | ID del grupo de anuncios (UUID). La campaña se resuelve a partir de él |
| `--text` | Sí, a menos que se use `--from-file` | Texto de la palabra clave. Repite para varias |
| `--from-file` | No | Archivo con una palabra clave por línea. Se combina con los valores `--text` indicados |
| `--bid` | No | Puja por palabra clave como importe simple |
| `--match-type` | No | `BROAD` o `EXACT`. Valor predeterminado: `BROAD` |
| `--currency` | No | Código de moneda para los importes de esta llamada. Valor predeterminado: `USD` |
| `--status` | No | `ACTIVE` o `PAUSED`. Valor predeterminado: `ACTIVE` |
Un ID no válido hace fallar todo el lote antes de llamar a Apple. Apple puede rechazar palabras clave individuales, y cada rechazo se notifica con su motivo.
### adapty asa keywords update
Cambia la puja, el estado, el texto o el tipo de coincidencia de una o varias palabras clave.
```bash
adapty asa keywords update --bid 2.00 --status PAUSED
```
| Argumento | Descripción |
|---|---|
| `keyword-id` | ID de la palabra clave (UUID). Pasa varios como argumentos adicionales |
| Flag | Descripción |
|---|---|
| `--bid` | Nueva puja |
| `--status` | `ACTIVE` o `PAUSED` |
| `--match-type` | `BROAD` o `EXACT` |
| `--text` | Nuevo texto de la palabra clave. Solo tiene sentido para una única palabra clave |
| `--currency` | Código de moneda para los importes de esta llamada. Por defecto: `USD` |
Un único cambio se aplica a cada ID pasado.
## Palabras clave negativas \{#negative-keywords\}
### adapty asa negative-keywords list
Lista las palabras clave negativas. Las filas con `ad_group_id` vacío corresponden al nivel de campaña.
```bash
adapty asa negative-keywords list --campaign
```
| Flag | Descripción |
|---|---|
| `--campaign-level-only` | Conserva solo las filas a nivel de campaña |
Acepta [flags de paginación](#global-flags) y los [filtros de lista](#list-filters) `--campaign-group`, `--app`, `--campaign`, `--ad-group` y `--search`.
### adapty asa negative-keywords add
Añade palabras clave negativas a un grupo de anuncios o a una campaña.
```bash
adapty asa negative-keywords add --ad-group --text free
```
Aplícalas a todos los grupos de anuncios de una campaña en su lugar:
```bash
adapty asa negative-keywords add --campaign --all-ad-groups --text free
```
| Flag | Obligatorio | Descripción |
|---|---|---|
| `--ad-group` | Uno de `--ad-group` o `--campaign` | ID del grupo de anuncios (UUID). La campaña se resuelve a partir de él |
| `--campaign` | Uno de `--ad-group` o `--campaign` | ID de la campaña (UUID) |
| `--text` | Sí | Texto de la palabra clave. Repite para varias |
| `--all-ad-groups` | No | Aplica a todos los grupos de anuncios de la campaña en lugar de a la campaña en sí. Requiere `--campaign` |
| `--match-type` | No | `BROAD` o `EXACT`. Por defecto: `EXACT` |
| `--status` | No | `ACTIVE` o `PAUSED`. Por defecto: `ACTIVE` |
`--ad-group` y `--campaign` son mutuamente excluyentes. Pasa exactamente uno de ellos.
## Términos de búsqueda \{#search-terms\}
### adapty asa search-terms list
Lista los términos de búsqueda que activaron tus anuncios. Úsala para encontrar nuevas palabras clave y nuevas palabras clave negativas.
```bash
adapty asa search-terms list --ad-group --date-from 2026-07-01 --date-to 2026-07-31
```
| Flag | Por defecto | Descripción |
|---|---|---|
| `--date-from` | Hoy | Inicio del período de informe (`YYYY-MM-DD`) |
| `--date-to` | Hoy | Fin del período de informe (`YYYY-MM-DD`) |
Acepta [flags de paginación](#global-flags) y los [filtros de lista](#list-filters) `--campaign-group`, `--app`, `--campaign`, `--ad-group` y `--search`.
Además de sus métricas de rendimiento, cada fila de término de búsqueda incluye los insights de Apple para ese término:
| Campo | Valor |
|---|---|
| `impression_share_all`, `impression_share_first` | Cuota de impresiones en cualquier posición de anuncio, o en la primera posición |
| `impression_midpoint_all`, `impression_midpoint_first` | Cuota de impresiones como un único porcentaje |
| `rank_all`, `rank_first` | La posición de tu app frente a otras apps para el término, en cualquier posición de anuncio o en la primera |
| `search_popularity` | Popularidad de búsqueda de 1 a 5 |
Cada campo es `null` cuando Apple no tiene datos para el término. Consulta [Insights](adapty-ads-manager-metrics#insights) para ver cómo Apple define estos valores.
Este comando comparte un pool de análisis con [`asa metrics`](#metrics). Consulta [Errors](#errors).
## Anuncios \{#ads\}
### Lista de anuncios de Adapty ASA \{#adapty-asa-ads-list\}
Lista [anuncios](ads-manager-manage-ads). El campo `serving_state_reasons` explica por qué un anuncio no está en ejecución.
```bash
adapty asa ads list --ad-group
```
Acepta [flags de paginación](#global-flags) y los [filtros de lista](#list-filters) `--campaign-group`, `--campaign`, `--ad-group`, `--search` y `--status`. Esta lista no tiene el filtro `--app`, ya que los anuncios pertenecen a grupos de anuncios.
### adapty asa ads get
Obtén los detalles de un anuncio específico.
```bash
adapty asa ads get
```
| Argument | Description |
|---|---|
| `ad-id` | Ad ID (UUID) |
### adapty asa ads create
Crea un anuncio en un grupo de anuncios.
```bash
adapty asa ads create --ad-group --creative-id 4321 --name "Summer ad"
```
| Flag | Obligatorio | Descripción |
|---|---|---|
| `--ad-group` | Sí | ID del grupo de anuncios (UUID). La campaña se obtiene a partir de él |
| `--creative-id` | Sí | ID de creatividad de Apple. Véase [`creatives list`](#adapty-asa-creatives-list) |
| `--name` | Sí | Nombre del anuncio |
| `--status` | No | Estado inicial: `ENABLED` o `PAUSED` |
### adapty asa ads update
Actualiza un anuncio existente.
```bash
adapty asa ads update --status PAUSED
```
| Argumento | Descripción |
|---|---|
| `ad-id` | ID del anuncio (UUID) |
| Flag | Descripción |
|---|---|
| `--name` | Nuevo nombre del anuncio |
| `--status` | `ENABLED` o `PAUSED` |
Se requiere al menos un flag. El creativo y el grupo de anuncios padre son fijos desde la creación.
## Creatives \{#creatives\}
### adapty asa creatives list
Lista los creativos disponibles para nuevos anuncios.
```bash
adapty asa creatives list --app
```
El `creative_id` devuelto aquí es el valor `--creative-id` para [`ads create`](#adapty-asa-ads-create).
Acepta [indicadores de paginación](#global-flags) y los filtros de lista `--campaign-group` y `--app` [list filters](#list-filters).
## Páginas de producto \{#product-pages\}
### adapty asa product-pages list
Lista las páginas de producto personalizadas disponibles para tus apps.
```bash
adapty asa product-pages list --app
```
Acepta [flags de paginación](#global-flags) y los filtros de lista `--campaign-group` y `--app` [list filters](#list-filters).
### adapty asa product-pages sync
Actualiza las páginas de producto personalizadas desde App Store Connect.
```bash
adapty asa product-pages sync --adam-id 123456
```
| Flag | Description |
|---|---|
| `--adam-id` | Limita la actualización a una sola app. Omítelo para cubrir todas las apps |
La actualización se pone en cola en lugar de ejecutarse de inmediato, y el comando confirma con `Sync queued.` Si la misma actualización ya está en curso, muestra `Already running; nothing new was queued.` en su lugar.
## Segmentos \{#segments\}
Estos comandos crean [segmentos](segments) de Adapty a partir de campañas, grupos de anuncios o palabras clave de Apple Ads, de la misma forma que **Create segment from…** en [Ads Manager](ads-manager-create-segments). Usa los segmentos como audiencias en placements y pruebas A/B para mostrar a los usuarios de una campaña específica un paywall diferente.
Cada segmento tiene un filtro de atribución sobre los Apple IDs de las entidades que elijas. El CLI busca esos IDs, por lo que debes pasar los UUIDs que muestran los comandos `list`.
A diferencia de otros comandos `adapty asa`, estos aceptan `--app`: el ID de la aplicación de Adapty a la que pertenece el segmento, obtenido de [`adapty apps list`](developer-cli-apps#adapty-apps-list). No aceptan `--idempotency-key`. Para segmentos con otros filtros, como país o fecha de instalación, usa [`adapty segments create`](developer-cli-placements#adapty-segments-create).
### adapty asa segments create
Crea un segmento a partir de campañas, grupos de anuncios o palabras clave.
```bash
adapty asa segments create --app --campaign
adapty asa segments create --app --ad-group --keyword --keyword
```
| Flag | Required | Description |
|---|---|---|
| `--app` | Yes | ID de la app de Adapty (UUID) |
| `--campaign` | Un tipo de entidad | ID de campaña (UUID). Repetible |
| `--ad-group` | Un tipo de entidad | ID de grupo de anuncios (UUID). Repetible. Con `--keyword`, indica exactamente uno: el grupo de anuncios que contiene las palabras clave |
| `--keyword` | Un tipo de entidad | ID de palabra clave (UUID). Repetible. Requiere un `--ad-group` |
| `--title` | No | Título del segmento. Por defecto usa el formato de Ads Manager, por ejemplo `[ASA] Campaign: ` |
| `--description` | No | Descripción del segmento. Por defecto usa el formato de Ads Manager |
Construye cada segmento a partir de un solo tipo de entidad. Pasar `--campaign` y `--ad-group` a la vez, o `--campaign` con `--keyword`, falla con el código de salida `2` antes de enviar ninguna petición. Varias entidades del mismo tipo generan un único segmento que incluye a los usuarios de cualquiera de ellas.
Conserva el título por defecto salvo que necesites otro. Ads Manager reconoce sus segmentos por el prefijo `[ASA]`, y [`asa segments list`](#adapty-asa-segments-list) solo muestra los segmentos con este prefijo.
La respuesta contiene el segmento completo, incluyendo `id` y `filters`. `profile_count` comienza en `0`, y Adapty lo recalcula después de que se crea el segmento.
### adapty asa segments update
Reemplaza las campañas, grupos de anuncios o palabras clave de un segmento existente.
```bash
adapty asa segments update --app --campaign --campaign