Skip to main content
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.
Los endpoints de Automatizaciones te permiten definir reglas que reaccionan automáticamente a las interacciones entrantes en Instagram y a los DMs de páginas de Facebook. 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 solo reacciona a la interacción que un usuario dirige hacia ti (un comentario, respuesta a historia, DM o reacción) — nunca envía DMs activados por seguidores, primeros DMs a desconocidos ni 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.
sent significa que Meta aceptó el mensaje, no que el destinatario lo haya recibido. En Instagram, la entrega está en última instancia dictada por la configuración de Message requests del destinatario: si no permite solicitudes de mensajes de todos, Meta devuelve una respuesta de éxito y descarta silenciosamente el mensaje, y esto es invisible en cada capa de la API. Incluso un DM activado por un comentario y entregado correctamente llega como una solicitud de mensaje que el destinatario debe aceptar (a menos que ya exista una conversación entre las dos cuentas). Consulta DM de automatización enviado pero no entregado para la explicación completa.

Cómo funciona

1

Crea una automatización

POST /automations con los disparadores y las acciones que deseas. La automatización se activa de inmediato.
2

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.
3

Ayrshare hace coincidir y despacha

Se aplica un jitter de 20 a 60 segundos a la interacción para mantenerse dentro de las heurísticas anti-spam de Instagram. Después, 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, y ejecuta cada acción.
4

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.

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. La columna Plataformas muestra dónde está disponible cada disparador; consulta Páginas de Facebook para ver lo que necesita Facebook. 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.

Reglas perennes con "all"

Establece postId (o storyId) en la cadena literal en minúsculas "all" para que se active en todas las publicaciones, reels o historias de la cuenta conectada en lugar de en una pieza de contenido específica. Esto es lo que quieres para una regla que deba seguir funcionando a medida que se publica contenido nuevo, sin una llamada a la API por cada publicación:
El valor debe ser exactamente "all". Una variante como "ALL" o " all" se rechaza con un error de validación en lugar de guardarse como un ID de publicación que nunca coincidiría. "all" nunca se amplía más allá de la cuenta conectada — una regla en un perfil no puede activarse con el contenido de otro perfil. Tu tope diario de DM y las reglas de envío ancladas a la interacción se aplican exactamente igual que en una regla de publicación única.
La desduplicación se cuenta por automatización y destinatario, no por publicación. En una regla "all", un usuario que comenta una palabra clave en dos publicaciones diferentes dentro de la ventana de desduplicación (7 días de forma predeterminada) recibe el DM solo una vez; la segunda actividad se registra como deduplicated. Un dedupWindowMinutes más pequeño solo acorta esa ventana; no hace que la desduplicación sea por publicación. Establecerlo en 0 desactiva la desduplicación, por lo que cada comentario coincidente envía un DM, incluidos los comentarios repetidos en la misma publicación.
En los disparadores de historia, omitir storyId se comporta igual que "all". Prefiere "all" — expresa la intención de forma explícita, y la omisión se retirará en una versión futura con aviso anticipado en Próximos cambios de la API.

Páginas de Facebook

Establece platform en facebook para ejecutar una automatización en la página de Facebook vinculada al perfil. Los DMs se envían desde la página a través de Messenger.
  • Disparadores: dm_keyword y dm_reaction. Por ahora, los disparadores de comentarios y de historias son solo para Instagram, y una automatización de Facebook que use uno de ellos se rechaza con un error de validación.
  • Mensajería: el perfil necesita tener Messaging activado para Facebook, igual que para enviar un DM de Facebook con la Messages API.
  • Destinatario: {{recipient_id}} es el ID del usuario con ámbito de página (PSID). {{recipient_username}} está vacío, porque los webhooks de Messenger no incluyen un nombre de usuario.

Acciones

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

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).
Action with a 24h dedup override

Contenido dinámico del mensaje

De forma predeterminada, send_dm envía el mismo message a todas las personas que activan la regla. Los placeholders como {{recipient_username}} son lo único que cambia de una persona a otra. Establece messageUrl en la acción y, en su lugar, tu propio servidor escribe el DM para cada persona: cada vez que la regla coincide, le preguntamos a tu endpoint qué decir y luego enviamos su respuesta como el DM. Ejemplo. Tu regla responde a cualquiera que comente “LINK” en una publicación, y messageUrl apunta a tu servidor. Cuando Ava comenta “LINK please!”:
  1. Hacemos un POST con los detalles a tu messageUrl: quién comentó ("recipientUsername": "ava"), qué escribió y en qué publicación.
  2. Tu servidor escribe una respuesta para Ava, por ejemplo con un enlace de seguimiento creado solo para ella, y responde { "message": "Hi ava, here's your link: https://example.com/r/12345" }.
  3. Enviamos ese texto a Ava como el DM, exactamente como lo escribiste.
