askacharge.com es una plataforma SaaS multi-tenant de gestión de cargadores de vehículos eléctricos (CSMS — Charging Station Management System). Backend en FastAPI (Python, async) con WebSocket nativo para OCPP, base de datos PostgreSQL, y frontend en React. Cada marca (brand) gestiona su propia flota de cargadores, tarifas, clientes y facturación de forma aislada, bajo un mismo despliegue.
Soporta OCPP 1.6J y OCPP 2.0.1 en el mismo servidor, testado con el OCTT (OCPP Compliance Testing Tool) de la Open Charge Alliance. La URL base de la API y el WebSocket es:
https://askacharge.com/askacharge
Autenticación por JWT (Bearer token), obtenido vía POST /api/auth/login
(OAuth2 password flow: username + password en form-data).
El access token expira a los 30 minutos; hay refresh token (cookie httpOnly) para renovarlo sin volver a hacer login.
| Rol | Alcance |
|---|---|
superadmin | Gestión global de marcas y del Hub |
brand_admin | Control total de su marca, incluida facturación y equipo |
brand_technician | Operación de la marca (cargadores, tarifas, incidencias) sin acceso a facturación ni equipo |
brand_viewer | Solo lectura: dashboard, tarifas y clientes, sin importes |
| conductor del portal | Cliente final autenticado en /portal/{slug}/ |
| conductor anónimo | Pago por QR sin cuenta, en /qr/{charge_point_id} |
Resumen de los grupos de endpoints principales. La lista completa y siempre al día
—511 operaciones sobre 430 rutas— se publica como OpenAPI 3.1 en
/askacharge/openapi.json, con visor
en /askacharge/docs. No hay ninguna operación del panel
que no esté ahí: la interfaz web consume exactamente esta misma API.
| Prefijo | Qué cubre |
|---|---|
/api/auth | Login, registro, 2FA (TOTP) |
/api/brand | Cargadores, tarifas, clientes, RFID, dashboard, incidencias, OCPI, webhooks, comandos OCPP avanzados |
/api/brand/team | Gestión de equipo: invitar, listar, cambiar rol, eliminar |
/api/admin | Superadmin: marcas, facturas, Hub |
/api/portal | Portal del conductor: login, sesiones, wallet, suscripciones, tarjeta guardada |
/api/public | Endpoints públicos: pago QR, info de cargador, mapa |
/api/hub | Estadísticas y gestión del Hub de roaming |
/api/ext | API pública para integraciones externas, autenticada con API key |
/ocpi/{brand_slug} | OCPI 2.2 — CPO por marca |
/ocpi/emsp/{brand_slug} | OCPI 2.2 — eMSP por marca |
/ocpi/hub | OCPI 2.2 del Hub como partido único ES*ACH |
Conexión por WebSocket, un cargador por conexión. Lo normal es darlo de alta en la marca antes de conectar; si conecta sin alta, aparece en el panel "a la espera" y no registra sesiones hasta que se le activa la credencial.
wss://askacharge.com/askacharge/ocpp/{brand_slug}/{charge_point_id}
Subprotocolo negociado vía cabecera Sec-WebSocket-Protocol: ocpp1.6 o ocpp2.0.1.
Sin cuenta y sin cargador: el panel de prueba enseña el panel con tu cargador o con un cargador virtual que corre en el navegador (OCPP 1.6J real), y el probador de casa deja ver el cargador de casa sin dar ningún dato. Es modo pruebas: no se guarda nada.
Antes de conectarlo, puedes probarlo: el servidor de pruebas OCPP es gratuito y no pide cuenta. Da una URL con un código propio, enseña en directo lo que manda el cargador, valida cada mensaje contra los esquemas oficiales y mira el saludo con el mismo código que producción (forma de la URL, cifrado, credencial, subprotocolo). Es un proceso aparte, sin base de datos.
Dónde se escribe todo esto en cada cargador: hay guías paso a paso por fabricante (Wallbox, Alfen, Zaptec, Easee, KEBA, ABB, Schneider, Fronius, Huawei, GARO, SMA…) con el campo exacto de cada marca y los fallos típicos; y si ya está puesto y no conecta, los errores OCPP más comunes y cómo arreglarlos.
Cada cargador tiene una credencial Basic Auth obligatoria
(usuario = charge_point_id, contraseña generada por el panel al dar de alta
el cargador — se muestra esa vez y se rota o se fija desde la sección "Seguridad OCPP"
de cada cargador). El handshake exige la cabecera
Authorization: Basic base64(charge_point_id:password) y se rechaza la
conexión sin ella o con credenciales incorrectas; no hay conexión solo por el
charge_point_id de la URL. La contraseña generada son 40 dígitos hexadecimales
(el AuthorizationKey del whitepaper de seguridad de OCPP 1.6, que algunos
cargadores exigen en ese formato).
POST /api/brand/commands/* y esperan la respuesta real del cargador
(Accepted/Rejected), no un 200 a ciegas.
Plug & Charge permite que un vehículo eléctrico se autentique y autorice una sesión de carga automáticamente al enchufar el cable, sin RFID, app ni QR. La autenticación se negocia entre el cargador y el vehículo por la propia línea de potencia (PLC) mediante el estándar ISO 15118-2.
Requiere cargadores con OCPP 2.0.1 y soporte ISO 15118 en el hardware. Los cargadores OCPP 1.6J no pueden participar en este flujo.
Cada marca genera su propia Root CA EC P-256 (V2G Root CA simplificada, válida 10 años) desde el panel o vía API. Esta CA firma los certificados de contrato de los vehículos de flota, y debe instalarse en los cargadores para que puedan validarlos.
| Endpoint | Acción |
|---|---|
POST /api/brand/pnc/ca/generate | Genera la CA de la marca (reemplaza la anterior si existe) |
GET /api/brand/pnc/ca | Consulta la CA activa: fingerprint, validez, PEM |
POST /api/brand/pnc/commands/install-ca | Envía InstallCertificate OCPP 2.0.1 al cargador indicado |
Para cada vehículo de flota se emite un certificado de contrato ligado a su
eMAID (Electric Mobility Account ID, formato ES-ACH-XXXXXXXXXX-C). El
vehículo lo almacena y lo presenta al cargador en cada sesión. askacharge.com lo entrega
automáticamente vía Get15118EVCertificate OCPP si el cargador lo solicita.
| Endpoint | Acción |
|---|---|
GET /api/brand/pnc/contracts | Lista todos los contratos activos y revocados |
POST /api/brand/pnc/contracts | Emite un contrato nuevo: emaid, owner_name, valid_days, client_id (opcional) |
POST /api/brand/pnc/contracts/{id}/renew | Renueva un contrato (revoca el anterior, emite nuevo) |
DELETE /api/brand/pnc/contracts/{id} | Revoca un contrato |
Cuando un vehículo compatible se enchufa, el cargador abre una sesión ISO 15118 y
envía un mensaje Authorize con id_token.type = "ISO15118" y
el campo iso15118CertificateHashData. askacharge.com verifica el eMAID en la
tabla de contratos activos y valida el hash del certificado para prevenir suplantación.
Si el vehículo no tiene aún el certificado descargado, el cargador solicita
Get15118EVCertificate y askacharge.com responde con la cadena (contrato + CA)
en formato EXI/DER.
https://askacharge.com/askacharge/api/ocsp/{brand_slug}. Los
cargadores que implementen OCSP pueden verificar en tiempo real si un certificado ha sido
revocado. La revocación vía API (DELETE /pnc/contracts/{id}) es efectiva
inmediatamente: el OCSP responde REVOKED y el próximo Authorize
devolverá Invalid.
Los coches de consumidor (IONIQ 6, BMW iX, etc.) vienen de fábrica con un certificado de contrato firmado por una CA raíz reconocida por los fabricantes — principalmente Hubject eMobility PKI en Europa. Para autorizar a esos conductores, askacharge.com tendría que conectarse a esa PKI externa, lo que requiere contrato con Hubject y está en hoja de ruta pero no activo aún.
Hoy, Plug & Charge en askacharge.com funciona para flota propia: vehículos cuyos eMAID hayas emitido tú como operador. Para el resto de conductores se recomienda combinar con RFID, pago QR o portal del conductor.
askacharge.com gestiona la potencia de carga de forma dinámica en tres niveles independientes que se pueden combinar: reparto de potencia por ubicación, reglas condicionales basadas en producción solar o precio de la energía, y perfiles de carga OCPP por cargador. Todo se aplica en tiempo real sin intervención del operador.
Cada ubicación puede tener un límite de potencia máxima (kW). askacharge.com reparte
ese techo entre los cargadores activos enviando SetChargingProfile
(OCPP 1.6J y 2.0.1) automáticamente cuando arranca o para una sesión. Estrategias
disponibles: even (igual para todos) y priority (prioridad
por cargador). Esto permite instalar cargadores sin ampliar la acometida eléctrica.
| Endpoint | Acción |
|---|---|
GET /api/brand/location-limits | Lista límites activos |
PUT /api/brand/location-limits | Crea o actualiza un límite (location_name, max_power_kw, strategy) |
DELETE /api/brand/location-limits/{id} | Elimina un límite |
El operador configura su instalación fotovoltaica (potencia pico, batería opcional, excedente mínimo para activar carga) y publica lecturas en tiempo real desde su inversor o contador. askacharge.com calcula el excedente disponible y lo usa en el motor de reglas.
| Endpoint | Acción |
|---|---|
GET /api/brand/solar/config | Configuración solar de la marca |
PUT /api/brand/solar/config | Actualiza: peak_kw, has_battery, battery_capacity_kwh, min_surplus_w |
POST /api/brand/solar/reading | Publica lectura: production_w, consumption_w, grid_w |
GET /api/brand/solar/readings | Histórico de lecturas (últimas N horas) |
El operador define reglas priorizadas que se evalúan cada 5 minutos contra el estado
actual (excedente solar, hora, precio de energía). La primera regla que cumple su
condición aplica su acción vía ChangeConfiguration OCPP a todos los
cargadores activos de la marca.
| Condición | Descripción |
|---|---|
surplus_min | Actúa si el excedente solar supera N vatios |
pvpc_max | Actúa si el precio de la energía de la marca (PVPC, mercado + recargo o fijo) es ≤ X €/kWh |
time_range | Actúa en una franja horaria (admite cruce de medianoche) |
always | Regla de fallback incondicional |
| Acción | Descripción |
|---|---|
charge_solar_only | Limita cada cargador al excedente disponible dividido entre sesiones activas |
charge_watts | Reparte un total de vatios fijos entre las sesiones activas |
charge_max | Carga al máximo (32 A) |
charge_min | Carga al mínimo OCPP (6 A) |
pause | Suspende la carga (MaxCurrentOffered = 0) |
POST /api/brand/solar/rules
{
"name": "Solo excedente solar",
"priority": 10,
"condition_type": "surplus_min",
"condition_value": { "watts": 1500 },
"action": "charge_solar_only"
}
El motor de reglas puede operar con tres fuentes de precio de la red:
GET /api/brand/pvpc/today.market_margin) solo está disponible si la marca cobra en euros.GET /api/public/indicadores-precio.POST /api/brand/energy-costs (weekdays: "12345" = laborables; inicio = fin, todo el día).
La condición pvpc_max en las reglas de carga permite, por ejemplo,
cargar solo cuando la energía cuesta menos de 0,10 €/kWh y pausar en horas punta —
sin ninguna intervención manual.
La plataforma ofrece dashboards en tiempo real, analítica histórica con comparativa de periodos, previsión financiera mensual, ranking de rendimiento por cargador, informes ESG exportables en PDF y detección automática de anomalías. Todos los datos son accesibles vía API para integración con BI externos.
| Endpoint | Qué devuelve |
|---|---|
GET /api/brand/dashboard/summary | KPIs del periodo seleccionado (energía, ingresos, margen, sesiones, CO₂) con delta % vs periodo anterior |
GET /api/brand/dashboard/live | Estado en vivo: sesiones activas, potencia actual, cargadores por estado |
GET /api/brand/dashboard/stream | Server-Sent Events — actualización en tiempo real sin polling |
| Endpoint | Qué devuelve |
|---|---|
GET /api/brand/analytics/usage | Uso diario/semanal/mensual: sesiones, kWh, ingresos por periodo |
GET /api/brand/analytics/financials | Desglose financiero: revenue, coste de energía, comisiones Stripe, margen neto, revenue shares |
GET /api/brand/analytics/forecast | Previsión del mes en curso basada en datos reales: revenue, margen, sesiones y kWh proyectados hasta fin de mes |
GET /api/brand/chargers/performance | Ranking de cargadores: disponibilidad, sesiones, energía entregada, ingresos, tasa de fallos |
GET /api/brand/pvpc/today | Precios PVPC hora a hora del día actual (€/kWh). Vacío fuera de España |
GET /api/brand/energy-price/today | Precio del día que corresponde a la marca: PVPC, o mercado diario de su zona con lo que paga ella (mercado + recargo, o su precio fijo) |
GET /api/brand/esg-report genera un PDF descargable con el impacto
ambiental del periodo: kWh entregados, CO₂ evitado (factor 130 g/kWh vs combustión),
equivalencia en árboles plantados y desglose por cliente fleet. Listo para incluir
en memorias de sostenibilidad corporativa o reporting CSRD.
Un motor de detección ejecuta cuatro analizadores independientes, de reglas y
estadística (no un modelo de IA), cada 30 minutos
sobre todas las transacciones recientes. Las alertas se almacenan en la tabla
anomaly_alerts con severidad y descripción, y se notifican al operador
por email.
| Detector | Qué busca |
|---|---|
| Energía imposible | Sesiones con kWh entregados superior a la potencia física del cargador × duración (indica manipulación de medidor) |
| Outliers estadísticos | Sesiones cuyo coste o energía se desvía más de 3σ de la media histórica de ese cargador |
| Tampering físico | Patrones de paradas y reinicios anormales que sugieren desconexión deliberada del cargador |
| Replay attack | Transacciones con el mismo transaction_id OCPP enviadas más de una vez desde el mismo punto de carga |
sessions:read, para integración con herramientas
BI externas como Power BI, Tableau o Metabase.
El Hub de askacharge.com es una red de roaming interna entre marcas/operadores que comparten
plataforma: una sola integración OCPI da acceso a todos los cargadores de la red, sin
necesidad de acuerdos bilaterales individuales. De cara a socios externos (Hubject,
GIREVE, ocpi.io...), el Hub se presenta como un único partido OCPI 2.2:
ES*ACH.
https://askacharge.com/askacharge/ocpi/hub/versions
Modelo de comisión: 1% por sesión cross-brand, liquidado el día 1 de cada mes. El
eMSP cobra al conductor con su tarjeta guardada y askacharge.com transfiere al CPO — sin
riesgo de impago entre marcas, porque ambas cuentas de cobro están en la misma
plataforma. Solicitudes de membresía externa: POST /api/public/hub/apply,
ver también la página del Hub.
askacharge.com genera y registra facturas en los sistemas tributarios españoles de forma automática, sin configuración adicional por parte del operador más allá de introducir sus datos fiscales en el onboarding. La plataforma detecta el territorio de la marca y aplica el sistema correspondiente.
Cada transacción completada genera un registro de factura en formato Verifactu
(Real Decreto 1007/2023): XML firmado con la cadena de huellas SHA-256 encadenadas,
código QR de validación y envío automático al webservice SOAP de la AEAT. Los
registros quedan almacenados con el estado de respuesta de hacienda (aeat_ok,
código de error, timestamp). Las facturas rechazadas entran en cola de reintento
automático.
Para operadores de Bizkaia, Gipuzkoa o Araba, la plataforma emite facturas TicketBAI con firma XAdES-EPES usando el certificado digital de la marca. Se envían al endpoint correcto de cada hacienda foral. Bizkaia también soporta el envío mensual agregado vía LROE (Lote de Registros de Operaciones Económicas). El QR TicketBAI se incluye en el PDF de la factura.
| Evento | Sistema |
|---|---|
| Sesión de carga QR (conductor anónimo) | Ticket independiente por transacción |
| Factura mensual a cliente fleet | Factura agregada con desglose de sesiones |
| Factura de askacharge.com a la marca (SaaS) | Factura del operador de la plataforma |
Las facturas emitidas se sincronizan opcionalmente con Holded vía API (PUT /api/brand/erp/config).
El operador proporciona su API key de Holded y la plataforma envía cada factura en
el momento de su generación.
La plataforma implementa seguridad en capas: autenticación robusta con rotación de tokens, 2FA por software, seguridad a nivel de protocolo OCPP, firma de eventos salientes y controles de privacidad GDPR.
El access token JWT tiene vida de 30 minutos. El refresh token se emite como cookie
httpOnly; SameSite=Lax; Secure (nunca accesible desde JavaScript) y
se rota en cada uso: al renovar el access token se invalida el refresh anterior y
se emite uno nuevo. Si un token ya usado vuelve a presentarse, la plataforma detecta
posible robo de sesión y revoca todos los refresh tokens del usuario inmediatamente.
Las cookies de la app principal (/app) y del portal de conductores
(/portal) son independientes para evitar escalada de privilegios entre
capas.
Los usuarios brand_admin pueden activar autenticación de dos factores
con cualquier app compatible (Google Authenticator, Aegis, 1Password…). El flujo:
setup → URI de aprovisionamiento + QR → verificación del primer código → activación
con entrega de 8 códigos de respaldo de un solo uso (SHA-256 en BD, valor en claro
mostrado una vez). El 2FA se exige en el login si está activo.
| Endpoint | Acción |
|---|---|
GET /api/auth/2fa/status | Estado actual del 2FA |
POST /api/auth/2fa/setup | Genera secreto TOTP y URI de aprovisionamiento |
POST /api/auth/2fa/enable | Activa el 2FA y devuelve los códigos de respaldo |
POST /api/auth/2fa/disable | Desactiva el 2FA (requiere código TOTP vigente) |
Cada cargador tiene su propia credencial: usuario = charge_point_id,
contraseña generada al darlo de alta y rotable desde el panel (se muestra una vez;
se guarda en claro porque el handshake la compara en tiempo constante, así que quien
lea la base de datos lee las contraseñas de los cargadores — es el mismo nivel que el
ws_secret de cualquier CSMS). El handshake WebSocket exige la cabecera
Authorization: Basic … y rechaza la conexión sin ella. El endpoint
PUT /api/brand/charge-points/{id}/ws-auth la rota
({"regenerate": true}) o la fija ({"secret": "…"}, 16-64 caracteres:
para fabricantes con una sola contraseña por instalación, como Zaptec) sin tocar el
resto de la flota.
Equipos que no hablan TLS. Algunos modelos solo admiten ws://
(el Circutor URBAN, por ejemplo). Para ellos, ws://askacharge.com/askacharge/ocpp/…
está abierto en el puerto 80, pero solo entra el cargador marcado en su ficha como
Admitir conexión sin cifrar (PUT …/ws-auth con {"sin_tls": true}).
Los demás se rechazan con el motivo sin_tls. Sin cifrar, la contraseña viaja en claro
y se sigue exigiendo. Un equipo que tampoco tenga usuario y contraseña solo entra con una
excepción concedida a mano para ese cargador, atada a su IP pública.
Las API keys se almacenan exclusivamente como hash SHA-256 — el valor en claro solo se muestra en el momento de creación y nunca se puede recuperar. Cada key lleva un conjunto de scopes de lectura y de escritura que delimitan lo que puede hacer, y toda escritura queda registrada: ver la sección de API keys.
Cada evento saliente incluye la cabecera
X-AskaCharge-Signature: sha256=<hex>, calculada con el secreto
propio del endpoint (distinto por endpoint, nunca compartido). El receptor puede
verificar la autenticidad del evento antes de procesarlo.
Para cada cliente fleet el operador puede ejecutar:
| Endpoint | Acción |
|---|---|
GET /api/brand/clients/{id}/gdpr-export | Exporta todos los datos del cliente en JSON (sesiones, pagos, datos personales) |
DELETE /api/brand/clients/{id}/gdpr-delete | Anonimiza y elimina los datos personales del cliente, manteniendo los registros fiscales con referencias neutras |
Vehicle-to-Grid (V2G) permite que un vehículo eléctrico devuelva energía a la red o al edificio. Hoy askacharge.com no gestiona descarga: no hay en la red cargadores bidireccionales y la API rechaza los perfiles de carga con límite negativo. Esto es lo que hay y lo que falta:
| Estándar | Qué aporta | Estado en askacharge.com |
|---|---|---|
| ISO 15118-2 | Plug & Charge: el coche se identifica por el cable, sin tarjeta ni app | Lado del servidor implementado por OCPP 2.0.1: PKI propia por marca, certificados de contrato (eMAID), OCSP y Get15118EVCertificate. La conversación ISO 15118 con el coche la hace el cargador; todavía no hay en la red un cargador real con Plug & Charge. |
| ISO 15118-20 | Extensión bidireccional: el protocolo de descarga V2G/V2H por el mismo cable | No implementado. Requiere cargadores bidireccionales. |
| OCPP 2.0.1 | SetChargingProfile con potencia negativa (descarga) |
No admitido hoy: la API rechaza límites negativos. Se abrirá cuando haya hardware bidireccional que probar. |
El motor de reglas de Smart Charging (ver sección anterior)
decide la potencia de carga según el precio: las condiciones pvpc_max y
time_range permiten, por ejemplo, cargar solo cuando el PVPC esté por debajo
de un umbral. Los precios PVPC y del mercado diario se actualizan hora a hora (REE para
España, SMARD para las zonas europeas).
Con la alta penetración solar en España, el patrón "noche barata / día caro" ya no sirve: el PVPC puede estar en mínimos al mediodía por la producción fotovoltaica y el pico se va a la tarde-noche (19-22 h). Las reglas evalúan el precio de cada momento, sin suponer horas fijas, así que se adaptan solas a la estación del año.
askacharge.com incluye una experiencia de conductor en tres capas complementarias, sin necesidad de app nativa: mapa público de acceso libre, flujo de carga por QR sin registro, y portal de conductor completo instalable como PWA.
Disponible en /mapa sin login. Muestra cargadores askacharge.com y la
red nacional REVE/REE en tiempo real. Al hacer clic en un cargador askacharge.com se
abre un modal con:
El conductor escanea el QR físico del cargador o el del mapa. El flujo completo:
Compatible con todos los modos de tarifa: por kWh, por hora, por sesión, combinado, gratuito y los que cambian con la hora —PVPC + margen, mercado + margen, franjas horarias que pone la marca (su propio "PVPC": punta, llano y valle por horas y días, en su hora local) y coste de la luz + margen—. En estos el conductor ve el precio de ahora y el del resto del día antes de pagar, y cada kWh se cobra al precio del momento en que se cargó. Las franjas se exportan a los socios OCPI con restricciones horarias.
Cada operador puede ofrecer un portal de conductor en /portal/{slug}/,
instalable como PWA en iOS y Android (sin pasar por App Store). Incluye:
| Feature | Detalle |
|---|---|
| Token eMSP | Tarjeta visual con UID y QR para carga RFID sin tarjeta física |
| Historial de sesiones | Sesiones propias + CDRs de roaming externo unificadas, con kWh y coste |
| Tarjeta guardada | Stripe SetupIntent (PSD2/SCA) para cobro automático en sesiones de roaming |
| Mapa de red | Cargadores propios del operador + red Hub de askacharge.com |
| Push notifications | Aviso al finalizar la carga (Web Push / VAPID, gestionado por el conductor) |
| Install prompt | Banner nativo para añadir a pantalla de inicio (Android/Chrome/Safari) |
Cada marca puede registrar endpoints HTTP propios para recibir eventos en tiempo real
(firmados con HMAC, secreto propio por endpoint) desde
/api/brand/webhooks. Eventos: session.started,
session.stopped (energía, importe, CO₂ ahorrado y motivo de parada),
charger.online (BootNotification: el que cierra un Reset),
charger.offline (desconexión o sin latido),
connector.status (cada StatusNotification), charger.error
(conector en Faulted), payment.captured y anomaly.detected.
El catálogo con la descripción de cada uno está en
GET /api/brand/webhooks/events. Con esto un agente que manda un comando
puede esperar el evento en vez de consultar en bucle.
Para probar sin hardware. En Cargadores hay un botón "Añadir 5 cargadores
simulados" (o POST /api/brand/sandbox, count 1–10): en menos de
un minuto conectan por OCPP, laten, cargan solos unas veces al día en horario de día y
responden a todos los comandos como un equipo real — un Reset los desconecta de verdad
20 segundos y vuelven, con su webhook charger.online. Cada uno trae una tarjeta
RFID <PREFIJO>-TARJETA-nn. Hasta 10 por marca; se quitan con un clic
(DELETE /api/brand/sandbox) con sus sesiones y tarjetas, y los cargadores reales
no se tocan. Cuando llegue el equipo real solo cambia la URL OCPP. Vale igual en un trial
que en una marca de pago que quiera ensayar una integración o un agente sin tocar su red.
Vídeo de dos minutos: prueba askacharge.com sin cargador.
Alternativa al JWT para integraciones servidor-a-servidor y para agentes IA. Se
gestionan desde /api/brand/api-keys, se guardan como hash SHA-256 y el
valor en claro solo se muestra una vez al crearla. Se envían en
X-Api-Key o como Authorization: Bearer.
Una API key alcanza lo mismo que el administrador humano de la marca, limitada por los scopes que esa marca le haya concedido. Es una decisión deliberada: la plataforma ofrece todas las opciones y es el operador quien decide cuáles entrega a su agente. Puede empezar por solo lectura y ampliar después, o dar acceso total.
El scope necesario se deduce del recurso y del método: GET pide
:read y el resto :write. Escribir incluye leer. Se admiten
los comodines * (todo) y familia:*.
| Familia | Qué abarca |
|---|---|
chargers | Cargadores, conectores, ubicaciones, límites de potencia, reservas y diagnósticos |
commands | Comandos OCPP: remote start y stop, reset, cambio de disponibilidad, perfiles de carga y firmware. Es el scope que mueve energía |
sessions | Sesiones de carga, dashboard, analítica, informe ESG e incidencias |
clients | Clientes de flota, tarjetas RFID y planes de suscripción |
tariffs | Tarifas, costes de energía, PVPC y reglas solares |
billing | Facturas de flota, pagos, reparto de ingresos, amortización de los equipos y servicios contratados |
fiscal | Certificados y configuración de TicketBAI/Verifactu, y datos legales |
integrations | Webhooks, OCPI, notificaciones y configuración de roaming |
keys | Crear y revocar API keys. Aparte del resto a propósito |
brand | Identidad de la marca, página pública, onboarding y equipo |
El catálogo vivo lo devuelve GET /api/brand/api-keys/scopes, para que un
agente pueda consultar qué permisos existen antes de pedirlos.
De las 511 operaciones de la API, 273 están al alcance de una API key y 238 quedan fuera de su perímetro a propósito: el portal del conductor (52), la superadministración de la plataforma (42), los endpoints OCPI de roaming (37+10), los públicos de pago por QR (18), la autenticación (16) y la facturación interna (19). Esa mitad no es una carencia: son operaciones que un agente de una marca no debe tocar.
| Scope | Familia | Operaciones | Acotable por ubicación |
|---|---|---|---|
chargers | Cargadores | 45 | Sí |
clients | Clientes | 38 | — |
billing | Facturación | 32 | — |
sessions | Sesiones | 25 | — |
commands | Comandos OCPP | 35 | Sí |
brand | Marca y equipo | 22 | — |
tariffs | Tarifas y energía | 21 | — |
integrations | Integraciones | 19 | — |
fiscal | Fiscal | 8 | — |
keys | API keys | 5 | — |
* | Traspaso de cargadores (solo con el comodín) | 9 | — |
| Total al alcance de una key | 259 | ||
Las cifras salen de contar el OpenAPI publicado contra la tabla de permisos, no de una estimación. Puede reproducirlo con openapi.json.
commands:write cubre todos los comandos OCPP, pero se pueden conceder
solo algunos: commands:remote-start, commands:remote-stop,
commands:reset, commands:change-availability,
commands:unlock-connector, commands:configuration,
commands:charging-profile, commands:firmware,
commands:diagnostics y commands:local-list. Así un agente
puede arrancar y parar cargas sin poder reiniciar el cargador ni cambiarle el firmware,
que son los comandos que dejan un equipo tirado. Las rutas 1.6 y 2.0.1 del mismo gesto
comparten scope, y admiten el sufijo de ubicación (commands:reset@hotel-madrid).
En chargers, commands y sessions, el scope admite
un sufijo con la ubicación: commands:write@hotel-madrid. Un instalador que
gestiona varias sedes bajo la misma marca puede así dar a un agente permiso para
reiniciar los cargadores de Madrid y ver sus cargas, sin tocar ni ver los de Barcelona. Se puede repetir el sufijo para varias
ubicaciones en la misma key.
La ubicación es el location_name del cargador, comparado por slug
(Parking Norte y parking-norte son la misma). Las ubicaciones
reales de su marca las devuelve GET /api/brand/api-keys/scopes, y en el
panel salen como botones al elegir los permisos.
Acota lo que la key puede tocar y lo que puede ver.
Un comando o un alta fuera de sus ubicaciones devuelve 403 diciendo cuáles
tiene permitidas; una escritura que no indique charge_point_id ni
location_name también se rechaza, porque no se puede comprobar dónde cae.
En lectura, los listados de cargadores (GET /charge-points,
/api/ext/chargers), de sesiones (GET /transactions y sus
exportaciones, /api/ext/sessions) y de comandos
(GET /commands/jobs) devuelven solo lo de sus ubicaciones, y un cargador,
una sesión o un job de otra ubicación no existen para ella (403 o
404). Lo que junta datos de toda la marca y no se puede recortar por
ubicación —el panel, la analítica, el informe ESG, el mapa— responde 403
a una key acotada: preferimos que no pueda verlo a que vea lo de otra sede.
En las demás familias el sufijo se rechaza al crear la key: una tarifa o una factura no pertenecen a una ubicación. Y una key sin sufijo sigue llegando a toda la marca — manda siempre el permiso más amplio que se le haya concedido.
Cualquier escritura acepta la cabecera Idempotency-Key. Si la petición se
repite con la misma clave, se devuelve la respuesta de la primera junto a
Idempotent-Replay: true en vez de ejecutarla otra vez. Repetir la clave con
un cuerpo distinto devuelve 422, y reintentar mientras la primera sigue en
curso devuelve 409. Un agente reintenta por diseño y esto evita que un
corte de red duplique un cargador, un cliente o un cobro.
job_id
Un comando tiene dos tiempos. POST /api/brand/commands/* devuelve en
línea el acuse del cargador (status Accepted o Rejected, o 400 si no está
conectado) y un job_id, también en la cabecera
X-Job-Id. El efecto real llega después por OCPP y cierra el job:
session.started tras un arranque, session.stopped tras una
parada, charger.online tras un Reset, connector.status tras un
cambio de disponibilidad.
GET /api/brand/commands/jobs/{job_id} devuelve el estado:
acked (aceptado, esperando el efecto; expected_event dice cuál),
confirmed (llegó; el evento va en event), timeout
(no llegó en 5 minutos, 10 para Reset), rejected (el cargador dijo que no) o
failed (no se pudo enviar). Los comandos cuya respuesta ya es el resultado
—leer configuración, diagnósticos, desbloquear— quedan confirmed en el acto.
GET /api/brand/commands/jobs?charge_point_id= lista los últimos. Los mismos
eventos siguen saliendo por webhook: el job es para quien no puede recibirlos, no un
sustituto.
Un agente puede conectarse por Model Context
Protocol a https://askacharge.com/askacharge/api/mcp, autenticándose
con la misma API key (Authorization: Bearer ask_live_… o
X-Api-Key). No hay nada que instalar: es HTTP, transporte JSON-RPC 2.0
sobre POST.
Devuelve las herramientas ya descritas —qué hace cada una y cuándo usarla— y
solo las que esa key puede ejecutar: si la marca no concedió
commands:write (o el comando concreto), las de arrancar, parar o reiniciar
ni siquiera aparecen en la lista. Para lo que no tenga herramienta propia está
askacharge_llamar_api, que abre las 511 operaciones con el mismo control
de permisos. Una key acotada a ubicaciones ve las herramientas de acción de sus
permisos y recibe el 403 al usarlas sobre un cargador de otra ubicación;
las de lectura que juntan toda la marca (resumen, estado en vivo, incidencias, límites
de potencia) no le aparecen, porque la API se las niega.
Un ejemplo completo, probado en producción con cargadores simulados: un agente que vigila y reinicia los cargadores de una ubicación, con los permisos que necesita y las respuestas reales.
El saludo del protocolo —initialize, ping y
tools/list— se responde sin API key, porque es lo que
consultan los directorios de MCP y los clientes antes de tener credenciales; sin key
se ve el catálogo completo de las 25 herramientas, que es público. Ejecutar cualquiera
de ellas sí exige la key, y entonces vuelve a valer todo lo anterior.
El MCP no es una puerta lateral: cada herramienta se ejecuta contra esta misma API REST, así que pasa por los mismos scopes, la misma traza de actividad y el mismo límite de uso.
Cada escritura y cada intento rechazado quedan registrados: qué key, qué operación,
con qué resultado, desde qué IP y cuánto tardó. Se consulta en el panel, en
API keys → Actividad de las keys, o por API con
GET /api/brand/api-keys/audit (scope keys:read). Se conserva
90 días. Las consultas correctas no se registran: un agente hace cientos y taparían lo
que importa. Un intento con una key que no existe también queda anotado.
300 peticiones por minuto y key. Al superarlo se responde 429 con
Retry-After.
Ni con el comodín *: /api/auth (identidad y contraseñas),
/api/admin (superadministración de la plataforma), el portal del conductor
y los endpoints OCPI. Ahí devuelve 401. Una key es siempre de una marca y
no puede salirse de ella.
Además de la API completa, hay dos endpoints de conveniencia con formato estable, pensados para integraciones que solo quieren volcar datos:
| Endpoint | Qué devuelve |
|---|---|
GET /api/ext/chargers | Cargadores de la marca y su estado |
GET /api/ext/sessions | Sesiones de carga |
Tus cargadores no dependen de nosotros. Hablan OCPP estándar: para cambiar de sistema central basta con poner en cada cargador la URL (y la clave) del nuevo. El hardware no se toca.
Tus datos salen por la API, con tu API key: cargadores (GET /api/brand/charge-points), tarjetas RFID (/api/brand/id-tags), tarifas (/api/brand/tariffs), clientes (/api/brand/clients) y sesiones en CSV o Excel (/api/brand/transactions/export.csv y .xlsx), además de la exportación RGPD de cada cliente. Y todo de una vez: el botón "Exportar todos mis datos" de Configuración, o GET /api/brand/export con una key *, descarga un ZIP con un CSV por tabla (cargadores, tarjetas, tarifas, clientes, sesiones, lecturas, facturas, pagos y configuración), marca.json y un LEEME.txt que explica cómo migrar. Sin claves OCPP de los cargadores, contraseñas, tokens, certificados ni datos de pago.
Copias de seguridad: la base de datos se copia cada día, cifrada, en el servidor (30 días) y fuera de él (14 días); el servidor completo, cada semana, cifrado y fuera del servidor. El código está versionado en un repositorio privado, aparte del servidor.
Quién está detrás: askacharge.com lo desarrolla y opera una sola persona, en Bizkaia. Para una red grande o crítica recomendamos un piloto antes de comprometerse; no ofrecemos SLA empresarial firmado. La disponibilidad la medimos cada minuto desde el 28-oct-2026 y publicaremos la cifra cuando haya meses de datos.
| Precios | Tarifa completa: qué se paga, qué no y por qué |
| Calculadora | Ingresos y amortización de una red, con las comisiones reales |
| Integración de Home Assistant | Estado, energía y potencia de la sesión en curso y arrancar/parar desde Home Assistant, con una API key (permiso Sesiones: leer). Se instala desde HACS. No es un servidor OCPP: el cargador sigue en askacharge.com |
| Mapa público de cargadores | Cobertura en tiempo real, sin login |
| Hub de askacharge.com | Red de roaming entre operadores, estadísticas en vivo |
| Crear cuenta | 30 días de prueba gratuita |