API REFERENCE · v1.0.0

EV Network Intelligence API

Built for CPOs, CPMS providers & E-roaming hubs – integrate without replacing your stack.
Push OCPP meter values, get anomaly verdicts back. No ML expertise required.

BASE URL https://api.solidstudio.ai
AUTH Bearer <token>
FORMAT JSON
LLM-FRIENDLY llms.txt
POST /v1/sessions

Create Session

Create a charging session and optionally run anomaly analysis. Meter values are optional — session can be created empty and populated later via PUT or PATCH. If >= 3 meter values are provided, the CSAR-2 pipeline runs automatically. Sessions longer than 6 hours are truncated to the last 6h window for inference.

Headers

Authorization *
string Bearer token with embedded tenant context

Request Body

session_id *
string Client unique session identifier (used for upsert)
charging_station_id *
string Charging station identifier (EVSE location)
connector_id
string | null Connector identifier within the charging station
evse_id
string | null EVSE identifier (EU standard)
meter_values
MeterValue[] Initial meter readings. Optional — session can be created empty.
timestamp *
datetime UTC timestamp of the meter reading
value *
number Measured value in the specified unit
measurand
OcppMeasurand OCPP measurand (e.g. Energy.Active.Import.Register, Power.Active.Import, SoC)
unit
OcppUnitOfMeasure OCPP unit (e.g. kWh, kW, Percent, A, V)
phase
OcppPhase OCPP phase (e.g. L1, L2, L3, L1-N)
location
OcppLocation OCPP location (e.g. Outlet, EV, Cable)
metadata
object | null Optional client metadata for the session

Response 200

session_id *
string Session identifier
status *
string "pending" | "active" | "failed"
is_anomaly
boolean | null Whether any anomaly was detected
anomaly_score
number | null Overall anomaly score (0.0–1.0)
anomaly_confidence
number | null Overall model confidence (0.0–1.0)
is_incident
boolean | null Confirmed incident flag
is_recurring
boolean | null Recurring pattern flag
anomalies *
AnomalyDetail[] Detected anomalies
category *
AnomalyCategory Anomaly classification
score *
number Severity score (0.0–1.0)
confidence *
number Model confidence (0.0–1.0)
bucket_range *
object Affected meter value range
start_unit *
integer Start bucket index (0-based)
end_unit *
integer End bucket index (inclusive)
time_range
object | null Affected time range
start_timestamp
datetime | null Start of anomaly time range
end_timestamp
datetime | null End of anomaly time range
analyzed_at
datetime | null Analysis timestamp
Request JSON
{
  "session_id": "sess-abc-001",
  "charging_station_id": "CP-NL-AMS-0042",
  "connector_id": "1",
  "meter_values": [
    {
      "timestamp": "2026-02-27T10:00:00Z",
      "measurand": "Energy.Active.Import.Register",
      "unit": "kWh",
      "value": 0.0
    },
    {
      "timestamp": "2026-02-27T10:15:00Z",
      "measurand": "Energy.Active.Import.Register",
      "unit": "kWh",
      "value": 5.5
    },
    {
      "timestamp": "2026-02-27T10:30:00Z",
      "measurand": "Energy.Active.Import.Register",
      "unit": "kWh",
      "value": 11.1
    }
  ]
}
Response · 200 JSON
{
  "session_id": "sess-abc-001",
  "status": "active",
  "is_anomaly": true,
  "anomaly_score": 0.85,
  "anomaly_confidence": 0.92,
  "is_incident": false,
  "is_recurring": true,
  "anomalies": [
    {
      "category": "KWH_DECREASE",
      "score": 0.87,
      "confidence": 0.92,
      "bucket_range": { "start_unit": 4, "end_unit": 7 },
      "time_range": {
        "start_timestamp": "2026-02-27T11:00:00Z",
        "end_timestamp": "2026-02-27T11:45:00Z"
      }
    }
  ],
  "analyzed_at": "2026-02-27T10:31:02Z"
}
PUT /v1/sessions/{session_id}

Replace Session

