/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 * Query Parameters
page pageSize chargingStationId evseId isAnomaly minScore minConfidence dateFrom dateTo Response 200
content * sessionId * chargingStationId * isAnomaly * anomalyScore * anomalyCount * status * createdAt * lastAnalyzedAt * pagination * totalCount * page * size * {
"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
}
} /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 * Request Body
sessionId * chargingStationId * connectorId evseId meterValues timestamp * value * measurand unit phase location reconstructed metadata status Response 200
sessionId * status * isAnomaly anomalyScore anomalyConfidence isIncident isRecurring anomalies category * score * bucketRange startUnit * endUnit * timeRange startTimestamp endTimestamp confidence * analyzedAt socReconstructed message createdAt {
"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"
} {
"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"
} /v1/sessions/{session_id} Get Session Detail
Get full session details including meter values, analysis result, and anomaly categories.
Headers
Authorization * Path Parameters
session_id * Response 200
sessionId * status * isAnomaly anomalyScore anomalyConfidence isIncident isRecurring anomalies category * score * bucketRange startUnit * endUnit * timeRange startTimestamp endTimestamp confidence * analyzedAt socReconstructed message createdAt * meterValues * timestamp * value * measurand unit phase location reconstructed {
"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"
} /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 * Path Parameters
session_id * Request Body
meterValues * timestamp * value * measurand unit phase location reconstructed metadata status Response 200
sessionId * status * isAnomaly anomalyScore anomalyConfidence isIncident isRecurring anomalies category * score * bucketRange startUnit * endUnit * timeRange startTimestamp endTimestamp confidence * analyzedAt socReconstructed message createdAt {
"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
}
]
} {
"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"
} /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 * Path Parameters
session_id * Request Body
meterValues timestamp * value * measurand unit phase location reconstructed metadata status Response 200
sessionId * status * isAnomaly anomalyScore anomalyConfidence isIncident isRecurring anomalies category * score * bucketRange startUnit * endUnit * timeRange startTimestamp endTimestamp confidence * analyzedAt socReconstructed message createdAt {
"meterValues": [
{
"measurand": "Energy.Active.Import.Register",
"timestamp": "2026-02-27T10:45:00Z",
"unit": "kWh",
"value": 16.5
}
]
} {
"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"
} /v1/sessions/{session_id}/ask Ask Session
Ask a natural language question about a specific session.
Headers
Authorization * Path Parameters
session_id * Request Body
question * lang Response 200
sessionId * answer * {
"lang": "en",
"question": "Why did the SoC drop unexpectedly?"
} {
"sessionId": "example",
"answer": "example"
} /v1/sessions/{session_id}/explain Get Session Explanation
Return cached LLM explanation if available.
Headers
Authorization * Path Parameters
session_id * Query Parameters
lang Response 200
sessionId * explanation * cached {
"sessionId": "example",
"explanation": "example",
"cached": false
} /v1/sessions/{session_id}/explain Explain Session
Get an LLM-generated explanation of session anomalies.
Headers
Authorization * Path Parameters
session_id * Request Body
Response 200
sessionId * explanation * cached {
"lang": "en",
"regenerate": false
} {
"sessionId": "example",
"explanation": "example",
"cached": false
} /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 * Request Body
sessions * sessionId * chargingStationId * connectorId evseId meterValues timestamp * value * measurand unit phase location reconstructed metadata status Response 200
batchId * totalSessions * status * {
"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"
}
]
} {
"batchId": "example",
"totalSessions": 0,
"status": "pending"
} /v1/sessions/batch/{batch_id} Get Batch Status
Get batch processing status and results (paginated).
Headers
Authorization * Path Parameters
batch_id * Query Parameters
page pageSize Response 200
batchId * status * totalSessions * processedSessions * failedSessions * results * sessionId * status * isAnomaly anomalyScore anomalyConfidence isIncident isRecurring anomalies category * score * bucketRange timeRange confidence * analyzedAt socReconstructed message createdAt page * pageSize * createdAt * completedAt * {
"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"
} /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 * Query Parameters
page pageSize Response 200
content * id * ocppChargingStationId * chargingStationId * aiScore totalAnomalies * lastAnomalyDate pagination * totalCount * page * size * {
"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
}
} /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 * Path Parameters
charging_station_id * Response 200
chargingStationId * connectors * connectorId * totalSessions * anomalousSessions * totalSessions * anomalousSessions * metadata {
"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
} /v1/stations/{charging_station_id}/anomalies List Station Anomalies
Get station-level anomaly history (SHADE detection results).
Headers
Authorization * Path Parameters
charging_station_id * Query Parameters
page pageSize Response 200
content * inferenceId * isAnomaly * anomalyScore * detectionDetails * analyzedAt * pagination * totalCount * page * size * {
"content": [
{
"inferenceId": "example",
"isAnomaly": false,
"anomalyScore": 0,
"detectionDetails": {},
"analyzedAt": "2026-01-01T00:00:00Z"
}
],
"pagination": {
"totalCount": 0,
"page": 0,
"size": 0
}
} /v1/stations/{charging_station_id}/connectors Get Station Connectors
Get station connectors with per-connector anomaly category breakdown.
Headers
Authorization * Path Parameters
charging_station_id * Response 200
chargingStationId * connectors * connectorId * totalSessions * anomalousSessions * anomalyCategories * {
"chargingStationId": "example",
"connectors": [
{
"anomalousSessions": 3,
"anomalyCategories": {
"ENERGY_PIT": 1,
"KWH_DECREASE": 2
},
"connectorId": "1",
"totalSessions": 80
}
]
} /v1/stations/{charging_station_id}/energy Get Station Energy
Get per-connector and aggregated energy timelines with SHADE anomaly markers.
Headers
Authorization * Path Parameters
charging_station_id * Response 200
chargingStationId * energyDelivered * energyConsumptionStation * timestamp * energy * energyConsumptionConnectors * connectorId * energy * timestamp * energy * anomalyOccurrences * {
"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
} /v1/stations/{charging_station_id}/inference Get Station Inference
Get latest SHADE inference result for a station.
Headers
Authorization * Path Parameters
charging_station_id * Response 200
chargingStationId * isAnomaly * anomalyScore * detectionDetails * analyzedAt * {
"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
} /v1/stations/{charging_station_id}/shade-overview Get Shade Overview
Get SHADE station overview: cumulative energy timeline with anomaly markers.
Headers
Authorization * Path Parameters
charging_station_id * Response 200
chargingStationId * dayScore * isAnomaly * energyTimeline * timestamp * cumulativeKwh * anomalyMarkers * startMinute * timestamp * score * analyzedAt * {
"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"
} /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 * Response 200
items * {
"items": [
"example"
]
} /v1/anomalies List Anomalies
List individual anomalies with pagination and optional filters.
Headers
Authorization * Query Parameters
page pageSize anomalyType connectorId chargingSessionId chargingPointId evseId occurrenceFrom occurrenceTo updateFrom updateTo sortByScore anomalyIssuesStatus assignedTo Response 200
content * id * anomalyType * anomalyTypeId * aiRiskScore * connectorId * chargingPointId * ocppChargingStationId * evseId * chargingSessionId * dateOfAnomalyOccurrence * dateOfLastUpdate * issues id * statusName * assignedTo pagination * totalCount * page * size * {
"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
}
} /v1/anomalies/connectors List Anomaly Connectors
List connectors with anomalies, aggregated by connector.
Headers
Authorization * Query Parameters
page pageSize connectorId anomalyType occurrenceFrom occurrenceTo sortBy Response 200
content * id * connectorId * anomalyCount * chargingPointId * evseId * detectionDate * lastUpdate * anomalyTypes type * typeId * count * pagination * totalCount * page * size * {
"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
}
} /v1/anomalies/issues/{issue_id} Update Issue
Update an anomaly issue status and/or assignment.
Headers
Authorization * Path Parameters
issue_id * Request Body
status * assignedTo Response 200
id * statusName * assignedTo {
"status": "OPEN",
"assignedTo": "example"
} {
"id": "example",
"statusName": "example",
"assignedTo": "example"
} /v1/anomalies/sessions List Anomaly Sessions
List sessions with anomalies, aggregated by session.
Headers
Authorization * Query Parameters
page pageSize anomalyType chargingSessionId occurrenceFrom occurrenceTo sortBy Response 200
content * id * chargingSessionId * anomalyCount * detectionDate * lastUpdate * aiRiskScore * anomalyTypes type * typeId * count * pagination * totalCount * page * size * {
"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
}
} /v1/anomalies/sessions/{session_id}/categories/{category_id}/details Get Anomaly Detail
Get full anomaly detail for a specific session and category.
Headers
Authorization * Path Parameters
session_id * category_id * Response 200
sessionId * clientId * connectorId * chargingPointId * ocppChargingStationId * evseId * detectionLevel * meterValues timestamp * energy * stateOfCharge * power * soc * currentRiskScore * firstDetectionDate * lastUpdateDate * anomalyCategory * id * name * description maxScore * riskScoreTimeline timestamp * riskScore * anomalyPeriod * start * end * issues id * statusName * assignedTo {
"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"
}
]
} /v1/models List Models
List available models: base SaaS models + tenant's fine-tuned models.
Headers
Authorization * Response 200
models * id * name * type * version * isBase * baseModel metrics * status * createdAt * {
"models": [
{
"id": "example",
"name": "example",
"type": "csar_2",
"version": "example",
"isBase": false,
"baseModel": "example",
"metrics": {},
"status": "active",
"createdAt": "2026-01-01T00:00:00Z"
}
]
} /v1/models/{model_id} Get Model Detail
Get model details: version, metrics, training date.
Headers
Authorization * Path Parameters
model_id * Response 200
id * name * type * version * isBase * baseModel metrics * status * createdAt * s3Path description {
"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"
} /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 * Request Body
baseModelId * name * trainingConfig dataSource * type * sessionFilter Response 200
jobId * status * baseModelId * createdAt * {
"baseModelId": "example",
"name": "example",
"trainingConfig": {},
"dataSource": {
"type": "example",
"sessionFilter": {}
}
} {
"jobId": "example",
"status": "queued",
"baseModelId": "example",
"createdAt": "2026-01-01T00:00:00Z"
} /v1/models/fine-tune/{job_id} Get Fine Tune Status
Get fine-tuning job status and progress.
Headers
Authorization * Path Parameters
job_id * Response 200
jobId * status * baseModelId * resultModelId * config * createdAt * startedAt * completedAt * errorMessage * {
"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"
} /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 * Response 200
activeAnomaliesCount * sessionsWithAnomaliesCount * connectorsWithAnomaliesCount * totalAnomaliesCount * chargingStationsWithAnomaliesCount * uptimePercentage * uptimeDelta * totalSessions * totalRevenue * revenueAtRisk * revenueLeakEstimate * {
"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
} /v1/webhooks List Webhooks
List tenant's webhooks (secrets are not included).
Headers
Authorization * Response 200
content * id * url * events * description enabled * failureCount * disabledAt createdAt updatedAt pagination * totalCount * page * size * {
"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
}
} /v1/webhooks Create Webhook
Register a new webhook. Secret is returned only once.
Headers
Authorization * Request Body
url * events * description Response 200
id * url * events * description enabled * failureCount * disabledAt createdAt updatedAt secret * {
"url": "example",
"events": [
"example"
],
"description": "example"
} {
"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"
} /v1/webhooks/{webhook_id} Get Webhook
Get webhook details with recent delivery history.
Headers
Authorization * Path Parameters
webhook_id * Response 200
id * url * events * description enabled * failureCount * disabledAt createdAt updatedAt recentDeliveries id * eventType * status * httpStatus attemptCount * createdAt completedAt {
"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"
}
]
} /v1/webhooks/{webhook_id} Update Webhook
Update webhook URL, events, or enabled state.
Headers
Authorization * Path Parameters
webhook_id * Request Body
url events description enabled Response 200
id * url * events * description enabled * failureCount * disabledAt createdAt updatedAt {
"url": "example",
"events": [
"example"
],
"description": "example",
"enabled": false
} {
"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"
} /v1/webhooks/{webhook_id} Delete Webhook
Delete a webhook and all its delivery records.
Headers
Authorization * Path Parameters
webhook_id * Response 200
/v1/webhooks/{webhook_id}/rotate-secret Rotate Secret
Rotate webhook secret. Old secret valid for 24h grace period.
Headers
Authorization * Path Parameters
webhook_id * Response 200
id * url * events * description enabled * failureCount * disabledAt createdAt updatedAt secret * {
"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"
} /v1/webhooks/{webhook_id}/test Test Webhook
Send a test event to the webhook URL.
Headers
Authorization * Path Parameters
webhook_id * Response 200
{} /v1/api-keys List Api Keys
List all API keys for the current tenant.
Headers
Authorization * Response 200
items * id * name * description * tenantId * createdAt * expiresAt * lastUsedAt * revokedAt * {
"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"
}
]
} /v1/api-keys Create Api Key
Create a new API key for the tenant. Returns the full key only once.
Headers
Authorization * Request Body
name * description Response 200
id * name * key * tenantId * expiresAt * createdAt * {
"name": "example",
"description": "example"
} {
"id": "example",
"name": "example",
"key": "example",
"tenantId": "example",
"expiresAt": "2026-01-01T00:00:00Z",
"createdAt": "2026-01-01T00:00:00Z"
} /v1/api-keys/{key_id} Revoke Api Key
Revoke an API key.
Headers
Authorization * Path Parameters
key_id * Response 200
/v1/organization Get Organization
Get organization details for the current tenant.
Headers
Authorization * Response 200
id * tenantId * name * phone address taxIdType taxIdValue createdAt * updatedAt {
"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"
} /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 * Request Body
name * phone address taxIdType taxIdValue Response 200
id * tenantId * name * phone address taxIdType taxIdValue createdAt * updatedAt {
"name": "example",
"phone": "example",
"address": "example",
"taxIdType": "example",
"taxIdValue": "example"
} {
"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"
} /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 * Response 200
members * userId * email * role * status * joinedAt invitedAt expiresAt invitedBy invitationId {
"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"
}
]
} /v1/members/{user_id} Remove Member
Remove a member from the tenant. Admin only.
Headers
Authorization * Path Parameters
user_id * Response 200