> ## Documentation Index
> Fetch the complete documentation index at: https://www.ayrshare.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Visión general de la API de Automatizaciones

> Automatizaciones de Instagram activadas por interacciones — envía un DM, un webhook o un correo electrónico cuando un usuario final comenta, responde a una historia, reacciona a un DM o envía un DM

export const PlansAvailable = ({plans = [], maxPackRequired}) => {
  let displayPlans = plans;
  if (plans && plans.length === 1) {
    const lowerCasePlan = plans[0].toLowerCase();
    if (lowerCasePlan === "business") {
      displayPlans = ["Launch", "Business", "Enterprise"];
    } else if (lowerCasePlan === "premium") {
      displayPlans = ["Premium", "Launch", "Business", "Enterprise"];
    }
  }
  return <Note>
Available on {displayPlans.length === 1 ? "the " : ""}
{displayPlans.join(", ").replace(/\b\w/g, l => l.toUpperCase())}{" "}
{displayPlans.length > 1 ? "plans" : "plan"}.

{maxPackRequired && <span onClick={() => window.open('https://www.ayrshare.com/docs/additional/maxpack', '_self')} className="flex items-center mt-2 cursor-pointer">
 <span className="px-1.5 py-0.5 rounded text-sm" style={{
    backgroundColor: '#C264B6',
    color: 'white',
    fontSize: '12px'
  }}>
   Max Pack required
 </span>
</span>}
</Note>;
};

<PlansAvailable plans={["business", "enterprise"]} maxPackRequired={false} />

<Note>
  **Beta.** La API de Automatizaciones está en beta y estamos recopilando comentarios activamente. Los endpoints, las cargas útiles y los límites pueden cambiar a medida que iteramos. Envía comentarios e informes de errores a soporte para que podamos priorizar las mejoras correctas.
</Note>

Los endpoints de Automatizaciones te permiten definir reglas que reaccionan automáticamente a las interacciones entrantes en Instagram. Cada automatización combina uno o más **disparadores** (el evento que activa la regla) con una o más **acciones** (lo que sucede cuando se activa). Una sola regla puede escuchar múltiples disparadores y despachar múltiples acciones: enviar un webhook a tu canal de analíticas Y enviar un DM a partir de la misma interacción.

El motor se ejecuta enteramente dentro del marco de políticas de Meta (sin DMs activados por seguidores, sin primer mensaje a desconocidos, sin envíos masivos) y hereda los límites de tasa por cuenta de Ayrshare, la desduplicación por destinatario y la ingesta idempotente de webhooks.

## Cómo funciona

<Steps>
  <Step title="Crea una automatización">
    `POST /automations` con los disparadores y las acciones que deseas. La automatización se activa de inmediato.
  </Step>

  <Step title="Un usuario final interactúa">
    Alguien comenta tu publicación, responde a tu historia, envía un DM o reacciona a un DM. Meta entrega el webhook a Ayrshare.
  </Step>

  <Step title="Ayrshare hace coincidir y despacha">
    El motor busca todas las reglas que coinciden con el evento, verifica la desduplicación por acción y tu límite diario de DM, luego ejecuta cada acción. Se aplica un jitter de 20 a 60 segundos a los envíos de DM para mantenerse dentro de las heurísticas anti-spam de Instagram.
  </Step>

  <Step title="Inspecciona qué se activó">
    `GET /automations/:id/activity` devuelve el registro de auditoría: cada intento de envío, los resultados por acción y cualquier error.
  </Step>
</Steps>

## Disparadores

Puedes adjuntar hasta **50 disparadores** a una sola automatización. Cada disparador es una unión discriminada por el campo `type`; los campos específicos del tipo están al mismo nivel. Todos los disparadores son solo para Instagram en la v1.

| Tipo              | Se activa cuando                                                                    | Configuración                                                 |
| ----------------- | ----------------------------------------------------------------------------------- | ------------------------------------------------------------- |
| `comment_keyword` | Un comentario que coincide con una palabra clave llega a una publicación específica | `postId` (requerido); `keywords` (requerido, ≥1 entrada)      |
| `story_reply`     | Un usuario responde a una historia mediante DM                                      | `storyId` (opcional)                                          |
| `dm_reaction`     | Un usuario reacciona a uno de tus DMs con un emoji                                  | `emoji` (opcional — omítelo para activar con cualquier emoji) |
| `dm_keyword`      | Un usuario envía un DM cuyo texto coincide con una palabra clave                    | `keywords` (requerido, ≥1 entrada)                            |

