curl \
-H "Authorization: Bearer API_KEY" \
-X GET "https://api.ayrshare.com/api/automations/auto_9xKp2Lm4nQ/activity?limit=25"
curl \
-H "Authorization: Bearer API_KEY" \
-X GET "https://api.ayrshare.com/api/automations/auto_9xKp2Lm4nQ/activity?limit=25&next=eyJ0aW1lIjoiMjAyNi0wNS0xMlQw..."
const API_KEY = "API_KEY";
const id = "auto_9xKp2Lm4nQ";
// Paginate through every page
let next;
do {
const url = new URL(`https://api.ayrshare.com/api/automations/${id}/activity`);
url.searchParams.set("limit", "25");
if (next) url.searchParams.set("next", next);
const res = await fetch(url, {
headers: { "Authorization": `Bearer ${API_KEY}` },
});
const json = await res.json();
console.log(json.activity);
next = json.meta?.pagination?.hasMore ? json.meta.pagination.next : undefined;
} while (next);
import requests
headers = {"Authorization": "Bearer API_KEY"}
automation_id = "auto_9xKp2Lm4nQ"
params = {"limit": 25}
while True:
r = requests.get(
f"https://api.ayrshare.com/api/automations/{automation_id}/activity",
params=params,
headers=headers,
).json()
print(r["activity"])
pagination = r.get("meta", {}).get("pagination", {})
if not pagination.get("hasMore"):
break
params["next"] = pagination["next"]
$id = "auto_9xKp2Lm4nQ";
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.ayrshare.com/api/automations/" . $id . "/activity?limit=25",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => ["Authorization: Bearer API_KEY"],
]);
$response = curl_exec($curl);
curl_close($curl);
echo $response;
{
"status": "success",
"automationId": "auto_9xKp2Lm4nQ",
"activity": [
{
"id": "auto_9xKp2Lm4nQ:trg_a1b2c3:comment.received:18012345678901234",
"automationId": "auto_9xKp2Lm4nQ",
"triggerId": "trg_a1b2c3",
"triggerType": "comment_keyword",
"recipientId": "17841401234567890",
"recipientUsername": "jane_doe",
"eventId": "comment.received:18012345678901234",
"commentId": "18012345678901234",
"platform": "instagram",
"status": "sent",
"actionResults": [
{
"actionId": "act_d4e5f6",
"type": "send_dm",
"status": "sent",
"errorDetails": null,
"messageSource": "template",
"config": { "message": "Hi {{recipient_username}}, here's the link: https://example.com" },
"sent": { "message": "Hi jane_doe, here's the link: https://example.com" },
"completedAt": "2026-05-12T09:14:48.000Z"
}
],
"keyword": "LINK",
"commentText": "Send me the LINK please!",
"created": "2026-05-12T09:14:22.000Z",
"completedAt": "2026-05-12T09:14:48.000Z"
},
{
"id": "auto_9xKp2Lm4nQ:trg_a1b2c3:comment.received:18012345678905555",
"automationId": "auto_9xKp2Lm4nQ",
"triggerId": "trg_a1b2c3",
"triggerType": "comment_keyword",
"recipientId": "17841405555555555",
"recipientUsername": "late_commenter",
"eventId": "comment.received:18012345678905555",
"commentId": "18012345678905555",
"platform": "instagram",
"status": "failed",
"actionResults": [
{
"actionId": "act_d4e5f6",
"type": "send_dm",
"status": "failed",
"errorDetails": "Cannot send private reply: This comment is no longer eligible for a private reply.",
"completedAt": "2026-05-12T09:12:03.000Z"
}
],
"keyword": "LINK",
"commentText": "LINK please!",
"created": "2026-05-12T09:12:01.000Z",
"completedAt": "2026-05-12T09:12:03.000Z"
},
{
"id": "auto_9xKp2Lm4nQ:trg_a1b2c3:comment.received:18012345678900000",
"automationId": "auto_9xKp2Lm4nQ",
"triggerId": "trg_a1b2c3",
"triggerType": "comment_keyword",
"recipientId": "17841409876543210",
"recipientUsername": "repeat_user",
"eventId": "comment.received:18012345678900000",
"commentId": "18012345678900000",
"platform": "instagram",
"status": "deduplicated",
"actionResults": [],
"keyword": "LINK",
"commentText": "LINK again please",
"created": "2026-05-12T09:00:11.000Z",
"completedAt": "2026-05-12T09:00:34.000Z"
}
],
"meta": {
"pagination": {
"hasMore": true,
"limit": 25,
"next": "eyJ0aW1lIjoiMjAyNi0wNS0xMlQwOTowMDoxMS4wMDBaIiwiaWQiOiJhdXRvXzl4S3AyTG00blE6dHJnX2ExYjJjMzoxODAxMjM0NTY3ODkwMDAwMCJ9"
}
}
}
{
"status": "error",
"message": "limit must be a positive integer"
}
{
"status": "error",
"message": "'previous' pagination is not supported by this endpoint"
}
{
"action": "automation",
"status": "error",
"code": 469,
"message": "Automation not found"
}
Automations
Obtener actividad de la automatización
Registro de auditoría paginado por cursor para una automatización
GET
/
automations
/
:id
/
activity
curl \
-H "Authorization: Bearer API_KEY" \
-X GET "https://api.ayrshare.com/api/automations/auto_9xKp2Lm4nQ/activity?limit=25"
curl \
-H "Authorization: Bearer API_KEY" \
-X GET "https://api.ayrshare.com/api/automations/auto_9xKp2Lm4nQ/activity?limit=25&next=eyJ0aW1lIjoiMjAyNi0wNS0xMlQw..."
const API_KEY = "API_KEY";
const id = "auto_9xKp2Lm4nQ";
// Paginate through every page
let next;
do {
const url = new URL(`https://api.ayrshare.com/api/automations/${id}/activity`);
url.searchParams.set("limit", "25");
if (next) url.searchParams.set("next", next);
const res = await fetch(url, {
headers: { "Authorization": `Bearer ${API_KEY}` },
});
const json = await res.json();
console.log(json.activity);
next = json.meta?.pagination?.hasMore ? json.meta.pagination.next : undefined;
} while (next);
import requests
headers = {"Authorization": "Bearer API_KEY"}
automation_id = "auto_9xKp2Lm4nQ"
params = {"limit": 25}
while True:
r = requests.get(
f"https://api.ayrshare.com/api/automations/{automation_id}/activity",
params=params,
headers=headers,
).json()
print(r["activity"])
pagination = r.get("meta", {}).get("pagination", {})
if not pagination.get("hasMore"):
break
params["next"] = pagination["next"]
$id = "auto_9xKp2Lm4nQ";
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.ayrshare.com/api/automations/" . $id . "/activity?limit=25",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => ["Authorization: Bearer API_KEY"],
]);
$response = curl_exec($curl);
curl_close($curl);
echo $response;
{
"status": "success",
"automationId": "auto_9xKp2Lm4nQ",
"activity": [
{
"id": "auto_9xKp2Lm4nQ:trg_a1b2c3:comment.received:18012345678901234",
"automationId": "auto_9xKp2Lm4nQ",
"triggerId": "trg_a1b2c3",
"triggerType": "comment_keyword",
"recipientId": "17841401234567890",
"recipientUsername": "jane_doe",
"eventId": "comment.received:18012345678901234",
"commentId": "18012345678901234",
"platform": "instagram",
"status": "sent",
"actionResults": [
{
"actionId": "act_d4e5f6",
"type": "send_dm",
"status": "sent",
"errorDetails": null,
"messageSource": "template",
"config": { "message": "Hi {{recipient_username}}, here's the link: https://example.com" },
"sent": { "message": "Hi jane_doe, here's the link: https://example.com" },
"completedAt": "2026-05-12T09:14:48.000Z"
}
],
"keyword": "LINK",
"commentText": "Send me the LINK please!",
"created": "2026-05-12T09:14:22.000Z",
"completedAt": "2026-05-12T09:14:48.000Z"
},
{
"id": "auto_9xKp2Lm4nQ:trg_a1b2c3:comment.received:18012345678905555",
"automationId": "auto_9xKp2Lm4nQ",
"triggerId": "trg_a1b2c3",
"triggerType": "comment_keyword",
"recipientId": "17841405555555555",
"recipientUsername": "late_commenter",
"eventId": "comment.received:18012345678905555",
"commentId": "18012345678905555",
"platform": "instagram",
"status": "failed",
"actionResults": [
{
"actionId": "act_d4e5f6",
"type": "send_dm",
"status": "failed",
"errorDetails": "Cannot send private reply: This comment is no longer eligible for a private reply.",
"completedAt": "2026-05-12T09:12:03.000Z"
}
],
"keyword": "LINK",
"commentText": "LINK please!",
"created": "2026-05-12T09:12:01.000Z",
"completedAt": "2026-05-12T09:12:03.000Z"
},
{
"id": "auto_9xKp2Lm4nQ:trg_a1b2c3:comment.received:18012345678900000",
"automationId": "auto_9xKp2Lm4nQ",
"triggerId": "trg_a1b2c3",
"triggerType": "comment_keyword",
"recipientId": "17841409876543210",
"recipientUsername": "repeat_user",
"eventId": "comment.received:18012345678900000",
"commentId": "18012345678900000",
"platform": "instagram",
"status": "deduplicated",
"actionResults": [],
"keyword": "LINK",
"commentText": "LINK again please",
"created": "2026-05-12T09:00:11.000Z",
"completedAt": "2026-05-12T09:00:34.000Z"
}
],
"meta": {
"pagination": {
"hasMore": true,
"limit": 25,
"next": "eyJ0aW1lIjoiMjAyNi0wNS0xMlQwOTowMDoxMS4wMDBaIiwiaWQiOiJhdXRvXzl4S3AyTG00blE6dHJnX2ExYjJjMzoxODAxMjM0NTY3ODkwMDAwMCJ9"
}
}
}
{
"status": "error",
"message": "limit must be a positive integer"
}
{
"status": "error",
"message": "'previous' pagination is not supported by this endpoint"
}
{
"action": "automation",
"status": "error",
"code": 469,
"message": "Automation not found"
}
Beta. Consulta la Visión general de las automatizaciones para ver la descripción completa de la funcionalidad.
Estado de la fila de actividad
Cada fila tiene unstatus de nivel superior más un status por acción dentro de actionResults[].
| Estado | Cuándo se registra |
|---|---|
pending | La fila se acaba de escribir; el worker aún no la ha tomado |
in_flight | El worker está enviando actualmente |
sent | Al menos una acción fue aceptada por la plataforma, y ninguna dio error de autenticación. Para send_dm esto significa que Meta aceptó el mensaje — no que el destinatario lo haya recibido (ver la nota a continuación) |
failed | Ninguna acción fue aceptada, y al menos una fue rechazada por la plataforma o no pudo ejecutarse (y ninguna dio error de autenticación). El motivo está en actionResults[].errorDetails |
auth_error | No se pudieron usar las credenciales de Instagram o de la página de Facebook, o los permisos de mensajería de la cuenta — por ejemplo, un token de acceso caducado o revocado, una Facebook Page no seleccionada, o Messaging no activado para el perfil. El DM no se reintentó. Los fallos de entrega por destinatario se registran como failed, no aquí |
rate_limited | Se alcanzó el límite 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 (predeterminado 7 días, configurable por acción) |
skipped | La automatización fue suprimida antes del envío — quedó inactiva o fue eliminada entre la propagación y el envío, no tiene acciones configuradas, o la interacción que la activó provino de la propia cuenta de la automatización — con mayor frecuencia un comentario en tu propia publicación. En ese último caso no se ejecuta ninguna acción: ni DM (una cuenta no puede enviarse mensajes a sí misma), ni tampoco fire_webhook ni send_email. Una automatización que activó automation.completed sigue recibiendo ese evento, con este estado |
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 confirma que Meta aceptó el mensaje, no que el destinatario lo haya recibido. Esto aplica a los DMs de Instagram y a los DMs de Messenger desde una página de Facebook: la automatización solo registra la aceptación y no hace seguimiento de la entrega. Instagram no expone ninguna señal de entrega en ninguna superficie de la API, y si la configuración de Message requests del destinatario bloquea a los desconocidos, Meta acepta el envío y lo descarta silenciosamente. Consulta DM de automatización enviado pero no entregado.Campos de resultado por acción
Cada entrada enactionResults[] describe el resultado de una acción:
| Campo | Tipo | Descripción |
|---|---|---|
actionId | string | El ID estable de la acción dentro de la automatización |
type | string | El tipo de acción (send_dm, fire_webhook, send_email) |
status | string | Estado por acción, usando el mismo vocabulario que el status de fila anterior |
errorDetails | string | null | Motivo del fallo legible por humanos cuando la acción no tuvo éxito; null (o ausente) en caso de éxito. Para un send_dm rechazado, contiene el mensaje de error mapeado (por ejemplo, la ventana de respuesta privada está cerrada, o el comentario ya recibió una respuesta). Una excepción a null en caso de éxito: un send_dm con messageSource: "fallback" es sent y lleva el motivo por el que no se usó su callback. Un fallback que luego no se pudo enviar lleva el error de envío seguido de ese motivo |
messageSource | string | Solo send_dm. A partir de qué texto se construyó el DM: template (el message estático), callback (tu messageUrl respondió y se usó su texto) o fallback (messageUrl estaba configurado pero no era utilizable, así que se usó message en su lugar, con el motivo en errorDetails). No indica si el DM se entregó; eso lo indica status. Presente una vez que se ha determinado el texto del DM, incluidos los envíos que luego fallaron. Ausente cuando la acción se detuvo antes de eso (un DM skipped a tu propia cuenta, una acción deduplicated o un error de configuración failed como un id de comentario faltante), y para otros tipos de acción |
config | object (opcional) | La configuración de la acción tal como estaba cuando se ejecutó este disparo, por ejemplo la plantilla message de send_dm. No cambia si editas la automatización más tarde, así que cada fila muestra lo que estaba configurado en ese momento. Ausente en las filas escritas antes de que se añadiera este campo, y cuando se eliminó para ajustarse al límite de tamaño (en ese caso truncated es true) |
sent | object (opcional) | Lo que la acción envió, o intentó enviar, en este disparo. Se registra una vez que la acción construyó su mensaje o carga útil, incluso cuando el envío falló después: status indica si salió. Ausente cuando la acción se detuvo antes de enviar, por ejemplo un resultado skipped para un comentario de tu propia cuenta, y para los resultados deduplicated. Consulta qué contiene sent |
truncated | boolean (opcional) | true cuando la entrada se recortó para ajustarse a su límite de tamaño: se acortó un valor de texto largo, o se omitieron por completo config y luego sent. Ausente en caso contrario |
completedAt | string | Marca de tiempo ISO 8601 de cuando finalizó la acción |
Qué contiene sent
| Tipo de acción | Campos de sent |
|---|---|
send_dm | message: el texto con el que se envió el DM. Es tu plantilla message con sus placeholders completados para este destinatario o, cuando messageSource es callback, el texto que devolvió tu messageUrl. fallbackMessage: presente solo cuando messageSource es callback; tu plantilla, completada, tal como se habría enviado sin el callback |
send_email | to, subject y message: el email tal como se puso en cola, con los placeholders completados |
fire_webhook | payload: los campos del evento enviados a tu webhook. El cuerpo entregado también lleva los campos estándar del webhook (action, created, hookId, refId, url y timeStamp cuando el webhook está firmado). hookId: el id de la entrega, presente cuando el webhook se puso en cola |
truncated se establece cuando eso ocurre. Los valores almacenados bajo nombres de clave que parecen credenciales, como token, secret, password o apiKey, se registran como "[redacted]". El messageUrl de una acción send_dm también se registra siempre como "[redacted]", porque una URL puede llevar un secreto en su ruta o en su query string.
Para automatizaciones activadas por comentarios (comment_keyword), la fila también lleva un commentId de nivel superior — el ID de comentario de Instagram sin procesar al que se ancló el DM. Es null para disparadores basados en mensajes (dm_keyword, story_reply, dm_reaction).
Las filas también llevan postId (la publicación en la que se dejó un comentario de comment_keyword) y storyId (la historia para story_reply y story_comment). Cada uno es null para los otros disparadores, y está ausente en las filas escritas antes de que se añadieran estos campos.
Parámetros de encabezado
Parámetros de ruta
string
requerido
El ID de la automatización devuelto por
POST /automations.Parámetros de consulta
number
predeterminado:25
Tamaño de página. Predeterminado
25, máximo 100. Los valores fuera de [1, 100] se ajustan al rango; los valores no enteros o ≤0 devuelven HTTP 400.string
Cursor opaco proveniente del
meta.pagination.next de una respuesta anterior. Omítelo en la primera solicitud.Solo hacia adelante — pasar ?previous= devuelve HTTP 400.Forma de la respuesta
La respuesta envuelve la lista de resultados enactivity[] y la información del cursor en meta.pagination:
{
"status": "success",
"automationId": "auto_9xKp2Lm4nQ",
"activity": [ /* …rows, newest first… */ ],
"meta": {
"pagination": {
"hasMore": true,
"limit": 25,
"next": "eyJ0aW1lIjoiMjAyNi0wNS0xMlQwOTowMDoxMS4wMDBaIiwiaWQiOiJhdXRvXzl4S3AyTG00blE6dHJnX2ExYjJjMzpjb21tZW50X3JlY2VpdmVkOjE4MDEyMzQ1Njc4OTAwMDAwIn0="
}
}
}
meta.pagination.next es un blob opaco codificado en base64 — trátalo como una caja negra y pásalo sin modificar en el ?next= de la siguiente solicitud. meta.pagination.hasMore es true cuando existe al menos una página más.
curl \
-H "Authorization: Bearer API_KEY" \
-X GET "https://api.ayrshare.com/api/automations/auto_9xKp2Lm4nQ/activity?limit=25"
curl \
-H "Authorization: Bearer API_KEY" \
-X GET "https://api.ayrshare.com/api/automations/auto_9xKp2Lm4nQ/activity?limit=25&next=eyJ0aW1lIjoiMjAyNi0wNS0xMlQw..."
const API_KEY = "API_KEY";
const id = "auto_9xKp2Lm4nQ";
// Paginate through every page
let next;
do {
const url = new URL(`https://api.ayrshare.com/api/automations/${id}/activity`);
url.searchParams.set("limit", "25");
if (next) url.searchParams.set("next", next);
const res = await fetch(url, {
headers: { "Authorization": `Bearer ${API_KEY}` },
});
const json = await res.json();
console.log(json.activity);
next = json.meta?.pagination?.hasMore ? json.meta.pagination.next : undefined;
} while (next);
import requests
headers = {"Authorization": "Bearer API_KEY"}
automation_id = "auto_9xKp2Lm4nQ"
params = {"limit": 25}
while True:
r = requests.get(
f"https://api.ayrshare.com/api/automations/{automation_id}/activity",
params=params,
headers=headers,
).json()
print(r["activity"])
pagination = r.get("meta", {}).get("pagination", {})
if not pagination.get("hasMore"):
break
params["next"] = pagination["next"]
$id = "auto_9xKp2Lm4nQ";
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.ayrshare.com/api/automations/" . $id . "/activity?limit=25",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => ["Authorization: Bearer API_KEY"],
]);
$response = curl_exec($curl);
curl_close($curl);
echo $response;
{
"status": "success",
"automationId": "auto_9xKp2Lm4nQ",
"activity": [
{
"id": "auto_9xKp2Lm4nQ:trg_a1b2c3:comment.received:18012345678901234",
"automationId": "auto_9xKp2Lm4nQ",
"triggerId": "trg_a1b2c3",
"triggerType": "comment_keyword",
"recipientId": "17841401234567890",
"recipientUsername": "jane_doe",
"eventId": "comment.received:18012345678901234",
"commentId": "18012345678901234",
"platform": "instagram",
"status": "sent",
"actionResults": [
{
"actionId": "act_d4e5f6",
"type": "send_dm",
"status": "sent",
"errorDetails": null,
"messageSource": "template",
"config": { "message": "Hi {{recipient_username}}, here's the link: https://example.com" },
"sent": { "message": "Hi jane_doe, here's the link: https://example.com" },
"completedAt": "2026-05-12T09:14:48.000Z"
}
],
"keyword": "LINK",
"commentText": "Send me the LINK please!",
"created": "2026-05-12T09:14:22.000Z",
"completedAt": "2026-05-12T09:14:48.000Z"
},
{
"id": "auto_9xKp2Lm4nQ:trg_a1b2c3:comment.received:18012345678905555",
"automationId": "auto_9xKp2Lm4nQ",
"triggerId": "trg_a1b2c3",
"triggerType": "comment_keyword",
"recipientId": "17841405555555555",
"recipientUsername": "late_commenter",
"eventId": "comment.received:18012345678905555",
"commentId": "18012345678905555",
"platform": "instagram",
"status": "failed",
"actionResults": [
{
"actionId": "act_d4e5f6",
"type": "send_dm",
"status": "failed",
"errorDetails": "Cannot send private reply: This comment is no longer eligible for a private reply.",
"completedAt": "2026-05-12T09:12:03.000Z"
}
],
"keyword": "LINK",
"commentText": "LINK please!",
"created": "2026-05-12T09:12:01.000Z",
"completedAt": "2026-05-12T09:12:03.000Z"
},
{
"id": "auto_9xKp2Lm4nQ:trg_a1b2c3:comment.received:18012345678900000",
"automationId": "auto_9xKp2Lm4nQ",
"triggerId": "trg_a1b2c3",
"triggerType": "comment_keyword",
"recipientId": "17841409876543210",
"recipientUsername": "repeat_user",
"eventId": "comment.received:18012345678900000",
"commentId": "18012345678900000",
"platform": "instagram",
"status": "deduplicated",
"actionResults": [],
"keyword": "LINK",
"commentText": "LINK again please",
"created": "2026-05-12T09:00:11.000Z",
"completedAt": "2026-05-12T09:00:34.000Z"
}
],
"meta": {
"pagination": {
"hasMore": true,
"limit": 25,
"next": "eyJ0aW1lIjoiMjAyNi0wNS0xMlQwOTowMDoxMS4wMDBaIiwiaWQiOiJhdXRvXzl4S3AyTG00blE6dHJnX2ExYjJjMzoxODAxMjM0NTY3ODkwMDAwMCJ9"
}
}
}
{
"status": "error",
"message": "limit must be a positive integer"
}
{
"status": "error",
"message": "'previous' pagination is not supported by this endpoint"
}
{
"action": "automation",
"status": "error",
"code": 469,
"message": "Automation not found"
}