Replace all meter values for a session. Deletes existing meter values and sets new ones. Requires at least 1 reading. If >= 3 meter values after replacement, CSAR-2 inference runs automatically. Sessions longer than 6 hours are truncated to the last 6h window for inference.

Headers

Authorization *
string Bearer token with embedded tenant context

Path Parameters

session_id *
string Session identifier

Request Body

meter_values *
MeterValue[] Complete set of meter readings (replaces all previous)
timestamp *
datetime UTC timestamp of the meter reading
value *
number Measured value in the specified unit
measurand
OcppMeasurand OCPP measurand type
unit
OcppUnitOfMeasure OCPP unit of measure
metadata
object | null Optional client metadata to set/update

Response 200

session_id *
string Session identifier
status *
string "pending" | "active" | "failed"
is_anomaly
boolean | null Whether any anomaly was detected
anomaly_score
number | null Overall anomaly score (0.0–1.0)
anomaly_confidence
number | null Overall model confidence (0.0–1.0)
anomalies *
AnomalyDetail[] Detected anomalies
analyzed_at
datetime | null Analysis timestamp
Request JSON
{
  "meter_values": [
    {
      "timestamp": "2026-02-27T10:00:00Z",
      "measurand": "Energy.Active.Import.Register",
      "unit": "kWh",
      "value": 0.0
    },
    {
      "timestamp": "2026-02-27T10:15:00Z",
      "measurand": "Energy.Active.Import.Register",
      "unit": "kWh",
      "value": 5.5
    },
    {
      "timestamp": "2026-02-27T10:30:00Z",
      "measurand": "Energy.Active.Import.Register",
      "unit": "kWh",
      "value": 11.1
    }
  ]
}
Response · 200 JSON
{
  "session_id": "sess-abc-001",
  "status": "active",
  "is_anomaly": false,
  "anomaly_score": 0.12,
  "anomaly_confidence": 0.95,
  "anomalies": [],
  "analyzed_at": "2026-02-27T10:31:02Z"
}
PATCH /v1/sessions/{session_id}

Update Session

Append meter values to an existing session (OCPI-like incremental push). Empty meter_values list = no changes, returns current state. If >= 3 accumulated meter values after append, CSAR-2 inference runs automatically. Sessions longer than 6 hours are truncated to the last 6h window for inference.

Headers

Authorization *
string Bearer token with embedded tenant context

Path Parameters

session_id *
string Session identifier

Request Body

meter_values *
MeterValue[] Meter readings to append to the session
timestamp *
datetime UTC timestamp of the meter reading
value *
number Measured value in the specified unit
measurand
OcppMeasurand OCPP measurand type
unit
OcppUnitOfMeasure OCPP unit of measure
metadata
object | null Optional client metadata to set/update

Response 200

session_id *
string Session identifier
status *
string "pending" | "active" | "failed"
is_anomaly
boolean | null Whether any anomaly was detected
anomaly_score
number | null Overall anomaly score (0.0–1.0)
anomaly_confidence
number | null Overall model confidence (0.0–1.0)
anomalies *
AnomalyDetail[] Detected anomalies
analyzed_at
datetime | null Analysis timestamp
Request JSON
{
  "meter_values": [
    {
      "timestamp": "2026-02-27T10:45:00Z",
      "measurand": "Energy.Active.Import.Register",
      "unit": "kWh",
      "value": 16.5
    }
  ]
}
Response · 200 JSON
{
  "session_id": "sess-abc-001",
  "status": "active",
  "is_anomaly": true,
  "anomaly_score": 0.85,
  "anomaly_confidence": 0.92,
  "anomalies": [
    {
      "category": "KWH_DECREASE",
      "score": 0.87,
      "confidence": 0.92,
      "bucket_range": { "start_unit": 4, "end_unit": 7 }
    }
  ],
  "analyzed_at": "2026-02-27T10:46:05Z"
}
GET /v1/sessions

List Sessions

List analyzed sessions with pagination and filters. Reads from pre-joined materialized view for session + latest inference + anomalies.

Headers

Authorization *
string Bearer token with embedded tenant context

Query Parameters