La coincidencia de palabras clave **no distingue entre mayúsculas y minúsculas** y es por palabra completa. Un evento satisface un disparador con filtro de palabras clave si contiene alguna de las palabras clave configuradas. Omite `storyId` en un disparador de historia para que se active en todas las historias de la cuenta conectada.

## Acciones

Puedes adjuntar hasta **50 acciones** a una sola automatización. Se ejecutan secuencialmente; cada resultado se registra en la fila de actividad.

| Tipo           | Efecto                                                                                                                                                          | Configuración                                                                                      |
| -------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- |
| `send_dm`      | Envía un DM de Instagram al usuario que activó la regla, usando un [mensaje con plantilla](#template-variables).                                                | `message` (requerido, con plantilla)                                                               |
| `fire_webhook` | Realiza un POST del contexto de la automatización a la URL de webhook a nivel de cuenta (configúrala mediante [`POST /hook/webhook`](/apis/webhooks/register)). | *(ninguna — la forma de la carga útil es fija; ver [abajo](#fire_webhook-payload))*                |
| `send_email`   | Encola un correo electrónico a través del pipeline de correo de la plataforma.                                                                                  | `to` (requerido, email); `subject` (opcional, con plantilla); `message` (requerido, con plantilla) |

### Ventana de desduplicación por acción

Cada acción, sin importar el tipo, acepta adicionalmente un campo `dedupWindowMinutes` opcional de nivel superior que sobrescribe la ventana de desduplicación por destinatario **predeterminada de 7 días** solo para esa acción.

* Establécelo en `0` para **deshabilitar** la desduplicación por completo para esa acción (típico para `fire_webhook` / `send_email` donde el receptor espera cada evento).
* Limitado a `525600` (un año).

```json Action with a 24h dedup override theme={"system"}
{
  "type": "send_dm",
  "message": "Thanks {{recipient_username}}!",
  "dedupWindowMinutes": 1440
}
```

### Carga útil de `fire_webhook`

Cuando se ejecuta `fire_webhook`, realiza un POST de un cuerpo JSON a tu URL de webhook a nivel de cuenta:

```json theme={"system"}
{
  "automationId":      "auto_9xKp2Lm4nQ",
  "triggerId":         "trg_a1b2c3",
  "trigger":           "comment_keyword",
  "platform":          "instagram",
  "recipientId":       "17841401234567890",
  "recipientUsername": "jane_doe",
  "keyword":           "LINK",
  "timestamp":         "2026-05-12T09:14:22.000Z"
}
```

`recipientUsername` y `keyword` son `null` cuando el disparador no los completa (por ejemplo, `dm_keyword` no incluye un nombre de usuario en la carga útil de Meta; `story_reply` no tiene una palabra clave).

## Variables de plantilla

`send_dm.message`, `send_email.subject` y `send_email.message` admiten sustitución con `{{placeholder}}`. **Los placeholders desconocidos se rechazan en el momento de creación/actualización** (como un error de validación `473`) para que un error tipográfico nunca deje pasar el literal `{{foo}}` a un mensaje visible para el cliente.

| Placeholder              | Se resuelve como                                                                             |
| ------------------------ | -------------------------------------------------------------------------------------------- |
| `{{recipient_username}}` | El handle de Instagram del usuario que interactúa (cuando el webhook lo incluye)             |
| `{{recipient_id}}`       | El ID de participante de Instagram (IGSID) del usuario que interactúa                        |
| `{{recipient_name}}`     | Reservado; se resuelve como vacío hasta que una futura fuente de enriquecimiento lo complete |
| `{{sender_username}}`    | Tu nombre de usuario de Instagram vinculado                                                  |
| `{{sender_name}}`        | Tu nombre para mostrar de Instagram vinculado                                                |
| `{{comment_text}}`       | El texto del comentario / DM / respuesta a la historia que activó el disparador              |
| `{{comment_id}}`         | El ID de plataforma del comentario / mensaje que se activó                                   |
| `{{comment_sent_at}}`    | Marca de tiempo ISO 8601 del evento (cuando esté disponible)                                 |
| `{{matched_keyword}}`    | La palabra clave que coincidió (o la cadena del emoji para `dm_reaction`)                    |
| `{{platform}}`           | Identificador de la plataforma (por ejemplo, `instagram`)                                    |
| `{{trigger_type}}`       | Tipo de disparador (por ejemplo, `comment_keyword`)                                          |

<Note>
  **No hay `sender_email` / `recipient_email`.** Estos no se exponen deliberadamente: tu correo electrónico de facturación no tiene lugar legítimo en un DM a un desconocido, y Meta no proporciona el correo electrónico del destinatario en ningún webhook de IG. Evitar los placeholders previene divulgaciones accidentales.
</Note>

Ejemplo de plantilla:

```
Hey {{recipient_username}}, thanks for the comment "{{comment_text}}" — here is the link you wanted: https://example.com
```

## Límites de tasa y topes

| Plan       | Automatizaciones activas (por perfil) | Tope diario de DM (por cuenta) |
| ---------- | ------------------------------------- | ------------------------------ |
| Business   | 10                                    | 1000                           |
| Enterprise | 50                                    | 5000                           |

El tope de automatizaciones activas se cuenta **por [perfil de usuario](/apis/profiles/overview)**, no por cuenta principal. Cada perfil bajo tu cuenta obtiene su propio 10 de Business / 50 de Enterprise, por lo que una cuenta con muchos perfiles puede ejecutar esa cantidad de automatizaciones en cada uno. Cuenta las automatizaciones activas y se aplica tanto en `POST` (crear) como en la reactivación con `PUT` (`active: false → true`), cada una arrojando el código de error `470`. ¿Necesitas un límite por perfil más alto? [Contacta a soporte](mailto:support@ayrshare.com) para que se aumente en tu cuenta.

El **tope diario de DM** se aplica por cuenta principal de Ayrshare, se comparte entre todos tus perfiles y tiene un sub-tope por perfil para que un perfil muy activo no consuma toda la cuota de la cuenta. Cuando se alcanza un tope de DM, la fila de actividad registra el estado `rate_limited` y no se envía ningún DM.

Topes estructurales en una sola automatización: **1–50 disparadores**, **1–50 acciones**.

Instagram por sí mismo limita los DMs a aproximadamente 200/hora por cuenta. El motor regula el envío con un jitter de 20 a 60 segundos para mantenerse con seguridad por debajo de este.

## Estados de actividad

Una fila en `GET /automations/:id/activity` lleva un `status` de nivel superior más un `status` por acción dentro de `actionResults[]`:

| Estado         | Significado                                                                             |
| -------------- | --------------------------------------------------------------------------------------- |
| `pending`      | Recién escrita; el worker aún no la ha tomado                                           |
| `in_flight`    | El worker está enviando actualmente                                                     |
| `sent`         | Todas las acciones tuvieron éxito                                                       |
| `failed`       | Al menos una acción falló (y ninguna dio error de autenticación)                        |
| `auth_error`   | El token de acceso de Instagram no era válido; el DM no se reintentó                    |
| `rate_limited` | Se alcanzó el tope diario de DM (por nivel o por perfil); no se envió el DM             |
| `deduplicated` | Esta acción ya se disparó para este destinatario dentro de su ventana de desduplicación |
| `skipped`      | La automatización quedó inactiva o fue eliminada entre la propagación y el envío        |

`pending` e `in_flight` son transitorios; todo lo demás es terminal.

## Códigos de error

La API devuelve dos formas de error:

* **Errores de regla de negocio** llevan un `code` numerado de automatización (por ejemplo, `{ "action": "automation", "code": 469, ... }`).
* **Errores de validación** — cualquier cuerpo de solicitud mal formado (campos faltantes o inválidos, variables de plantilla desconocidas, claves no reconocidas) — se devuelven como una única respuesta **`473`** con un objeto `details` que lista los campos ofensivos. `details` es la salida del validador (`formErrors` más `fieldErrors`). Ramifica en `details`, no en un código por condición. En `fieldErrors`, las claves son los campos de nivel superior de la solicitud (`triggers`, `actions`): un problema dentro de una entrada específica, como un disparador al que le falta `keywords`, se reporta bajo ese campo (por ejemplo, `triggers`), mientras que `formErrors` contiene problemas de nivel de objeto, como claves no reconocidas.

| Código | HTTP | Significado                                                                                |
| ------ | ---- | ------------------------------------------------------------------------------------------ |
| 468    | 403  | Se requiere plan Business o Enterprise                                                     |
| 469    | 404  | Automatización no encontrada (también se devuelve cuando el llamador no es su propietario) |
| 470    | 429  | Se alcanzó el tope de automatizaciones activas para tu nivel de plan                       |
| 471    | 400  | No hay cuenta social vinculada en la plataforma solicitada para este perfil                |
| 472    | 403  | Funcionalidad aún no disponible en tu cuenta — contáctanos para acceso anticipado          |
| 473    | 400  | La validación falló (cuerpo de solicitud mal formado) — inspecciona `details`              |

## Lo que Meta NO permite

Algunas capacidades comúnmente solicitadas no se admiten porque Meta no las permite en la API pública de Instagram:

* **Auto-DM en nuevos seguidores.** Instagram no publica un webhook de seguimiento.
* **Primeros DMs a desconocidos.** Meta requiere que el destinatario inicie el contacto (comentario, respuesta, DM, reacción) antes de que una cuenta comercial pueda enviarle un mensaje, que es exactamente lo que representa cada disparador admitido aquí.
* **Campañas masivas de salida.** Los topes de DM por hora y las heurísticas anti-abuso se aplican a nivel de plataforma.

## Uso multi-perfil

Los endpoints respetan el encabezado `profileKey`. Pasa la clave de un perfil secundario y la automatización se crea/gestiona bajo ese perfil. Los límites de tasa se dividen entre perfiles mediante un sub-tope por perfil, para que un perfil muy conversador no drene la cuota de la cuenta principal.

## Preguntas frecuentes

<AccordionGroup>
  <Accordion title="¿Puedo activar en un nuevo seguidor?">
    No. Instagram no publica un webhook de seguimiento, y Meta no permite que las aplicaciones de terceros envíen un DM a un usuario que no ha iniciado una conversación. Cada disparador admitido (`comment_keyword`, `story_reply`, `dm_reaction`, `dm_keyword`) satisface el requisito de "el usuario te contactó primero".
  </Accordion>

  <Accordion title="¿Qué sucede si mi token de acceso no es válido cuando se activa una automatización?">
    La fila de actividad registra el estado `auth_error` y el DM no se reintenta. Vuelve a vincular la cuenta; a continuación, la siguiente interacción coincidente se activará normalmente.
  </Accordion>

  <Accordion title="¿Por qué hay un retraso antes de que se envíe el DM?">
    Cada envío de `send_dm` se programa entre 20 y 60 segundos después de la interacción para parecer orgánico ante los sistemas anti-spam de Instagram. Las acciones `fire_webhook` y `send_email` NO tienen jitter. La marca de tiempo `created` de la fila de actividad es cuando coincidió el disparador; `completedAt` es cuando terminó el envío.
  </Accordion>

  <Accordion title="¿Las filas de actividad se conservan para siempre?">
    Las filas de actividad se conservan de forma indefinida para trazabilidad y analíticas. El endpoint `GET /automations/:id/activity` devuelve las filas de los últimos 30 días por rendimiento. (La protección de desduplicación usa su propia ventana por acción — con un valor predeterminado de 7 días — que no está relacionada con el retroactivo de actividad.)
  </Accordion>

  <Accordion title="¿Eliminar una automatización elimina su historial de actividad?">
    No. La eliminación es un borrado lógico: la fila maestra se marca como `deleted`, no se producen nuevos envíos, pero las filas de actividad históricas siguen siendo legibles a través del endpoint de actividad.
  </Accordion>
</AccordionGroup>

## Endpoints

* [`POST /automations`](/apis/automations/create-automation) — crea una nueva automatización
* [`GET /automations`](/apis/automations/list-automations) — lista tus automatizaciones
* [`GET /automations/:id`](/apis/automations/get-automation) — obtén una automatización con sus disparadores y acciones
* [`PUT /automations/:id`](/apis/automations/update-automation) — actualización parcial; pausa con `active: false`
* [`DELETE /automations/:id`](/apis/automations/delete-automation) — borrado lógico
* [`GET /automations/:id/activity`](/apis/automations/get-activity) — registro de auditoría de envíos paginado por cursor
