API REFERENCE · v0.1.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
GET /v1/sessions

List Sessions

List analyzed sessions with pagination and filters. Returns all sessions for the authenticated tenant, most-recent first. Each item includes the latest inference result when available.

Headers

Authorization *
string Bearer token with embedded tenant context

Query Parameters

page
integer Page
pageSize
integer Pagesize
chargingStationId
string Chargingstationid
evseId
string Evseid
isAnomaly
boolean Isanomaly
minScore
number Minscore
minConfidence
number Minconfidence
dateFrom
string Datefrom
dateTo
string Dateto

Response 200

content *
object[] Sessions on the current page
sessionId *
string Client-provided session identifier
chargingStationId *
string Charging station identifier
isAnomaly *
boolean | null Anomaly flag from latest inference (null if not yet analyzed)
anomalyScore *
number | null Latest anomaly score (null if not yet analyzed)
anomalyCount *
integer Number of anomaly categories detected in latest inference
status *
string Session lifecycle status: pending → active → failed
createdAt *
string Session creation timestamp (UTC)
lastAnalyzedAt *
string | null Last successful analysis timestamp (UTC)
pagination *
object Pagination metadata
totalCount *
integer Total number of items matching the query
page *
integer Current page number (1-based)
size *
integer Number of items per page
Response · 200 JSON
{
  "content": [
    {
      "anomalyCount": 2,
      "anomalyScore": 0.85,
      "chargingStationId": "CP-NL-AMS-0042",
      "createdAt": "2026-02-27T10:00:00Z",
      "isAnomaly": true,
      "lastAnalyzedAt": "2026-02-27T10:31:02Z",
      "sessionId": "sess-abc-001",
      "status": "active"
    }
  ],
  "pagination": {
    "totalCount": 0,
    "page": 0,
    "size": 0
  }
}
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 and returns analysis results.

Headers

Authorization *
string Bearer token with embedded tenant context

Request Body

sessionId *
string Client's unique session identifier. Used for upsert (find-or-create)
chargingStationId *
string Charging station identifier (EVSE location)
connectorId
string | null Connector identifier within the charging station
evseId
string | null EVSE identifier (EU standard)
meterValues
object[] Initial meter readings. Optional — session can be created empty and populated later via PATCH or PUT.
timestamp *
string UTC timestamp of the meter reading (OCPP MeterValues timestamp)
value *
number Measured value in the specified unit (0 to 10,000,000,000)
measurand
string | null OCPP measurand type (e.g. Energy.Active.Import.Register, Power.Active.Import, SoC)
unit
string | null OCPP unit of measure (e.g. kWh, kW, Percent, A, V)
phase
string | null OCPP phase (e.g. L1, L2, L3, L1-N)
location
string | null OCPP meter value location (e.g. Outlet, EV, Cable)
reconstructed
boolean True if value was reconstructed by SORC model
metadata
object | null Optional client metadata for the session
status
string | null Optional initial session status (active, pending, completed, or invalid)

Response 200

sessionId *
string Session identifier
status *
string Session status: pending, active, or failed
isAnomaly
boolean | null Whether any anomaly was detected (null if pending)
anomalyScore
number | null Overall anomaly score (null if pending)
anomalyConfidence
number | null Overall model confidence (null if pending)
isIncident
boolean | null Confirmed incident (null if pending)
isRecurring
boolean | null Recurring pattern (null if pending)
anomalies
object[] Detected anomalies (empty if pending)
category *
string Anomaly classification category
score *
number Anomaly severity score (0.0 = normal, 1.0 = extreme)
bucketRange
object | null Affected meter value range (bucket indexes, null when not available)
startUnit *
integer Start bucket index (0-based, maps to meter value position)
endUnit *
integer End bucket index (inclusive)
timeRange
object | null Affected time range (start/end timestamps, null if not available)
startTimestamp
string | null Start of the anomaly time range
endTimestamp
string | null End of the anomaly time range
confidence *
number Model confidence in this detection (0.0–1.0)
analyzedAt
string | null Analysis timestamp (null if pending)
socReconstructed
boolean Whether SoC was reconstructed by SORC model
message
string | null Informational message about the analysis status (e.g. why inference was not performed)
createdAt
string | null Session creation timestamp (null if unavailable)
Request JSON
{
  "chargingStationId": "CP-NL-AMS-0042",
  "connectorId": "1",
  "meterValues": [
    {
      "measurand": "Energy.Active.Import.Register",
      "timestamp": "2026-02-27T10:00:00Z",
      "unit": "kWh",
      "value": 0
    },
    {
      "measurand": "Power.Active.Import",
      "timestamp": "2026-02-27T10:00:00Z",
      "unit": "kW",
      "value": 0
    },
    {
      "measurand": "SoC",
      "timestamp": "2026-02-27T10:00:00Z",
      "unit": "Percent",
      "value": 80
    },
    {
      "measurand": "Energy.Active.Import.Register",
      "timestamp": "2026-02-27T10:15:00Z",
      "unit": "kWh",
      "value": 5.5
    },
    {
      "measurand": "Power.Active.Import",
      "timestamp": "2026-02-27T10:15:00Z",
      "unit": "kW",
      "value": 22
    },
    {
      "measurand": "SoC",
      "timestamp": "2026-02-27T10:15:00Z",
      "unit": "Percent",
      "value": 65
    },
    {
      "measurand": "Energy.Active.Import.Register",
      "timestamp": "2026-02-27T10:30:00Z",
      "unit": "kWh",
      "value": 11.1
    },
    {
      "measurand": "Power.Active.Import",
      "timestamp": "2026-02-27T10:30:00Z",
      "unit": "kW",
      "value": 22
    },
    {
      "measurand": "SoC",
      "timestamp": "2026-02-27T10:30:00Z",
      "unit": "Percent",
      "value": 50
    }
  ],
  "sessionId": "sess-abc-001"
}
Response · 200 JSON
{
  "analyzedAt": "2026-02-27T10:31:02Z",
  "anomalies": [
    {
      "bucketRange": {
        "endUnit": 7,
        "startUnit": 4
      },
      "category": "KWH_DECREASE",
      "confidence": 0.92,
      "score": 0.87
    }
  ],
  "anomalyConfidence": 0.92,
  "anomalyScore": 0.85,
  "isAnomaly": true,
  "isIncident": false,
  "isRecurring": true,
  "sessionId": "sess-abc-001",
  "status": "active"
}
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 Id

Response 200

