API · Estadísticas — lleva tus números a donde ya trabajas
Los endpoints de estadísticas te devuelven los mismos números que ves en la sección Estadísticas —leads, conversiones y rendimiento por publicación— para que los lleves a Looker Studio, Google Sheets, n8n o tu propio backend.
Esta página cubre solo esos endpoints. Cómo conseguir la clave, cómo autenticarte, la forma de las respuestas, el límite de peticiones y los errores comunes a toda la API están en API de ZeroChats. Empieza por ahí si es tu primera llamada.
La URL base es:
https://app.zerochats.com/api/statistics/v1Todas las llamadas son GET y la clave viaja en la cabecera Authorization:
curl -H "Authorization: Bearer zcst_tu_clave" \ https://app.zerochats.com/api/statistics/v1/overviewEn estos endpoints meta viene siempre, y te dice qué periodo y qué zona horaria han producido los números:
{ "success": true, "data": {}, "meta": { "startDay": "2026-07-01", "endDay": "2026-07-30", "timezone": "Europe/Madrid" }}Endpoints
Sección titulada «Endpoints»| Endpoint | Acepta fechas | Qué devuelve |
|---|---|---|
/me | No | El negocio al que pertenece la clave y su zona horaria. |
/overview | Sí | Totales históricos y reparto por etapa del embudo, separando entrantes y salientes. |
/leads/daily | Sí | Una fila por día: leads recibidos y hasta dónde llegaron. |
/leads/by-weekday | No | Reparto histórico de los leads inbound por día de la semana. |
/leads/by-hour | No | Reparto histórico de los leads inbound por hora del día. |
/conversions/goals | Sí | Por enlace de venta y día de envío: en Propuesta y convertidos. |
/conversions/tags | Sí | Leads convertidos (Agendado o Pagado) por etiqueta y día. |
/conversions/contents | Sí | Por contenido y día de envío: en Propuesta y convertidos. |
/performance | Sí | Rendimiento por publicación, anuncio u origen, con enlace al post. |
/welcome-messages | Sí | Mensajes de bienvenida enviados, respondidos y tasa de respuesta, por día. |
Los tres endpoints que no aceptan fechas (/me, /leads/by-weekday y /leads/by-hour) cubren toda la historia del negocio. Si les mandas startDay y endDay no da error: simplemente los ignora, y lo notas porque meta viene sin fechas.
/overview
Sección titulada «/overview»{ "lifetime": { "totalLeads": 1840, "positiveLeads": 213 }, "funnel": { "inbound": [ { "state": "OPEN_CONVERSATION", "count": 48 }, { "state": "LEAD", "count": 21 }, { "state": "CLIENT", "count": 7 } ], "outbound": [{ "state": "IN_PROGRESS", "count": 12 }] }}lifetime es histórico y no depende del rango que pidas: totalLeads son todos tus leads y positiveLeads los que están en Propuesta, Agendado o Pagado (la Propuesta realizada, no las conversiones).
funnel sí cubre el rango, y separa los leads entrantes (te escribieron ellos) de los salientes (empezaste tú la conversación). Van aparte a propósito: son dos formas distintas de captar y mezclarlas esconde cuál de las dos convierte.
Cada etapa llega por su nombre en inglés, igual que en el Webhook personalizado y en los endpoints de leads, y por el mismo motivo: los nombres son iguales en todas las cuentas trabajes en el idioma que trabajes, así que un filtro construido sobre ellos no se rompe.
| Etapa en la app | state |
|---|---|
| Abierta | OPEN_CONVERSATION |
| Descubriendo | IN_PROGRESS |
| Cualificando | QUALIFYING |
| Propuesta | LEAD |
| Agendado | BOOKED |
| Pagado | CLIENT |
| Pospuesto | POSTPONED |
| No cualificado | NO_QUALIFY |
| Perdido | LOST |
/leads/daily
Sección titulada «/leads/daily»[{ "date": "2026-07-01", "total": 34, "qualified": 6, "booked": 2, "paid": 1 }]| Campo | Qué es |
|---|---|
date | El día, en formato YYYY-MM-DD. |
total | Conversaciones de ese día: leads con los que habló tu IA, en el día de su último cambio de estado. |
qualified | De esos, los que están hoy en Propuesta. |
booked | De esos, los que están hoy en Agendado. |
paid | De esos, los que están hoy en Pagado. |
Los días sin actividad vienen igualmente, con ceros, para que puedas pintar la serie tal cual sin rellenar huecos.
/leads/by-weekday y /leads/by-hour
Sección titulada «/leads/by-weekday y /leads/by-hour»[{ "dayOfWeek": 0, "day": "MONDAY", "total": 240, "qualified": 31, "booked": 14 }][{ "hour": 9, "total": 88, "qualified": 12, "booked": 5 }]dayOfWeek va de 0 (lunes) a 6 (domingo) y day te da el nombre para que no tengas que recordar la convención. hour va de 0 a 23. Ambos vienen siempre completos: los siete días y las veinticuatro horas, aunque alguna esté a cero.
Igual que los gráficos por día de la semana y por hora de Estadísticas, solo cuentan los leads que te escribieron ellos (inbound) y con los que habló tu IA, en el momento en que escribieron. Aquí qualified son los leads en Propuesta y booked agrupa Agendado y Pagado. No intentes cuadrar estos dos endpoints fila a fila con /leads/daily: responden a otra pregunta —a qué hora y qué día te escribe la gente— y no al recorrido de una cohorte.
/conversions/goals, /conversions/tags y /conversions/contents
Sección titulada «/conversions/goals, /conversions/tags y /conversions/contents»Los tres devuelven la misma forma, una fila por entidad y día:
[ { "date": "2026-07-14", "id": "9f1c8a4e-2b77-4d0a-9d1c-3f2b6a5c7e10", "name": "Sesión de valoración", "leads": 4, "clients": 1 }]name te llega ya resuelto —el nombre del enlace de venta, de la etiqueta o del contenido— para que no tengas que hacer una segunda consulta ni mantener tu propia tabla de equivalencias.
Una conversión es un lead que hoy está en Agendado o Pagado; la Propuesta no cuenta.
- En
/conversions/goalsy/conversions/contents, cada fila es un día de envío:leadsson las personas que recibieron el enlace o el contenido ese día y hoy están en Propuesta, yclientslas que hoy están en Agendado o Pagado, es decir, las conversiones. - En
/conversions/tags,leadsson los leads con esa etiqueta que hoy están en Agendado o Pagado, yclientsvale lo mismo: una etiqueta está puesta o no lo está, no hay una distinción entre lead y cliente que reportar. Hasta el 15 de octubre de 2026 este endpoint también contaba a los leads en Propuesta.
/performance
Sección titulada «/performance»Una fila por publicación, anuncio u origen de los leads del periodo:
[ { "kind": "media", "id": "17900000000000000", "name": null, "mediaId": "17900000000000000", "mediaType": "REELS", "url": "https://www.instagram.com/reel/CxYzAbCdEfG/", "leads": 120, "answered": 86, "qualified": 24, "booked": 9, "paid": 4, "rates": { "answered": 71.67, "qualified": 20, "booked": 7.5, "paid": 3.33 } }]| Campo | Qué es |
|---|---|
kind | media (una publicación o un anuncio), personalized (un origen que has definido tú), inbound, outbound. |
id | Identificador de la fila. En media es el de la publicación en Instagram. |
name | El nombre del origen personalizado. Vacío en el resto de filas. |
mediaId | Identificador de la publicación. null si la fila no es una publicación. |
mediaType | STORY, FEED, REELS o AD. null si la fila no es una publicación. |
url | Enlace público al post en Instagram. null si no lo conocemos. |
leads | Leads que tocaron esa publicación u origen. |
answered | De esos, los que te escribieron por privado después de un mensaje tuyo. Los comentarios no cuentan. |
qualified | De esos, los que llegaron a Propuesta, Agendado o Pagado. |
booked | Los que están hoy en Agendado. |
paid | Los que están hoy en Pagado. |
rates | Esos mismos cuatro números en porcentaje sobre leads, con dos decimales. |
El url es la pieza que convierte un informe en algo accionable: cada fila de tu panel puede enlazar al post real, así que quien lo lee pasa del número al contenido de un clic. Es un enlace normal de Instagram, estable y público — no caduca.
qualified incluye a los que agendaron y a los que pagaron, así que se lee como un embudo: qualified es más ancho que booked y paid, que son excluyentes entre sí (un lead en Pagado no cuenta en booked). answered usa la misma definición de «Respondió» que la app —un DM del lead después de un mensaje tuyo, cuente o no después como Perdido—, explicada en Estadísticas e informes. La fila outbound va por el día en que se envió la bienvenida; el resto, por el último cambio de estado.
/welcome-messages
Sección titulada «/welcome-messages»[{ "date": "2026-07-01", "sent": 40, "responded": 11, "responseRate": 27.5 }]responseRate es el porcentaje de sent con dos decimales, y vale 0 los días en que no enviaste nada. Cada bienvenida cuenta en el día en que se envió, y responded sigue la definición de Respondió: los envíos de un día ya no cambian, pero sus respuestas aún pueden subir.
Rangos de fechas
Sección titulada «Rangos de fechas»Los endpoints marcados como «Acepta fechas» reciben dos parámetros:
| Parámetro | Formato | Qué es |
|---|---|---|
startDay | YYYY-MM-DD | Primer día, incluido. |
endDay | YYYY-MM-DD | Último día, incluido. |
curl -H "Authorization: Bearer zcst_tu_clave" \ "https://app.zerochats.com/api/statistics/v1/leads/daily?startDay=2026-07-01&endDay=2026-07-31"Las reglas son cuatro:
- Los dos días son días de calendario en la zona horaria de tu negocio, no marcas de tiempo. Si tu negocio está en Madrid, el 1 de julio va de las 00:00 a las 23:59 de Madrid, aunque tú lances la consulta desde México. Ese es el motivo de que
meta.timezoneviaje en todas las respuestas. - O mandas los dos, o no mandas ninguno. Mandar solo uno da error en vez de suponer el otro.
- Si no mandas ninguno, te damos los últimos 30 días, hoy incluido.
- El máximo son 366 días. Un rango más largo da error; parte la consulta en trozos.
Un ejemplo de las dos primeras reglas juntas: pedir startDay=2026-07-01&endDay=2026-07-31 te da julio entero, los 31 días, con la primera y la última fila incluidas. Pedir startDay=2026-07-31&endDay=2026-07-01 da error, porque el inicio tiene que ir antes que el final. Y pedir solo startDay=2026-07-01 también da error, con el mensaje startDay and endDay must be provided together.
Todos esos errores llegan como 400 con error.code a invalid_request: fecha con formato incorrecto, solo uno de los dos días, orden invertido o rango de más de 366 días.
Si necesitas muchos días, pide un rango amplio en una sola llamada en vez de un día por petición: los endpoints por día ya te devuelven la serie completa, y una llamada de 30 días es más rápida y más barata que 30 llamadas de un día.
Ejemplo práctico: informe semanal de contenido
Sección titulada «Ejemplo práctico: informe semanal de contenido»Un caso real y completo: cada lunes quieres saber qué publicaciones te trajeron clientes la semana pasada, con enlace a cada post para poder repasarlas.
-
Calcula el rango. Del lunes anterior al domingo anterior, en formato
YYYY-MM-DD. Por ejemplostartDay=2026-08-17yendDay=2026-08-23. -
Llama a
/performancecon ese rango.Ventana de terminal curl -H "Authorization: Bearer zcst_tu_clave" \"https://app.zerochats.com/api/statistics/v1/performance?startDay=2026-08-17&endDay=2026-08-23" -
Quédate con las filas
kind: "media". Son las publicaciones y los anuncios;inboundyoutboundson las bolsas generales y no te sirven para este informe. -
Ordena por
paid—o porrates.paidsi te interesa más la eficiencia que el volumen— y quédate con las cinco primeras. -
Monta el mensaje usando
url. Cada línea lleva el enlace al post, así que quien lo lee puede abrirlo sin buscarlo.Top contenidos del 17 al 23 de agosto1. REELS — 120 leads · 4 clientes (3,33 %) → https://www.instagram.com/reel/CxYzAbCdEfG/2. FEED — 86 leads · 3 clientes (3,49 %) → https://www.instagram.com/p/CxAbCdEfGhI/ -
Publícalo donde lo vayas a leer: un canal de Slack, un email o una fila nueva en una hoja de cálculo.
Si quieres añadir contexto de negocio a ese mismo informe, llama también a /leads/daily con el mismo rango para el volumen total de la semana, y a /conversions/goals para saber qué enlace de venta cerró esos clientes.
Buenas prácticas
Sección titulada «Buenas prácticas»- Guarda la zona horaria de
metajunto a los datos si los almacenas. Un número sin saber en qué calendario está medido no se puede comparar con otro más adelante. - Usa
idcomo clave, noname. Los nombres de etiquetas, contenidos y enlaces de venta se pueden cambiar desde la app; los identificadores no. - Pide rangos, no días sueltos. Una llamada de 30 días es más rápida y más barata que 30 llamadas de un día.
Problemas comunes
Sección titulada «Problemas comunes»Los problemas con la clave —un 401 recién copiada, una clave que deja de funcionar— están en API de ZeroChats. Estos son los propios de las estadísticas.
Los números no coinciden con lo que veo en Estadísticas
Sección titulada «Los números no coinciden con lo que veo en Estadísticas»Casi siempre es el rango. Repasa que estés pidiendo los mismos días —recuerda que ambos extremos van incluidos— y mira meta.timezone: si tu herramienta calcula las fechas en su propia zona horaria y tu negocio está en otra, estarás comparando periodos ligeramente distintos.
En /leads/by-weekday y /leads/by-hour hay además una diferencia de criterio deliberada, explicada más arriba: booked incluye ahí también a los que ya han pagado.
/performance me devuelve más leads de los que tengo
Sección titulada «/performance me devuelve más leads de los que tengo»Es lo esperado y está explicado más arriba: un lead que ha tocado varias publicaciones cuenta en todas. Para el total del negocio, usa /overview o /leads/daily.
Algunas filas de /performance traen url a null
Sección titulada «Algunas filas de /performance traen url a null»Significa que no tenemos el enlace público de esa publicación —suele pasar con contenidos antiguos o eliminados—. Muestra la fila igual usando mediaType como etiqueta, pero sin enlace.