page
integer Page number (default: 1)
page_size
integer Items per page, max 100 (default: 20)
charging_station_id
string Filter by charging station identifier
evse_id
string Filter by EVSE identifier
is_anomaly
boolean Filter anomalous sessions only
min_score
number Minimum anomaly score (0.0–1.0)
min_confidence
number Minimum model confidence (0.0–1.0)
date_from
string Start date filter (ISO 8601)
date_to
string End date filter (ISO 8601)

Response 200

items *
SessionListItem[] Sessions on the current page
session_id *
string Internal session UUID
external_session_id *
string Client-provided session identifier
charging_station_id *
string Charging station identifier
is_anomaly *
boolean | null Anomaly flag from latest inference
anomaly_score *
number | null Latest anomaly score
anomaly_count *
integer Number of anomaly categories detected
status *
string "pending" | "active" | "failed"
created_at *
datetime Session creation timestamp
last_analyzed_at *
datetime | null Last successful analysis timestamp
total *
integer Total items matching filters
page *
integer Current page number
page_size *
integer Items per page
Response · 200 JSON
{
  "items": [
    {
      "session_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "external_session_id": "sess-abc-001",
      "charging_station_id": "CP-NL-AMS-0042",
      "is_anomaly": true,
      "anomaly_score": 0.85,
      "anomaly_count": 2,
      "status": "active",
      "created_at": "2026-02-27T10:00:00Z",
      "last_analyzed_at": "2026-02-27T10:31:02Z"
    }
  ],
  "total": 1250,
  "page": 1,
  "page_size": 20
}
GET /v1/sessions/{session_id}

Get Session Detail

Get full session details including meter values, analysis result, and anomaly categories.

Headers

Authorization *
string Bearer token with embedded tenant context

Path Parameters

session_id *
string Session identifier

Response 200

session_id *
string Session identifier
status *
string "pending" | "active" | "failed"
is_anomaly
boolean | null Whether any anomaly was detected
anomaly_score
number | null Overall anomaly score (0.0–1.0)
anomaly_confidence
number | null Overall model confidence (0.0–1.0)
is_incident
boolean | null Confirmed incident flag
is_recurring
boolean | null Recurring pattern flag
anomalies *
AnomalyDetail[] Detected anomalies
analyzed_at
datetime | null Analysis timestamp
meter_values *
MeterValue[] All meter readings for this session
timestamp *
datetime UTC timestamp
value *
number Measured value
measurand
OcppMeasurand OCPP measurand type
unit
OcppUnitOfMeasure OCPP unit of measure
created_at *
datetime Session creation timestamp
Response · 200 JSON
{
  "session_id": "sess-abc-001",
  "status": "active",
  "is_anomaly": true,
  "anomaly_score": 0.85,
  "anomaly_confidence": 0.92,
  "is_incident": false,
  "is_recurring": true,
  "anomalies": [
    {
      "category": "KWH_DECREASE",
      "score": 0.87,
      "confidence": 0.92,
      "bucket_range": { "start_unit": 4, "end_unit": 7 },
      "time_range": {
        "start_timestamp": "2026-02-27T11:00:00Z",
        "end_timestamp": "2026-02-27T11:45:00Z"
      }
    }
  ],
  "analyzed_at": "2026-02-27T10:31:02Z",
  "meter_values": [
    { "timestamp": "2026-02-27T10:00:00Z", "measurand": "Energy.Active.Import.Register", "unit": "kWh", "value": 0.0 },
    { "timestamp": "2026-02-27T10:15:00Z", "measurand": "Energy.Active.Import.Register", "unit": "kWh", "value": 5.5 },
    { "timestamp": "2026-02-27T10:30:00Z", "measurand": "Energy.Active.Import.Register", "unit": "kWh", "value": 11.1 }
  ],
  "created_at": "2026-02-27T09:58:00Z"
}
POST /v1/sessions/{session_id}/explain

Explain Session

Get an LLM-generated explanation of session anomalies.

Headers

Authorization *
string Bearer token with embedded tenant context

Path Parameters

session_id *
string Session identifier

Request Body

Response 200