sessionId *
string Session identifier
status *
string Session lifecycle status: pending → active → failed
isAnomaly
boolean | null Whether any anomaly was detected (null if pending)
anomalyScore
number | null Overall anomaly score (null if pending)
anomalyConfidence
number | null Overall model confidence (null if pending)
isIncident
boolean | null Confirmed incident (null if pending)
isRecurring
boolean | null Recurring pattern (null if pending)
anomalies
object[] Detected anomalies (empty if pending)
category *
string Anomaly classification category
score *
number Anomaly severity score (0.0 = normal, 1.0 = extreme)
bucketRange
object | null Affected meter value range (bucket indexes, null when not available)
startUnit *
integer Start bucket index (0-based, maps to meter value position)
endUnit *
integer End bucket index (inclusive)
timeRange
object | null Affected time range (start/end timestamps, null if not available)
startTimestamp
string | null Start of the anomaly time range
endTimestamp
string | null End of the anomaly time range
confidence *
number Model confidence in this detection (0.0–1.0)
analyzedAt
string | null Analysis timestamp (null if pending)
socReconstructed
boolean Whether SoC was reconstructed by SORC model
message
string | null Informational message about the analysis status (e.g. why inference was not performed)
createdAt *
string Session creation timestamp (UTC)
meterValues *
object[] All meter readings received for this session
timestamp *
string UTC timestamp of the meter reading (OCPP MeterValues timestamp)
value *
number Measured value in the specified unit (0 to 10,000,000,000)
measurand
string | null OCPP measurand type (e.g. Energy.Active.Import.Register, Power.Active.Import, SoC)
unit
string | null OCPP unit of measure (e.g. kWh, kW, Percent, A, V)
phase
string | null OCPP phase (e.g. L1, L2, L3, L1-N)
location
string | null OCPP meter value location (e.g. Outlet, EV, Cable)
reconstructed
boolean True if value was reconstructed by SORC model
Response · 200 JSON
{
  "analyzedAt": "2026-02-27T10:31:02Z",
  "anomalies": [
    {
      "bucketRange": {
        "endUnit": 7,
        "startUnit": 4
      },
      "category": "KWH_DECREASE",
      "confidence": 0.92,
      "score": 0.87
    }
  ],
  "anomalyConfidence": 0.92,
  "anomalyScore": 0.85,
  "isAnomaly": true,
  "isIncident": false,
  "isRecurring": true,
  "sessionId": "sess-abc-001",
  "status": "active"
}
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.

Headers

Authorization *
string Bearer token with embedded tenant context

Path Parameters

session_id *
string Session Id

Request Body

meterValues *
object[] Complete set of meter readings (replaces all previous)
timestamp *
string UTC timestamp of the meter reading (OCPP MeterValues timestamp)
value *
number Measured value in the specified unit (0 to 10,000,000,000)
measurand
string | null OCPP measurand type (e.g. Energy.Active.Import.Register, Power.Active.Import, SoC)
unit
string | null OCPP unit of measure (e.g. kWh, kW, Percent, A, V)
phase
string | null OCPP phase (e.g. L1, L2, L3, L1-N)
location
string | null OCPP meter value location (e.g. Outlet, EV, Cable)
reconstructed
boolean True if value was reconstructed by SORC model
metadata
object | null Optional client metadata to set/update
status
string | null Optional session status update (completed or invalid)

Response 200

sessionId *
string Session identifier
status *
string Session status: pending, active, or failed
isAnomaly
boolean | null Whether any anomaly was detected (null if pending)
anomalyScore
number | null Overall anomaly score (null if pending)
anomalyConfidence
number | null Overall model confidence (null if pending)
isIncident
boolean | null Confirmed incident (null if pending)
isRecurring
boolean | null Recurring pattern (null if pending)
anomalies
object[] Detected anomalies (empty if pending)
category *
string Anomaly classification category
score *
number Anomaly severity score (0.0 = normal, 1.0 = extreme)
bucketRange
object | null Affected meter value range (bucket indexes, null when not available)
startUnit *
integer Start bucket index (0-based, maps to meter value position)
endUnit *
integer End bucket index (inclusive)
timeRange
object | null Affected time range (start/end timestamps, null if not available)
startTimestamp
string | null Start of the anomaly time range
endTimestamp
string | null End of the anomaly time range
confidence *
number Model confidence in this detection (0.0–1.0)
analyzedAt
string | null Analysis timestamp (null if pending)
socReconstructed
boolean Whether SoC was reconstructed by SORC model
message
string | null Informational message about the analysis status (e.g. why inference was not performed)
createdAt
string | null Session creation timestamp (null if unavailable)
Request JSON
{
  "meterValues": [
    {
      "measurand": "Energy.Active.Import.Register",
      "timestamp": "2026-02-27T10:00:00Z",
      "unit": "kWh",
      "value": 0
    },
    {
      "measurand": "Energy.Active.Import.Register",
      "timestamp": "2026-02-27T10:15:00Z",
      "unit": "kWh",
      "value": 5.5
    },
    {
      "measurand": "Energy.Active.Import.Register",
      "timestamp": "2026-02-27T10:30:00Z",
      "unit": "kWh",
      "value": 11.1
    }
  ]
}
Response · 200 JSON
{
  "analyzedAt": "2026-02-27T10:31:02Z",
  "anomalies": [
    {
      "bucketRange": {
        "endUnit": 7,
        "startUnit": 4
      },
      "category": "KWH_DECREASE",
      "confidence": 0.92,
      "score": 0.87
    }
  ],
  "anomalyConfidence": 0.92,
  "anomalyScore": 0.85,
  "isAnomaly": true,
  "isIncident": false,
  "isRecurring": true,
  "sessionId": "sess-abc-001",
  "status": "active"
}
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.

Headers

Authorization *
string Bearer token with embedded tenant context

Path Parameters

session_id *
string Session Id

Request Body

meterValues
object[] Meter readings to append to the session
timestamp *
string UTC timestamp of the meter reading (OCPP MeterValues timestamp)
value *
number Measured value in the specified unit (0 to 10,000,000,000)
measurand
string | null OCPP measurand type (e.g. Energy.Active.Import.Register, Power.Active.Import, SoC)
unit
string | null OCPP unit of measure (e.g. kWh, kW, Percent, A, V)
phase
string | null OCPP phase (e.g. L1, L2, L3, L1-N)
location
string | null OCPP meter value location (e.g. Outlet, EV, Cable)
reconstructed
boolean True if value was reconstructed by SORC model
metadata
object | null Optional client metadata to set/update
status
string | null Optional session status update (completed or invalid)

Response 200

sessionId *
string Session identifier
status *
string Session status: pending, active, or failed
isAnomaly
boolean | null Whether any anomaly was detected (null if pending)
anomalyScore
number | null Overall anomaly score (null if pending)
anomalyConfidence
number | null Overall model confidence (null if pending)
isIncident
boolean | null Confirmed incident (null if pending)
isRecurring
boolean | null Recurring pattern (null if pending)
anomalies
object[] Detected anomalies (empty if pending)
category *
string Anomaly classification category
score *
number Anomaly severity score (0.0 = normal, 1.0 = extreme)
bucketRange
object | null Affected meter value range (bucket indexes, null when not available)
startUnit *
integer Start bucket index (0-based, maps to meter value position)
endUnit *
integer End bucket index (inclusive)
timeRange
object | null Affected time range (start/end timestamps, null if not available)
startTimestamp
string | null Start of the anomaly time range
endTimestamp
string | null End of the anomaly time range
confidence *
number Model confidence in this detection (0.0–1.0)
analyzedAt
string | null Analysis timestamp (null if pending)
socReconstructed
boolean Whether SoC was reconstructed by SORC model
message
string | null Informational message about the analysis status (e.g. why inference was not performed)
createdAt
string | null Session creation timestamp (null if unavailable)
Request JSON
{
  "meterValues": [
    {
      "measurand": "Energy.Active.Import.Register",
      "timestamp": "2026-02-27T10:45:00Z",
      "unit": "kWh",
      "value": 16.5
    }
  ]
}
Response · 200 JSON
{
  "analyzedAt": "2026-02-27T10:31:02Z",
  "anomalies": [
    {
      "bucketRange": {
        "endUnit": 7,
        "startUnit": 4
      },
      "category": "KWH_DECREASE",
      "confidence": 0.92,
      "score": 0.87
    }
  ],
  "anomalyConfidence": 0.92,
  "anomalyScore": 0.85,
  "isAnomaly": true,
  "isIncident": false,
  "isRecurring": true,
  "sessionId": "sess-abc-001",
  "status": "active"
}
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 Id

