API Reference
Squirrel Backend provides a REST API for managing EPICS PVs, snapshots, and tags.
Base URL
All API endpoints are prefixed with /v1/.
- Local Development:
http://localhost:8000/v1/
- Docker:
http://localhost:8080/v1/
Interactive Documentation
When the server is running, interactive API documentation is available at:
Successful responses return the resource directly (no envelope):
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Area",
...
}
Error responses always include a machine-readable code slug and a human-readable detail string:
{
"code": "tag_group_not_found",
"detail": "Tag group abc123 not found"
}
| Field |
Type |
Description |
code |
string |
Machine-readable error slug — stable across releases, safe to branch on in client code |
detail |
string |
Human-readable description — may change, do not parse |
Error Codes
All possible code values are listed below, grouped by domain.
General
| Code |
HTTP Status |
Meaning |
unhandled_exception |
500 |
Unexpected server error |
no_code_given |
varies |
HTTP exception raised without a code |
Authentication
| Code |
HTTP Status |
Meaning |
invalid_api_key |
401 |
Missing or deactivated API key |
insufficient_read_access |
401 |
Key does not have read access |
insufficient_write_access |
401 |
Key does not have write access |
| Code |
HTTP Status |
Meaning |
tag_group_not_found |
404 |
Tag group ID does not exist or is not a valid UUID |
tag_group_conflict |
409 |
Tag group name already exists |
tag_not_found |
404 |
Tag ID does not exist or is not a valid UUID |
PVs
| Code |
HTTP Status |
Meaning |
pv_not_found |
404 |
PV ID does not exist or is not a valid UUID |
pv_already_exists |
409 |
PV address already registered |
invalid_tag_filters |
400 |
tagFilters query parameter is not valid JSON |
live_values_fetch_failed |
500 |
Redis cache unavailable |
Snapshots
| Code |
HTTP Status |
Meaning |
snapshot_not_found |
404 |
Snapshot ID does not exist or is not a valid UUID |
Jobs
| Code |
HTTP Status |
Meaning |
job_not_found |
404 |
Job ID does not exist |
API Keys
| Code |
HTTP Status |
Meaning |
api_key_not_found |
404 |
API key ID does not exist |
api_key_already_exists |
409 |
App name already has a key |
api_key_conflict |
409 |
API key state conflict (e.g. already deactivated) |
api_key_self_deactivation |
409 |
Attempted to deactivate the key currently used for authentication without ?force=true |
Health
| Code |
HTTP Status |
Meaning |
health_check_failed |
503 |
General health check error |
watchdog_stats_failed |
503 |
Could not retrieve watchdog statistics |
watchdog_check_failed |
503 |
Watchdog force-check failed |
disconnected_pvs_fetch_failed |
503 |
Could not retrieve disconnected PV list |
stale_pvs_fetch_failed |
503 |
Could not retrieve stale PV list |
circuit_action_failed |
500 |
Force open/close circuit breaker failed |
Endpoint Summary
PV Endpoints (/v1/pvs)
| Method |
Endpoint |
Description |
GET |
/v1/pvs |
Search PVs (simple) |
GET |
/v1/pvs/paged |
Search PVs with pagination |
POST |
/v1/pvs |
Create single PV |
POST |
/v1/pvs/multi |
Bulk create PVs |
PUT |
/v1/pvs/{id} |
Update PV |
DELETE |
/v1/pvs/{id} |
Delete PV |
Snapshot Endpoints (/v1/snapshots)
| Method |
Endpoint |
Description |
GET |
/v1/snapshots |
List snapshots |
POST |
/v1/snapshots |
Create snapshot (async) |
GET |
/v1/snapshots/{id} |
Get snapshot with values |
DELETE |
/v1/snapshots/{id} |
Delete snapshot |
POST |
/v1/snapshots/{id}/restore |
Restore to EPICS |
GET |
/v1/snapshots/{id}/compare/{id2} |
Compare two snapshots |
| Method |
Endpoint |
Description |
GET |
/v1/tags |
List tag groups |
POST |
/v1/tags |
Create tag group |
GET |
/v1/tags/{id} |
Get tag group with tags |
PUT |
/v1/tags/{id} |
Update tag group |
DELETE |
/v1/tags/{id} |
Delete tag group |
Job Endpoints (/v1/jobs)
| Method |
Endpoint |
Description |
GET |
/v1/jobs/{id} |
Get job status and progress |
Health Endpoints (/v1/health)
| Method |
Endpoint |
Description |
GET |
/v1/health |
Overall health |
GET |
/v1/health/db |
Database connectivity |
GET |
/v1/health/redis |
Redis connectivity |
GET |
/v1/health/monitor/status |
PV monitor health |
GET |
/v1/health/circuits |
Circuit breaker status |
WebSocket (/ws)
Real-time PV value streaming.
Paginated endpoints use continuation tokens (not offset-based):
{
"items": [...],
"next_cursor": "abc123",
"has_more": true
}
To get the next page:
GET /v1/pvs/paged?cursor=abc123
Authentication
All endpoints require an API key passed via the X-API-Key header:
X-API-Key: sq_your_token_here
Requests without a valid key return 401 Unauthorized.
Permission Levels
| Permission |
Required for |
read_access |
GET requests, WebSocket connections |
write_access |
POST, PUT, DELETE requests |
Getting an API Key
Use the management script to create your first key:
# Docker
docker exec squirrel-api python scripts/create_key.py <app-name> [--read] [--write]
See API Key Management for full details on creating and managing keys.
API Key Endpoints
The /v1/api-keys endpoints allow managing keys via the REST API (requires write_access):
| Method |
Endpoint |
Description |
GET |
/v1/api-keys |
List all API keys |
POST |
/v1/api-keys |
Create a new API key |
DELETE |
/v1/api-keys/{id} |
Deactivate an API key |
GET |
/v1/api-keys/count |
Count API keys |
Rate Limiting
No rate limiting is currently enforced. For production deployments, consider adding rate limiting at the load balancer level.
Detailed Documentation