session_id *
string Session identifier
explanation *
string Human-readable explanation of detected anomalies
Request JSON
{}
Response · 200 JSON
{
  "session_id": "sess-abc-001",
  "explanation": "The session shows a kWh decrease between meter values 4–7, indicating the energy register dropped unexpectedly. This typically signals a meter reset or communication error between the charger and the backend."
}
POST /v1/sessions/{session_id}/ask

Ask Session

Ask a natural language question about a specific session.

Headers

Authorization *
string Bearer token with embedded tenant context

Path Parameters

session_id *
string Session identifier

Request Body

question *
string Natural language question about the session

Response 200

session_id *
string Session identifier
answer *
string Answer to the question about this session
Request JSON
{
  "question": "Why did the SoC drop unexpectedly?"
}
Response · 200 JSON
{
  "session_id": "sess-abc-001",
  "answer": "The SoC dropped from 80% to 65% because the charger reported an unexpected discharge event during meter values 3–5, likely caused by a bi-directional charging cycle (V2G)."
}
POST /v1/sessions/batch

Submit Batch

Submit multiple sessions for asynchronous batch analysis. Returns batch_id for polling status.

Headers

Authorization *
string Bearer token with embedded tenant context

Request Body

sessions *
SessionSubmitRequest[] Array of sessions to analyze (min 1)
session_id *
string Client unique session identifier
charging_point_id *
string Charging point identifier
meter_values *
MeterValue[] Meter readings

Response 200

batch_id *
string Batch identifier for polling
total_sessions *
integer Number of sessions submitted
status *
string "pending" | "processing" | "completed" | "failed"
Request JSON
{
  "sessions": [
    {
      "session_id": "sess-001",
      "charging_point_id": "CP-001",
      "meter_values": [
        { "timestamp": "2026-02-27T10:00:00Z", "unit": "kwh", "value": 0.0 },
        { "timestamp": "2026-02-27T10:15:00Z", "unit": "kwh", "value": 5.5 },
        { "timestamp": "2026-02-27T10:30:00Z", "unit": "kwh", "value": 11.1 }
      ]
    },
    {
      "session_id": "sess-002",
      "charging_point_id": "CP-002",
      "meter_values": [
        { "timestamp": "2026-02-27T11:00:00Z", "unit": "kwh", "value": 0.0 },
        { "timestamp": "2026-02-27T11:15:00Z", "unit": "kwh", "value": 7.2 },
        { "timestamp": "2026-02-27T11:30:00Z", "unit": "kwh", "value": 14.8 }
      ]
    }
  ]
}
Response · 200 JSON
{
  "batch_id": "batch-a1b2c3d4",
  "total_sessions": 2,
  "status": "pending"
}
GET /v1/sessions/batch/{batch_id}

Get Batch Status

Get batch processing status and results. Poll until status is "completed" or "failed".

Headers

Authorization *
string Bearer token with embedded tenant context

Path Parameters

batch_id *
string Batch identifier

Response 200

batch_id *
string Batch identifier
status *
string "pending" | "processing" | "completed" | "failed"
total_sessions *
integer Total sessions in batch
processed_sessions *
integer Sessions processed so far
failed_sessions *
integer Sessions that failed analysis
results *
SessionAnalysisResponse[] Analysis results for completed sessions
created_at *
datetime Batch creation timestamp
completed_at *
datetime | null Batch completion timestamp
Response · 200 JSON
{
  "batch_id": "batch-a1b2c3d4",
  "status": "completed",
  "total_sessions": 2,
  "processed_sessions": 2,
  "failed_sessions": 0,
  "results": [
    {
      "session_id": "sess-001",
      "status": "active",
      "is_anomaly": false,
      "anomaly_score": 0.12,
      "sequence_length": 9,
      "anomalies": []
    }
  ],
  "created_at": "2026-02-27T10:00:00Z",
  "completed_at": "2026-02-27T10:02:15Z"
}
GET /v1/stations

List Stations

List tenant charging stations with aggregated anomaly statistics. Reads from pre-aggregated materialized view.

Headers

Authorization *
string Bearer token with embedded tenant context

Query Parameters