Request Body

question *
string Natural language question about the session
lang
string | null Response language (e.g. 'en', 'pl'). If omitted, LLM responds in question language.

Response 200

sessionId *
string Session identifier
answer *
string Answer to the question about this session
Request JSON
{
  "lang": "en",
  "question": "Why did the SoC drop unexpectedly?"
}
Response · 200 JSON
{
  "sessionId": "example",
  "answer": "example"
}
GET /v1/sessions/{session_id}/explain

Get Session Explanation

Return cached LLM explanation if available.

Headers

Authorization *
string Bearer token with embedded tenant context

Path Parameters

session_id *
string Session Id

Query Parameters

lang
string Lang

Response 200

sessionId *
string Session identifier
explanation *
string Human-readable explanation of the detected anomalies
cached
boolean Whether this explanation was served from cache
Response · 200 JSON
{
  "sessionId": "example",
  "explanation": "example",
  "cached": false
}
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 Id

Request Body

Response 200

sessionId *
string Session identifier
explanation *
string Human-readable explanation of the detected anomalies
cached
boolean Whether this explanation was served from cache
Request JSON
{
  "lang": "en",
  "regenerate": false
}
Response · 200 JSON
{
  "sessionId": "example",
  "explanation": "example",
  "cached": false
}
POST /v1/sessions/batch

Submit Batch

Submit multiple sessions for batch analysis. Creates a batch record and enqueues background processing. Returns batch_id for polling via GET /sessions/batch/{batch_id}.

Headers

Authorization *
string Bearer token with embedded tenant context

Request Body

sessions *
object[] Sessions
sessionId *
string Client's unique session identifier. Used for upsert (find-or-create)
chargingStationId *
string Charging station identifier (EVSE location)
connectorId
string | null Connector identifier within the charging station
evseId
string | null EVSE identifier (EU standard)
meterValues
object[] Initial meter readings. Optional — session can be created empty and populated later via PATCH or PUT.
timestamp *
string UTC timestamp of the meter reading (OCPP MeterValues timestamp)
value *
number Measured value in the specified unit (0 to 10,000,000,000)
measurand
string | null OCPP measurand type (e.g. Energy.Active.Import.Register, Power.Active.Import, SoC)
unit
string | null OCPP unit of measure (e.g. kWh, kW, Percent, A, V)
phase
string | null OCPP phase (e.g. L1, L2, L3, L1-N)
location
string | null OCPP meter value location (e.g. Outlet, EV, Cable)
reconstructed
boolean True if value was reconstructed by SORC model
metadata
object | null Optional client metadata for the session
status
string | null Optional initial session status (active, pending, completed, or invalid)

Response 200

batchId *
string Batchid
totalSessions *
integer Totalsessions
status *
string Processing status of a batch upload.
Request JSON
{
  "sessions": [
    {
      "chargingStationId": "CP-NL-AMS-0042",
      "connectorId": "1",
      "meterValues": [
        {
          "measurand": "Energy.Active.Import.Register",
          "timestamp": "2026-02-27T10:00:00Z",
          "unit": "kWh",
          "value": 0
        },
        {
          "measurand": "Power.Active.Import",
          "timestamp": "2026-02-27T10:00:00Z",
          "unit": "kW",
          "value": 0
        },
        {
          "measurand": "SoC",
          "timestamp": "2026-02-27T10:00:00Z",
          "unit": "Percent",
          "value": 80
        },
        {
          "measurand": "Energy.Active.Import.Register",
          "timestamp": "2026-02-27T10:15:00Z",
          "unit": "kWh",
          "value": 5.5
        },
        {
          "measurand": "Power.Active.Import",
          "timestamp": "2026-02-27T10:15:00Z",
          "unit": "kW",
          "value": 22
        },
        {
          "measurand": "SoC",
          "timestamp": "2026-02-27T10:15:00Z",
          "unit": "Percent",
          "value": 65
        },
        {
          "measurand": "Energy.Active.Import.Register",
          "timestamp": "2026-02-27T10:30:00Z",
          "unit": "kWh",
          "value": 11.1
        },
        {
          "measurand": "Power.Active.Import",
          "timestamp": "2026-02-27T10:30:00Z",
          "unit": "kW",
          "value": 22
        },
        {
          "measurand": "SoC",
          "timestamp": "2026-02-27T10:30:00Z",
          "unit": "Percent",
          "value": 50
        }
      ],
      "sessionId": "sess-abc-001"
    }
  ]
}
Response · 200 JSON
{
  "batchId": "example",
  "totalSessions": 0,
  "status": "pending"
}
GET /v1/sessions/batch/{batch_id}

Get Batch Status

Get batch processing status and results (paginated).

Headers

Authorization *
string Bearer token with embedded tenant context

Path Parameters

batch_id *
string Batch Id

Query Parameters

page
integer Page
pageSize
integer Pagesize

Response 200

batchId *
string Batchid
status *
string Processing status of a batch upload.
totalSessions *
integer Totalsessions
processedSessions *
integer Processedsessions
failedSessions *
integer Failedsessions
results *
object[] Results
sessionId *
string Session identifier
status *
string Session status: pending, active, or failed
isAnomaly
boolean | null Whether any anomaly was detected (null if pending)
anomalyScore
number | null Overall anomaly score (null if pending)
anomalyConfidence
number | null Overall model confidence (null if pending)
isIncident
boolean | null Confirmed incident (null if pending)
isRecurring
boolean | null Recurring pattern (null if pending)
anomalies
object[] Detected anomalies (empty if pending)
category *
string Anomaly classification category
score *
number Anomaly severity score (0.0 = normal, 1.0 = extreme)
bucketRange
object | null Affected meter value range (bucket indexes, null when not available)
timeRange
object | null Affected time range (start/end timestamps, null if not available)
confidence *
number Model confidence in this detection (0.0–1.0)
analyzedAt
string | null Analysis timestamp (null if pending)
socReconstructed
boolean Whether SoC was reconstructed by SORC model
message
string | null Informational message about the analysis status (e.g. why inference was not performed)
createdAt
string | null Session creation timestamp (null if unavailable)
page *
integer Page
pageSize *
integer Pagesize
createdAt *
string Createdat
completedAt *
string | null Completedat
Response · 200 JSON
{
  "batchId": "example",
  "status": "pending",
  "totalSessions": 0,
  "processedSessions": 0,
  "failedSessions": 0,
  "results": [
    {
      "analyzedAt": "2026-02-27T10:31:02Z",
      "anomalies": [
        {
          "bucketRange": {
            "endUnit": 7,
            "startUnit": 4
          },
          "category": "KWH_DECREASE",
          "confidence": 0.92,
          "score": 0.87
        }
      ],
      "anomalyConfidence": 0.92,
      "anomalyScore": 0.85,
      "isAnomaly": true,
      "isIncident": false,
      "isRecurring": true,
      "sessionId": "sess-abc-001",
      "status": "active"
    }
  ],
  "page": 0,
  "pageSize": 0,
  "createdAt": "2026-01-01T00:00:00Z",
  "completedAt": "2026-01-01T00:00:00Z"
}
GET /v1/stations

