askacharge.com is a multi-tenant SaaS platform for managing electric vehicle chargers (CSMS — Charging Station Management System). The backend is built on FastAPI (Python, async) with native WebSocket support for OCPP, a PostgreSQL database, and a React frontend. Each brand manages its own charger fleet, tariffs, clients and billing in full isolation, all running on a shared deployment.
Both OCPP 1.6J and OCPP 2.0.1 are supported on the same server, tested with the OCTT (OCPP Compliance Testing Tool) from the Open Charge Alliance. The base URL for the API and WebSocket is:
https://askacharge.com/askacharge
Authentication uses JWT (Bearer token), obtained via POST /api/auth/login
(OAuth2 password flow: username + password as form-data).
The access token expires after 30 minutes; a refresh token (httpOnly cookie) is used to renew it without logging in again.
| Role | Scope |
|---|---|
superadmin | Global management of brands and the Hub |
brand_admin | Full control of their brand, including billing and team management |
brand_technician | Brand operations (chargers, tariffs, incidents) without access to billing or team settings |
brand_viewer | Read-only: dashboard, tariffs and clients, without financial figures |
| portal driver | Authenticated end user in /portal/{slug}/ |
| anonymous driver | QR payment without an account, at /qr/{charge_point_id} |
Overview of the main endpoint groups (not exhaustive):
| Prefix | What it covers |
|---|---|
/api/auth | Login, registration, 2FA (TOTP) |
/api/brand | Chargers, tariffs, clients, RFID, dashboard, incidents, OCPI, webhooks, advanced OCPP commands |
/api/brand/team | Team management: invite, list, change role, remove |
/api/admin | Superadmin: brands, invoices, Hub |
/api/portal | Driver portal: login, sessions, wallet, subscriptions, saved payment method |
/api/public | Public endpoints: QR payment, charger info, map |
/api/hub | Roaming Hub statistics and management |
/api/ext | Public API for external integrations, authenticated with API key |
/ocpi/{brand_slug} | OCPI 2.2 — CPO per brand |
/ocpi/emsp/{brand_slug} | OCPI 2.2 — eMSP per brand |
/ocpi/hub | OCPI 2.2 of the Hub as a single party ES*ACH |
Connection via WebSocket, one charger per connection. The charge point must be pre-registered under the brand before connecting.
wss://askacharge.com/ocpp/{brand_slug}/{charge_point_id}
Subprotocol negotiated via the Sec-WebSocket-Protocol header: ocpp1.6 or ocpp2.0.1.
Each charger can optionally have a Basic Auth credential associated with it
(username = charge_point_id, password generated by the operator from the
panel — in the "OCPP Security" section of each charger). When enabled, the WebSocket
handshake requires the Authorization: Basic base64(charge_point_id:password)
header, and connections without it or with incorrect credentials are rejected. If not
enabled, the connection is accepted based solely on the charge_point_id
in the URL — we recommend enabling this on every charger exposed to the internet.
Plug & Charge allows an electric vehicle to authenticate and authorise a charging session automatically when the cable is plugged in — no RFID, app or QR required. The authentication is negotiated between the charger and the vehicle over the power line itself (PLC) using the ISO 15118-2 standard.
It requires chargers with OCPP 2.0.1 and ISO 15118 hardware support. OCPP 1.6J chargers cannot participate in this flow.
Each brand generates its own EC P-256 Root CA (simplified V2G Root CA, valid for 10 years) from the panel or via API. This CA signs the contract certificates for fleet vehicles, and must be installed on the chargers so they can validate them.
| Endpoint | Action |
|---|---|
POST /api/brand/pnc/ca/generate | Generates the brand CA (replaces the previous one if it exists) |
GET /api/brand/pnc/ca | Retrieves the active CA: fingerprint, validity, PEM |
POST /api/brand/pnc/commands/install-ca | Sends InstallCertificate OCPP 2.0.1 to the specified charger |
For each fleet vehicle, a contract certificate is issued linked to its
eMAID (Electric Mobility Account ID, format ES-ACH-XXXXXXXXXX-C). The
vehicle stores it and presents it to the charger at each session. askacharge.com
delivers it automatically via Get15118EVCertificate OCPP when the
charger requests it.
| Endpoint | Action |
|---|---|
GET /api/brand/pnc/contracts | Lists all active and revoked contracts |
POST /api/brand/pnc/contracts | Issues a new contract: emaid, owner_name, valid_days, client_id (optional) |
POST /api/brand/pnc/contracts/{id}/renew | Renews a contract (revokes the previous one, issues a new one) |
DELETE /api/brand/pnc/contracts/{id} | Revokes a contract |
When a compatible vehicle is plugged in, the charger opens an ISO 15118 session and
sends an Authorize message with id_token.type = "ISO15118"
and the iso15118CertificateHashData field. askacharge.com verifies the eMAID
against the active contract table and validates the certificate hash to prevent
impersonation. If the vehicle does not yet have the certificate downloaded, the
charger requests Get15118EVCertificate and askacharge.com responds with the
certificate chain (contract + CA) in EXI/DER format.
https://askacharge.com/askacharge/api/ocsp/{brand_slug}.
Chargers that implement OCSP can verify in real time whether a certificate has been
revoked. Revocation via API (DELETE /pnc/contracts/{id}) is immediate:
the OCSP responds REVOKED and the next Authorize will
return Invalid.
Consumer vehicles (IONIQ 6, BMW iX, etc.) come from the factory with a contract certificate signed by a root CA recognised by the manufacturers — primarily Hubject eMobility PKI in Europe. To authorise those drivers, askacharge.com would need to connect to that external PKI, which requires a contract with Hubject and is on the roadmap but not yet active.
Today, Plug & Charge on askacharge.com works for own fleet: vehicles whose eMAIDs you have issued as the operator. For all other drivers, combining with RFID, QR payment or the driver portal is recommended.
askacharge.com manages charging power dynamically across three independent levels that can be combined: power distribution by location, conditional rules based on solar output or energy price, and OCPP charging profiles per charger. Everything is applied in real time without operator intervention.
Each location can have a maximum power limit (kW). askacharge.com distributes that
ceiling across active chargers by sending SetChargingProfile
(OCPP 1.6J and 2.0.1) automatically when a session starts or stops. Available
strategies: even (equal for all) and priority (per-charger
priority). This allows chargers to be installed without upgrading the electrical
supply connection.
| Endpoint | Action |
|---|---|
GET /api/brand/location-limits | Lists active limits |
PUT /api/brand/location-limits | Creates or updates a limit (location_name, max_power_kw, strategy) |
DELETE /api/brand/location-limits/{id} | Removes a limit |
The operator configures their photovoltaic installation (peak power, optional battery, minimum surplus to trigger charging) and publishes real-time readings from their inverter or meter. askacharge.com calculates the available surplus and feeds it into the rules engine.
| Endpoint | Action |
|---|---|
GET /api/brand/solar/config | Brand solar configuration |
PUT /api/brand/solar/config | Updates: peak_kw, has_battery, battery_capacity_kwh, min_surplus_w |
POST /api/brand/solar/reading | Publishes a reading: production_w, consumption_w, grid_w |
GET /api/brand/solar/readings | Historical readings (last N hours) |
The operator defines prioritised rules that are evaluated every 5 minutes against the
current state (solar surplus, time of day, energy price). The first rule whose condition
is met applies its action via ChangeConfiguration OCPP to all active
chargers on the brand.
| Condition | Description |
|---|---|
surplus_min | Triggers if solar surplus exceeds N watts |
pvpc_max | Triggers if PVPC/OMIE price is ≤ X €/kWh |
time_range | Triggers within a time window (supports midnight crossover) |
always | Unconditional fallback rule |
| Action | Description |
|---|---|
charge_solar_only | Limits each charger to the available surplus divided among active sessions |
charge_watts | Distributes a fixed total wattage across active sessions |
charge_max | Charges at maximum rate (32 A) |
charge_min | Charges at OCPP minimum (6 A) |
pause | Suspends charging (MaxCurrentOffered = 0) |
POST /api/brand/solar/rules
{
"name": "Solar surplus only",
"priority": 10,
"condition_type": "surplus_min",
"condition_value": { "watts": 1500 },
"action": "charge_solar_only"
}
The rules engine can operate with three grid price sources:
GET /api/brand/pvpc/today.
The pvpc_max condition in charging rules makes it straightforward to
charge only when energy costs less than €0.10/kWh and pause during peak hours —
with no manual intervention at all.
The platform provides real-time dashboards, historical analytics with period comparison, monthly financial forecasting, per-charger performance rankings, exportable ESG reports in PDF, and automatic AI-based anomaly detection. All data is accessible via API for integration with external BI tools.
| Endpoint | What it returns |
|---|---|
GET /api/brand/dashboard/summary | KPIs for the selected period (energy, revenue, margin, sessions, CO₂) with % delta vs previous period |
GET /api/brand/dashboard/live | Live state: active sessions, current power, chargers by status |
GET /api/brand/dashboard/stream | Server-Sent Events — real-time updates without polling |
| Endpoint | What it returns |
|---|---|
GET /api/brand/analytics/usage | Daily/weekly/monthly usage: sessions, kWh, revenue per period |
GET /api/brand/analytics/financials | Financial breakdown: revenue, energy cost, Stripe fees, net margin, revenue shares |
GET /api/brand/analytics/forecast | Current-month forecast based on real data: projected revenue, margin, sessions and kWh through end of month |
GET /api/brand/chargers/performance | Charger ranking: availability, sessions, energy delivered, revenue, failure rate |
GET /api/brand/pvpc/today | Hourly PVPC prices for the current day (€/kWh) |
GET /api/brand/esg-report generates a downloadable PDF with the
environmental impact of the period: kWh delivered, CO₂ avoided (factor 130 g/kWh
vs combustion), equivalent trees planted, and a breakdown by fleet client. Ready
for inclusion in corporate sustainability reports or CSRD disclosures.
A detection engine runs four independent analysers every 30 minutes across all
recent transactions. Alerts are stored in the anomaly_alerts table
with severity and description, and the operator is notified by email.
| Detector | What it looks for |
|---|---|
| Impossible energy | Sessions with kWh delivered exceeding the charger's physical rated power × duration (indicates meter tampering) |
| Statistical outliers | Sessions whose cost or energy deviates more than 3σ from the historical average for that charger |
| Physical tampering | Abnormal stop/restart patterns suggesting deliberate disconnection of the charger |
| Replay attack | Transactions with the same OCPP transaction_id sent more than once from the same charge point |
read) for
integration with external BI tools such as Power BI, Tableau or Metabase.
The AskaCharge Hub is an internal roaming network between brands/operators sharing
the platform: a single OCPI integration gives access to all chargers in the network,
with no need for individual bilateral agreements. Towards external partners (Hubject,
GIREVE, ocpi.io...), the Hub presents itself as a single OCPI 2.2 party:
ES*ACH.
https://askacharge.com/askacharge/ocpi/hub/versions
Commission model: 1% per cross-brand session, settled on the 1st of each month. The
eMSP charges the driver using their saved card and askacharge.com transfers to the CPO —
with no payment risk between brands, since both billing accounts are on the same
platform. External membership requests: POST /api/public/hub/apply,
see also the Hub page.
askacharge.com generates and submits invoices to Spanish tax systems automatically, with no additional configuration required from the operator beyond entering their tax details during onboarding. The platform detects the brand's territory and applies the corresponding system.
Each completed transaction generates an invoice record in Verifactu format
(Royal Decree 1007/2023): XML signed with the chained SHA-256 hash chain,
a validation QR code, and automatic submission to the AEAT SOAP web service.
Records are stored with the tax authority's response status (aeat_ok,
error code, timestamp). Rejected invoices enter an automatic retry queue.
For operators in Bizkaia, Gipuzkoa or Araba, the platform issues TicketBAI invoices with XAdES-EPES signature using the brand's digital certificate. They are submitted to the correct endpoint for each foral treasury. Bizkaia also supports monthly aggregated submission via LROE (Lote de Registros de Operaciones Económicas). The TicketBAI QR is included in the invoice PDF.
| Event | System |
|---|---|
| QR charging session (anonymous driver) | Individual ticket per transaction |
| Monthly invoice to fleet client | Aggregated invoice with session breakdown |
| askacharge.com invoice to brand (SaaS) | Platform operator invoice |
Issued invoices can optionally be synchronised with Holded via API (PUT /api/brand/erp/config).
The operator provides their Holded API key and the platform sends each invoice
at the moment of generation.
The platform implements layered security: robust authentication with token rotation, software-based 2FA, OCPP protocol-level security, signing of outbound events, and GDPR privacy controls.
The JWT access token has a 30-minute lifetime. The refresh token is issued as an
httpOnly; SameSite=Lax; Secure cookie (never accessible from JavaScript)
and is rotated on every use: when the access token is renewed, the previous refresh
token is invalidated and a new one is issued. If an already-used token is presented
again, the platform detects a potential session theft and immediately revokes all
refresh tokens for that user. The main app cookies (/app) and driver
portal cookies (/portal) are independent to prevent privilege escalation
between layers.
brand_admin users can enable two-factor authentication with any compatible
app (Google Authenticator, Aegis, 1Password…). The flow: setup → provisioning URI + QR
→ first code verification → activation with delivery of 8 single-use backup codes
(SHA-256 in the database, plaintext shown once). 2FA is required at login if enabled.
| Endpoint | Action |
|---|---|
GET /api/auth/2fa/status | Current 2FA status |
POST /api/auth/2fa/setup | Generates TOTP secret and provisioning URI |
POST /api/auth/2fa/enable | Activates 2FA and returns backup codes |
POST /api/auth/2fa/disable | Disables 2FA (requires a valid TOTP code) |
Each charger can have an independent credential: username =
charge_point_id, password generated and rotatable from the panel
(SHA-256 hash stored, plaintext shown once). When enabled,
the WebSocket handshake requires the Authorization: Basic … header
and rejects connections without it. The endpoint POST /api/brand/chargers/{id}/rotate-password
allows rotating the credential without touching the configuration of the rest of the fleet.
API keys for external integrations are stored exclusively as SHA-256 hashes —
the plaintext value is only shown at creation time and can never be retrieved.
Each key has a set of scopes (currently read) that limit
the permitted operations.
Each outbound event includes the header
X-AskaCharge-Signature: sha256=<hex>, computed using the
endpoint's own secret (unique per endpoint, never shared). The receiver can
verify the authenticity of the event before processing it.
For each fleet client the operator can execute:
| Endpoint | Action |
|---|---|
GET /api/brand/clients/{id}/gdpr-export | Exports all client data as JSON (sessions, payments, personal data) |
DELETE /api/brand/clients/{id}/gdpr-delete | Anonymises and deletes the client's personal data, retaining tax records with neutral references |
Vehicle-to-Grid (V2G) allows electric vehicles to return energy to the grid during periods of high demand or elevated prices, turning them into manageable distributed batteries. askacharge.com is designed to operate as a V2G aggregation platform as soon as the hardware allows — the standards, protocols and dispatch logic are already built into the architecture.
| Standard | V2G contribution | Status |
|---|---|---|
| ISO 15118-2 | Plug & Charge — automatic cable-based authentication (foundation of the V2G stack) | Implemented (own PKI, eMAID, OCSP) |
| ISO 15118-20 | Bidirectional extension — defines the V2G/V2H discharge protocol over the same cable | On the roadmap (requires CHAdeMO V2H or CCS2 V2G compatible hardware) |
| OCPP 2.0.1 | Device Model, SetChargingProfile with negative power (discharge), Get15118EVCertificate |
Implemented — the server accepts charging profiles with negative limits as soon as the hardware reports them |
The Smart Charging rules engine (see previous section)
is designed for bidirectional dispatch: the pvpc_max and
time_range conditions already allow defining discharge windows ("discharge
when PVPC > €0.18/kWh"), and the charge_watts action with a negative
value will be mapped to an OCPP discharge profile when the charger supports it.
PVPC and OMIE spot prices are updated hourly from REE ESIOS — the price signal for
dispatch is already available in real time.
The Spanish regulatory framework (Royal Decree 88/2026) establishes the role of the Active Demand Response System (SRAD): an aggregator that pools distributed flexibility capacity (EV batteries, solar, heat pumps) and offers it to Red Eléctrica as a balancing service. askacharge.com is positioned to operate as a SRAD as soon as:
The platform already aggregates real-time power metrics by location
(location_limits), knows the status of every charger and active session,
and has the OCPP channel to modify charging profiles within seconds — the three
key ingredients of demand response dispatch.
Royal Decree 88/2026 creates in Spain the role of the independent aggregator: an entity that pools distributed flexibility capacity (EV batteries, solar, heat pumps) and offers it to Red Eléctrica in balancing and adjustment service markets, without needing to be a licensed electricity supplier.
askacharge.com is positioned to register as an independent aggregator with a unique structural advantage: it already controls in real time the chargers of all brands in the network. Every operator that joins contributes their installed capacity to the aggregated pool. The regulatory threshold is 1 MW — achievable by aggregating several network brands before any individual operator could reach it alone.
| Concept | Detail |
|---|---|
| Legal role | Independent aggregator — RD 88/2026, art. 23 |
| Minimum threshold | 1 MW of aggregated manageable capacity |
| Revenue reference | ~€246,000/MW/year in availability auctions (REE, 2025) |
| Dispatch signal | OpenADR 2.0 or direct REE API → askacharge.com → OCPP to chargers |
| Revenue sharing with operators | Same settlement model as the Hub: monthly payout proportional to capacity contributed |
For askacharge.com's operator clients, joining the aggregation pool means a new passive revenue stream: their chargers keep working normally, and when REE activates a curtailment signal (load reduction), askacharge.com handles the dispatch automatically and transfers their share of the compensation.
With bidirectional hardware, a fleet of parked EVs can return energy to the grid during peak demand — an additional service that REE remunerates above availability. Combined with price arbitrage, the EV becomes a financial asset for the operator:
| Mode | When | Remuneration |
|---|---|---|
| Curtailment | REE activates a load reduction signal | Availability + activation |
| V2G injection | REE needs energy during a demand peak | Energy in the balancing market + regulation |
| PVPC arbitrage | Charge at price trough, inject at peak | Price differential (up to ×15) |
Important: with Spain's high solar penetration, the traditional "cheap at night / expensive during the day" model no longer holds. PVPC prices can hit historical lows at midday due to photovoltaic overproduction (values below €0.02/kWh are common), while the real price peak occurs in the late afternoon and evening (19–22h), when the sun drops but demand remains high. The optimal arbitrage window is solar midday trough → late afternoon peak, with spreads that can exceed a 15× factor.
askacharge.com handles this natively: PVPC and OMIE spot prices are updated hourly
from REE ESIOS and are already available in real time on each operator's dashboard.
The pvpc_max condition in the rules engine evaluates the current price
at every charging decision — without assuming fixed time patterns, adapting
automatically to solar seasonality.
askacharge.com includes a three-layer driver experience with no native app required: a publicly accessible map, a registration-free QR charging flow, and a full driver portal installable as a PWA.
Available at /mapa without login. Shows askacharge.com chargers and the
national REVE/REE network in real time. Clicking on an askacharge.com charger opens
a modal with:
The driver scans the physical QR on the charger or the one from the map. The full flow:
Compatible with all tariff modes: per kWh, per hour, per session, combined, dynamic PVPC and free. The cost estimate is displayed before confirming payment.
Each operator can offer a driver portal at /portal/{slug}/,
installable as a PWA on iOS and Android (without going through the App Store). It includes:
| Feature | Detail |
|---|---|
| eMSP token | Visual card with UID and QR for RFID charging without a physical card |
| Session history | Own sessions + external roaming CDRs unified, with kWh and cost |
| Saved payment method | Stripe SetupIntent (PSD2/SCA) for automatic billing during roaming sessions |
| Network map | Operator's own chargers + AskaCharge Hub network |
| Push notifications | Notification when charging is complete (Web Push / VAPID, managed by the driver) |
| Install prompt | Native banner to add to home screen (Android/Chrome/Safari) |
Each brand can register custom HTTP endpoints to receive real-time events
(HMAC-signed, unique secret per endpoint) from
/api/brand/webhooks. Events include: session.stopped (among
others), with energy, amount, CO₂ saved and stop reason.
An alternative to JWT for server-to-server integrations: scoped keys per brand,
managed from /api/brand/api-keys
(SHA-256 hash in the database, plaintext shown only once at creation time). Endpoints
available with an API key:
| Endpoint | What it returns |
|---|---|
GET /api/ext/chargers | Brand's chargers and their status |
GET /api/ext/sessions | Charging sessions |
| Public charger map | Real-time coverage, no login required |
| AskaCharge Hub | Operator roaming network, live statistics |
| Create an account | 30-day free trial |