page
integer Page number (default: 1)
page_size
integer Items per page, max 100 (default: 20)

Response 200

items *
StationListItem[] Stations on the current page
charging_station_id *
string Internal station UUID
external_station_id *
string Client-provided station identifier
total_sessions *
integer Total sessions at this station
anomalous_sessions *
integer Sessions with detected anomalies
max_anomaly_score *
number | null Highest anomaly score across sessions
last_anomaly_at *
datetime | null Most recent anomaly detection
total *
integer Total items matching filters
page *
integer Current page number
page_size *
integer Items per page
Response · 200 JSON
{
  "items": [
    {
      "charging_station_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "external_station_id": "ST-NL-AMS-01",
      "total_sessions": 142,
      "anomalous_sessions": 7,
      "max_anomaly_score": 0.91,
      "last_anomaly_at": "2026-02-27T09:45:00Z"
    }
  ],
  "total": 12,
  "page": 1,
  "page_size": 20
}
GET /v1/stations/{charging_station_id}

Get Station Detail

Get station details: connectors, energy data, anomaly counts. Joins station aggregates with per-session anomaly details.

Headers

Authorization *
string Bearer token with embedded tenant context

Path Parameters

charging_station_id *
string Charging station identifier

Response 200

charging_station_id *
string Internal station UUID
external_station_id *
string Client-provided station identifier
connectors *
ConnectorInfo[] Connectors at this station
connector_id *
string Connector identifier
total_sessions *
integer Total sessions on this connector
anomalous_sessions *
integer Anomalous sessions count
total_sessions *
integer Total sessions at this station
anomalous_sessions *
integer Sessions with anomalies
metadata *
object | null Station metadata (address, operator, etc.)
Response · 200 JSON
{
  "charging_station_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "external_station_id": "ST-NL-AMS-01",
  "connectors": [
    { "connector_id": "1", "total_sessions": 80, "anomalous_sessions": 3 },
    { "connector_id": "2", "total_sessions": 62, "anomalous_sessions": 4 }
  ],
  "total_sessions": 142,
  "anomalous_sessions": 7,
  "metadata": {
    "address": "Keizersgracht 100, Amsterdam",
    "operator": "FastNed"
  }
}
GET /v1/stations/{charging_station_id}/connectors

Get Station Connectors

Get station connectors with per-category anomaly breakdown.

Headers

Authorization *
string Bearer token with embedded tenant context

Path Parameters

charging_station_id *
string Charging station identifier

Response 200

charging_station_id *
string Station identifier
connectors *
StationConnectorItem[] Connectors with anomaly statistics
connector_id *
string Connector identifier
total_sessions *
integer Total sessions
anomalous_sessions *
integer Anomalous sessions
anomaly_categories *
object Count per anomaly category
Response · 200 JSON
{
  "charging_station_id": "ST-NL-AMS-01",
  "connectors": [
    {
      "connector_id": "1",
      "total_sessions": 80,
      "anomalous_sessions": 3,
      "anomaly_categories": {
        "KWH_DECREASE": 2,
        "ENERGY_PIT": 1
      }
    },
    {
      "connector_id": "2",
      "total_sessions": 62,
      "anomalous_sessions": 4,
      "anomaly_categories": {
        "ZERO_SESSION": 3,
        "CHARGING_EXPECTED": 1
      }
    }
  ]
}
GET /v1/stations/{charging_station_id}/inference

Station Inference

Get latest SHADE inference result for a station. Replaces the former POST /stations/analyze endpoint.

Headers

Authorization *
string Bearer token with embedded tenant context

Path Parameters

charging_station_id *
string Charging station identifier

Response 200

charging_station_id *
string Analyzed station identifier
is_anomaly *
boolean Whether station-level anomaly was detected
anomaly_score *
number Station anomaly severity (0.0–1.0)
detection_details *
object SHADE detection breakdown
analyzed_at *
datetime Analysis completion timestamp
Response · 200 JSON
{
  "charging_station_id": "ST-NL-AMS-01",
  "is_anomaly": true,
  "anomaly_score": 0.72,
  "detection_details": {
    "anomaly_type": "energy_drop",
    "affected_period": "2026-02-27",
    "expected_energy_kwh": 1200.0,
    "actual_energy_kwh": 980.2
  },
  "analyzed_at": "2026-02-27T12:00:00Z"
}
GET /v1/stations/{charging_station_id}/anomalies