List Stations

List tenant's charging stations with aggregated anomaly statistics. Reads from ``charging_stations_aggregated_mv`` materialized view (refreshed ~60 s) for pre-aggregated session/anomaly counts per station.

Headers

Authorization *
string Bearer token with embedded tenant context

Query Parameters

page
integer Page
pageSize
integer Pagesize

Response 200

content *
object[] Stations on the current page
id *
string Internal station identifier
ocppChargingStationId *
string Client-provided station identifier
chargingStationId *
string Client-provided station identifier (alias)
aiScore
number Highest anomaly score across all sessions
totalAnomalies *
integer Sessions with at least one detected anomaly
lastAnomalyDate
string | null Timestamp of the most recent anomaly detection (UTC)
pagination *
object Pagination metadata
totalCount *
integer Total number of items matching the query
page *
integer Current page number (1-based)
size *
integer Number of items per page
Response · 200 JSON
{
  "content": [
    {
      "aiScore": 0.91,
      "chargingStationId": "ST-NL-AMS-01",
      "id": "019c...",
      "lastAnomalyDate": "2026-02-27T09:45:00Z",
      "ocppChargingStationId": "ST-NL-AMS-01",
      "totalAnomalies": 7
    }
  ],
  "pagination": {
    "totalCount": 0,
    "page": 0,
    "size": 0
  }
}
GET /v1/stations/{charging_station_id}

Get Station Detail

Get station details: connectors, anomaly statistics, metadata. Uses ``charging_stations_aggregated_mv`` materialized view (refreshed ~60 s) for station-level aggregates.

Headers

Authorization *
string Bearer token with embedded tenant context

Path Parameters

charging_station_id *
string Charging Station Id

Response 200

chargingStationId *
string Client-provided station identifier
connectors *
object[] Connectors at this station with per-connector statistics
connectorId *
string Connector identifier within the charging point
totalSessions *
integer Total charging sessions on this connector
anomalousSessions *
integer Sessions with detected anomalies on this connector
totalSessions *
integer Total charging sessions at this station
anomalousSessions *
integer Sessions with at least one detected anomaly
metadata
object | null Station metadata (address, operator, etc.) as provided by client
Response · 200 JSON
{
  "anomalousSessions": 7,
  "chargingStationId": "ST-NL-AMS-01",
  "connectors": [
    {
      "anomalousSessions": 3,
      "connectorId": "1",
      "totalSessions": 80
    },
    {
      "anomalousSessions": 4,
      "connectorId": "2",
      "totalSessions": 62
    }
  ],
  "metadata": {
    "address": "Keizersgracht 100, Amsterdam",
    "operator": "FastNed"
  },
  "totalSessions": 142
}
GET /v1/stations/{charging_station_id}/anomalies

List Station Anomalies

Get station-level anomaly history (SHADE detection results).

Headers

Authorization *
string Bearer token with embedded tenant context

Path Parameters

charging_station_id *
string Charging Station Id

Query Parameters

page
integer Page
pageSize
integer Pagesize

Response 200

content *
object[] Anomaly records on the current page
inferenceId *
string Inference run identifier
isAnomaly *
boolean Always true (only anomaly buckets are returned)
anomalyScore *
number Anomaly score for this bucket
detectionDetails *
object Bucket details (bucket_index, start_minute)
analyzedAt *
string Absolute UTC timestamp of the anomaly bucket
pagination *
object Pagination metadata
totalCount *
integer Total number of items matching the query
page *
integer Current page number (1-based)
size *
integer Number of items per page
Response · 200 JSON
{
  "content": [
    {
      "inferenceId": "example",
      "isAnomaly": false,
      "anomalyScore": 0,
      "detectionDetails": {},
      "analyzedAt": "2026-01-01T00:00:00Z"
    }
  ],
  "pagination": {
    "totalCount": 0,
    "page": 0,
    "size": 0
  }
}
GET /v1/stations/{charging_station_id}/connectors

Get Station Connectors

Get station connectors with per-connector anomaly category breakdown.

Headers

Authorization *
string Bearer token with embedded tenant context

Path Parameters

charging_station_id *
string Charging Station Id

Response 200

chargingStationId *
string Station identifier
connectors *
object[] Connectors with anomaly statistics
connectorId *
string Connector identifier
totalSessions *
integer Total sessions on this connector
anomalousSessions *
integer Anomalous sessions on this connector
anomalyCategories *
object Anomaly count per category (e.g. KWH_DECREASE: 2)
Response · 200 JSON
{
  "chargingStationId": "example",
  "connectors": [
    {
      "anomalousSessions": 3,
      "anomalyCategories": {
        "ENERGY_PIT": 1,
        "KWH_DECREASE": 2
      },
      "connectorId": "1",
      "totalSessions": 80
    }
  ]
}
GET /v1/stations/{charging_station_id}/energy

Get Station Energy

Get per-connector and aggregated energy timelines with SHADE anomaly markers.

Headers

Authorization *
string Bearer token with embedded tenant context

Path Parameters

charging_station_id *
string Charging Station Id

Response 200

chargingStationId *
string Station identifier
energyDelivered *
number Total energy delivered in the window (kWh)
energyConsumptionStation *
object[] Aggregated energy timeline (sum of all connectors)
timestamp *
string Point in time (UTC)
energy *
number Cumulative energy delivered (kWh)
energyConsumptionConnectors *
object[] Per-connector energy timelines
connectorId *
string Connector identifier
energy *
object[] Energy timeline for this connector
timestamp *
string Point in time (UTC)
energy *
number Cumulative energy delivered (kWh)
anomalyOccurrences *
string[] ISO timestamps of SHADE anomaly buckets in the window
Response · 200 JSON
{
  "anomalyOccurrences": [
    "2026-04-05T22:30:00Z"
  ],
  "chargingStationId": "ST-NL-AMS-01",
  "energyConsumptionConnectors": [
    {
      "connectorId": "1",
      "energy": [
        {
          "energy": 5.1,
          "timestamp": "2026-04-05T17:00:00Z"
        }
      ]
    }
  ],
  "energyConsumptionStation": [
    {
      "energy": 0,
      "timestamp": "2026-04-05T17:00:00Z"
    },
    {
      "energy": 12.5,
      "timestamp": "2026-04-05T18:00:00Z"
    }
  ],
  "energyDelivered": 38
}
GET /v1/stations/{charging_station_id}/inference

