Referencia de la API

URL base

https://api.vbatpower.com

Todos los endpoints llevan el prefijo /api/v1. La autenticación se realiza mediante cookies de sesión (para clientes de navegador) o claves de API (para clientes MCU/servidor). La API es gratuita y sin límites de uso más allá de los límites de tasa de protección contra abuso descritos a continuación.

Autenticación

POST /api/v1/auth/register

Crea una cuenta nueva con correo electrónico y contraseña (mínimo 8 caracteres, máximo 72).

{"email": "user@example.com", "password": "securePassword123"}

Devuelve 201 con el objeto de usuario y establece la cookie de sesión. Devuelve 409 si el correo ya existe. Limitado a 5 peticiones / 15 min por IP en producción.

POST /api/v1/auth/login

Inicia sesión con correo electrónico y contraseña.

{"email": "user@example.com", "password": "securePassword123"}

Devuelve 200 con el objeto de usuario y establece la cookie de sesión. Devuelve 401 con credenciales incorrectas. Limitado a 10 peticiones / 15 min por IP en producción.

GET /api/v1/auth/me

Obtiene el usuario actualmente autenticado. Requiere cookie de sesión.

Devuelve 200 con el objeto de usuario que contiene los campos id, email, name y role, o 401 si no está autenticado.

POST /api/v1/auth/logout

Finaliza la sesión actual. Borra la cookie de sesión y elimina la fila de sesión.

POST /api/v1/auth/logout-all

Revoca todas las sesiones del usuario actual (cierra sesión en todos los dispositivos). Requiere cookie de sesión. Devuelve 200 con {"status": "ok"}, o 401 si no está autenticado.

GET /api/v1/auth/providers

Lista los proveedores de OAuth actualmente habilitados en el servidor. Público: no requiere autenticación. Devuelve {"providers": ["google", "github"]} (el array contiene solo los proveedores configurados en el momento del despliegue).

GET /api/v1/auth/oauth/:provider

Redirige al inicio de sesión del proveedor de OAuth. Proveedores admitidos: google, microsoft, github. Tras el consentimiento, el proveedor regresa a /api/v1/auth/oauth/:provider/callback, que establece la cookie de sesión y redirige de vuelta a la aplicación.

Proyectos

Todos los endpoints de proyectos requieren autenticación (cookie de sesión). Los cuerpos de proyecto pueden ser de hasta 2 MB.

GET /api/v1/projects

Lista todos los proyectos del usuario autenticado, ordenados por última actualización. Devuelve id, name, description, tags y marcas de tiempo (no el blob completo de data).

POST /api/v1/projects

Crea un proyecto nuevo. name es obligatorio (máx. 255 caracteres); description (máx. 4096 caracteres), tags (array de hasta 50 cadenas, cada una de hasta 64 caracteres) y data son opcionales. Devuelve 201.

{"name": "Sensor Node", "data": {"batteries": [...]}}
GET /api/v1/projects/:id

Obtiene un proyecto por ID (devuelve los datos completos, incluidas las baterías). Devuelve 404 si no se encuentra o no pertenece al usuario.

PUT /api/v1/projects/:id

Actualiza un proyecto. Solo se actualizan los campos proporcionados (semántica PATCH: los campos omitidos conservan su valor actual). Devuelve 404 si el proyecto no pertenece al usuario.

DELETE /api/v1/projects/:id

Elimina un proyecto y todos sus datos asociados. Devuelve 204 si tiene éxito.

Esquema de data del proyecto

El campo data contiene el modelo del proyecto: un objeto con un array de batteries. Cada batería tiene un id numérico (su índice jerárquico de nivel 1) y un array de components; cada componente tiene un id y un array de states; cada estado tiene un id más sus campos de modo de funcionamiento. Los valores de id se corresponden directamente con los ID de telemetría en notación de punto (batería 0 → componente 0.0 → estado 0.0.0).