Station Anomalies

Get station-level anomaly history from SHADE detection results.

Headers

Authorization *
string Bearer token with embedded tenant context

Path Parameters

charging_station_id *
string Charging station identifier

Query Parameters

page
integer Page number (default: 1)
page_size
integer Items per page, max 100 (default: 20)

Response 200

items *
StationAnomalyItem[] Anomaly records on the current page
inference_id *
string Unique inference run identifier
is_anomaly *
boolean Whether anomaly was detected
anomaly_score *
number Severity score (0.0–1.0)
detection_details *
object SHADE detection breakdown
analyzed_at *
datetime Analysis timestamp
total *
integer Total items matching filters
page *
integer Current page number
page_size *
integer Items per page
Response · 200 JSON
{
  "items": [
    {
      "inference_id": "inf-xyz-001",
      "is_anomaly": true,
      "anomaly_score": 0.72,
      "detection_details": {
        "anomaly_type": "energy_drop",
        "affected_period": "2026-02-27"
      },
      "analyzed_at": "2026-02-27T12:00:00Z"
    }
  ],
  "total": 5,
  "page": 1,
  "page_size": 20
}
GET /v1/models

List Models

List available base models and tenant fine-tuned models.

Headers

Authorization *
string Bearer token with embedded tenant context

Response 200

models *
ModelListItem[] Available models
id *
string Model identifier
name *
string Display name
type *
string "csar_2" | "csar_c_2" | "shade"
version *
string Semantic version
is_base *
boolean Whether this is a base model
base_model
string | null Parent model ID if fine-tuned
metrics *
object | null Model performance metrics
status *
string "active" | "training" | "archived"
created_at *
datetime Model creation timestamp
Response · 200 JSON
{
  "models": [
    {
      "id": "model-csar2-base",
      "name": "CSAR-2 Base",
      "type": "csar_2",
      "version": "1.0.0",
      "is_base": true,
      "base_model": null,
      "metrics": { "f1_score": 0.94, "precision": 0.92 },
      "status": "active",
      "created_at": "2026-01-15T00:00:00Z"
    }
  ]
}
GET /v1/models/{model_id}

Get Model Detail

Get model details: version, metrics, training date, status.

Headers

Authorization *
string Bearer token with embedded tenant context

Path Parameters

model_id *
string Model identifier

Response 200

id *
string Model identifier
name *
string Display name
type *
string "csar_2" | "csar_c_2" | "shade"
version *
string Semantic version
is_base *
boolean Whether this is a base model
base_model
string | null Parent model ID
metrics *
object | null Performance metrics
status *
string "active" | "training" | "archived"
created_at *
datetime Creation timestamp
s3_path
string | null Model artifact path
description
string | null Model description
Response · 200 JSON
{
  "id": "model-csar2-base",
  "name": "CSAR-2 Base",
  "type": "csar_2",
  "version": "1.0.0",
  "is_base": true,
  "base_model": null,
  "metrics": {
    "f1_score": 0.94,
    "precision": 0.92,
    "recall": 0.96
  },
  "status": "active",
  "created_at": "2026-01-15T00:00:00Z",
  "s3_path": "models/csar2/v1.0.0/model.pt",
  "description": "Base CSAR-2 autoencoder model"
}
POST /v1/models/fine-tune

Start Fine-Tune

Trigger model fine-tuning on your session data. Specify base model and training data source.

Headers

Authorization *
string Bearer token with embedded tenant context

Request Body

base_model_id *
string Base model ID to fine-tune from
name *
string Name for the fine-tuned model (max 128 chars)
data_source *
object Training data source configuration
type *
string "sessions" or "upload"
session_filter
object | null Filter criteria for session selection
training_config
object Training hyperparameters

Response 200