Get Station Inference

Get latest SHADE inference result for a station.

Headers

Authorization *
string Bearer token with embedded tenant context

Path Parameters

charging_station_id *
string Charging Station Id

Response 200

chargingStationId *
string Analyzed station identifier
isAnomaly *
boolean Whether a station-level anomaly was detected
anomalyScore *
number Station anomaly severity score (SHADE reconstruction error)
detectionDetails *
object SHADE detection breakdown (anomaly type, affected period, metrics)
analyzedAt *
string Analysis completion timestamp (UTC)
Response · 200 JSON
{
  "analyzedAt": "2026-02-27T12:00:00Z",
  "anomalyScore": 0.72,
  "chargingStationId": "ST-NL-AMS-01",
  "detectionDetails": {
    "actual_energy_kwh": 980.2,
    "affected_period": "2026-02-27",
    "anomaly_type": "energy_drop",
    "expected_energy_kwh": 1200
  },
  "isAnomaly": true
}
GET /v1/stations/{charging_station_id}/shade-overview

Get Shade Overview

Get SHADE station overview: cumulative energy timeline with anomaly markers.

Headers

Authorization *
string Bearer token with embedded tenant context

Path Parameters

charging_station_id *
string Charging Station Id

Response 200

chargingStationId *
string Station identifier
dayScore *
number Overall day anomaly score
isAnomaly *
boolean Whether the station has active anomalies
energyTimeline *
object[] Cumulative kWh over the analysis day
timestamp *
string Point in time (UTC)
cumulativeKwh *
number Cumulative energy delivered up to this point (kWh)
anomalyMarkers *
object[] SHADE-detected anomaly time ranges
startMinute *
integer Minute offset from day start (0-1439)
timestamp *
string Absolute timestamp of the anomaly bucket (UTC)
score *
number Normalized anomaly score for this bucket (0-1)
analyzedAt *
string When the SHADE inference was run (UTC)
Response · 200 JSON
{
  "chargingStationId": "example",
  "dayScore": 0,
  "isAnomaly": false,
  "energyTimeline": [
    {
      "timestamp": "2026-01-01T00:00:00Z",
      "cumulativeKwh": 0
    }
  ],
  "anomalyMarkers": [
    {
      "startMinute": 0,
      "timestamp": "2026-01-01T00:00:00Z",
      "score": 0
    }
  ],
  "analyzedAt": "2026-01-01T00:00:00Z"
}
GET /v1/stations/lookup

Lookup Station Ids

Return distinct station IDs for filter dropdowns. Reads from the ``charging_stations`` base table (no MV dependency).

Headers

Authorization *
string Bearer token with embedded tenant context

Response 200

items *
string[] Distinct station identifiers for this tenant
Response · 200 JSON
{
  "items": [
    "example"
  ]
}
GET /v1/anomalies

List Anomalies

List individual anomalies with pagination and optional filters.

Headers

Authorization *
string Bearer token with embedded tenant context

Query Parameters

page
integer Page
pageSize
integer Pagesize
anomalyType
string[] Filter by anomaly category
connectorId
string Filter by connector
chargingSessionId
string Filter by session
chargingPointId
string[] Filter by charging point(s)
evseId
string[] Filter by EVSE(s)
occurrenceFrom
string Detection date lower bound
occurrenceTo
string Detection date upper bound
updateFrom
string Last update date lower bound
updateTo
string Last update date upper bound
sortByScore
string Sort by score: asc or desc
anomalyIssuesStatus
string[] Filter by issue status(es)
assignedTo
string[] Filter by assignee email(s) (use 'me' for current user)

Response 200

content *
object[] Anomaly items on the current page
id *
string Anomaly identifier
anomalyType *
string Display name of the anomaly type
anomalyTypeId *
string Internal category enum value (use in URLs)
aiRiskScore *
number AI-computed risk score (0.0–1.0)
connectorId *
string Connector identifier
chargingPointId *
string Charging point identifier
ocppChargingStationId *
string OCPP charging station identifier
evseId *
string EVSE identifier
chargingSessionId *
string Associated charging session identifier
dateOfAnomalyOccurrence *
string When the anomaly was first detected
dateOfLastUpdate *
string When the anomaly was last updated
issues
object[] Linked issues
id *
string Issue identifier
statusName *
string Current issue status (e.g. OPEN, RESOLVED)
assignedTo
string Email of the assignee (empty if unassigned)
pagination *
object Pagination metadata
totalCount *
integer Total number of items matching the query
page *
integer Current page number (1-based)
size *
integer Number of items per page
Response · 200 JSON
{
  "content": [
    {
      "id": "example",
      "anomalyType": "example",
      "anomalyTypeId": "example",
      "aiRiskScore": 0,
      "connectorId": "example",
      "chargingPointId": "example",
      "ocppChargingStationId": "example",
      "evseId": "example",
      "chargingSessionId": "example",
      "dateOfAnomalyOccurrence": "2026-01-01T00:00:00Z",
      "dateOfLastUpdate": "2026-01-01T00:00:00Z",
      "issues": [
        {}
      ]
    }
  ],
  "pagination": {
    "totalCount": 0,
    "page": 0,
    "size": 0
  }
}
GET /v1/anomalies/connectors

List Anomaly Connectors

List connectors with anomalies, aggregated by connector.

Headers

Authorization *
string Bearer token with embedded tenant context

Query Parameters

page
integer Page
pageSize
integer Pagesize
connectorId
string Filter by connector
anomalyType
string[] Filter by anomaly category
occurrenceFrom
string Detection date lower bound
occurrenceTo
string Detection date upper bound
sortBy
string Sort: count_asc, count_desc

Response 200

content *
object[] Connector anomaly items on the current page
id *
string Internal connector anomaly identifier
connectorId *
string Connector identifier
anomalyCount *
integer Number of anomalies on this connector
chargingPointId *
string Charging point identifier
evseId *
string EVSE identifier
detectionDate *
string When anomalies were first detected
lastUpdate *
string When connector anomalies were last updated
anomalyTypes
object[] Breakdown of anomaly types on this connector
type *
string Display name of the anomaly type
typeId *
string Internal category enum value (use in URLs)
count *
integer Number of occurrences
pagination *
object Pagination metadata
totalCount *
integer Total number of items matching the query
page *
integer Current page number (1-based)
size *
integer Number of items per page
Response · 200 JSON
{
  "content": [
    {
      "id": "example",
      "connectorId": "example",
      "anomalyCount": 0,
      "chargingPointId": "example",
      "evseId": "example",
      "detectionDate": "2026-01-01T00:00:00Z",
      "lastUpdate": "2026-01-01T00:00:00Z",
      "anomalyTypes": [
        {}
      ]
    }
  ],
  "pagination": {
    "totalCount": 0,
    "page": 0,
    "size": 0
  }
}
PUT /v1/anomalies/issues/{issue_id}