Si tu servidor no responde dentro de timeoutMs, devuelve un error o devuelve algo que no podemos usar, enviamos a Ava el message habitual de la acción, para que igualmente reciba una respuesta. Agrégalo a una acción send_dm así:
send_dm with messageUrl
messageUrl es donde pedimos el texto. message sigue siendo requerido y es la alternativa: nunca se envía a tu servidor, y lo enviamos por DM en su lugar siempre que tu servidor no responda a tiempo, devuelva un error o devuelva algo que no podemos usar (consulta la advertencia a continuación). timeoutMs es opcional (predeterminado 3000, máximo 5000). Qué enviamos a tu endpoint. Un POST con este cuerpo JSON:
Callback request body
Si has registrado un secreto de webhook, el cuerpo se firma con el mismo secreto que tus webhooks de automations, de la misma manera: X-Authorization-Content-SHA256 es el HMAC-SHA256 del cuerpo sin procesar, y X-Authorization-Timestamp lleva el timeStamp del cuerpo. El código de verificación que ya usas para nuestros webhooks funciona sin cambios. Si hay un secreto registrado pero no podemos leerlo en ese momento, no enviamos el callback sin firmar; en su lugar enviamos tu plantilla message. A dónde puede apuntar. messageUrl debe ser una dirección HTTPS pública. Se rechaza una URL que se resuelva a una dirección privada, de loopback, link-local o de metadatos de la nube, y no se siguen las redirecciones — una respuesta 3xx cuenta como un fallo. En cualquier caso, se envía la plantilla en su lugar. Qué devuelve tu endpoint. Devuelve 200 con un cuerpo JSON, de 16 KB como máximo, que contenga una cadena message de 1 a 1000 caracteres:
Tu texto se envía tal cual. No se le aplica la sustitución de {{placeholder}}, por lo que un {{ literal en tu texto generado llega al destinatario tal como está escrito.
message sigue siendo requerido, y no es decorativo. Si tu endpoint agota el tiempo de espera, devuelve un código distinto de 2xx, devuelve un cuerpo que no podemos usar o ha sido cortado temporalmente por el circuit breaker tras fallos repetidos, enviamos en su lugar la plantilla message renderizada. Ese envío aún puede fallar, por ejemplo si la plantilla se renderiza vacía (ver más abajo) o Instagram la rechaza. Nunca reintentamos el callback — un reintento podría enviar dos mensajes al destinatario.
timeoutMs es 3000 de forma predeterminada. El máximo es 5000: un valor mayor se rechaza con un error de validación al crear o actualizar la automatización. Cubre todo el intercambio, incluida la lectura del cuerpo de tu respuesta. Tenlo en cuenta: el DM se envía después de que tu endpoint responde, así que un endpoint lento retrasa el mensaje. Comprueba qué camino tomó un disparo en GET /automations/:id/activity. Una entrada send_dm en actionResults[] lleva messageSource una vez que se ha determinado el texto del DM, incluso cuando el envío falla después. Está ausente cuando la acción se detuvo antes de eso, por ejemplo un DM skipped a tu propia cuenta o una acción deduplicated: messageSource indica a partir de qué texto se construyó el DM, no si se entregó. Para eso, lee el status de la entrada. Una alternativa por sí sola no hace fallar la acción: cuando el DM de la plantilla se entrega, la entrada es sent, con el motivo por el que no se usó el callback en errorDetails. Si el DM de la plantilla también falla, la entrada es failed y errorDetails da el error de envío seguido del motivo del callback. Vigílalo: de lo contrario, un callback que falla en cada disparo se ve exactamente igual que uno que funciona. Mantén tu message enviable por sí solo. Si se renderiza vacío para un destinatario, por ejemplo {{recipient_username}} solo en un disparador de DM que no incluye nombre de usuario, y no se usa el texto de tu callback, no se envía ningún DM y la acción es failed con el motivo en errorDetails.

Eventos de webhook

Se entregan dos eventos a la acción de webhook automations que registras con POST /hook/webhook. Ambos llevan un campo type — ramifica en él antes de leer cualquier otra cosa.
automation.completed está desactivado de forma predeterminada. Actívalo para una automatización estableciendo "sendCompletedEvent": true en su acción fire_webhook. De lo contrario permanece desactivado, para que un receptor construido para una carga útil por disparo siga recibiendo exactamente una. automation.triggered no es un registro de cada coincidencia: se envía solo cuando fire_webhook en sí se ejecuta, por lo que una coincidencia que termina en rate_limited o deduplicated produce únicamente automation.completed. Ninguno de los dos eventos se envía para una automatización que fue desactivada o eliminada antes de que se ejecutara el envío.

automation.triggered

activityId es la fila que devuelve GET /automations/:id/activity, para que puedas unir los dos con exactitud en lugar de hacer coincidir recipientId + triggerId + keyword — lo cual es ambiguo cuando varias personas comentan la misma palabra clave a la vez. actionId es la acción fire_webhook que envió el evento, y coincide con actionResults[].actionId; distingue entre dos acciones fire_webhook en la misma regla. Los campos que un disparador no completa son null en lugar de omitirse, para que la forma sea estable. recipientUsername es null para dm_keyword, dm_reaction y story_reply, porque la carga útil de Meta no incluye uno. commentId se establece solo para comment_keyword y story_comment, postId solo para comment_keyword, y storyId solo para los disparadores de historia. story_reply no tiene keyword. Para dm_keyword, commentText es el texto del DM; para dm_reaction, commentText y keyword son ambos el emoji de la reacción.

automation.completed

Se envía solo cuando la automatización lo activa en su acción fire_webhook:
fire_webhook action with the outcome event on
status y cada actionResults[].status usan los mismos valores que el registro de actividad — sent, failed, rate_limited, deduplicated, skipped, auth_error — por lo que en el caso normal sabes cómo terminó un envío sin hacer polling. Sin embargo, la entrega de este evento es de mejor esfuerzo: si el proceso se detiene entre registrar el resultado y encolar el evento, no se envía. El registro de actividad es la fuente de verdad, así que si necesitas todos los resultados, reconcilia contra GET /automations/:id/activity para cualquier activityId que no haya reportado uno. Un resultado de send_dm también lleva messageSource, como en el registro de actividad: template, callback o fallback, para que puedas detectar un messageUrl que recurre repetidamente a la alternativa sin hacer polling. Haz coincidir los resultados con tus acciones configuradas por actionId, no por posición — dos acciones del mismo tipo solo se distinguen de esa manera. actionResults está vacío en tres casos, cada uno con el motivo en el errorDetails de nivel superior cuando lo hay: rate_limited (se alcanzó tu tope diario), deduplicated (todas las acciones estaban dentro de su ventana de desduplicación), y failed después de que el envío se reintentara el número máximo de veces sin terminar. En este último caso, algunas acciones pueden haberse ejecutado ya, por lo que un DM puede haber salido y automation.triggered puede haberse enviado ya. La entrega de webhooks es al menos una vez, por lo que el mismo evento puede llegar ocasionalmente dos veces, y un envío que se reintenta puede enviar automation.triggered de nuevo con un nuevo hookId. Nunca desdupliques por hookId. Usa una clave distinta para cada tipo de evento, de modo que procesar uno nunca suprima el otro: automation.completed por activityId (cada actividad tiene un solo resultado), y automation.triggered por activityId más actionId (uno por cada acción fire_webhook). Los dos eventos se entregan de forma independiente, por lo que automation.completed puede llegar ocasionalmente antes que automation.triggered.

Si no hay ningún webhook registrado

fire_webhook publica en la acción automations registrada en el perfil, con tu Primary Profile como respaldo. No hay respaldo a otra acción como messages. Si no existe ninguno de los dos registros, automation.triggered no se descarta silenciosamente: la acción se registra en la fila de actividad como failed, con el motivo en actionResults[].errorDetails. (automation.completed tampoco tiene adónde ir, y no se registra.) El estado general del envío sigue entonces la precedencia habitual: auth_error si alguna acción tuvo un error de autenticación, en caso contrario sent si alguna acción fue aceptada, en caso contrario failed. Así que el webhook faltante cuenta para las estadísticas de fallos de la automatización solo cuando nada más en la regla envió; cuando otra acción sí envió (y ninguna tuvo un error de autenticación), el envío termina en sent y el webhook fallido aparece solo en actionResults[]. Un resultado sent de fire_webhook significa que el evento se encoló para su entrega a tu URL, no que tu endpoint lo haya aceptado. La entrega se reintenta después según su propio calendario.

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.
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.
Ejemplo de plantilla:

Límites de tasa y topes

El tope de automatizaciones activas se cuenta por perfil de usuario, no por cuenta principal. Cada perfil bajo tu cuenta obtiene sus propios 10 de Launch/Business o 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 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. El límite de conversaciones de mensajería también se aplica. send_dm requiere el complemento Messaging en el perfil, y cada DM que envía cuenta para el límite de conversaciones mensual de ese perfil, igual que un DM que envías tú mismo. Cuando se alcanza el límite, un send_dm a un nuevo destinatario no se envía y la fila de actividad registra el estado failed, con el mensaje del límite en actionResults[].errorDetails. Los DM activados por un comentario (comment_keyword y story_comment) son la excepción: se siguen enviando al alcanzar el límite, y se siguen contando. 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[]: pending e in_flight son transitorios; todo lo demás es terminal. Cuando una automatización tiene más de una acción, el status de nivel superior se deriva de los resultados por acción en este orden: auth_error si alguna acción tuvo un error de autenticación, luego sent si alguna acción fue aceptada, luego deduplicated si todas las acciones fueron desduplicadas, luego skipped si todas las acciones fueron suprimidas deliberadamente (skipped o deduplicated), en caso contrario failed. Consulta actionResults[] para el detalle por acción.
sent es un acuse de recepción de aceptación por parte de la plataforma, no un acuse de entrega. Una acción send_dm se marca como sent en el momento en que Meta acepta el mensaje, ya se envíe desde tu cuenta de Instagram o por Messenger desde tu página de Facebook. La automatización solo registra esa aceptación; no hace seguimiento de la entrega. Instagram no expone la entrega de mensajes a ninguna API, y que el destinatario lo reciba realmente depende de su configuración de Message requests de Instagram, que Ayrshare no puede leer ni modificar. Consulta DM de automatización enviado pero no entregado.

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.
Los planes Launch están incluidos. Business Launch se resuelve al nivel Business, por lo que las automatizaciones están disponibles en Launch, Business y Enterprise. 468 solo se devuelve a los planes que no incluyen automatizaciones.

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 haya interactuado primero (comentario, respuesta, DM, reacción) antes de que una cuenta comercial pueda enviarle un mensaje. Cada disparador admitido está anclado a esa interacción, pero ten en cuenta que estar autorizado a enviar no es lo mismo que el mensaje sea entregado: la configuración de Message requests de Instagram del destinatario aún puede provocar que Meta acepte y después descarte silenciosamente el mensaje (consulta DM de automatización enviado pero no entregado).
  • 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

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 interactuado primero. Cada disparador admitido (comment_keyword, story_reply, dm_reaction, dm_keyword) está anclado a una interacción de ese tipo, que es lo que hace admisible el envío.
sent significa que Meta aceptó el mensaje, no que se haya entregado. Esto aplica tanto en Instagram como en Facebook (Messenger desde tu página): la automatización solo registra la aceptación y no hace seguimiento de la entrega. En Instagram, la entrega depende de la configuración de Message requests de Instagram del destinatario — si no permite solicitudes de mensajes de todos, Meta devuelve una respuesta de éxito y descarta silenciosamente el mensaje, sin error, webhook ni ninguna otra señal en ninguna superficie de la API. Un DM activado por un comentario y entregado correctamente también llega como una solicitud de mensaje que el destinatario debe aceptar (a menos que ya exista una conversación). Esta es una limitación permanente de la plataforma Instagram. Consulta DM de automatización enviado pero no entregado.
Si las credenciales de Instagram o de la página de Facebook, o los permisos de mensajería de la cuenta fallan de verdad — por ejemplo, un token de acceso caducado o revocado, una Facebook Page no seleccionada, o Messaging no activado para el perfil — la fila de actividad registra el estado auth_error y el DM no se reintenta. Al resolver el estado de la cuenta (volviendo a vincularla, seleccionando una Page o activando Messaging), la siguiente interacción coincidente se activará normalmente. Esto solo se aplica a fallos reales de credenciales y permisos: si un DM concreto no se pudo entregar por otro motivo — por ejemplo, no se pudo encontrar al destinatario, o la interacción que activó la regla provino de la cuenta que enviaría el DM — la fila se registra como failed o skipped con el motivo en actionResults[].errorDetails, y volver a vincular no cambiará el resultado.
Cada envío se programa entre 20 y 60 segundos después de la interacción para que los envíos de DM parezcan orgánicos ante los sistemas anti-spam de Instagram. El retraso se aplica a la interacción antes de evaluar cualquier regla, por lo que afecta a todas las acciones de la regla, incluidas fire_webhook y send_email: tu webhook llegará entre 20 y 60 segundos después del comentario, no de inmediato. La marca de tiempo created de la fila de actividad es cuando coincidió el disparador; completedAt es cuando terminó el envío.
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.)
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.

Endpoints