LinkedIn Reactions
Reacciones en cualquier publicación. Perfil completo por reacción.
Ejecuta como Apify Actor. Extrae todas las reacciones de cualquier publicación de LinkedIn.
Inicio rápido (Apify API)
# Trigger the actor with the Apify APIcurl -X POST "https://api.apify.com/v2/acts/atomus~linkedin-reactions-scraper-pro/runs?token=YOUR_APIFY_TOKEN" \ -H "Content-Type: application/json" \ -d '{ }'Qué hace
Obtén cada reacción de una publicación de LinkedIn con el perfil
completo de quien reaccionó. Pagina hasta unas 1.200 reacciones
por publicación (límite de la lista pública de LinkedIn). Los
filtros opcionales marcan entradas vía matches_filters
pero nunca reducen el conteo de la página. 1 crédito por página
(100 reacciones).
Endpoint
POST https://api.atomusapi.dev/v1/linkedin-reactions/extractAutenticación
Envía tu API key como Bearer token en el header Authorization. Las claves están limitadas a un solo tenant.
Authorization: Bearer atm_live_xxxxxxxxxxxxxx — or X-RapidAPI-Proxy-Secret: <secret> when calling through the RapidAPI gatewayIdempotency
Send Idempotency-Key: <uuid> to make a request safely retryable. Atomus stores the response for 24h and replays it on retries with the same key.
Entrada
Request body
| Field | Type | Description | |
|---|---|---|---|
| postUrl | string | requerido | Identificador de un post de LinkedIn. Acepta: URLs /feed/update/urn:li:share:... o /feed/update/urn:li:activity:..., URLs /posts/..., URNs share/activity, o un activity ID en bruto de 10+ dígitos. Las share URNs se resuelven a activity IDs en el upstream en la primera llamada. |
| cursor | string | null | opcional | Cursor opaco de paginación devuelto por una llamada anterior. Omítelo en la primera solicitud. Devuelve data.pagination.cursor literal para obtener la siguiente página. |
| filters.reactionType | string | null | opcional | Filtra reactors por tipo de reacción. ALL (u omitido) devuelve todas las reacciones. Tipos de LinkedIn: LIKE, PRAISE (Celebrar), EMPATHY (Encantar), APPRECIATION (Interesante), INTEREST (Curioso), ENTERTAINMENT (Divertido). |
| filters.headlineKeywords | string[] | opcional | Hasta 20 keywords case-insensitive. Un reactor coincide cuando su headline contiene al menos una. Marca a los reactors vía matches_filters; los reactors se devuelven igualmente. |
| filters.excludeCompanies | boolean | null | opcional | Cuando es true, marca a los reactors que son páginas de empresa (URLs /company/ de LinkedIn) como no-coincidentes con los filtros. Se devuelven igualmente con is_company=true para auditar el corte. |
| metadataOnly | boolean | null | opcional | Cuando es true, omite la extracción de reactors y devuelve solo data.pagination.total_reactions_on_post. data.reactions siempre es [], pagination.has_more siempre es false, cursor y filters se ignoran. Más barato que una extracción completa (RapidAPI: 1 reaction unit; Atomus: 1 crédito). Úsalo para comprobar si un post tiene nuevas reactions antes de pagar una extracción completa. |
Salida
Response object
| Field | Type | Description | |
|---|---|---|---|
| data.reactions | object[] | requerido | Reactors de esta página, en el orden del upstream. Longitud máxima de 100 (LinkedIn devuelve páginas de reactors de tamaño fijo; la última página puede ser más corta). |
| data.reactions[].reaction_type | string | requerido | Tipo de reacción en bruto de LinkedIn (LIKE, PRAISE, EMPATHY, APPRECIATION, INTEREST, ENTERTAINMENT). |
| data.reactions[].is_company | boolean | requerido | True cuando el reactor es una página de empresa de LinkedIn en lugar de una persona. |
| data.reactions[].matches_filters | boolean | requerido | True cuando este reactor cumple con todos los filtros enviados (reactionType, headlineKeywords, excludeCompanies). True para todos los reactors cuando no se envían filtros. |
| data.reactions[].reactor.id | string | requerido | ID estilo URN de LinkedIn para el reactor. Estable entre llamadas; úsalo como clave de dedup al agregar entre páginas o ejecuciones. |
| data.reactions[].reactor.name | string | requerido | Nombre de visualización del reactor. |
| data.reactions[].reactor.headline | string | requerido | Headline del reactor (la frase corta debajo del nombre en LinkedIn). String vacío cuando el perfil upstream no tiene. |
| data.reactions[].reactor.linkedinUrl | string | requerido | URL canónica de LinkedIn — /in/<slug>/ para personas, /company/<slug>/ para páginas de empresa. Los segmentos de path y query strings finales se eliminan. |
| data.reactions[].reactor.profile_pic | string | null | requerido | URL del avatar cuando LinkedIn la expone, null en caso contrario. |
| data.reactions[]._metadata.post_url | string | requerido | Repite el postUrl enviado tras la resolución share-to-activity. |
| data.reactions[]._metadata.activity_id | string | requerido | Activity ID de LinkedIn del post al que pertenece esta reacción. |
| data.reactions[]._metadata.extracted_at | string | requerido | Timestamp ISO 8601 UTC registrado cuando esta reacción fue extraída. |
| data.pagination.cursor | string | null | requerido | Token opaco. Pásalo como request.cursor para obtener la siguiente página. null cuando has_more=false. |
| data.pagination.has_more | boolean | requerido | True mientras queden más páginas. False en la última página. |
| data.pagination.total_reactions_on_post | number | requerido | Conteo total de reactors en el post reportado por el upstream. Puede exceder lo accesible vía paginación — ver truncated. |
| data.pagination.truncated | boolean | requerido | True en la última página cuando LinkedIn no expuso a todos los reactors en su lista pública. LinkedIn limita la lista pública de reactions a aproximadamente 1.200-1.250 entradas por post; los reactors por encima de ese límite no son accesibles para ninguna API sin cookie. False cuando has_more=true (el truncamiento solo se puede detectar en la última página). |
| data.pagination.truncation_note | string | null | requerido | Explicación legible cuando truncated=true; null en caso contrario. Úsala verbatim en respuestas de soporte. |
| meta.request_id | string | requerido | ID de rastreo opaco. Inclúyelo al abrir un ticket de soporte. |
| meta.api | string | requerido | Identificador de la API: linkedin-reactions. |
| meta.version | string | requerido | Versión de la API. |
| meta.mode | string | requerido | Modo de entorno en el que se ejecutó la solicitud. live y test son autenticación Bearer Atomus; rapidapi indica que la solicitud vino por el gateway RapidAPI y se cobra ahí, no por Atomus. |
| meta.credits_used | number | requerido | Créditos cobrados por esta solicitud. Siempre 0 en modo rapidapi (RapidAPI cobra al consumidor de su lado). |
| meta.credits_remaining | number | null | requerido | Saldo de créditos del tenant tras esta solicitud. null en modo rapidapi (no se debita ninguna cuenta de crédito Atomus). |
| meta.duration_ms | number | requerido | Duración del procesamiento en el servidor en milisegundos. |
Ejemplo de request
curl
curl -X POST "https://api.atomusapi.dev/v1/linkedin-reactions/extract" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "postUrl": "https://www.linkedin.com/feed/update/urn:li:activity:7404946870776868864/" }'JavaScript
// Atomus Bearer auth. Pass cursor on subsequent calls to paginate.async function* extractAllReactions(postUrl) { let cursor; do { const res = await fetch( "https://api.atomusapi.dev/v1/linkedin-reactions/extract", { method: "POST", headers: { "Authorization": "Bearer YOUR_API_KEY", "Content-Type": "application/json", }, body: JSON.stringify({ postUrl, cursor }), } );
if (!res.ok) { const { error } = await res.json(); throw new Error(`${error.code}: ${error.message}`); }
const { data } = await res.json(); for (const r of data.reactions) yield r; cursor = data.pagination.cursor; } while (cursor);}
for await (const r of extractAllReactions( "https://www.linkedin.com/feed/update/urn:li:activity:7404946870776868864/")) { if (r.matches_filters) console.log(r.reactor.name, "—", r.reactor.headline);}Python
import requests
# Atomus Bearer auth. Pass cursor on subsequent calls to paginate.def extract_all_reactions(post_url, api_key): cursor = None while True: res = requests.post( "https://api.atomusapi.dev/v1/linkedin-reactions/extract", headers={ "Authorization": f"Bearer {api_key}", "Content-Type": "application/json", }, json={"postUrl": post_url, "cursor": cursor}, timeout=60, ) if not res.ok: err = res.json()["error"] raise RuntimeError(f"{err['code']}: {err['message']}") data = res.json()["data"] for r in data["reactions"]: yield r cursor = data["pagination"]["cursor"] if not cursor: break
for r in extract_all_reactions( "https://www.linkedin.com/feed/update/urn:li:activity:7404946870776868864/", "YOUR_API_KEY",): if r["matches_filters"]: print(r["reactor"]["name"], "—", r["reactor"]["headline"])curl (RapidAPI)
# RapidAPI gateway auth. Use this when calling the API through your# RapidAPI subscription instead of an Atomus account. RapidAPI bills# the consumer at the gateway; the response reports mode="rapidapi"# and credits_used=0.curl -X POST "https://api.atomusapi.dev/v1/linkedin-reactions/extract" \ -H "X-RapidAPI-Proxy-Secret: YOUR_RAPIDAPI_PROXY_SECRET" \ -H "Content-Type: application/json" \ -d '{ "postUrl": "https://www.linkedin.com/feed/update/urn:li:activity:7404946870776868864/" }'curl (metadata only)
# Metadata-only mode. Returns just the post's total reaction count# without extracting individual reactors. RapidAPI: 1 reaction unit;# Atomus: 1 credit. Useful as a cheap pre-check before committing to# a full scrape — e.g. compare against a previous total to decide# whether new reactions arrived since last run.curl -X POST "https://api.atomusapi.dev/v1/linkedin-reactions/extract" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "postUrl": "https://www.linkedin.com/feed/update/urn:li:activity:7404946870776868864/", "metadataOnly": true }'Errores y límites
{ "error": { "code": "rate_limit_exceeded", "message": "Human-readable explanation.", "retryable": true, "request_id": "req_01HXXX..." }}unauthenticatedHTTP 401 : Falta el header Authorization o está mal formado. (no reintentar)invalid_api_keyHTTP 401 : La API key no es reconocida o ha sido revocada. (no reintentar)insufficient_creditsHTTP 402 : El saldo de créditos del tenant Atomus está por debajo de 1. No se lanza para llamadas autenticadas vía RapidAPI gateway (esas las cobra RapidAPI). (no reintentar)invalid_inputHTTP 400 : El cuerpo de la solicitud no es JSON válido o el cursor está mal formado (debe ser el token opaco devuelto por una llamada anterior). (no reintentar)validation_failedHTTP 422 : postUrl falta, tiene más de 500 caracteres, o el upstream lo rechazó como un post público inválido de LinkedIn. (no reintentar)rate_limit_exceededHTTP 429 : La tasa sostenida de solicitudes superó el límite del tenant. (reintentable)upstream_errorHTTP 502 : El proveedor upstream devolvió una respuesta de error. (reintentable)upstream_timeoutHTTP 504 : El proveedor upstream no respondió dentro del tiempo límite. (reintentable)internal_errorHTTP 500 : Error inesperado del servidor. (reintentable)
Límites de tasa
5 requests/segundo por cuenta (compartido entre todas las API keys de la misma cuenta). Cada llamada trae una página del upstream (hasta 100 reactors). Picos por encima del límite devuelven 429 rate_limit_exceeded; haz backoff usando los response headers. La ventana por segundo se aplica en el servidor; las filas por minuto, hora, día, semana y mes son derivaciones de throughput sostenido.
| Ventana | Máx. solicitudes |
|---|---|
| Por segundo | 5 |
| Por minuto | 300 |
| Por hora | 18,000 |
| Por día | 432,000 |
| Por semana | 3,024,000 |
| Por mes | 12,960,000 |
x-ratelimit-limit: máximo de requests por segundo de la cuenta (compartido entre todas las keys)x-ratelimit-remaining: requests restantes en la ventana actualx-ratelimit-reset: unix epoch (segundos) cuando la ventana se reinicia
Facturación
- US$ 0,005 por reactor devuelto (US$ 5 por 1.000) — cobrado como 1 crédito Atomus por página (100 reactors) = US$ 0,50 por página
Modo Atomus (live): un crédito reservado por llamada, liquidado en un crédito en caso de éxito sin importar cuántas reactions devolvió LinkedIn (los filtros marcan entradas vía matches_filters pero nunca reducen el conteo de la página). Los errores antes de cualquier llamada upstream reembolsan la reserva. Modo RapidAPI (X-RapidAPI-Proxy-Secret): RapidAPI cobra al consumidor en el gateway vía el response header X-RapidAPI-Billing (objeto de quota Reactions, US$ 0,005 cada uno); Atomus no descuenta créditos y reporta credits_used=0 con credits_remaining=null en el meta de la respuesta.
Usa el gateway RapidAPI. Cobro por reacción en el gateway, sin necesidad de cuenta Atomus.
Inicio rápido (gateway RapidAPI)
# RapidAPI gateway authenticationcurl -X POST "https://api.atomusapi.dev/v1/linkedin-reactions/extract" \ -H "X-RapidAPI-Key: YOUR_RAPIDAPI_KEY" \ -H "X-RapidAPI-Host: api.atomusapi.dev" \ -H "Content-Type: application/json" \ -d '{ }'¿Altos volúmenes?
Sáltate los tiers del marketplace y obtén precio unitario ajustado a tu volumen real de llamadas, con línea directa al equipo que opera el pipeline.
Obtener precio por volumen