Rivalwin API — Meta Political Ads
Descripción general
La API de Meta Political permite generar informes de publicidad política en la plataforma Meta (Facebook, Instagram) de forma programática. Los informes analizan los anuncios políticos de un rival durante un período determinado, proporcionando datos de creatividades, copys, inversión estimada, segmentación y análisis de IA.
Base URL: https://rivalwin.com/api/v1/meta/political/
Autenticación
Todas las peticiones requieren una API Key válida enviada en el header X-API-Key.
X-API-Key: tu_api_key_aqui
Rate Limiting
La API aplica dos tipos de limitación:
Rate limit por hora
Cada API Key tiene un límite de peticiones por hora configurado. Los headers de respuesta indican el estado:
X-RateLimit-Limit-Hour: 600
X-RateLimit-Remaining-Hour: 598
Si se excede el límite: 429 Too Many Requests con header Retry-After.
Cooldown entre informes
Existe un tiempo mínimo de espera entre la creación de informes consecutivos (por defecto 10 segundos, configurable por plan/empresa). Si intentas crear un informe antes de que transcurra este tiempo:
{
"error": "cooldown_active",
"message": "Please wait 7 seconds before creating another report.",
"cooldown_seconds": 10,
"retry_after": 7
}
Requisitos de la cuenta
- Su cuenta de Rivalwin debe estar activa.
- El plan contratado debe estar activo y no vencido (contrato o trial).
- El plan debe incluir acceso a la API.
Si alguna de estas condiciones no se cumple, recibirás un error 403 Forbidden con el motivo específico.
Recepción de resultados
Existen dos formas de recibir los datos de un informe completado:
Polling
Consulta el endpoint report_status periódicamente (cada 15-30 segundos) hasta que el estado sea DONE. Es el método más simple y no requiere configuración adicional.
Webhook
Configura una URL de webhook en el módulo Integraciones & API Keys del sistema. Cuando un informe pase al estado DONE, la API enviará automáticamente un POST a la URL configurada con el payload completo del informe (mismo contenido que devuelve report_status en estado DONE).
De esta forma no necesitas hacer polling: simplemente esperas a recibir la notificación en tu servidor.
Endpoints
1. Crear un nuevo informe (new_report)
Crea un informe de publicidad política de Meta de forma asíncrona. La API devuelve inmediatamente un hash identificador que debes usar para consultar el estado del informe.
POST /api/v1/meta/political/new_report
Headers
| Header | Tipo | Requerido | Descripción |
|---|---|---|---|
| X-API-Key | string | Sí | Tu API Key |
| Idempotency-Key | string | No | Clave de idempotencia para evitar informes duplicados |
| Content-Type | string | Sí | application/json |
Body (JSON)
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
rival_ref | string | Sí | Referencia del rival |
date_from | string | Sí | Fecha inicio del período (formato YYYY-MM-DD) |
date_to | string | Sí | Fecha fin del período (formato YYYY-MM-DD) |
country | string | Sí | ISO-2 (ES, AR, EU, etc.) |
Ejemplo de petición
curl -X POST https://rivalwin.com/api/v1/meta/political/new_report \
-H "X-API-Key: tu_api_key" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: unique-key-123" \
-d '{
"rival_ref": "rvl_8f3b2c4a",
"date_from": "2026-03-01",
"date_to": "2026-03-31",
"country": "AR"
}'
Respuesta exitosa (202 Accepted)
{
"hash": "...",
"status": "PENDING",
"created_at": "2026-03-15 10:30:00"
}
Validaciones y restricciones
| Regla | Detalle |
|---|---|
| Rango máximo de fechas | 60 días |
| Fecha fin máxima | Ayer (no se permite el día actual ni futuro) |
| Fecha inicio mínima | Hasta 1 año atrás |
| Formato de fecha | YYYY-MM-DD estricto |
| País | Código ISO de 2 letras |
| Créditos | Se descuentan al crear el informe |
Idempotencia
Si envías el header Idempotency-Key con un valor que ya fue usado, la API devuelve el informe existente sin crear uno nuevo ni descontar créditos adicionales.
2. Consultar estado del informe (report_status)
Consulta el estado de un informe creado previamente. Cuando el informe está completado, devuelve los datos del reporte completo.
POST /api/v1/meta/political/report_status
Headers requeridos
| Header | Tipo | Requerido | Descripción |
|---|---|---|---|
| X-API-Key | string | Sí | Tu API Key |
| Content-Type | string | Sí | application/json |
Body (JSON)
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
hash | string | Sí | Hash del informe (obtenido de new_report) |
Ejemplo de petición
curl -X POST https://rivalwin.com/api/v1/meta/political/report_status \
-H "X-API-Key: tu_api_key" \
-H "Content-Type: application/json" \
-d '{"hash": "..."}'
Respuesta según estado
PENDING — El informe está en cola:
{
"hash": "...",
"status": "PENDING",
"created_at": "2026-03-15 10:30:00",
"message": "The report is queued and will start processing shortly."
}
PROCESSING — El informe se está generando:
{
"hash": "...",
"status": "PROCESSING",
"created_at": "2026-03-15 10:30:00",
"started_at": "2026-03-15 10:30:05",
"message": "The report is being generated. Please check back in a few moments."
}
DONE — El informe está completo:
{
"hash": "...",
"status": "DONE",
"created_at": "2026-03-15 10:30:00",
"started_at": "2026-03-15 10:30:05",
"completed_at": "2026-03-15 10:31:20",
"report": {
"rival_name": "Candidato Ejemplo",
"campaign_start": "2026-03-01",
"campaign_end": "2026-03-31",
"country": "AR",
"kpis": {
"ads_total": 45,
"investment_min_ars": 150000,
"investment_max_ars": 320000,
"investment_min_usd": 150,
"investment_max_usd": 320,
"investment_min_eur": 138,
"investment_max_eur": 295,
"impressions_lower": 500000,
"impressions_upper": 1000000
},
"ads": [
{
"ad_id": "123456789",
"start_date": "2026-03-05",
"end_date": "2026-03-20",
"content": "Texto del anuncio político...",
"image_url": "https://...",
"video_url": null,
"platforms": ["facebook", "instagram"],
"demographics": {
"age": "25-54",
"gender": "All"
},
"regions": ["Buenos Aires", "Córdoba"],
"spend_min": 5000,
"spend_max": 10000,
"impressions_lower": 10000,
"impressions_upper": 50000
}
],
"gpt_analysis": {
"summary": "Análisis generado por IA sobre la estrategia publicitaria...",
"key_messages": ["Mensaje clave 1", "Mensaje clave 2"],
"tone": "Persuasivo y emocional",
"target_audience": "Adultos 25-54, zonas urbanas"
},
"pdf_url": "https://.../report_1234.pdf"
}
}
ERROR — Ocurrió un error durante la generación:
{
"hash": "...",
"status": "ERROR",
"created_at": "2026-03-15 10:30:00",
"completed_at": "2026-03-15 10:31:00",
"error_message": "Report failed during processing."
}
Campos del reporte (report)
| Campo | Tipo | Descripción |
|---|---|---|
rival_name | string | Nombre del rival analizado |
campaign_start | string | Fecha inicio del período analizado |
campaign_end | string | Fecha fin del período analizado |
country | string | País filtrado |
kpis | object | Indicadores clave (ver tabla inferior) |
ads | array | Lista de anuncios encontrados en el período |
gpt_analysis | object | Análisis de IA sobre la estrategia publicitaria |
pdf_url | string | URL firmada para descargar informe |
KPIs disponibles
| KPI | Tipo | Descripción |
|---|---|---|
ads_total | integer | Cantidad total de anuncios en el período |
investment_min_ars | number | Inversión mínima estimada (ARS) |
investment_max_ars | number | Inversión máxima estimada (ARS) |
investment_min_usd | number | Inversión mínima estimada (USD) |
investment_max_usd | number | Inversión máxima estimada (USD) |
investment_min_eur | number | Inversión mínima estimada (EUR) |
investment_max_eur | number | Inversión máxima estimada (EUR) |
impressions_lower | integer | Límite inferior de impresiones estimadas |
impressions_upper | integer | Límite superior de impresiones estimadas |
Campos de cada anuncio (ads[])
| Campo | Tipo | Descripción |
|---|---|---|
ad_id | string | ID del anuncio en Meta Ad Library |
start_date | string | Fecha de inicio del anuncio |
end_date | string | Fecha de finalización (o última vez visto) |
content | string | Texto/copy del anuncio |
image_url | string | URL de la imagen del anuncio (puede ser null) |
video_url | string | URL del video del anuncio (puede ser null) |
platforms | array | Plataformas donde se mostró (facebook, instagram) |
demographics | object | Segmentación demográfica (edad, género) |
regions | array | Regiones geográficas donde se mostró |
spend_min | number | Inversión mínima del anuncio |
spend_max | number | Inversión máxima del anuncio |
impressions_lower | integer | Impresiones mínimas estimadas |
impressions_upper | integer | Impresiones máximas estimadas |
Ejemplos de código
PHP
<?php
$apiKey = "tu_api_key";
$baseUrl = "https://rivalwin.com/api/v1/meta/political";
$rivalRef = "rvl_8f3b2c4a";
// 1. Crear informe
$report = apiCall("$baseUrl/new_report", [
'rival_ref' => $rivalRef,
'date_from' => '2026-03-01',
'date_to' => '2026-03-31',
'country' => 'AR',
], $apiKey);
$hash = $report['hash'];
echo "Informe creado: $hash\n";
// 2. Polling hasta que esté listo
do {
sleep(15);
$status = apiCall("$baseUrl/report_status", ['hash' => $hash], $apiKey);
echo "Estado: " . $status['status'] . "\n";
} while (in_array($status['status'], ['PENDING', 'PROCESSING']));
// 3. Obtener resultado
if ($status['status'] === 'DONE') {
$report = $status['report'];
echo "Anuncios encontrados: " . $report['kpis']['ads_total'] . "\n";
echo "Inversión estimada: $" . $report['kpis']['investment_min_usd'] . " - $" . $report['kpis']['investment_max_usd'] . "\n";
}
function apiCall(string $url, array $body, string $apiKey): array {
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode($body),
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
'X-API-Key: ' . $apiKey,
],
]);
$response = curl_exec($ch);
curl_close($ch);
return json_decode($response, true);
}
Códigos de error
| Código HTTP | Error | Descripción |
|---|---|---|
| 400 | missing_parameters | Faltan parámetros requeridos |
| 400 | invalid_date_from | Formato de fecha_from inválido |
| 400 | invalid_date_to | Formato de fecha_to inválido |
| 400 | invalid_date_range | Rango de fechas inválido (futuro, invertido, >60 días) |
| 400 | invalid_country | Código de país inválido |
| 401 | missing_api_key | No se envió el header X-API-Key |
| 401 | invalid_api_key | La API Key no es válida o está revocada |
| 402 | insufficient_credits | Créditos insuficientes para generar el informe |
| 403 | account_inactive | La cuenta de la empresa está desactivada |
| 403 | plan_inactive | El plan contratado está desactivado |
| 403 | contract_expired | El contrato ha expirado |
| 403 | trial_expired | El período de prueba ha expirado |
| 403 | api_not_in_plan | El plan no incluye acceso a la API |
| 404 | rival_not_found | El rival_ref no existe o está inactivo |
| 404 | job_not_found | No se encontró un informe con el hash proporcionado |
| 429 | rate_limit_exceeded | Se excedió el límite de peticiones por hora |
| 429 | cooldown_active | Debe esperar antes de crear otro informe |
| 500 | internal_error | Error interno del servidor |
Notas importantes
- Los informes se generan de forma asíncrona. El endpoint
new_reportdevuelve inmediatamente con unhashy el informe se procesa en segundo plano. - El tiempo de generación típico es de 1 a 3 minutos, dependiendo del volumen de anuncios del rival.
- Cada informe consume créditos según el sistema.