Awenlytics API v1
API REST para consultar campañas, adsets, anuncios, leads, métricas y reportes de tu organización.
https://awenlytics.com/api/v1
Authorization: Bearer {token}
Autenticación
Genera un token en Settings → API Keys. Úsalo en el header Authorization: Bearer <token>. Todos los endpoints están scopeados a la organización del token — sólo ves tus propios datos.
curl -H "Authorization: Bearer <YOUR_TOKEN>" \
https://awenlytics.com/api/v1/me
Paginación
Todos los listados soportan ?page y ?per_page (máximo 200, default 50).
GET /api/v1/campaigns?page=2&per_page=100
Respuesta:
{
"success": true,
"data": [ ... ],
"meta": {
"current_page": 2,
"last_page": 8,
"per_page": 100,
"total": 742
},
"links": {
"first": "...?page=1",
"last": "...?page=8",
"prev": "...?page=1",
"next": "...?page=3"
}
}
Filtros y ordenamiento
Cada listado expone sus propios filtros (ver cada endpoint). El parámetro ?sort acepta columnas separadas por coma; prefija con - para descendente.
# campañas de Google, activas, ordenadas por nombre
GET /api/v1/campaigns?platform=google&status=ACTIVE&sort=name
# leads recientes primero
GET /api/v1/leads?sort=-created_at
Errores
Respuestas no 2xx incluyen error y message. Códigos usados:
| HTTP | Significado |
|---|---|
401 | Token ausente, inválido, revocado o expirado |
403 | Token no tiene el permiso requerido |
404 | Recurso no existe o no pertenece a tu organización |
422 | Validación fallida (faltan parámetros requeridos) |
500 | Error interno del servidor |
Rate limits
60 requests/min por token. Al exceder recibes HTTP 429.
Health & Me
/v1/healthHealth check público dentro del API. No devuelve datos de la organización.
/v1/meDevuelve la organización y token asociados a tu API key. Útil para verificar a qué cuenta pertenece el token.
{
"success": true,
"data": {
"organization": { "id": 1, "name": "Alciscorp" },
"token": { "name": "production", "permissions": null, "last_used_at": "2026-04-24T12:33:10+00:00" }
}
}
Business lines
/v1/business-linesLista las líneas de negocio activas de tu organización.
{
"success": true,
"data": [
{ "id": 1, "name": "J. García López", "color": "#3b82f6", "sort_order": 1 },
{ "id": 2, "name": "Santa Gloria", "color": "#10b981", "sort_order": 2 }
]
}
Ad accounts
Cuentas conectadas (Facebook, Google, TikTok).
/v1/ad-accountsFilters: platform · status. Sort: name, platform, status, created_at
GET /v1/ad-accounts?platform=facebook&sort=name
{
"success": true,
"data": [{
"id": 2,
"platform": "facebook",
"external_id": "715957848259017",
"name": "Bye Bye Friend",
"currency": "MXN",
"status": "active",
"auto_sync": true,
"sync_frequency_hours": 6,
"last_synced_at": "2026-04-24T06:00:00+00:00",
"created_at": "2026-01-19T06:05:40+00:00"
}],
"meta": { ... }
}
/v1/ad-accounts/{id}Detalle de una ad account.
Campaigns
/v1/campaignsFilters: ad_account_id · platform · status · name (substring ilike). Sort: name, status, created_at, start_time, stop_time
GET /v1/campaigns?platform=google&status=ACTIVE
{
"success": true,
"data": [{
"id": 626,
"external_id": "21345678901",
"name": "jgl_lvly_sem_categoria",
"status": "ACTIVE",
"objective": "OUTCOME_LEADS",
"buying_type": "AUCTION",
"daily_budget": 2000.00,
"lifetime_budget": null,
"start_time": "2026-01-01T00:00:00+00:00",
"stop_time": null,
"ad_account": { "id": 13, "platform": "google", "name": "JGL Google" },
"created_at": "2026-01-19T06:15:00+00:00"
}],
"meta": { ... }
}
/v1/campaigns/{id}Detalle de una campaña.
Adsets
/v1/adsetsFilters: campaign_id · status · facebook_page_id. Sort: name, status, created_at, start_time
GET /v1/adsets?campaign_id=626
{
"success": true,
"data": [{
"id": 1234,
"external_id": "...",
"name": "sem_categoria - mx - broad",
"status": "ACTIVE",
"optimization_goal": "LEAD_GENERATION",
"bid_strategy": "LOWEST_COST_WITHOUT_CAP",
"daily_budget": 500.00,
"lifetime_budget": null,
"start_time": "...",
"end_time": null,
"targeting": { ... },
"facebook_page_id": null,
"campaign": { "id": 626, "name": "jgl_lvly_sem_categoria", "platform": "google" },
"created_at": "..."
}],
"meta": { ... }
}
/v1/adsets/{id}Ads
/v1/adsFilters: adset_id · campaign_id · status. Sort: name, status, created_at
{
"success": true,
"data": [{
"id": 5678,
"external_id": "...",
"name": "Ad variant A — image",
"status": "ACTIVE",
"creative": { ... },
"preview_url": "https://...",
"thumbnail_url": "https://...",
"adset": { "id": 1234, "name": "sem_categoria - mx - broad" },
"campaign": { "id": 626, "name": "jgl_lvly_sem_categoria", "platform": "google" },
"created_at": "..."
}],
"meta": { ... }
}
/v1/ads/{id}Facebook pages
/v1/pagesFilters: ad_account_id · business_line_id · is_active. Sort: page_name, created_at
Lead forms
/v1/lead-formsFilters: facebook_page_id · status
/v1/lead-forms/{id}Incluye el schema completo de questions.
Leads
Leads capturados (Lead Ads, CTWA, website, manuales). Status enum: new, contacted, qualified, interested, negotiation, won, lost.
Listar leads
/v1/leadsQuery params: status · source_type (lead_form/website/api/manual) · source_platform (facebook/google/tiktok/whatsapp/website/manual) · from_date · to_date (YYYY-MM-DD) · business_line_id · search (busca en name/email/phone/company) · page · per_page (default 50)
GET /v1/leads?status=won&business_line_id=1&from_date=2026-04-01
{
"success": true,
"data": [{
"id": 13185,
"organization_id": 1,
"campaign_id": 604,
"adset_id": 2088,
"ad_id": 7327,
"lead_form_id": 1,
"facebook_page_id": 1,
"business_line_id": 1,
"external_lead_id": "991275503584243",
"external_crm_id": "D102340",
"name": "Luz Martinez",
"email": "luzmartinezmerlos77@gmail.com",
"phone": "+525532759002",
"source_platform": "facebook",
"source_type": "lead_form",
"status": "won",
"sale_value": "84514.80",
"fbclid": null,
"gclid": null,
"utm_data": {"utm_source": "facebook", "utm_campaign": "jgl_lvly_perf_la"},
"lead_created_at": "2026-04-24T08:44:51.000000Z",
"contacted_at": "2026-04-24T15:30:00.000000Z",
"converted_at": "2026-04-24T20:26:48.000000Z",
"campaign": { "id": 604, "name": "jgl_lvly_perf_la" },
"ad": { "id": 7327, "name": "30abr_na_comercial_aon_vid_plan1055" }
}],
"meta": { "current_page": 1, "last_page": 12, "per_page": 50, "total": 580 }
}
Crear o actualizar lead (upsert)
/v1/leads
Hace upsert por external_crm_id → email → phone.
Si encuentra match: actualiza. Si no: requiere atribución (clickID o UTM) o se descarta.
Si pasa status y cambia, dispara CAPI automáticamente vía LeadObserver.
Body params (todos opcionales salvo lo indicado):
- Identificación:
email,phone,name,first_name,last_name,company,external_crm_id - Estado:
status(enum),sale_value(numeric),notes - Atribución por click ID:
fbclid,gclid,gbraid,wbraid,ttclid,gad_source - Atribución por ID externo:
external_ad_id,external_adset_id,external_campaign_id - UTMs:
utm_source,utm_medium,utm_campaign,utm_content,utm_term,landing_page_url,referrer_url - CAPI extras:
ip_address,user_agent,fb_browser_id(fbp),fb_click_id(fbc) - Otros:
source_platform,source_type,custom_fields(object),business_line_id(integer — debe existir en /v1/business-lines)
Request — crear nuevo lead con atribución por gclid + business_line:
POST /v1/leads
Content-Type: application/json
Authorization: Bearer <TOKEN>
{
"email": "ana@ejemplo.com",
"phone": "+525512345678",
"name": "Ana Pérez",
"external_crm_id": "CRM-7842",
"status": "new",
"gclid": "Cj0KCQjw...",
"utm_source": "google",
"utm_medium": "cpc",
"utm_campaign": "jgl_lvly_sem_categoria",
"landing_page_url": "https://jgarcialopez.com/planes",
"fb_browser_id": "fb.1.1700000000000.1234567890",
"business_line_id": 1,
"custom_fields": {
"preferred_contact_time": "afternoon",
"lead_score": 85
}
}
Response 201 (lead creado):
{
"success": true,
"action": "created",
"message": "Lead created successfully",
"data": {
"id": 13201,
"campaign_id": 626,
"adset_id": null,
"ad_id": null,
"business_line_id": 1,
"name": "Ana Pérez",
"email": "ana@ejemplo.com",
"status": "new",
"source_platform": "google",
"source_type": "api",
"campaign": { "id": 626, "name": "jgl_lvly_sem_categoria" }
},
"attribution": {
"matched_by": "utm_campaign",
"campaign": "jgl_lvly_sem_categoria",
"adset": null,
"ad": null
}
}
Response 200 (lead encontrado y actualizado):
{
"success": true,
"action": "updated",
"message": "Lead updated successfully",
"data": { /* lead completo */ }
}
Response 200 (sin atribución, descartado):
{
"success": false,
"action": "skipped",
"message": "Lead not found in platform and has no ad attribution (click IDs or UTMs). Skipped."
}
Ver un lead
/v1/leads/{id}Devuelve el lead con relaciones campaign, adset, ad, leadForm.
Actualizar lead
/v1/leads/{id}
Actualiza solo los campos enviados. Si status pasa a won dispara
CAPI Purchase a Meta/Google/TikTok automáticamente.
Body params:
status·sale_value·notes·external_crm_id·assigned_to(user id) ·custom_fields·business_line_id
PATCH /v1/leads/13201
Content-Type: application/json
{
"status": "won",
"sale_value": 45600.00,
"notes": "Cierre por teléfono. Cliente recurrente.",
"business_line_id": 1
}
{
"success": true,
"message": "Lead updated successfully",
"data": { "id": 13201, "status": "won", "sale_value": "45600.00", "converted_at": "2026-04-25T12:34:56.000000Z", ... }
}
Buscar por CRM ID
/v1/leads/find-by-crm-id?external_crm_id={id}Útil para bridge con CRMs externos (Leader, HubSpot, etc.). 404 si no existe.
GET /v1/leads/find-by-crm-id?external_crm_id=D102340
{ "success": true, "data": { /* lead completo */ } }
Re-enviar conversión
/v1/leads/{id}/sync-conversion
Fuerza re-envío de Purchase event a Meta/Google/TikTok aunque ya se haya enviado antes.
Requiere que el lead esté en estado won (con converted_at).
POST /v1/leads/13201/sync-conversion
{
"success": true,
"message": "Conversion sync triggered",
"results": {
"facebook": { "success": true, "event_id": "..." },
"google": { "success": true }
}
}
Insights
Métricas agregadas (spend, impressions, clicks, reach, leads, revenue). Las métricas derivadas (CTR, CPC, CPM, CPL, ROAS) se calculan del lado del servidor.
/v1/insightsRequeridos: date_start, date_end (YYYY-MM-DD).
Optionals: group_by=date|campaign|adset|ad (default: date) · platform · ad_account_id · campaign_id · adset_id · ad_id · business_line_id
GET /v1/insights?group_by=campaign&date_start=2026-03-24&date_end=2026-04-23&platform=google
{
"success": true,
"data": [{
"campaign_id": 626,
"campaign_name": "jgl_lvly_sem_categoria",
"spend": 47412.88,
"impressions": 36406,
"clicks": 5235,
"reach": 28914,
"leads": 116,
"purchases": 13,
"revenue": 789947.98,
"ctr": 14.3795,
"cpc": 9.0570,
"cpm": 1302.3462,
"cpl": 408.7317,
"cpp": 3647.1446,
"roas": 16.6610
}],
"meta": { ... }
}
/v1/insights/totalsMismos filtros, pero devuelve un solo objeto con totales y métricas derivadas.
Reports
Endpoints accionables: ROAS, CPA, ganadores, fugas de dinero, recomendaciones. Todos aceptan ?date_start, ?date_end (default últimos 30 días), y ?business_line_id.
/v1/reports/totalsKPIs globales del rango: spend, leads, won, revenue, CPL, CPA, ROAS.
{
"success": true,
"data": {
"spend": 775750.48,
"impressions": 17330807,
"clicks": 254945,
"leads": 5685,
"won": 76,
"revenue": 3119359.12,
"cpl": 136.46,
"cpa": 10207.24,
"roas": 4.02,
"ctr": 1.47,
"lead_to_won": 1.34
}
}
/v1/reports/platformsBreakdown por plataforma (Facebook vs Google vs TikTok vs WhatsApp vs Website).
/v1/reports/platform-winnersIdentifica la plataforma con mejor y peor ROAS en el rango.
{
"success": true,
"data": {
"best": { "platform": "google", "roas": 8.07, "revenue": 2266046, "cpa": 6688 },
"worst": { "platform": "facebook", "roas": 0.14, "revenue": 69057, "cpa": 247426 },
"all": [ ... ]
}
}
/v1/reports/top-campaigns?limit=5Top N campañas por ROAS (mínimo 5 leads para evitar ruido). Límite 1–50, default 5.
/v1/reports/money-leaks?limit=5Campañas con spend ≥ $500 y 0 ventas atribuidas. Ordenadas por spend descendente.
/v1/reports/top-ads?limit=5Top N anuncios individuales por ROAS.
/v1/reports/recommendations?limit=3Pares heurísticos "mueve $X de [perdedor] a [ganador]".
{
"success": true,
"data": [{
"from": { "id": 812, "name": "sgv_lvly_perf_wa", "platform": "facebook", "spend": 78862, "won": 0 },
"to": { "id": 626, "name": "jgl_lvly_sem_categoria", "platform": "google", "roas": 16.66 },
"amount": 1500,
"reason": "\"sgv_lvly_perf_wa\" lleva $78,862 gastados sin una sola venta..."
}]
}
¿Preguntas o feedback? zamarrong@gmail.com