Update Issue

Update an anomaly issue status and/or assignment.

Headers

Authorization *
string Bearer token with embedded tenant context

Path Parameters

issue_id *
string Issue Id

Request Body

status *
string New issue status
assignedTo
string | null Email of the assignee

Response 200

id *
string Issue identifier
statusName *
string Current issue status (e.g. OPEN, RESOLVED)
assignedTo
string Email of the assignee (empty if unassigned)
Request JSON
{
  "status": "OPEN",
  "assignedTo": "example"
}
Response · 200 JSON
{
  "id": "example",
  "statusName": "example",
  "assignedTo": "example"
}
GET /v1/anomalies/sessions

List Anomaly Sessions

List sessions with anomalies, aggregated by session.

Headers

Authorization *
string Bearer token with embedded tenant context

Query Parameters

page
integer Page
pageSize
integer Pagesize
anomalyType
string[] Filter by anomaly category
chargingSessionId
string Filter by session
occurrenceFrom
string Detection date lower bound
occurrenceTo
string Detection date upper bound
sortBy
string Sort: score_asc, score_desc, count_desc

Response 200

content *
object[] Session anomaly items on the current page
id *
string Internal session anomaly identifier
chargingSessionId *
string Client-provided session identifier
anomalyCount *
integer Number of anomalies in this session
detectionDate *
string When anomalies were first detected
lastUpdate *
string When session anomalies were last updated
aiRiskScore *
number Highest AI risk score in this session
anomalyTypes
object[] Breakdown of anomaly types in this session
type *
string Display name of the anomaly type
typeId *
string Internal category enum value (use in URLs)
count *
integer Number of occurrences
pagination *
object Pagination metadata
totalCount *
integer Total number of items matching the query
page *
integer Current page number (1-based)
size *
integer Number of items per page
Response · 200 JSON
{
  "content": [
    {
      "id": "example",
      "chargingSessionId": "example",
      "anomalyCount": 0,
      "detectionDate": "2026-01-01T00:00:00Z",
      "lastUpdate": "2026-01-01T00:00:00Z",
      "aiRiskScore": 0,
      "anomalyTypes": [
        {}
      ]
    }
  ],
  "pagination": {
    "totalCount": 0,
    "page": 0,
    "size": 0
  }
}
GET /v1/anomalies/sessions/{session_id}/categories/{category_id}/details

Get Anomaly Detail

Get full anomaly detail for a specific session and category.

Headers

Authorization *
string Bearer token with embedded tenant context

Path Parameters

session_id *
string Session Id
category_id *
string Category Id

Response 200

sessionId *
string Charging session identifier
clientId *
string Tenant/client identifier
connectorId *
string Connector identifier
chargingPointId *
string Charging point identifier
ocppChargingStationId *
string OCPP charging station identifier
evseId *
string EVSE identifier
detectionLevel *
string Detection granularity level (e.g. connector)
meterValues
object[] Meter values for the session
timestamp *
string Meter reading timestamp
energy *
number Energy value (kWh)
stateOfCharge *
number State of charge (0.0–1.0)
power *
number Active power (kW)
soc *
number State of charge (alias, 0.0–1.0)
currentRiskScore *
integer Current risk score (0–100)
firstDetectionDate *
string When this anomaly was first detected
lastUpdateDate *
string When this anomaly was last updated
anomalyCategory *
object Anomaly category details
id *
string Category identifier
name *
string Display name of the anomaly category
description
string Human-readable description
maxScore *
number Maximum observed risk score for this category
riskScoreTimeline
object[] Risk score evolution over time
timestamp *
string Timestamp of the risk score observation
riskScore *
number Risk score at this point in time
anomalyPeriod *
object Time range of the anomaly
start *
string Start of the anomaly period
end *
string End of the anomaly period
issues
object[] Linked issues
id *
string Issue identifier
statusName *
string Current issue status (e.g. OPEN, RESOLVED)
assignedTo
string Email of the assignee (empty if unassigned)
Response · 200 JSON
{
  "sessionId": "example",
  "clientId": "example",
  "connectorId": "example",
  "chargingPointId": "example",
  "ocppChargingStationId": "example",
  "evseId": "example",
  "detectionLevel": "example",
  "meterValues": [
    {
      "timestamp": "2026-01-01T00:00:00Z",
      "energy": 0,
      "stateOfCharge": 0,
      "power": 0,
      "soc": 0
    }
  ],
  "currentRiskScore": 0,
  "firstDetectionDate": "2026-01-01T00:00:00Z",
  "lastUpdateDate": "2026-01-01T00:00:00Z",
  "anomalyCategory": {
    "id": "example",
    "name": "example",
    "description": "example",
    "maxScore": 0
  },
  "riskScoreTimeline": [
    {
      "timestamp": "2026-01-01T00:00:00Z",
      "riskScore": 0
    }
  ],
  "anomalyPeriod": {
    "start": "2026-01-01T00:00:00Z",
    "end": "2026-01-01T00:00:00Z"
  },
  "issues": [
    {
      "id": "example",
      "statusName": "example",
      "assignedTo": "example"
    }
  ]
}
GET /v1/models

List Models

List available models: base SaaS models + tenant's fine-tuned models.

Headers

Authorization *
string Bearer token with embedded tenant context

Response 200

models *
object[] Models
id *
string Id
name *
string Name
type *
string Type of ML model.
version *
string Version
isBase *
boolean Isbase
baseModel
string | null Basemodel
metrics *
object | null Metrics
status *
string Lifecycle status of an ML model.
createdAt *
string Createdat
Response · 200 JSON
{
  "models": [
    {
      "id": "example",
      "name": "example",
      "type": "csar_2",
      "version": "example",
      "isBase": false,
      "baseModel": "example",
      "metrics": {},
      "status": "active",
      "createdAt": "2026-01-01T00:00:00Z"
    }
  ]
}
GET /v1/models/{model_id}

Get Model Detail

Get model details: version, metrics, training date.

Headers

Authorization *
string Bearer token with embedded tenant context

Path Parameters

model_id *
string Model Id

Response 200

id *
string Id
name *
string Name
type *
string Type of ML model.
version *
string Version
isBase *
boolean Isbase
baseModel
string | null Basemodel
metrics *
object | null Metrics
status *
string Lifecycle status of an ML model.
createdAt *
string Createdat
s3Path
string | null S3Path
description
string | null Description
Response · 200 JSON
{
  "id": "example",
  "name": "example",
  "type": "csar_2",
  "version": "example",
  "isBase": false,
  "baseModel": "example",
  "metrics": {},
  "status": "active",
  "createdAt": "2026-01-01T00:00:00Z",
  "s3Path": "example",
  "description": "example"
}
POST /v1/models/fine-tune

Start Fine Tune

Trigger model fine-tuning. Client specifies base model and training data source (previously submitted sessions or direct upload).

Headers