{
  "name": "Sensor Node",
  "description": "ESP32 + INA219",
  "tags": ["esp32", "lipo"],
  "data": {
    "batteries": [
      {
        "id": 0,
        "name": "18650 cell",
        "voltageMin": 3.0,
        "voltageMax": 4.2,
        "current": 2.5,
        "currentUnit": "Ah",
        "components": [
          {
            "id": 0,
            "name": "ESP32",
            "states": [
              {"id": 0, "name": "Deep Sleep", "alwaysOn": true, "current": 10, "currentUnit": "u"},
              {"id": 1, "name": "Active", "current": 80, "currentUnit": "m", "interval": 60, "intervalUnit": "s", "execTime": 5, "execTimeUnit": "s"}
            ]
          }
        ]
      }
    ]
  }
}

Campos comunes de estado: name, alwaysOn (booleano), current + currentUnit, interval + intervalUnit, execTime + execTimeUnit y runOnce (booleano). El objeto data se almacena tal cual, por lo que cualquier campo producido por la aplicación se conserva en el ciclo de ida y vuelta.

Telemetría

POST /api/v1/telemetry

Sube registros de telemetría. Requiere la clave de API como cabecera Authorization: Bearer <key>. Hasta 10.000 registros por petición; la clave determina el proyecto de destino. Limitado a 60 peticiones / minuto por proyecto (devuelve 429 cuando se supera). Devuelve 201 con {"status": "ok", "inserted": N}.

{"records": [
  {"id": "0", "type": "v", "value": 3.28, "unit": "V", "nonce": 1, "runid": 1},
  {"id": "0.0.0", "type": "t", "value": 1523, "unit": "ms", "nonce": 1, "runid": 1},
  {"id": "0.0.0", "type": "v", "value": 12.5, "unit": "mA", "nonce": 1, "runid": 1}
]}
GET /api/v1/telemetry/:projectId

Recupera los registros de telemetría de un proyecto. Requiere la clave de API como Authorization: Bearer <key>; la clave debe estar acotada al proyecto solicitado (de lo contrario, 403).

Los resultados se paginan mediante un cursor de id. Parámetros de consulta: limit (1–1000, predeterminado 1000) y cursor (devuelve las filas con id mayor que este valor, predeterminado 0). La respuesta incluye next_cursor: pásalo de vuelta como cursor para obtener la página siguiente; es null cuando no se devolvió ninguna fila.

{
  "project_id": 1,
  "records": [
    {"id": 42, "record_id": "0", "record_type": "v", "value": 3.28, "unit": "V", "nonce": 1, "runid": 1, "received_at": "2026-01-01T12:00:00.000Z"}
  ],
  "next_cursor": 42
}

Historial de fórmulas

Todos los endpoints del historial de fórmulas requieren autenticación (cookie de sesión).

POST /api/v1/formulas/history

Guarda un cálculo de fórmula en el historial. formula_id y solve_for son obligatorios. Devuelve 201.

{"formula_id": "ohms-law", "solve_for": "V", "inputs": {"I": 0.5, "R": 100}, "result": 50}
GET /api/v1/formulas/history?limit=50

Obtiene los cálculos de fórmula recientes, del más nuevo al más antiguo. limit se acota a 1–500 (predeterminado 50).

DELETE /api/v1/formulas/history/:id

Elimina una única entrada del historial por ID. Devuelve 200 con {"status": "ok"}, o 404 si la entrada no se encuentra o no pertenece al usuario.

DELETE /api/v1/formulas/history

Borra todo el historial de fórmulas del usuario actual. Devuelve 200 con {"status": "ok"}.

Claves de API

Todos los endpoints de gestión de claves de API requieren autenticación (cookie de sesión). Las claves las usan los MCU y los scripts para subir telemetría sin una sesión de navegador.

POST /api/v1/keys

Crea una clave de API acotada a un proyecto. project_id es obligatorio; name es opcional (máx. 128 caracteres). Hasta 50 claves activas por usuario.

{"project_id": 1, "name": "ESP32 Sensor"}

Devuelve 201 con la cadena de la clave (con el prefijo vbat_). Guárdala de forma segura: no se puede recuperar de nuevo.

GET /api/v1/keys

Lista las claves de API del usuario, de la más nueva a la más antigua. Devuelve id, project_id, prefijo de la clave, name, marca de tiempo de creación y bandera de revocación, nunca la clave completa.

DELETE /api/v1/keys/:id