job_id *
string Fine-tune job identifier
status *
string "queued" | "running" | "completed" | "failed"
base_model_id *
string Base model used
created_at *
datetime Job creation timestamp
Request JSON
{
  "base_model_id": "model-csar2-base",
  "name": "CSAR-2 Amsterdam Fine-Tuned",
  "data_source": {
    "type": "sessions",
    "session_filter": {
      "station_id": "ST-NL-AMS-01",
      "date_from": "2026-01-01"
    }
  },
  "training_config": {
    "epochs": 50,
    "learning_rate": 0.001
  }
}
Response · 200 JSON
{
  "job_id": "ft-job-xyz-001",
  "status": "queued",
  "base_model_id": "model-csar2-base",
  "created_at": "2026-02-27T14:00:00Z"
}
GET /v1/models/fine-tune/{job_id}

Fine-Tune Status

Get fine-tuning job progress and result model ID.

Headers

Authorization *
string Bearer token with embedded tenant context

Path Parameters

job_id *
string Fine-tune job identifier

Response 200

job_id *
string Job identifier
status *
string "queued" | "running" | "completed" | "failed"
base_model_id *
string Base model used
result_model_id *
string | null Resulting model ID (available when completed)
config *
object Training configuration used
created_at *
datetime Job creation timestamp
started_at *
datetime | null Training start timestamp
completed_at *
datetime | null Training completion timestamp
error_message *
string | null Error message if failed
Response · 200 JSON
{
  "job_id": "ft-job-xyz-001",
  "status": "completed",
  "base_model_id": "model-csar2-base",
  "result_model_id": "model-csar2-ams-ft-001",
  "config": { "epochs": 50, "learning_rate": 0.001 },
  "created_at": "2026-02-27T14:00:00Z",
  "started_at": "2026-02-27T14:01:00Z",
  "completed_at": "2026-02-27T14:45:00Z",
  "error_message": null
}
GET /v1/statistics

Get Statistics

Get tenant-wide summary: sessions, anomalies, stations, anomaly rate. Reads from pre-aggregated materialized views.

Headers

Authorization *
string Bearer token with embedded tenant context

Response 200

total_sessions *
integer Total charging sessions for this tenant
anomalous_sessions *
integer Sessions with at least one anomaly
total_stations *
integer Total registered stations
stations_with_anomalies *
integer Stations with anomalous sessions
anomaly_rate *
number Ratio of anomalous to total sessions (0.0–1.0)
Response · 200 JSON
{
  "total_sessions": 1250,
  "anomalous_sessions": 47,
  "total_stations": 12,
  "stations_with_anomalies": 4,
  "anomaly_rate": 0.0376
}
POST /v1/webhooks (configured via Dashboard)

Webhook Configuration

The platform can send webhook notifications for station health events detected by SHADE (Station Health Anomaly Detection Engine). Webhooks are configured through the management dashboard — no API endpoint is needed. When SHADE detects a station-level anomaly, a POST request is sent to your configured URL with the event payload below.

Headers

Authorization *
string Bearer token with embedded tenant context

Response 200

event *
string "station.anomaly_detected" — event type
charging_station_id *
string Affected station identifier
is_anomaly *
boolean Whether anomaly was detected
anomaly_score *
number Station anomaly severity (0.0–1.0)
detection_details *
object SHADE detection breakdown (anomaly type, affected period, metrics)
analyzed_at *
datetime Analysis completion timestamp (UTC)
webhook_id *
string Unique webhook delivery identifier for deduplication
Response · 200 JSON
{
  "event": "station.anomaly_detected",
  "charging_station_id": "CP-NL-AMS-0042",
  "is_anomaly": true,
  "anomaly_score": 0.72,
  "detection_details": {
    "anomaly_type": "energy_drop",
    "affected_period": "2026-02-27",
    "expected_energy_kwh": 1200.0,
    "actual_energy_kwh": 980.2
  },
  "analyzed_at": "2026-02-27T12:00:00Z",
  "webhook_id": "wh-evt-a1b2c3d4"
}
Talk to us

Register your interest today

Registration opens soon. We'll be in touch within a few hours to demonstrate our models.

By submitting, you agree to our Privacy Policy.