Authorization *
string Bearer token with embedded tenant context

Request Body

baseModelId *
string Basemodelid
name *
string Name
trainingConfig
object Trainingconfig
dataSource *
object FineTuneDataSource
type *
string 'sessions' or 'upload'
sessionFilter
object | null Sessionfilter

Response 200

jobId *
string Jobid
status *
string Processing status of a fine-tuning job.
baseModelId *
string Basemodelid
createdAt *
string Createdat
Request JSON
{
  "baseModelId": "example",
  "name": "example",
  "trainingConfig": {},
  "dataSource": {
    "type": "example",
    "sessionFilter": {}
  }
}
Response · 200 JSON
{
  "jobId": "example",
  "status": "queued",
  "baseModelId": "example",
  "createdAt": "2026-01-01T00:00:00Z"
}
GET /v1/models/fine-tune/{job_id}

Get Fine Tune Status

Get fine-tuning job status and progress.

Headers

Authorization *
string Bearer token with embedded tenant context

Path Parameters

job_id *
string Job Id

Response 200

jobId *
string Jobid
status *
string Processing status of a fine-tuning job.
baseModelId *
string Basemodelid
resultModelId *
string | null Resultmodelid
config *
object Config
createdAt *
string Createdat
startedAt *
string | null Startedat
completedAt *
string | null Completedat
errorMessage *
string | null Errormessage
Response · 200 JSON
{
  "jobId": "example",
  "status": "queued",
  "baseModelId": "example",
  "resultModelId": "example",
  "config": {},
  "createdAt": "2026-01-01T00:00:00Z",
  "startedAt": "2026-01-01T00:00:00Z",
  "completedAt": "2026-01-01T00:00:00Z",
  "errorMessage": "example"
}
GET /v1/statistics

Get Statistics

Get tenant statistics summary: sessions, anomalies, stations. Queries charging session and inference tables to compute tenant-wide aggregated metrics.

Headers

Authorization *
string Bearer token with embedded tenant context

Response 200

activeAnomaliesCount *
integer Number of currently active (unresolved) anomalies
sessionsWithAnomaliesCount *
integer Sessions with at least one detected anomaly
connectorsWithAnomaliesCount *
integer Connectors with at least one detected anomaly
totalAnomaliesCount *
integer Total anomalies detected across all sessions
chargingStationsWithAnomaliesCount *
integer Charging stations with at least one anomalous session
uptimePercentage *
number Overall system uptime percentage
uptimeDelta *
number Change in uptime percentage compared to previous period
totalSessions *
integer Total charging sessions for this tenant
totalRevenue *
number Total revenue across all sessions
revenueAtRisk *
number Revenue associated with anomalous sessions
revenueLeakEstimate *
number Estimated revenue loss due to anomalies
Response · 200 JSON
{
  "activeAnomaliesCount": 12,
  "chargingStationsWithAnomaliesCount": 4,
  "connectorsWithAnomaliesCount": 8,
  "revenueAtRisk": 1200,
  "revenueLeakEstimate": 380.25,
  "sessionsWithAnomaliesCount": 47,
  "totalAnomaliesCount": 134,
  "totalRevenue": 45200.5,
  "totalSessions": 1250,
  "uptimeDelta": 0.3,
  "uptimePercentage": 98.5
}
GET /v1/webhooks

List Webhooks

List tenant's webhooks (secrets are not included).

Headers

Authorization *
string Bearer token with embedded tenant context

Response 200

content *
object[] Content
id *
string Id
url *
string Url
events *
string[] Events
description
string | null Description
enabled *
boolean Enabled
failureCount *
integer Failurecount
disabledAt
string | null Disabledat
createdAt
string | null Createdat
updatedAt
string | null Updatedat
pagination *
object Pagination metadata returned alongside list content.
totalCount *
integer Total number of items matching the query
page *
integer Current page number (1-based)
size *
integer Number of items per page
Response · 200 JSON
{
  "content": [
    {
      "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "url": "example",
      "events": [
        {}
      ],
      "description": "example",
      "enabled": false,
      "failureCount": 0,
      "disabledAt": "2026-01-01T00:00:00Z",
      "createdAt": "2026-01-01T00:00:00Z",
      "updatedAt": "2026-01-01T00:00:00Z"
    }
  ],
  "pagination": {
    "totalCount": 0,
    "page": 0,
    "size": 0
  }
}
POST /v1/webhooks

Create Webhook

Register a new webhook. Secret is returned only once.

Headers

Authorization *
string Bearer token with embedded tenant context

Request Body

url *
string Webhook target URL (must be HTTPS)
events *
string[] Event types to subscribe to
description
string | null Optional description

Response 200

id *
string Id
url *
string Url
events *
string[] Events
description
string | null Description
enabled *
boolean Enabled
failureCount *
integer Failurecount
disabledAt
string | null Disabledat
createdAt
string | null Createdat
updatedAt
string | null Updatedat
secret *
string Secret
Request JSON
{
  "url": "example",
  "events": [
    "example"
  ],
  "description": "example"
}
Response · 200 JSON
{
  "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "url": "example",
  "events": [
    "example"
  ],
  "description": "example",
  "enabled": false,
  "failureCount": 0,
  "disabledAt": "2026-01-01T00:00:00Z",
  "createdAt": "2026-01-01T00:00:00Z",
  "updatedAt": "2026-01-01T00:00:00Z",
  "secret": "example"
}
GET /v1/webhooks/{webhook_id}

Get Webhook

Get webhook details with recent delivery history.

Headers

Authorization *
string Bearer token with embedded tenant context

Path Parameters

webhook_id *
string Webhook Id

Response 200

id *
string Id
url *
string Url
events *
string[] Events
description
string | null Description
enabled *
boolean Enabled
failureCount *
integer Failurecount
disabledAt
string | null Disabledat
createdAt
string | null Createdat
updatedAt
string | null Updatedat
recentDeliveries
object[] Recentdeliveries
id *
string Id
eventType *
string Eventtype
status *
string Status
httpStatus
integer | null Httpstatus
attemptCount *
integer Attemptcount
createdAt
string | null Createdat
completedAt
string | null Completedat
Response · 200 JSON
{
  "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "url": "example",
  "events": [
    "example"
  ],
  "description": "example",
  "enabled": false,
  "failureCount": 0,
  "disabledAt": "2026-01-01T00:00:00Z",
  "createdAt": "2026-01-01T00:00:00Z",
  "updatedAt": "2026-01-01T00:00:00Z",
  "recentDeliveries": [
    {
      "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "eventType": "example",
      "status": "example",
      "httpStatus": 0,
      "attemptCount": 0,
      "createdAt": "2026-01-01T00:00:00Z",
      "completedAt": "2026-01-01T00:00:00Z"
    }
  ]
}
PATCH /v1/webhooks/{webhook_id}

Update Webhook

Update webhook URL, events, or enabled state.

Headers

Authorization *
string Bearer token with embedded tenant context

Path Parameters

webhook_id *
string Webhook Id

Request Body

url
string | null Url
events
string[] | null Events
description
string | null Description
enabled
boolean | null Enabled