Revoca una clave de API por ID. La clave deja de funcionar de inmediato. Devuelve 200 con {"status": "ok"}, o 404 si la clave no se encuentra o ya está revocada.

Límites de tasa

VBatPower es gratuito y sin cuotas de uso. Los únicos límites son los límites de tasa de protección contra abuso, aplicados por IP (autenticación) o por proyecto (telemetría) en producción:

  • POST /api/v1/auth/register — 5 peticiones cada 15 minutos por IP
  • POST /api/v1/auth/login — 10 peticiones cada 15 minutos por IP
  • POST /api/v1/telemetry — 60 peticiones por minuto por proyecto

Superar un límite devuelve 429 con el cuerpo {"error": "Too many requests"}. Los cuerpos de las peticiones también tienen un tope: 64 KB para las rutas de autenticación, claves e historial de fórmulas; 2 MB para proyectos y telemetría. Los cuerpos de tamaño excesivo devuelven 413 con {"error": "Payload too large"}.

Respuestas de error

Todos los errores devuelven JSON con un campo error que describe el problema:

{"error": "Not authenticated"}

Códigos de estado HTTP usados por la API:

  • 400 — petición incorrecta (JSON no válido, campo ausente o mal formado)
  • 401 — no autenticado (sesión ausente/expirada o clave de API no válida)
  • 403 — prohibido (clave de API no acotada al proyecto solicitado)
  • 404 — no encontrado (o no perteneciente al usuario autenticado)
  • 409 — conflicto (correo electrónico ya registrado)
  • 413 — carga útil demasiado grande
  • 429 — demasiadas peticiones (límite de tasa superado)
  • 500 — error interno

Recorrido de extremo a extremo con MCU

Esto enlaza los endpoints para el flujo de hardware típico: generar una clave, crear un proyecto, enviar telemetría y leerla de vuelta. Todas las peticiones usan la URL base https://api.vbatpower.com.

1. Crea un proyecto (sesión de navegador)

Inicia sesión en la aplicación o llama a la API con tu cookie de sesión:

curl -X POST https://api.vbatpower.com/api/v1/projects \
  -H "Content-Type: application/json" \
  --cookie "session=YOUR_SESSION" \
  -d '{"name":"Sensor Node","data":{"batteries":[{"id":0,"components":[{"id":0,"states":[{"id":0}]}]}]}}'
# -> 201 {"project": {"id": 1, ...}}

2. Genera una clave de API para ese proyecto

curl -X POST https://api.vbatpower.com/api/v1/keys \
  -H "Content-Type: application/json" \
  --cookie "session=YOUR_SESSION" \
  -d '{"project_id":1,"name":"ESP32 Sensor"}'
# -> 201 {"key": "vbat_xxxxxxxx...", "project_id": 1}
# Copy the key now — it is shown only once.

3. Envía telemetría por POST desde el dispositivo (clave Bearer)

No se necesita sesión ni cookie: la clave autentica el dispositivo y selecciona el proyecto. Consulta Integración con MCU para ver código de Arduino/ESP32/STM32 que produce esta petición.

curl -X POST https://api.vbatpower.com/api/v1/telemetry \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer vbat_xxxxxxxx..." \
  -d '{"records":[
    {"id":"0","type":"v","value":3.28,"unit":"V","nonce":1,"runid":1},
    {"id":"0.0.0","type":"t","value":1523,"unit":"ms","nonce":1,"runid":1},
    {"id":"0.0.0","type":"v","value":12.5,"unit":"mA","nonce":1,"runid":1},
    {"id":"0.0.0","type":"n","value":0,"unit":"ms","nonce":1,"runid":1}
  ]}'
# -> 201 {"status": "ok", "inserted": 4}

4. Verifica que los datos llegaron

Léelos de vuelta con la misma clave, o abre la página de Gráficos del proyecto en la aplicación:

curl https://api.vbatpower.com/api/v1/telemetry/1?limit=1000 \
  -H "Authorization: Bearer vbat_xxxxxxxx..."
# -> 200 {"project_id": 1, "records": [...], "next_cursor": 42}
# Page through more rows by passing ?cursor=42 on the next call.