API Overview
API Reference
Section titled “API Reference”Base URL
Section titled “Base URL”Production: https://api.roboscope.example.com/api/v1Development: http://localhost:8080/api/v1Authentication
Section titled “Authentication”Currently, the API does not require authentication. Future versions will support:
- API keys
- OAuth 2.0
- JWT tokens
Content Type
Section titled “Content Type”All requests and responses use JSON:
Content-Type: application/jsonResponse Format
Section titled “Response Format”Success Response
Section titled “Success Response”{ "id": "550e8400-e29b-41d4-a716-446655440000", "name": "Example Space", ...}Error Response
Section titled “Error Response”{ "error": "Not Found", "message": "Work session not found", "status": 404}Status Codes
Section titled “Status Codes”| Code | Meaning | Description |
|---|---|---|
| 200 | OK | Request successful |
| 201 | Created | Resource created successfully |
| 204 | No Content | Deletion successful |
| 400 | Bad Request | Invalid request data |
| 404 | Not Found | Resource not found |
| 409 | Conflict | Version conflict (optimistic locking) |
| 500 | Internal Server Error | Server error |
Endpoints
Section titled “Endpoints”Spaces
Section titled “Spaces”List Spaces
Section titled “List Spaces”GET /api/v1/spacesResponse: Array of Space objects
Example:
curl http://localhost:8080/api/v1/spacesGet Space
Section titled “Get Space”GET /api/v1/spaces/{id}Path Parameters:
id(UUID): Space identifier
Response: Space object
Example:
curl http://localhost:8080/api/v1/spaces/550e8400-e29b-41d4-a716-446655440000Create Space
Section titled “Create Space”POST /api/v1/spacesRequest Body:
{ "key": "warehouse-a1", "name": "Warehouse A1", "description": "Main warehouse storage area", "model_glb_url": "https://example.com/models/warehouse.glb", "model_usdc_url": "https://example.com/models/warehouse.usdc", "preview_url": "https://example.com/previews/warehouse.jpg", "scan_url": "https://example.com/scans/warehouse.obj", "calibration_vector": [1.5, 0.0, 2.0]}Response: Created Space object (201)
Example:
curl -X POST http://localhost:8080/api/v1/spaces \ -H "Content-Type: application/json" \ -d '{ "key": "warehouse-a1", "name": "Warehouse A1", "calibration_vector": [0, 0, 0] }'Update Space
Section titled “Update Space”PATCH /api/v1/spaces/{id}Path Parameters:
id(UUID): Space identifier
Request Body (all fields optional):
{ "name": "Updated Name", "description": "Updated description", "calibration_vector": [2.0, 0.0, 3.0]}Response: Updated Space object
Delete Space
Section titled “Delete Space”DELETE /api/v1/spaces/{id}Path Parameters:
id(UUID): Space identifier
Response: 204 No Content
Note: Deletes all associated work sessions and markers (CASCADE)
Work Sessions
Section titled “Work Sessions”List Work Sessions
Section titled “List Work Sessions”GET /api/v1/work-sessions?space_id={spaceId}&status={status}&session_type={type}Query Parameters (all optional):
space_id(UUID): Filter by spacestatus(enum): Filter by status (draft,active,done,archived)session_type(enum): Filter by type (inspection,repair,other)
Response: Array of Work Session objects with marker counts
Example:
# All sessionscurl http://localhost:8080/api/v1/work-sessions
# Active inspections in a spacecurl "http://localhost:8080/api/v1/work-sessions?space_id=550e8400-e29b-41d4-a716-446655440000&status=active&session_type=inspection"Get Work Session
Section titled “Get Work Session”GET /api/v1/work-sessions/{id}Path Parameters:
id(UUID): Work session identifier
Response: Work Session object with marker count
Create Work Session
Section titled “Create Work Session”POST /api/v1/work-sessionsRequest Body:
{ "space_id": "550e8400-e29b-41d4-a716-446655440000", "session_type": "inspection", "status": "draft", "started_at": "2025-01-16T09:00:00Z", "completed_at": null}Response: Created Work Session object (201)
Example:
curl -X POST http://localhost:8080/api/v1/work-sessions \ -H "Content-Type: application/json" \ -d '{ "space_id": "550e8400-e29b-41d4-a716-446655440000", "session_type": "inspection", "status": "active", "started_at": "2025-01-16T09:00:00Z" }'Update Work Session
Section titled “Update Work Session”PATCH /api/v1/work-sessions/{id}Path Parameters:
id(UUID): Work session identifier
Request Body (all fields optional):
{ "status": "done", "completed_at": "2025-01-16T12:00:00Z", "version": 3}Response: Updated Work Session object
Note: Include version for optimistic concurrency control
Delete Work Session
Section titled “Delete Work Session”DELETE /api/v1/work-sessions/{id}Path Parameters:
id(UUID): Work session identifier
Response: 204 No Content
Note: Deletes all associated markers and marker details (CASCADE)
Export Work Session
Section titled “Export Work Session”GET /api/v1/work-sessions/{id}/exportPath Parameters:
id(UUID): Work session identifier
Response: Exported work session data (excludes IDs, includes all markers and details)
{ "session_type": "inspection", "status": "active", "started_at": "2025-01-16T09:00:00Z", "completed_at": null, "meta": {}, "markers": [ { "label": "Issue 1", "p1": [0, 0, 0], "p2": [0.1, 0, 0], "p3": [0.1, 0.1, 0], "p4": [0, 0.1, 0], "color": "#FF0000", "custom_props": {}, "calibrated_data": null, "details": { "center_location_long": 0.05, "center_location_cross": 0.05, ... } } ]}Import Work Session
Section titled “Import Work Session”POST /api/v1/work-sessions/importRequest Body:
{ "space_id": "target-space-uuid", "session": { "session_type": "inspection", "status": "active", "started_at": "2025-01-16T09:00:00Z", "completed_at": null, "meta": {}, "markers": [...] }}Response: Created Work Session object (201)
Use Cases:
- Move session to different space
- Duplicate session for comparison
- Backup and restore
- Data migration
Calibrate All Markers
Section titled “Calibrate All Markers”POST /api/v1/work-sessions/{id}/calibrate-markersPath Parameters:
id(UUID): Work session identifier
Response: Array of updated Marker objects
Description: Applies space calibration vector to all markers in the session, populating calibrated_data field.
Markers
Section titled “Markers”List Markers
Section titled “List Markers”GET /api/v1/markers?work_session_id={sessionId}Query Parameters (optional):
work_session_id(UUID): Filter by work session
Response: Array of Marker objects
Example:
curl "http://localhost:8080/api/v1/markers?work_session_id=660e8400-e29b-41d4-a716-446655440001"Get Marker
Section titled “Get Marker”GET /api/v1/markers/{id}Path Parameters:
id(UUID): Marker identifier
Response: Marker object
Create Marker
Section titled “Create Marker”POST /api/v1/markersRequest Body:
{ "work_session_id": "660e8400-e29b-41d4-a716-446655440001", "label": "Crack in wall", "p1": [-0.230, 0.060, 0.030], "p2": [-0.165, 0.057, 0.037], "p3": [-0.167, 0.050, 0.262], "p4": [-0.232, 0.053, 0.255], "color": "#FF0000", "custom_props": { "severity": "medium", "type": "crack" }, "calibrated_data": null}Response: Created Marker object (201)
Validation:
- All edge lengths must be ≥ 5mm
- Coordinates must be finite numbers
- Points must form valid quadrilateral
Bulk Create Markers
Section titled “Bulk Create Markers”POST /api/v1/markers/bulkRequest Body:
{ "markers": [ { "work_session_id": "660e8400-e29b-41d4-a716-446655440001", "label": "Marker 1", "p1": [0, 0, 0], "p2": [0.1, 0, 0], "p3": [0.1, 0.1, 0], "p4": [0, 0.1, 0], "color": "#FF0000" }, { "work_session_id": "660e8400-e29b-41d4-a716-446655440001", "label": "Marker 2", "p1": [0.5, 0, 0], "p2": [0.6, 0, 0], "p3": [0.6, 0.1, 0], "p4": [0.5, 0.1, 0], "color": "#00FF00" } ]}Response: Array of created Marker objects (201)
Update Marker
Section titled “Update Marker”PATCH /api/v1/markers/{id}Path Parameters:
id(UUID): Marker identifier
Request Body (all fields optional):
{ "label": "Updated label", "color": "#00FF00", "custom_props": { "severity": "high" }, "version": 2}Response: Updated Marker object
Delete Marker
Section titled “Delete Marker”DELETE /api/v1/markers/{id}Path Parameters:
id(UUID): Marker identifier
Response: 204 No Content
Note: Deletes associated marker details (CASCADE)
Marker Details
Section titled “Marker Details”Get Marker Details
Section titled “Get Marker Details”GET /api/v1/markers/{id}/detailsPath Parameters:
id(UUID): Marker identifier
Response: Marker Details object or 404
Create/Update Marker Details
Section titled “Create/Update Marker Details”PUT /api/v1/markers/{id}/detailsPath Parameters:
id(UUID): Marker identifier
Request Body:
{ "center_location_long": 0.146, "center_location_cross": -0.198, "x_negative": -0.232, "x_positive": -0.165, "z_negative": 0.030, "z_positive": 0.262, "long_size": 0.232, "cross_size": 0.067, "custom_props": {}}Response: Marker Details object (200 for update, 201 for create)
Note: Upsert operation - creates if doesn’t exist, updates if exists
Delete Marker Details
Section titled “Delete Marker Details”DELETE /api/v1/markers/{id}/detailsPath Parameters:
id(UUID): Marker identifier
Response: 204 No Content
Calculate Marker Details
Section titled “Calculate Marker Details”POST /api/v1/markers/{id}/details/calculatePath Parameters:
id(UUID): Marker identifier
Response: Calculated and saved Marker Details object (201)
Description: Automatically calculates all metrics from marker corner points and saves as marker details.
Calculate All Marker Details for Session
Section titled “Calculate All Marker Details for Session”POST /api/v1/work-sessions/{id}/markers/calculate-detailsPath Parameters:
id(UUID): Work session identifier
Response: Count of calculated marker details
{ "calculated": 25}Description: Batch calculates details for all markers in the session.
Presence
Section titled “Presence”Join Session
Section titled “Join Session”POST /api/v1/presence/sessions/{sessionId}/joinPath Parameters:
sessionId(UUID): Work session identifier
Request Body:
{ "user_id": "user-123", "user_name": "John Doe"}Response: 200 OK
Leave Session
Section titled “Leave Session”POST /api/v1/presence/sessions/{sessionId}/leavePath Parameters:
sessionId(UUID): Work session identifier
Request Body:
{ "user_id": "user-123"}Response: 200 OK
Heartbeat
Section titled “Heartbeat”POST /api/v1/presence/sessions/{sessionId}/heartbeatPath Parameters:
sessionId(UUID): Work session identifier
Request Body:
{ "user_id": "user-123"}Response: 200 OK
Note: Send every 10 seconds to maintain presence
List Active Users
Section titled “List Active Users”GET /api/v1/presence/sessions/{sessionId}/usersPath Parameters:
sessionId(UUID): Work session identifier
Response: Array of active users
[ { "user_id": "user-123", "user_name": "John Doe", "joined_at": "2025-01-16T10:00:00Z", "last_seen": "2025-01-16T10:05:23Z" }]Acquire Lock
Section titled “Acquire Lock”POST /api/v1/locks/sessions/{sessionId}/acquirePath Parameters:
sessionId(UUID): Work session identifier
Request Body:
{ "user_id": "user-123", "ttl": 60}Response:
{ "acquired": true}Status: 200 if acquired, 409 if already locked
Release Lock
Section titled “Release Lock”POST /api/v1/locks/sessions/{sessionId}/releasePath Parameters:
sessionId(UUID): Work session identifier
Request Body:
{ "user_id": "user-123"}Response: 200 OK
Check Lock Status
Section titled “Check Lock Status”GET /api/v1/locks/sessions/{sessionId}/statusPath Parameters:
sessionId(UUID): Work session identifier
Response:
{ "locked": true, "holder": "user-123", "expires_at": "2025-01-16T10:06:00Z"}Events
Section titled “Events”List Events
Section titled “List Events”GET /api/v1/events?entity={entity}&entity_id={id}&kind={kind}&limit={limit}Query Parameters (all optional):
entity(string): Filter by entity type (space,work_session,marker)entity_id(UUID): Filter by specific entitykind(string): Filter by event kind (created,updated,deleted)limit(int): Maximum results (default: 100)
Response: Array of Event objects
[ { "id": 1, "kind": "created", "entity": "marker", "entity_id": "770e8400-e29b-41d4-a716-446655440002", "payload": { "label": "New marker", "user_id": "user-123" }, "created_at": "2025-01-16T10:00:00Z" }]Rate Limiting
Section titled “Rate Limiting”Currently not implemented. Future versions will support:
- 1000 requests per minute per IP
- 10,000 requests per hour per API key
Webhooks
Section titled “Webhooks”Not currently supported. Planned for future releases.
Versioning
Section titled “Versioning”API version is included in the URL path: /api/v1/
Breaking changes will increment the version number.
Error Handling
Section titled “Error Handling”Validation Errors
Section titled “Validation Errors”{ "error": "Validation Error", "message": "Edge 1 too short: 0.003m (minimum 0.005m)", "status": 400}Conflict Errors
Section titled “Conflict Errors”{ "error": "Conflict", "message": "Version mismatch: expected 3, got 2", "status": 409}Not Found Errors
Section titled “Not Found Errors”{ "error": "Not Found", "message": "Marker not found", "status": 404}Best Practices
Section titled “Best Practices”- Use bulk endpoints for creating multiple markers
- Include version in updates for optimistic concurrency
- Filter lists with query parameters to reduce payload
- Handle 409 conflicts by refetching and retrying
- Calculate details in batch for better performance
- Send heartbeats regularly when using presence
- Release locks explicitly when done editing