REST Endpoints¶
Detailed documentation for all REST API endpoints.
Authentication required
All endpoints require an X-API-Key header. GET endpoints need readAccess; POST/PUT/DELETE endpoints need writeAccess. See API Key Management.
API Key Endpoints¶
List API Keys¶
Requires readAccess.
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
active_only |
boolean | Filter to active keys only (default: false) |
Response:
[
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"appName": "my-app",
"isActive": true,
"readAccess": true,
"writeAccess": true,
"createdAt": "2026-03-27T10:00:00Z",
"updatedAt": "2026-03-27T10:00:00Z"
}
]
Create API Key¶
Requires writeAccess.
Request Body:
Response:
{
"id": "660e8400-e29b-41d4-a716-446655440001",
"appName": "new-client",
"token": "sq_abc123...",
"isActive": true,
"readAccess": true,
"writeAccess": false,
"createdAt": "2026-03-27T12:00:00Z",
"updatedAt": "2026-03-27T12:00:00Z"
}
Warning
The token field only appears in the creation response. It cannot be retrieved again.
Deactivate API Key¶
Requires writeAccess. Soft-deletes the key (sets isActive=false) and returns the updated ApiKeyDTO.
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
id |
UUID | API key ID |
Count API Keys¶
Requires readAccess. Returns a bare integer.
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
active_only |
boolean | Count only active keys (default: false) |
PV Endpoints¶
All request/response fields use camelCase. id in paths is a UUID.
Search PVs¶
Non-paginated search by name (backward-compatibility helper; returns up to 1000 rows).
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
pvName |
string | Search term |
Search PVs (Paginated)¶
Search PVs with cursor-based pagination and tag filtering.
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
pvName |
string | Search term (matches address or description) |
pageSize |
integer | Page size (1-1000, default 100) |
continuationToken |
string | Opaque cursor returned by the previous response |
tagFilters |
string | JSON object: {groupId: [tagId1, tagId2], ...} — returns PVs matching (any tag in group A) AND (any tag in group B) |
Response payload:
{
"results": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"setpointAddress": "QUAD:LI21:201:BDES",
"readbackAddress": "QUAD:LI21:201:BACT",
"description": "Quadrupole magnet",
"absTolerance": 0.01,
"relTolerance": 0.001,
"readOnly": false,
"tags": [{"id": "...", "name": "Magnet"}]
}
],
"continuationToken": "eyJpZCI6IjU1MGU4...",
"hasMore": true
}
Filtered Search (with optional live values)¶
Server-side filtered search that optionally returns live values from the Redis cache alongside metadata.
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
q |
string | Text search |
devices |
array | Filter by device name(s) |
tags |
array | Filter by tag IDs |
limit |
integer | Max results (≤1000, default 100) |
offset |
integer | Pagination offset |
include_live_values |
boolean | Include Redis cache values in liveValues |
List Devices¶
Returns the distinct set of device names currently in use.
Live Values (GET / POST)¶
Fetch cached live values from Redis. Use POST with body {"pv_names": ["..."]} when the list is too long for a query string.
All Live Values¶
Every PV value currently in the cache (for initial table load).
Cache Status¶
Returns cached PV count and Redis connectivity status.
Create PV¶
Create a new PV. At least one of setpointAddress, readbackAddress, or configAddress must be provided.
Request Body:
{
"setpointAddress": "TEST:PV:SETPOINT",
"readbackAddress": "TEST:PV:READBACK",
"configAddress": null,
"device": "Test Device",
"description": "Test PV for documentation",
"absTolerance": 0.01,
"relTolerance": 0.001,
"readOnly": false,
"tags": ["550e8400-e29b-41d4-a716-446655440000"]
}
Bulk Create PVs¶
Create multiple PVs in one request. Body is a JSON array of NewPVElementDTO objects (same shape as POST /v1/pvs).
Update PV¶
Partially update a PV. Unspecified fields are left unchanged.
Request Body:
{
"description": "Updated description",
"absTolerance": 0.02,
"relTolerance": null,
"readOnly": true,
"tags": ["tag-id-1", "tag-id-2"]
}
Delete PV¶
Snapshot Endpoints¶
List Snapshots¶
List all snapshots, optionally filtered.
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
title |
string | Filter by title substring |
tags |
array | Filter by tag IDs (returns snapshots containing PVs with any of these tags) |
Response is an array of SnapshotSummaryDTO (id, title, description, createdDate, createdBy, pvCount).
Create Snapshot¶
Create a new snapshot. Captures the current state of all configured PVs.
Request Body:
| Field | Type | Description |
|---|---|---|
title |
string | Snapshot name (required, 1-255 chars) |
description |
string | Optional description |
Query Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
async |
boolean | true |
Return a job ID immediately and run in the background |
use_cache |
boolean | true |
true reads from Redis cache (<5s for 40K PVs); false reads directly from EPICS (30-60s) |
use_arq |
boolean | true |
true uses the Arq persistent queue; false uses FastAPI BackgroundTasks (lost on restart) |
Response (async=true):
{
"jobId": "770e8400-e29b-41d4-a716-446655440002",
"message": "Snapshot creation queued for 'Morning snapshot' (from cache)"
}
Poll /v1/jobs/{jobId} for progress and completion. With async=false, the endpoint blocks and returns the completed SnapshotDTO inline (may time out on large PV sets).
Get Snapshot¶
Get a snapshot with its PV values.
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
limit |
integer | Limit number of PV values returned |
offset |
integer | Offset for pagination (default 0) |
Returns SnapshotDTO with pvValues: PVValueDTO[]. Each PVValueDTO has pvId, pvName, setpointName, readbackName, setpointValue (EpicsValueDTO), readbackValue (EpicsValueDTO), tags.
Update Snapshot¶
Update snapshot title and/or description.
Request Body:
Both fields are optional (nullable).
Delete Snapshot¶
Delete a snapshot and all its values.
Restore Snapshot¶
Restore snapshot values to EPICS.
Request Body (optional):
If omitted (or pvIds is null), all PVs in the snapshot are restored.
Query Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
async |
boolean | true |
Return a job ID and run in the background |
use_arq |
boolean | true |
true uses Arq; false uses FastAPI BackgroundTasks |
Response (async=true):
With async=false, returns a RestoreResultDTO ({ "totalPVs": ..., "successCount": ..., "failureCount": ..., "failures": [...] }).
Compare Snapshots¶
Compare two snapshots. PV-level tolerance (absTolerance / relTolerance on the PV record) decides whether each pair is within tolerance.
Response:
{
"snapshot1Id": "...",
"snapshot2Id": "...",
"differences": [
{
"pvId": "...",
"pvName": "QUAD:LI21:201:BDES",
"value1": 42.5,
"value2": 43.2,
"withinTolerance": false
}
],
"matchCount": 1477,
"differenceCount": 23
}
Tag Endpoints¶
List Tag Groups¶
List all tag groups with their tags.
Response:
[
{
"id": "...",
"name": "Area",
"description": "Machine areas",
"tags": [
{"id": "...", "name": "LI21"},
{"id": "...", "name": "LI22"}
],
"createdDate": "2026-01-15T10:00:00Z",
"lastModifiedDate": "2026-01-15T10:00:00Z"
}
]
Create Tag Group¶
Create a new tag group.
Request Body:
{
"name": "Subsystem",
"description": "Device subsystems",
"tags": [
{"name": "Magnet"},
{"name": "BPM"},
{"name": "Feedback"}
]
}
Get Tag Group¶
Get a tag group with all its tags.
Update Tag Group¶
Update a tag group.
Delete Tag Group¶
Delete a tag group and all its tags. Pass ?force=true to delete even if the group still has tags referenced by PVs.
Add Tag to Group¶
Add a single tag to an existing group.
Query Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
skip_duplicates |
boolean | false |
If true, adding an existing tag returns wasCreated: false instead of 409 |
Request Body: TagCreate ({ "name": "...", "description": null }).
Update Tag¶
Rename or update a tag's description. Body: TagUpdate (name and/or description).
Remove Tag from Group¶
Bulk Import Tags¶
Requires writeAccess. Import multiple tag groups and tags in one call, with duplicate handling.
Request Body:
Response:
Job Endpoints¶
Get Job Status¶
Get the status and progress of a background job.
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
id |
UUID | Job ID |
Response:
{
"id": "...",
"type": "snapshot_create",
"status": "running",
"progress": 45,
"message": "Capturing PV values",
"resultId": null,
"error": null,
"jobData": {
"processed": 675,
"total": 1500
},
"createdAt": "2026-01-15T10:30:00Z",
"startedAt": "2026-01-15T10:30:02Z",
"completedAt": null
}
Job Type Values:
| Type | Description |
|---|---|
snapshot_create |
Creating a snapshot |
snapshot_restore |
Restoring a snapshot to EPICS |
Job Status Values:
| Status | Description |
|---|---|
pending |
Job created, waiting for worker |
running |
Worker is processing |
completed |
Successfully finished |
failed |
Error occurred |
Health Endpoints¶
Heartbeat¶
Simple heartbeat check for frontend polling. No authentication required.
Health Summary¶
Complete health summary for monitoring dashboards. Includes database, Redis, monitor, and watchdog status in a single response.
Monitor Health¶
Detailed PV monitor health information.
Monitor Status¶
Check PV monitor process health via Redis heartbeat.
Response:
{
"status": "healthy",
"message": "Monitor process is alive",
"age_seconds": 2.4,
"leader": "monitor-1"
}
status is one of healthy, stale, unknown, error.
Watchdog Statistics¶
Get watchdog health monitoring statistics.
Force Watchdog Check¶
Force an immediate watchdog health check. Requires writeAccess.
Disconnected PVs¶
List all PVs currently disconnected from EPICS.
Stale PVs¶
List PVs that haven't been updated recently.
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
max_age_seconds |
float | Consider PVs stale after this many seconds |
Circuit Breaker Status¶
Check circuit breaker status by IOC prefix.
Response:
{
"open_circuit_count": 1,
"total_circuits": 2,
"open_circuits": ["BPM:LI22"],
"circuits": [
{
"name": "QUAD:LI21",
"state": "closed",
"failure_count": 0,
"success_count": 1024,
"call_count": 1024,
"last_failure": null,
"opened_at": null
},
{
"name": "BPM:LI22",
"state": "open",
"failure_count": 5,
"success_count": 12,
"call_count": 17,
"last_failure": "2026-01-15T10:25:00",
"opened_at": "2026-01-15T10:25:00"
}
],
"error": null
}
state is closed, open, or half_open.
Force Close Circuit Breaker¶
Force close (reset) a circuit breaker. Requires writeAccess.
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
circuit_name |
string | Circuit name (IOC identifier derived from PV name, e.g., QUAD:LI21) |
Force Open Circuit Breaker¶
Force open a circuit breaker (block all requests to this IOC). Requires writeAccess.
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
circuit_name |
string | Circuit name (e.g., BPM:LI22) |