Documentación API
Integra LogsNinja en tu aplicación en minutos. Envía eventos desde cualquier lenguaje con una simple petición HTTP POST.
Inicio rápido
Obtener el prompt de inicioAutenticación
Todas las solicitudes deben incluir un token API en el encabezado Authorization.
Authorization: Bearer YOUR_API_TOKEN
Puedes crear tokens API desde la configuración de tu proyecto. Ir a los tokens
Si eres un agente de IA en lugar de un humano, puedes obtener un token sin que alguien te lo copie y pegue. Ver la autorización de dispositivo
Límites de velocidad y cuotas
Los límites dependen de su plan. El límite de velocidad se aplica por organización y se comparte entre todos los tokens de API; crear tokens adicionales no lo aumenta.
El límite global por organización se aplica a cada endpoint autenticado con un token de API, incluyendo POST /v1/events, PUT /v1/users, POST /v1/ping, PUT /v1/metrics, /v1/org/charts, /v1/org/widgets, y las operaciones de eliminación. Cada llamada consume una solicitud de ese mismo límite compartido.
/v1/device/authorize (aún sin token en ese punto) está limitado a 10 solicitudes por hora por dirección IP, y /v1/device/token a 60 solicitudes por 5 minutos por dirección IP.
| Plan | Límite de llamadas | Eventos / mes | Imágenes / mes | Imágenes por evento |
|---|---|---|---|---|
| Free | 60 req/min | 3,000 | – | No incluido |
| Starter | 300 req/min | 100,000 | 20,000 | 1 por evento · 1 MB máx · redimensionada a 1024px · cuerpo de la solicitud hasta 1 MB |
| Plus | 1,200 req/min | 500,000 | 100,000 | 4 por evento · 1 MB máx · redimensionada a 1024px · cuerpo de la solicitud hasta 8 MB |
| Enterprise | Personalizado | Personalizado | Personalizado | Personalizado |
Cuando se supera el límite de solicitudes, la API devuelve 429 con Too many requests. El número de eventos y el número de imágenes tienen cada uno su propia cuota mensual; cuando se alcanza cualquiera de las dos, la API devuelve 429 con Monthly event or hosted image quota exceeded. Upgrade your plan to continue.
Encabezados de cuota
Cada respuesta correcta de POST /v1/events incluye estos encabezados:
X-Quota-Remaining: 2497
X-Image-Quota-Remaining: 18320
X-Plan: starter
X-Quota-Remaining– eventos restantes en el mes natural en curso.-1significa ilimitado (Enterprise).X-Image-Quota-Remaining– imágenes restantes en el mes natural en curso.-1significa ilimitado (Enterprise).X-Plan– el plan actual de la organización (free,starter,plus,enterprise).
Formato de metadatos
El campo metadata en eventos y usuarios sigue las mismas reglas:
- Claves: solo letras minúsculas, dígitos, guiones y guiones bajos (
^[a-z0-9_-]+$) - Valores:
string,number, oboolean - Máximo 20 claves por objeto
- Claves: 100 caracteres máximo
- Valores de texto: 255 caracteres máximo
{
"plan": "pro",
"amount": 49,
"score": 4.8,
"is-trial": false
}
Prompt de inicio
Pega este prompt en Claude Code, Cursor, Codex o cualquier agente de IA para empezar de inmediato.
You are integrating LogsNinja into this project.
LogsNinja is a real-time event tracking and push notification platform. Use its REST API to log application events, track users, update dashboard metrics, and trigger instant push notifications to mobile and desktop devices.
LogsNinja provides no SDK – all integration is done via plain HTTP calls using the libraries and conventions already present in this project.
## Fetch the full API documentation
Before writing any integration code, fetch the complete reference in Markdown:
curl https://logsninja.com/es/docs -H "Accept: text/markdown"
Read it carefully – it covers all endpoints, request fields, response codes, rate limits, and examples.
## Core concepts
**Events** – send a POST to /v1/events. All fields are covered in the documentation.
**Streams** – lightweight channels grouping events. Auto-created on first use (e.g. "payments", "errors").
**Users** – PUT /v1/users to create or update a user profile. The same id is used in the user field when sending events. Optional country_code is caller-supplied (LogsNinja does not geolocate IPs itself) – see the full docs for how to obtain it.
**Metrics** – PUT /v1/metrics to create or update a numeric, text, currency, or percent dashboard tile. Supports atomic diff increments.
**Presence** – POST /v1/ping to signal a user is online without creating an event.
**Event chains** – link events sequentially with before/after fields to trace multi-step workflows.
**Charts** – POST/GET/PATCH/DELETE /v1/org/charts to manage dashboard charts. Same fields and validation rules as the dashboard's own chart editor.
**Widgets** – POST/GET/PATCH/DELETE /v1/org/widgets (plus POST /v1/org/widgets/reorder) to manage what's on the dashboard. The dashboard is a masonry layout, not a rigid grid: "small" widgets (metric, online_users) are meant for width 1 or 2 and render at exactly half the visual height of "large" widgets (chart, world_map, events_7d, top_countries), meant for width 2 or 3 (full row) – keep that in mind when arranging one via the API.
## Authentication
All requests require:
Authorization: Bearer YOUR_API_TOKEN
Creating an account and generating a token both require a human to sign in
to the LogsNinja dashboard - you cannot do either yourself. If you don't
already have a token (e.g. in an environment variable), stop and ask the
person you're working with to create one at https://logsninja.com/es/my/tokens
and give it to you (for example as a LOGSNINJA_API_TOKEN environment
variable) before you continue.
## API base URL
https://api.logsninja.com/v1
## MCP server
If you are an AI agent with MCP support rather than a code-generation assistant, LogsNinja is also usable directly as an MCP server at https://logsninja.com/mcp (same Bearer token as above) – it exposes tools to manage charts and dashboard widgets, explore project data, and create/delete test events, users, and metrics, without writing HTTP calls yourself. See the full docs for the tool list.
## Integration guidelines
- Use the HTTP client and patterns already established in this project – do not introduce new dependencies.
- All LogsNinja calls must be fire-and-forget from the application's perspective: they must never block the main flow or surface errors to the end user.
- Apply a 3-second timeout to every HTTP call, if possible.
- If this project already has a job queue, background worker, or retry mechanism, use it for LogsNinja calls.
- If no such mechanism exists, wrap calls in a silent try/catch (or equivalent) so that a LogsNinja failure has zero impact on the application.
## What to instrument
Scan the codebase and identify meaningful moments to send events: key user actions, business transactions, errors, background jobs, and any other signal that would be useful to monitor. For each, choose a descriptive title and a fitting emoji. Once done, provide a summary of every integration point added.
## Presence
Use presence sparingly. Sending an event with a user field already updates that user's online status for 15 minutes, so a separate ping is redundant in those cases. Only call POST /v1/ping when you know the user is active but no event will be sent soon – for example on login, or during an idle session. Do not ping on every page view or API call.
Enviar un evento
https://api.logsninja.com/v1/events
Cabeceras
Authorization: Bearer YOUR_API_TOKEN
Content-Type: application/json
Cuerpo de la solicitud
{
"project": "YOUR_PROJECT_ID",
"stream": "payments",
"title": "New subscription",
"content": "[email protected] subscribed to Pro",
"emoji": "💳",
"metadata": { "plan": "pro", "amount": 49 },
"notify": true
}
Ejemplos
curl -X POST https://api.logsninja.com/v1/events \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"project": "YOUR_PROJECT_ID",
"stream": "payments",
"title": "New subscription",
"content": "[email protected] subscribed to Pro",
"notify": true
}'
await fetch('https://api.logsninja.com/v1/events', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_TOKEN',
'Content-Type': 'application/json',
},
body: JSON.stringify({
project: 'YOUR_PROJECT_ID',
stream: 'payments',
title: 'New subscription',
content: '[email protected] subscribed to Pro',
notify: true,
}),
});
import requests
requests.post(
'https://api.logsninja.com/v1/events',
headers={
'Authorization': 'Bearer YOUR_API_TOKEN',
'Content-Type': 'application/json',
},
json={
'project': 'YOUR_PROJECT_ID',
'stream': 'payments',
'title': 'New subscription',
'content': '[email protected] subscribed to Pro',
'notify': True,
},
)
Campos del evento
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
project |
string | ✓ | ID del proyecto. Encuéntralo en la configuración del proyecto. |
stream |
string | ✓ | El stream al que pertenece este evento. Creado automáticamente en el primer uso. |
title |
string | ✓ | Título breve del evento. 100 caracteres máximo. |
content |
string | Detalles adicionales, 500 caracteres máximo. Admite Markdown: negrita, cursiva, código, listas y enlaces. | |
emoji |
string | Emoji para identificar visualmente el evento. Por defecto 🔔 si se omite. Formatos aceptados: carácter emoji ("💳"), shortcode (":credit_card:"), o código hexadecimal ("1F4B3"). También se usa como imagen de la notificación push. Explorar emojis disponibles. |
|
metadata |
object | Metadatos clave/valor. Consulta las reglas de formato más arriba. | |
user |
string | El ID de su usuario en su aplicación (el mismo id que se pasa a PUT /v1/users). El usuario no necesita existir todavía: los eventos se vinculan automáticamente al crearlo. Enviar un evento en tiempo real con el campo user también cuenta como presencia: el usuario se considera en línea durante 15 minutos tras su último evento vinculado o ping. Los eventos backdatados con timestamp no afectan la presencia en línea. |
|
images |
string[] | Imágenes para este evento. Requiere un plan de pago. Un arreglo de URLs HTTPS públicas de imágenes para obtener y almacenar (los duplicados dentro de un mismo evento se deduplican), o los archivos enviados como multipart/form-data. Las imágenes se procesan de forma asíncrona y se conservan 30 días. Consulte Subida de imágenes para el contrato completo, los límites de tamaño, los formatos aceptados, los requisitos de las URLs y cómo leer images_status. |
|
notify |
boolean | Enviar una notificación push a los dispositivos suscritos. Por defecto: false. No puede ser true si timestamp está definido. Cuando notify está presente, la respuesta también incluye notification_queued; false significa que el evento se guardó, pero la cola de notificaciones móviles seguía sin estar disponible después del reintento. | |
timestamp |
integer | Timestamp Unix (en segundos) para retrofechar el evento. Debe ser en el pasado. No puede combinarse con notify: true. Los eventos backdatados no afectan la presencia en línea. | |
before |
string | El evento se colocará antes que aquel cuyo ID se haya transmitido en esta propiedad, dentro de una cadena de eventos. | |
after |
string | El evento se colocará después de aquel cuyo ID se haya transmitido en esta propiedad, dentro de una cadena de eventos. |
Subida de imágenes
Hay dos formas de adjuntar imágenes a un evento, ambas en planes de pago y procesadas de la misma manera, de forma asíncrona: pasar un arreglo de URLs HTTPS públicas en el campo JSON images para que LogsNinja las obtenga y las almacene, o enviar los propios archivos en la misma solicitud POST /v1/events como multipart/form-data.
Subida binaria (multipart/form-data)
La solicitud tiene una parte event y una o más partes de archivo llamadas image:
| Parte | Descripción |
|---|---|
event |
Una cadena con el cuerpo JSON exacto que enviaría de otro modo como application/json: project, stream, title y cualquier otro campo, con metadata como un objeto JSON real (no campos de formulario metadata[key]). Puede seguir incluyendo un arreglo images de URLs, almacenadas junto con los archivos subidos. |
image |
Una parte por archivo, cada una enviada como archivo (con un nombre de archivo) y con un Content-Type de image/jpeg, image/png o image/webp. Las partes con cualquier otro nombre, y las partes image que no son archivos, se ignoran. |
curl -X POST https://api.logsninja.com/v1/events \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-F 'event={"project":"YOUR_PROJECT_ID","stream":"payments","title":"New subscription","metadata":{"plan":"pro"},"notify":true};type=application/json' \
-F 'image=@./screenshot.png;type=image/png'
const form = new FormData();
form.append('event', JSON.stringify({
project: 'YOUR_PROJECT_ID',
stream: 'payments',
title: 'New subscription',
metadata: { plan: 'pro' },
notify: true,
}));
form.append('image', fileOrBlob, 'screenshot.png'); // Content-Type image/png
await fetch('https://api.logsninja.com/v1/events', {
method: 'POST',
headers: { 'Authorization': 'Bearer YOUR_API_TOKEN' }, // no Content-Type
body: form,
});
Errores síncronos
Se devuelven de inmediato en la respuesta del POST, antes de crear el evento:
| Código | Causa |
|---|---|
400 | Falta la parte event o no es un objeto JSON. |
403 | Su plan no incluye imágenes en los eventos. |
411 | La solicitud no tiene el encabezado Content-Length. |
413 | Un archivo supera el límite de tamaño por imagen de su plan, o el cuerpo completo de la solicitud supera el tamaño máximo de su plan. |
415 | El Content-Type de una parte image no empieza por image/. Un tipo de imagen incorrecto (p. ej. image/gif) supera esta comprobación pero luego falla como bad_format. |
422 | Más imágenes de las que su plan permite por evento. |
Consulte Límites de tasa y cuotas para el número de imágenes por plan, el tamaño por imagen y el tamaño máximo del cuerpo de la solicitud.
Obtención desde una URL
Cuando pasa URLs en lugar de archivos, cada una debe cumplir todo lo siguiente o la imagen se marca como failed:
- Solo HTTPS, en el puerto 443. Sin hosts con IP literal, sin
localhost,.localni.internal. La URL debe tener como máximo 2048 caracteres. - La respuesta debe llevar
Content-Type: image/jpeg,image/pngoimage/webp. Un200que devuelvetext/html(una página de error, un muro de inicio de sesión) es un fallo permanente: nunca se reintenta. - La obtención expira tras 15 segundos y sigue como máximo 3 redirecciones.
- Con
403,404,408,425,429,500,502,503o504, la obtención se reintenta durante aproximadamente un minuto antes de marcar la imagen comofailed. Cualquier otro estado falla de forma permanente en el primer intento.
Formatos y procesamiento
- Formatos aceptados: JPEG, PNG y WebP, detectados a partir de los bytes mágicos del archivo, no de su extensión ni de su tipo declarado.
- Cada imagen se redimensiona para ajustarse a la dimensión máxima de su plan y se almacena en JPEG y WebP. Las imágenes se conservan 30 días.
- Un evento retrofechado (
timestamp) cuya fecha ya está fuera de la ventana de 30 días omite por completo el procesamiento de imágenes; suimages_statusesexpired.
Leer el resultado
La respuesta del POST incluye images_status, pero en ese momento siempre es pending (o none / expired) porque el procesamiento aún no se ha ejecutado. No hay webhook: vuelva a leer el evento más tarde, con la herramienta get_event del MCP o en el feed de eventos del Studio, para ver el resultado.
images_status |
Significado |
|---|---|
none | El evento no tiene imágenes. |
pending | En cola o en curso. |
ready | Se procesaron todas las imágenes. |
partial | Algunas imágenes están listas, otras fallaron. |
failed | Fallaron todas las imágenes. |
expired | El evento es anterior a la ventana de imágenes de 30 días; no se subió nada. |
Cada imagen también lleva una cadena error y un error_code (too_large, bad_format o unreachable) cuando falló.
Recomendación: para un evento que emite justo después de generar una imagen (un render, una captura, una exportación), suba el archivo en lugar de una URL. Una URL que aún no es accesible, o que ya se eliminó, cuando LogsNinja la obtiene hace fallar la imagen, y nada le avisa cuando eso ocurre.
Cadenas de eventos
Los campos before y after enlazan eventos en una cadena. El panel de detalles muestra los eventos adyacentes y permite ver la secuencia completa.
Solo se resuelven referencias a eventos del mismo proyecto y únicamente cuando sus marcas de tiempo son coherentes. El destino de after (predecesor) debe tener una marca de tiempo anterior, y el de before (sucesor) una posterior.
Eliminar un evento
https://api.logsninja.com/v1/events/:id?project=YOUR_PROJECT_ID
Elimina permanentemente un evento.
Crear o actualizar un usuario
https://api.logsninja.com/v1/users
Crea o actualiza un usuario de la app. Una llamada con el mismo id sustituye el registro.
{
"project": "YOUR_PROJECT_ID",
"id": "user_123",
"country_code": "FR",
"display_as": "[email protected]",
"metadata": { "plan": "pro", "mrr": 49 }
}
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
project |
string | ✓ | ID del proyecto. |
id |
string | ✓ | Tu propio identificador estable para este usuario (ej. tu ID de base de datos). Es el valor que usas en el campo user al enviar eventos. |
country_code |
string | Código de país ISO 3166-1 alpha-2 (p. ej. FR, US). Consulta Geolocalización para saber cómo obtenerlo. | |
display_as |
string | Nombre mostrado en el sitio y la aplicación móvil para este usuario. Si no está definido o es null, se usa el id del usuario. |
|
metadata |
object | Metadatos clave/valor. Consulta las reglas de formato más arriba. |
Ejemplos
curl -X PUT https://api.logsninja.com/v1/users \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"project": "YOUR_PROJECT_ID",
"id": "user_123",
"country_code": "FR",
"metadata": { "plan": "pro" }
}'
await fetch('https://api.logsninja.com/v1/users', {
method: 'PUT',
headers: {
'Authorization': 'Bearer YOUR_API_TOKEN',
'Content-Type': 'application/json',
},
body: JSON.stringify({
project: 'YOUR_PROJECT_ID',
id: 'user_123',
country_code: 'FR',
metadata: { plan: 'pro' },
}),
});
import requests
requests.put(
'https://api.logsninja.com/v1/users',
headers={
'Authorization': 'Bearer YOUR_API_TOKEN',
'Content-Type': 'application/json',
},
json={
'project': 'YOUR_PROJECT_ID',
'id': 'user_123',
'country_code': 'FR',
'metadata': {'plan': 'pro'},
},
)
Geolocalización
LogsNinja nunca determina el país de un usuario a partir de su dirección IP – country_code lo proporciona enteramente quien llama a la API.
- Si tu backend pasa por Cloudflare (Workers/Pages, o un registro DNS con la nube naranja activada), lee directamente la cabecera de solicitud
CF-IPCountry– ya está presente en cada solicitud entrante. - La misma idea aplica detrás de la mayoría de otras CDN/redes perimetrales (p. ej. Akamai, Bunny, Fastly, Amazon CloudFront) – normalmente añaden su propia cabecera geo equivalente. Consulta la documentación de ese proveedor para el nombre y formato exactos de la cabecera.
- Si no, usa una biblioteca o servicio GeoIP sobre la dirección IP de la solicitud (p. ej. MaxMind GeoLite2, ipinfo.io, ip-api.com).
Envía el código resultante como country_code – alimenta el gráfico de desglose por país y el widget del mapa mundial.
Eliminar un usuario
https://api.logsninja.com/v1/users/:id?project=YOUR_PROJECT_ID
Elimina un usuario de la app. Sus eventos se conservan pero ya no están vinculados al usuario.
Señalar presencia de usuario
https://api.logsninja.com/v1/ping
Registra que un usuario está conectado en este momento, sin crear un evento. Un usuario se considera conectado si ha enviado un ping o ha tenido un evento vinculado en los últimos 15 minutos. Si el usuario aún no existe, el ping se ignora silenciosamente – cree primero el usuario con PUT /v1/users.
{
"project": "YOUR_PROJECT_ID",
"id": "user_123"
}
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
project |
string | ✓ | ID del proyecto. |
id |
string | ✓ | El identificador de tu usuario de la app (el mismo id enviado a PUT /v1/users). |
Crear o actualizar una métrica
https://api.logsninja.com/v1/metrics
Crea o actualiza una métrica. Una llamada con el mismo id reemplaza el valor. Para tipos numéricos, también puedes aplicar un delta en lugar de definir un valor absoluto.
{
"project": "YOUR_PROJECT_ID",
"id": "mrr",
"title": "MRR",
"emoji": "💰",
"value": 4900,
"value_type": "currency",
"currency": "EUR"
}
{
"project": "YOUR_PROJECT_ID",
"id": "active-users",
"title": "Active users",
"value": { "diff": 1 },
"value_type": "number"
}
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
project |
string | ✓ | ID del proyecto. |
id |
string | ✓ | Identificador estable de esta métrica (p. ej. mrr, active-users). |
title |
string | ✓ | Etiqueta mostrada en el mosaico de métrica. |
value |
string | number | object | ✓ | El valor de la métrica. Para tipos numéricos, pasa {"diff": N} para sumar o restar N atómicamente (p. ej. {"diff": -1}). No disponible para value_type text. |
value_type |
string | ✓ | Uno de: number, text, currency, percent. |
currency |
string | Código de moneda ISO 4217 (p. ej. EUR, USD). Obligatorio cuando value_type es currency. |
|
emoji |
string | Emoji mostrado en la ficha de métrica. Formatos aceptados: carácter emoji ("💰"), shortcode (":money-bag:") o código hexadecimal ("1F4B0"). Si se omite, ℹ️ se muestra de forma predeterminada sin almacenarse en la métrica. Consulta los emojis disponibles. |
Ejemplos
curl -X PUT https://api.logsninja.com/v1/metrics \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"project": "YOUR_PROJECT_ID",
"id": "mrr",
"title": "MRR",
"value": 4900,
"value_type": "currency",
"currency": "EUR"
}'
await fetch('https://api.logsninja.com/v1/metrics', {
method: 'PUT',
headers: {
'Authorization': 'Bearer YOUR_API_TOKEN',
'Content-Type': 'application/json',
},
body: JSON.stringify({
project: 'YOUR_PROJECT_ID',
id: 'mrr',
title: 'MRR',
value: 4900,
value_type: 'currency',
currency: 'EUR',
}),
});
import requests
requests.put(
'https://api.logsninja.com/v1/metrics',
headers={
'Authorization': 'Bearer YOUR_API_TOKEN',
'Content-Type': 'application/json',
},
json={
'project': 'YOUR_PROJECT_ID',
'id': 'mrr',
'title': 'MRR',
'value': 4900,
'value_type': 'currency',
'currency': 'EUR',
},
)
Eliminar una métrica
https://api.logsninja.com/v1/metrics/:id?project=YOUR_PROJECT_ID
Elimina un mosaico de métrica del panel.
Proyectos
Listar proyectos
https://api.logsninja.com/v1/org/projects
Devuelve los proyectos de la organización con paginación. Un token limitado a un proyecto solo recibe su proyecto vinculado. Acepta los parámetros page (1 por defecto) y limit (50 por defecto, máximo 200). La respuesta incluye page, limit, total y has_more.
Crear un proyecto
https://api.logsninja.com/v1/org/projects
Crear un proyecto requiere un token válido para toda la organización. Un token limitado a un proyecto no puede crear proyectos.
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
name |
string | ✓ | El nombre del proyecto. |
Tokens
Listar tokens
https://api.logsninja.com/v1/org/tokens
Devuelve los tokens de API de la organización con paginación. Un token limitado a un proyecto solo recibe los tokens vinculados al mismo proyecto. Acepta los parámetros page (1 por defecto) y limit (50 por defecto, máximo 200). La respuesta incluye page, limit, total, has_more y la capacidad can_manage_tokens de cada token. Los valores de los tokens nunca se devuelven después de crearlos.
Crear un token
https://api.logsninja.com/v1/org/tokens
La credencial que realiza la llamada debe tener can_manage_tokens=true. El valor del token se devuelve una sola vez y no puede recuperarse de nuevo. Un llamante limitado a un proyecto solo puede crear otro token para su propio proyecto; omitir project_id no concede acceso a toda la organización.
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
name |
string | ✓ | El nombre del token. |
project_id |
string | Limita el token a un solo proyecto. Si se omite, el token tiene acceso a todos los proyectos de la organización. | |
can_manage_tokens |
boolean | Permite que este token cree y delegue otros tokens dentro de los límites de su organización o proyecto. Desactivado por defecto. |
Autorización de dispositivo
Permite que una herramienta CLI o un agente de IA obtenga un token de API sin que un humano tenga que copiarlo y pegarlo. La herramienta solicita un código corto y se lo muestra a un humano; un humano con una cuenta de LogsNinja existente abre un enlace y aprueba la solicitud desde su propia sesión de navegador; la herramienta recibe entonces el token automáticamente. Esto nunca crea una cuenta ni evita el registro – solo un humano ya conectado puede aprobar una solicitud.
Iniciar el flujo
https://api.logsninja.com/v1/device/authorize
No requiere autenticación. Devuelve un device_code, un user_code corto para mostrar al humano, y un verification_uri para abrir en un navegador.
{
"device_code": "a1b2c3...",
"user_code": "WXYZ-1234",
"verification_uri": "https://logsninja.com/en/my/tokens#devices",
"verification_uri_complete": "https://logsninja.com/en/my/tokens?user_code=WXYZ-1234#devices",
"expires_in": 600,
"interval": 5
}
Muestra el user_code (o el enlace verification_uri_complete) al humano y pídele que lo abra y apruebe la solicitud.
Consultar para obtener el token
https://api.logsninja.com/v1/device/token
No requiere autenticación. Consulta con el device_code al intervalo indicado arriba hasta que el estado ya no sea pending.
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
device_code |
string | ✓ | El device_code devuelto por la llamada authorize. |
La respuesta es {"status": "pending"}, {"status": "denied"}, {"status": "expired"}, o, una vez aprobada, {"status": "approved", "token": "..."}. El token solo se devuelve una vez: guárdalo de inmediato.
Servidor MCP
Permite que un agente de IA (Claude, etc.) use LogsNinja directamente desde una conversación en lugar de escribir llamadas HTTP.
https://logsninja.com/mcp
Configura tu cliente MCP con esta URL, autenticado con el mismo token de API que el resto de esta API: Authorization: Bearer YOUR_API_TOKEN.
Claude Code
claude mcp add --transport http logsninja https://logsninja.com/mcp \
--header "Authorization: Bearer YOUR_API_TOKEN"
Claude Desktop
El archivo de configuración de Claude Desktop ya no acepta directamente el url ni los headers de un servidor remoto – solo servidores stdio (command/args). Conecta con este endpoint HTTP usando mcp-remote:
{
"mcpServers": {
"logsninja": {
"command": "npx",
"args": [
"-y",
"mcp-remote",
"https://logsninja.com/mcp",
"--header",
"Authorization: Bearer YOUR_API_TOKEN"
]
}
}
}
| Plataforma | Ubicación del archivo de configuración |
|---|---|
| macOS | ~/Library/Application Support/Claude/claude_desktop_config.json |
| Windows | %APPDATA%\Claude\claude_desktop_config.json |
Cursor
Cursor admite directamente el url y los headers de un servidor remoto, sin necesidad de puente:
{
"mcpServers": {
"logsninja": {
"url": "https://logsninja.com/mcp",
"headers": {
"Authorization": "Bearer YOUR_API_TOKEN"
}
}
}
}
Archivo de configuración: ~/.cursor/mcp.json (global) o .cursor/mcp.json (proyecto)
Codex CLI y la aplicación ChatGPT
Ambos comparten el mismo ~/.codex/config.toml – el formulario Configuración → Plugins → MCPs → Add Server de la aplicación ChatGPT también escribe ahí. Edítalo directamente para usar bearer_token_env_var, que lee el token desde una variable de entorno en lugar de guardarlo en texto plano:
[mcp_servers.logsninja]
url = "https://logsninja.com/mcp"
bearer_token_env_var = "LOGSNINJA_API_TOKEN"
Define la variable de entorno en tu perfil de shell antes de lanzar Codex o la aplicación ChatGPT, por ejemplo export LOGSNINJA_API_TOKEN=YOUR_API_TOKEN.
Archivo de configuración: ~/.codex/config.toml
Herramientas
| Herramienta | Descripción |
|---|---|
list_projects, create_project |
Lista los proyectos dentro del ámbito del llamante. Crear un proyecto requiere un token válido para toda la organización. |
list_charts, create_chart, update_chart, delete_chart |
Mismos campos y reglas de validación que el editor de gráficos del panel. |
list_widgets, create_widget, update_widget, reorder_widgets, delete_widget |
Mismas reglas de disposición tipo masonry que los endpoints REST de widgets. |
get_data_inventory |
Nombres de streams, títulos de eventos y claves de metadatos conocidos – útil antes de construir un gráfico. |
preview_chart_data |
Calcular los datos de un gráfico sin crearlo. |
search_emojis |
Buscar emojis por nombre, shortcode o palabra clave – útil para elegir uno para un evento. |
get_documentation |
La documentación completa de la API en Markdown, en el idioma que elijas. |
list_events, get_event |
Los últimos 100 eventos (opcionalmente por stream), o el detalle de un evento con sus vecinos cronológicos. Sin paginación. |
list_users, get_user |
Los últimos 100 usuarios, o el detalle de un usuario por id. Sin paginación ni búsqueda. |
list_streams, list_metrics |
Streams y métricas personalizadas definidas en un proyecto. |
create_event, delete_event, create_or_update_user, delete_user, create_or_update_metric, delete_metric |
Igual que los endpoints de ingesta – pensado para crear y limpiar datos de prueba, no para enviar eventos reales de producción en nombre de un usuario. |
La mayoría de los tools reciben un argumento project_id, obligatorio salvo que el token esté limitado a un único proyecto – misma regla que los endpoints REST de abajo.
Gráficos
Crea y gestiona los mismos gráficos que construirías a mano en tu panel – cada opción de abajo y cada regla de validación es idéntica, tanto si usas el editor de gráficos del panel como la API. Esto es solo la configuración del gráfico: define lo que muestra, no sus valores calculados – no existe un endpoint para obtener los puntos de datos de un gráfico mediante esta API.
Tipos de gráfico
Un gráfico de líneas (line) traza un valor por período como una línea continua – ideal para seguir una tendencia a lo largo del tiempo. Un gráfico circular (pie) muestra una única instantánea dividida en porciones – ideal para ver un reparto de un vistazo. Un gráfico de barras (bar) muestra una barra por período; en cuanto añades un desglose (ver « Group by » más abajo), se dibuja automáticamente con segmentos apilados en lugar de una sola barra – no existe un tipo « barras apiladas » aparte para elegir. Un gráfico de embudo (funnel) plantea un tipo de pregunta totalmente distinto: en lugar de una métrica a lo largo del tiempo, muestra cuántos de los mismos usuarios pasaron por una secuencia ordenada de pasos.
Intervalo de tiempo y granularidad
Elige hasta cuándo se remonta el gráfico: los últimos 7 días (7d), los últimos 30 días (30d), o los últimos 90 días (90d). También puedes definir tu propia ventana móvil en horas, días o meses (duration, con periodDurationValue y periodDurationUnit, ej. « los últimos 45 días »), o fijar una fecha de inicio que siempre llega hasta hoy (custom, con periodDateFrom) – no existe un campo para una fecha de fin fija, siempre llega hasta hoy.
El intervalo de tiempo (granularity) define cómo se divide ese período en tramos: por hora, día, semana o mes (hour, day, week, month). No se aplica a los gráficos de embudo: igualmente usan el intervalo de tiempo de arriba para filtrar eventos, pero muestran una barra por paso en lugar de una serie de tramos a lo largo del tiempo.
Algunas combinaciones solo tienen 90 días de historial disponibles, sea cual sea el período elegido: un embudo, un gráfico circular con un desglose, un desglose por país/usuario/metadata, más de un desglose a la vez, cualquier cálculo distinto de un simple recuento, o un filtrado por metadata. Un simple recuento sin desglose, o un desglose solo por stream o título de evento, puede remontarse más atrás.
Filtrar qué eventos cuentan
Por defecto, un gráfico incluye todos los eventos (all). Puedes limitarlo a un único stream (stream, ej. solo "payments"), un único título de evento (title, ej. solo "Order placed"), o a eventos que coincidan con un valor de metadatos específico (metadata, ej. solo eventos donde "plan" sea igual a "pro").
| Objetivo | Configuración |
|---|---|
| Contar solo eventos del stream "payments" | event_source_type: "stream", event_source_value: "payments" |
| Contar solo eventos "Order placed", sea cual sea su stream | event_source_type: "title", event_source_value: "Order placed" |
| Contar solo eventos donde el metadato "plan" es igual a "pro" | event_source_type: "metadata", event_source_value: "plan=pro" |
Agregación
Esto determina cómo los eventos coincidentes en cada intervalo de tiempo se convierten en el único número representado: un simple recuento de eventos (count), un recuento de usuarios únicos (count_distinct), o un cálculo sobre un valor numérico de metadatos de tus eventos – su total (sum), media (avg), mínimo (min), máximo (max) o mediana (median). Para cualquier cálculo distinto de un simple recuento, también eliges qué clave de metadatos contiene ese número mediante aggregation_field; los eventos que no la tengan, o donde no sea numérica, se omiten.
| Objetivo | Configuración |
|---|---|
| Eventos por día | aggregation: "count" |
| Usuarios únicos activos por día | aggregation: "count_distinct" |
| Ingresos totales por día (una clave de metadatos "amount" en tus eventos) | aggregation: "sum", aggregation_field: "amount" |
| Valor medio del pedido por día (una clave de metadatos "amount" en tus eventos) | aggregation: "avg", aggregation_field: "amount" |
| Pedido más pequeño por día (una clave de metadatos "amount" en tus eventos) | aggregation: "min", aggregation_field: "amount" |
| Pedido más grande por día (una clave de metadatos "amount" en tus eventos) | aggregation: "max", aggregation_field: "amount" |
| Duración media de sesión por día (una clave de metadatos "duration_seconds" en tus eventos) | aggregation: "median", aggregation_field: "duration_seconds" |
Agrupar por
Por defecto, un gráfico muestra un único valor agregado por período. Agrupar (group_by) lo divide en varias series o segmentos en su lugar – uno por cada valor distinto de aquello por lo que agrupas – dibujados como líneas separadas, segmentos apilados, o porciones de circular según el tipo de gráfico.
Puedes agrupar por stream (stream), título de evento (title), país (country) o usuario (user) sin necesidad de configurar nada más, o por una clave de metadatos de tu elección (metadata, con aggregation_field conteniendo la clave por la que dividir).
| Objetivo | Configuración |
|---|---|
| Eventos por día, una línea por stream | type: line, aggregation: count, group_by: ["stream"] |
| Qué títulos de evento son más comunes cada día | type: bar, aggregation: count, group_by: ["title"] |
| Registros por día, divididos por país | type: bar, aggregation: count_distinct, group_by: ["country"] |
| Comparar la actividad de un puñado específico de usuarios (tu propio equipo, algunas cuentas VIP) – una serie por usuario coincidente, así que solo se lee bien para un conjunto pequeño y deliberadamente acotado | type: line, aggregation: count, group_by: ["user"] |
| Volumen de eventos por día, un segmento por plan (una clave de metadatos "plan" en tus eventos, ej. free/pro/enterprise) | type: bar, aggregation: count, group_by: ["metadata"], aggregation_field: "plan" |
| Reparto de eventos por plan, como gráfico circular | type: pie, aggregation: count, group_by: ["metadata"], aggregation_field: "plan" |
Una restricción a tener en cuenta: la clave de metadatos por la que agrupas y la clave de metadatos que agregas son el mismo ajuste (aggregation_field), ya que un gráfico solo tiene uno. Así que "importe total de pedidos por día, dividido por plan" no es posible en un único gráfico – tendrías que sumar el importe sin desglose, o contar pedidos desglosados por plan, no ambos en el mismo gráfico.
Gráficos de embudo
Un embudo (funnel) plantea un tipo de pregunta totalmente distinto: no « cuántos eventos » sino « cuántos de los mismos usuarios pasaron del paso 1, al paso 2, al paso 3 ». Le das una lista ordenada de al menos dos títulos de eventos mediante funnel_steps; el gráfico muestra una barra por paso, cada una contando solo a los usuarios que también completaron cada paso anterior en orden. El intervalo de tiempo de arriba sigue aplicándose, pero no la granularidad, la agregación ni el agrupamiento.
| Objetivo | Configuración |
|---|---|
| Conversión de registro: cuántos vieron los precios, iniciaron el pago y lo completaron | type: "funnel", funnel_steps: ["Pricing viewed", "Checkout started", "Subscription created"] |
Opciones de visualización
Puedes mostrar u ocultar la leyenda (show_legend), y elegir tus propios colores (colors, un array de códigos hexadecimales aplicados en orden) para cada serie o segmento en lugar de la paleta por defecto. También puedes cambiar a un total acumulado (cumulative) en lugar de un valor por período – solo tiene sentido para un gráfico de líneas o de barras que sume un recuento o una suma, ya que un total acumulado de una media, un recuento de usuarios distintos, o un circular/embudo no tiene sentido.
Listar gráficos
https://api.logsninja.com/v1/org/charts
Acepta un parámetro de consulta project_id, obligatorio a menos que el token ya esté restringido a un solo proyecto.
Crear un gráfico
https://api.logsninja.com/v1/org/charts
Actualizar un gráfico
https://api.logsninja.com/v1/org/charts/{id}
Solo se modifican los campos enviados.
Eliminar un gráfico
https://api.logsninja.com/v1/org/charts/{id}
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
project_id |
string | ✓ | Obligatorio a menos que el token esté restringido a un solo proyecto. |
name |
string | ✓ | Nombre del gráfico. |
type |
string | ✓ | line, bar, pie, funnel. No existe un tipo « barras apiladas » aparte: un gráfico de barras con group_by definido sigue siendo de tipo bar, mostrado automáticamente como segmentos apilados. |
period |
string | ✓ | 7d, 30d, 90d, duration, custom |
period_date_from |
string | Obligatorio cuando period es custom, formato AAAA-MM-DD. | |
period_duration_value / period_duration_unit |
integer / string | Obligatorio cuando period es duration. La unidad es hour, day o month. | |
granularity |
string | ✓ | hour, day, week, month |
aggregation |
string | ✓ | count, count_distinct, sum, avg, min, max, median |
aggregation_field |
string | Nombre del campo de metadatos, obligatorio para sum/avg/min/max/median y cuando group_by incluye metadata. | |
group_by |
array | Cualquiera entre stream, title, country, user, metadata. | |
event_source_type |
string | ✓ | all, stream, title, metadata |
event_source_value |
string | Obligatorio a menos que event_source_type sea all. | |
funnel_steps |
array | Al menos dos nombres de paso ordenados, obligatorio cuando type es funnel. | |
show_legend / cumulative |
boolean | cumulative solo se aplica a gráficos line/bar con agregación count o sum. | |
colors |
array | Colores de las series como cadenas hexadecimales. |
El histórico más allá de la ventana de retención no está disponible para combinaciones que escanean eventos en bruto (funnel, pie con un group-by, group-by country/user/metadata, o cualquier agregación distinta de count).
Widgets
Gestiona qué tarjetas aparecen en el panel y cómo se organizan – esto es solo la configuración de la disposición, no los datos mostrados dentro de una tarjeta.
El panel es una disposición de tipo masonry, no una cuadrícula rígida. Los widgets « pequeños » (metric, online_users) están pensados para ocupar un tercio o la mitad de la fila (width 1 o 2) y se muestran con exactamente la mitad de la altura visual de los widgets « grandes » (chart, world_map, events_7d, top_countries), pensados para ocupar la mitad de la fila o toda la fila (width 2 o 3). Ten esto en cuenta al organizar un panel mediante la API.
Listar widgets
https://api.logsninja.com/v1/org/widgets
Acepta un parámetro de consulta project_id, obligatorio a menos que el token ya esté restringido a un solo proyecto.
Añadir widget
https://api.logsninja.com/v1/org/widgets
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
project_id |
string | ✓ | Obligatorio a menos que el token esté restringido a un solo proyecto. |
type |
string | ✓ | metric, chart, events_7d, world_map, top_countries, online_users. Solo puede existir un widget de cada tipo nativo (events_7d/world_map/top_countries/online_users) por panel. |
metric_id |
string | Obligatorio cuando type es metric. Debe ser un id de métrica existente. | |
chart_id |
string | Obligatorio cuando type es chart. Debe ser un gráfico del mismo proyecto. | |
width |
integer | 1 (1/3), 2 (1/2, por defecto), o 3 (fila completa). |
Redimensionar o mover un widget
https://api.logsninja.com/v1/org/widgets/{id}
Envía width y/o position (índice basado en 0 entre los widgets del proyecto). Definir una posición mueve el widget ahí y desplaza un lugar hacia abajo a todos los widgets siguientes – no intercambia dos widgets. Solo se modifican los campos enviados.
Reordenar todo el panel
https://api.logsninja.com/v1/org/widgets/reorder
Envía order como la lista ordenada completa de todos los id de widgets del proyecto (se rechaza una lista parcial), y opcionalmente widths como un mapa de id a width.
Quitar un widget
https://api.logsninja.com/v1/org/widgets/{id}
Códigos de respuesta
| Endpoint | Éxito | Cuerpo |
|---|---|---|
POST /v1/events |
201 | { "id": "...", "image_count": 0, "images_status": "none", "notification_queued": true } |
DELETE /v1/events/:id |
200 | { "ok": true } |
PUT /v1/users |
200 | { "id": "..." } |
DELETE /v1/users/:id |
200 | { "ok": true } |
POST /v1/ping |
200 | { "ok": true } |
PUT /v1/metrics |
200 | { "id": "..." } |
DELETE /v1/metrics/:id |
200 | { "ok": true } |
Códigos de error: 400 error de validación, 401 token ausente o inválido, 403 token restringido a otro proyecto, 404 proyecto no encontrado.
Referencia de emojis
1837 emojis compatibles
emoticonos y emoción
sonriendo
cariñoso
con lengua
con las manos
neutral / escéptico
somnoliento
enfermo
con sombreros
con gafas
preocupado
negativo
disfrazado & criaturas
caras de gato
caras de mono
corazones
emociones
personas y cuerpo
dedos abiertos
signos de mano
señalando con el dedo
dedos cerrados
manos
apoyos de mano
partes del cuerpo
personas
gestos
roles y carreras
fantasía
actividades
atletismo
descansando
familia
símbolos de la gente
animales y la naturaleza
mamíferos
aves
anfibios
reptiles
vida marina
insectos
flores
otras plantas
comida y bebida
fruta
verduras y hortalizas
cocido / preparado
asiático
dulces y dulces
bebida
vajilla
viajes y lugares
globos y mapas
ubicaciones geográficas
edificios
edificios religiosos
otros lugares
transporte terrestre
transporte de agua
transporte aéreo
hotel
hora
clima
actividades
eventos y días festivos
medallas de premio
deportes
juegos y pasatiempos
artes y oficios
objetos
ropa
sonido
música
instrumentos musicales
teléfono
computadora
luz, película y vídeo
libros & papel
dinero
correo
escrito
suministros de oficina
bloquear y llaves
herramientas
equipos de ciencia
médico
artículos del hogar
otros objetos
símbolos
señales de transporte
símbolos de advertencia
flechas
símbolos religiosos
signos del zodiaco
símbolos de audio y vídeo
signos de género
símbolos matemáticos
puntuación
monedas
otros símbolos
caracteres del teclado
símbolos alfanuméricos
formas y colores
banderas
otras banderas
banderas del país