Response 200

id *
string Id
url *
string Url
events *
string[] Events
description
string | null Description
enabled *
boolean Enabled
failureCount *
integer Failurecount
disabledAt
string | null Disabledat
createdAt
string | null Createdat
updatedAt
string | null Updatedat
Request JSON
{
  "url": "example",
  "events": [
    "example"
  ],
  "description": "example",
  "enabled": false
}
Response · 200 JSON
{
  "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "url": "example",
  "events": [
    "example"
  ],
  "description": "example",
  "enabled": false,
  "failureCount": 0,
  "disabledAt": "2026-01-01T00:00:00Z",
  "createdAt": "2026-01-01T00:00:00Z",
  "updatedAt": "2026-01-01T00:00:00Z"
}
DELETE /v1/webhooks/{webhook_id}

Delete Webhook

Delete a webhook and all its delivery records.

Headers

Authorization *
string Bearer token with embedded tenant context

Path Parameters

webhook_id *
string Webhook Id

Response 200

Response · 200 JSON
POST /v1/webhooks/{webhook_id}/rotate-secret

Rotate Secret

Rotate webhook secret. Old secret valid for 24h grace period.

Headers

Authorization *
string Bearer token with embedded tenant context

Path Parameters

webhook_id *
string Webhook Id

Response 200

id *
string Id
url *
string Url
events *
string[] Events
description
string | null Description
enabled *
boolean Enabled
failureCount *
integer Failurecount
disabledAt
string | null Disabledat
createdAt
string | null Createdat
updatedAt
string | null Updatedat
secret *
string Secret
Response · 200 JSON
{
  "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "url": "example",
  "events": [
    "example"
  ],
  "description": "example",
  "enabled": false,
  "failureCount": 0,
  "disabledAt": "2026-01-01T00:00:00Z",
  "createdAt": "2026-01-01T00:00:00Z",
  "updatedAt": "2026-01-01T00:00:00Z",
  "secret": "example"
}
POST /v1/webhooks/{webhook_id}/test

Test Webhook

Send a test event to the webhook URL.

Headers

Authorization *
string Bearer token with embedded tenant context

Path Parameters

webhook_id *
string Webhook Id

Response 200

Response · 200 JSON
{}
GET /v1/api-keys

List Api Keys

List all API keys for the current tenant.

Headers

Authorization *
string Bearer token with embedded tenant context

Response 200

items *
object[] Items
id *
string Id
name *
string Name
description *
string Description
tenantId *
string Tenantid
createdAt *
string Createdat
expiresAt *
string Expiresat
lastUsedAt *
string | null Lastusedat
revokedAt *
string | null Revokedat
Response · 200 JSON
{
  "items": [
    {
      "id": "example",
      "name": "example",
      "description": "example",
      "tenantId": "example",
      "createdAt": "2026-01-01T00:00:00Z",
      "expiresAt": "2026-01-01T00:00:00Z",
      "lastUsedAt": "2026-01-01T00:00:00Z",
      "revokedAt": "2026-01-01T00:00:00Z"
    }
  ]
}
POST /v1/api-keys

Create Api Key

Create a new API key for the tenant. Returns the full key only once.

Headers

Authorization *
string Bearer token with embedded tenant context

Request Body

name *
string Name
description
string Description

Response 200

id *
string Id
name *
string Name
key *
string Key
tenantId *
string Tenantid
expiresAt *
string Expiresat
createdAt *
string Createdat
Request JSON
{
  "name": "example",
  "description": "example"
}
Response · 200 JSON
{
  "id": "example",
  "name": "example",
  "key": "example",
  "tenantId": "example",
  "expiresAt": "2026-01-01T00:00:00Z",
  "createdAt": "2026-01-01T00:00:00Z"
}
DELETE /v1/api-keys/{key_id}

Revoke Api Key

Revoke an API key.

Headers

Authorization *
string Bearer token with embedded tenant context

Path Parameters

key_id *
string Key Id

Response 200

Response · 200 JSON
GET /v1/organization

Get Organization

Get organization details for the current tenant.

Headers

Authorization *
string Bearer token with embedded tenant context

Response 200

id *
string Id
tenantId *
string Tenantid
name *
string Name
phone
string | null Phone
address
string | null Address
taxIdType
string | null Taxidtype
taxIdValue
string | null Taxidvalue
createdAt *
string Createdat
updatedAt
string | null Updatedat
Response · 200 JSON
{
  "id": "example",
  "tenantId": "example",
  "name": "example",
  "phone": "example",
  "address": "example",
  "taxIdType": "example",
  "taxIdValue": "example",
  "createdAt": "2026-01-01T00:00:00Z",
  "updatedAt": "2026-01-01T00:00:00Z"
}
PUT /v1/organization

Update Organization

Create or update organization details. Admin only. For open signup users (tenant_id=None): provisions org, billing, subscription, and tenant mapping, then refreshes session claims. For existing tenants: updates org fields. On first creation, also provisions billing.

Headers

Authorization *
string Bearer token with embedded tenant context

Request Body

name *
string Name
phone
string | null Phone
address
string | null Address
taxIdType
string | null Taxidtype
taxIdValue
string | null Taxidvalue

Response 200

id *
string Id
tenantId *
string Tenantid
name *
string Name
phone
string | null Phone
address
string | null Address
taxIdType
string | null Taxidtype
taxIdValue
string | null Taxidvalue
createdAt *
string Createdat
updatedAt
string | null Updatedat
Request JSON
{
  "name": "example",
  "phone": "example",
  "address": "example",
  "taxIdType": "example",
  "taxIdValue": "example"
}
Response · 200 JSON
{
  "id": "example",
  "tenantId": "example",
  "name": "example",
  "phone": "example",
  "address": "example",
  "taxIdType": "example",
  "taxIdValue": "example",
  "createdAt": "2026-01-01T00:00:00Z",
  "updatedAt": "2026-01-01T00:00:00Z"
}
GET /v1/members

List Members

List all members and pending invitations for the current tenant. Pending invitations are only visible to admin and super_admin callers.

Headers

Authorization *
string Bearer token with embedded tenant context

Response 200

members *
object[] Members
userId *
string Userid
email *
string Email
role *
string Role
status *
string Status
joinedAt
string | null Joinedat
invitedAt
string | null Invitedat
expiresAt
string | null Expiresat
invitedBy
string | null Invitedby
invitationId
string | null Invitationid
Response · 200 JSON
{
  "members": [
    {
      "userId": "example",
      "email": "example",
      "role": "example",
      "status": "active",
      "joinedAt": "2026-01-01T00:00:00Z",
      "invitedAt": "2026-01-01T00:00:00Z",
      "expiresAt": "2026-01-01T00:00:00Z",
      "invitedBy": "example",
      "invitationId": "example"
    }
  ]
}
DELETE /v1/members/{user_id}

Remove Member

Remove a member from the tenant. Admin only.

Headers

Authorization *
string Bearer token with embedded tenant context

Path Parameters

user_id *
string User Id

Response 200

Response · 200 JSON
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.