The Event Store runs on a managed device and stores inference events produced by pipelines on that device. Base URL is http://<device-ip>:8001, and interactive Swagger documentation is served at /docs. See Services for the base URL, authentication, and error-shape rules shared by all on-device service APIs.
The v2 API accepts camelCase input (ex: base64Image, objectDetections) and returns snake_case responses.
This is not the cloud Vision Events API. The local contract uses event_schema, event_data, and inference_timestamp where the cloud uses eventType, useCaseId, and timestamp, and it takes image bytes directly rather than references to uploaded images. A cloud payload will not validate here.
If API_KEY is set on the service, every endpoint except /health requires an X-API-Key header. See Authentication.
curl -H "X-API-Key: $EVENT_STORE_API_KEY" \
"http://<device-ip>:8001/v2/events/latest/query?limit=5"Create an Event
Bounding box coordinates are center-based absolute pixels: x and y are the center of the box, width and height are the full dimensions. Confidence runs from 0.0 to 1.0.
Set draft: true to keep the event open so a video or local-only file can be attached after the fact, then finalize it. Omitting draft finalizes the event on creation, so existing producers are unaffected.
solution is optional in the schema but conditionally required at runtime. When cloud upload is enabled on the service and DEFAULT_SOLUTION_ID is not set, creating an event without solution returns 400. Either send it on every event or set the environment variable.
Create V2 Event
Show propertiesHide properties
Show propertiesHide properties
Center X of bounding box in absolute pixels
Center Y of bounding box in absolute pixels
Full width of bounding box in pixels
Full height of bounding box in pixels
Show propertiesHide properties
Show propertiesHide properties
Center X of bounding box in absolute pixels
Center Y of bounding box in absolute pixels
Full width of bounding box in pixels
Full height of bounding box in pixels
Polygon points as [[x, y], ...] in absolute pixels
Show propertiesHide properties
Center X of bounding box in absolute pixels
Center Y of bounding box in absolute pixels
Full width of bounding box in pixels
Full height of bounding box in pixels
Index into the images list indicating which image to display by default in a UI
True while the event is a draft: media may still be attached, and it is not yet uploaded. A draft is protected from cleanup only while cloud upload is enabled on the service. With cloud upload off, retention and capacity cleanup can delete an unfinished draft and its attachments.
false201Successful Responseapplication/json
True while the event is a draft: media may still be attached, and it is not yet uploaded. A draft is protected from cleanup only while cloud upload is enabled on the service. With cloud upload off, retention and capacity cleanup can delete an unfinished draft and its attachments.
falseEvent created successfully400`event_data` does not conform to the named `event_schema`, an image whose `base64Image` or `inputBase64Image` failed to decode, or a missing `solution`: it is required when cloud upload is enabled unless DEFAULT_SOLUTION_ID is set on the service.application/json
401Missing or invalid `X-API-Key`. Only returned when API_KEY is set on the service; authentication is disabled by default.application/json
413Record exceeds the maximum allowed sizeapplication/json
422Validation Errorapplication/json
Show propertiesHide properties
500Failed to store the event.application/json
529Store is over its capacity limits and is waiting for uploads to drain (`capacity_blocked`). The request is rejected before any data is written.application/json
capacity_blockedPOST /v2/events HTTP/1.1
Host: device-ip:8001
X-API-Key: YOUR_API_KEY
Content-Type: application/json
Accept: application/json
{
"solution": "text",
"workflow_id": "text",
"workflow_version": "text",
"inference_timestamp": "text",
"device_id": "text",
"stream_id": "text",
"image_id": "text",
"event_schema": "text",
"event_data": {},
"custom_metadata": {
"ANY_ADDITIONAL_PROPERTY": "anything"
},
"images": [
{
"label": "text",
"base64Image": "text",
"inputBase64Image": "text",
"objectDetections": [
{
"class": "text",
"x": 1,
"y": 1,
"width": 1,
"height": 1,
"confidence": 1
}
],
"classifications": [
{
"class": "text",
"confidence": 1
}
],
"instanceSegmentations": [
{
"class": "text",
"x": 1,
"y": 1,
"width": 1,
"height": 1,
"confidence": 1,
"points": [
[
1
]
]
}
],
"keypoints": [
{
"class": "text",
"x": 1,
"y": 1,
"width": 1,
"height": 1,
"confidence": 1,
"keypoints": [
{
"id": 1,
"x": 1,
"y": 1,
"occluded": true
}
]
}
],
"metadata": {
"ANY_ADDITIONAL_PROPERTY": "anything"
}
}
],
"displayImagePosition": 1,
"draft": false
}curl -L \
--request POST \
--url 'http://device-ip:8001/v2/events' \
--header 'X-API-Key: YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data '{
"solution": "text",
"workflow_id": "text",
"workflow_version": "text",
"inference_timestamp": "text",
"device_id": "text",
"stream_id": "text",
"image_id": "text",
"event_schema": "text",
"event_data": {},
"custom_metadata": {
"ANY_ADDITIONAL_PROPERTY": "anything"
},
"images": [
{
"label": "text",
"base64Image": "text",
"inputBase64Image": "text",
"objectDetections": [
{
"class": "text",
"x": 1,
"y": 1,
"width": 1,
"height": 1,
"confidence": 1
}
],
"classifications": [
{
"class": "text",
"confidence": 1
}
],
"instanceSegmentations": [
{
"class": "text",
"x": 1,
"y": 1,
"width": 1,
"height": 1,
"confidence": 1,
"points": [
[
1
]
]
}
],
"keypoints": [
{
"class": "text",
"x": 1,
"y": 1,
"width": 1,
"height": 1,
"confidence": 1,
"keypoints": [
{
"id": 1,
"x": 1,
"y": 1,
"occluded": true
}
]
}
],
"metadata": {
"ANY_ADDITIONAL_PROPERTY": "anything"
}
}
],
"displayImagePosition": 1,
"draft": false
}'const response = await fetch("http://device-ip:8001/v2/events", {
method: "POST",
headers: {
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json",
"Accept": "application/json"
},
body: JSON.stringify({
"solution": "text",
"workflow_id": "text",
"workflow_version": "text",
"inference_timestamp": "text",
"device_id": "text",
"stream_id": "text",
"image_id": "text",
"event_schema": "text",
"event_data": {},
"custom_metadata": {
"ANY_ADDITIONAL_PROPERTY": "anything"
},
"images": [
{
"label": "text",
"base64Image": "text",
"inputBase64Image": "text",
"objectDetections": [
{
"class": "text",
"x": 1,
"y": 1,
"width": 1,
"height": 1,
"confidence": 1
}
],
"classifications": [
{
"class": "text",
"confidence": 1
}
],
"instanceSegmentations": [
{
"class": "text",
"x": 1,
"y": 1,
"width": 1,
"height": 1,
"confidence": 1,
"points": [
[
1
]
]
}
],
"keypoints": [
{
"class": "text",
"x": 1,
"y": 1,
"width": 1,
"height": 1,
"confidence": 1,
"keypoints": [
{
"id": 1,
"x": 1,
"y": 1,
"occluded": true
}
]
}
],
"metadata": {
"ANY_ADDITIONAL_PROPERTY": "anything"
}
}
],
"displayImagePosition": 1,
"draft": false
})
});
const data = await response.json();
console.log(data);import requests
url = "http://device-ip:8001/v2/events"
headers = {
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json",
"Accept": "application/json"
}
payload = {
"solution": "text",
"workflow_id": "text",
"workflow_version": "text",
"inference_timestamp": "text",
"device_id": "text",
"stream_id": "text",
"image_id": "text",
"event_schema": "text",
"event_data": {},
"custom_metadata": {
"ANY_ADDITIONAL_PROPERTY": "anything"
},
"images": [
{
"label": "text",
"base64Image": "text",
"inputBase64Image": "text",
"objectDetections": [
{
"class": "text",
"x": 1,
"y": 1,
"width": 1,
"height": 1,
"confidence": 1
}
],
"classifications": [
{
"class": "text",
"confidence": 1
}
],
"instanceSegmentations": [
{
"class": "text",
"x": 1,
"y": 1,
"width": 1,
"height": 1,
"confidence": 1,
"points": [
[
1
]
]
}
],
"keypoints": [
{
"class": "text",
"x": 1,
"y": 1,
"width": 1,
"height": 1,
"confidence": 1,
"keypoints": [
{
"id": 1,
"x": 1,
"y": 1,
"occluded": True
}
]
}
],
"metadata": {
"ANY_ADDITIONAL_PROPERTY": "anything"
}
}
],
"displayImagePosition": 1,
"draft": False
}
response = requests.post(url, headers=headers, json=payload)
print(response.json()){
"id": "text",
"image_ids": [
"anything"
],
"created_at": "text",
"draft": false,
"message": "Event created successfully"
}{
"detail": "text"
}{
"detail": "text"
}{
"detail": "text"
}{
"detail": [
{
"loc": [
"anything"
],
"msg": "text",
"type": "text",
"input": "anything",
"ctx": {}
}
]
}{
"detail": "text"
}{
"detail": "text",
"error": "capacity_blocked"
}Query Events
GET /v2/events filters by time window, source, and custom metadata. metadata_filter takes key:value or key:op:value with the operators eq, ne, gt, lt, gte, and lte, and repeats with AND logic.
Per-image metadata is not queryable through metadata_filter. Only custom_metadata on the event is.
Get V2 Events
Get events with optional filtering. Returns every stored event, including any written by an earlier version of the service.
ISO8601 timestamp to start from (filters by created_at)
Maximum number of events to return
100ISO8601 timestamp to end at (filters by created_at)
Filter by device_id (exact match)
Filter by event_schema (exact match)
Filter by workflow_id (exact match)
Filter by external_id (exact match)
Filter by related_event_id (for feedback events)
Sort direction: 'asc' or 'desc'
descFilter by multiple device_ids (comma-separated)
Filter by multiple event_schemas (comma-separated)
Filter by multiple workflow_ids (comma-separated)
Filter by multiple external_ids (comma-separated)
Filter by custom_metadata. Format: 'key:value' or 'key:op:value'. Operators: eq, ne, gt, lt, gte, lte.
[]Include draft (not yet finalized) events. Set false to see only finalized events.
true200Successful Responseapplication/json
Show propertiesHide properties
Show propertiesHide properties
Show propertiesHide properties
Files attached to this event that are stored on-device only and never uploaded to the cloud (e.g. inspection blobs, thumbnails, arbitrary JSON). Served via GET /local-only-files/{file_id}.
Show propertiesHide properties
v200True while the event is a draft: media may still be attached, and it is not yet uploaded. A draft is protected from cleanup only while cloud upload is enabled on the service. With cloud upload off, retention and capacity cleanup can delete an unfinished draft and its attachments.
falseWhen the event was finalized (null while draft)
Set when the event was force-finalized by the DRAFT_AUTO_FINALIZE_SECONDS sweep
400Invalid filter: a malformed timestamp, a `sort_direction` other than `asc` or `desc`, or an unparseable metadata_filter. An out-of-range `limit` is caught by request validation instead and returns 422.application/json
401Missing or invalid `X-API-Key`. Only returned when API_KEY is set on the service; authentication is disabled by default.application/json
422Validation Errorapplication/json
Show propertiesHide properties
500Failed to retrieve events.application/json
529Store is over its capacity limits and is waiting for uploads to drain (`capacity_blocked`). The request is rejected before any data is written.application/json
capacity_blockedGET /v2/events HTTP/1.1
Host: device-ip:8001
X-API-Key: YOUR_API_KEY
Accept: application/jsoncurl -L \
--request GET \
--url 'http://device-ip:8001/v2/events' \
--header 'X-API-Key: YOUR_API_KEY' \
--header 'Accept: application/json'const response = await fetch("http://device-ip:8001/v2/events", {
method: "GET",
headers: {
"X-API-Key": "YOUR_API_KEY",
"Accept": "application/json"
}
});
const data = await response.json();
console.log(data);import requests
url = "http://device-ip:8001/v2/events"
headers = {
"X-API-Key": "YOUR_API_KEY",
"Accept": "application/json"
}
response = requests.get(url, headers=headers)
print(response.json()){
"events": [
{
"id": "text",
"solution": "text",
"workflow_id": "text",
"workflow_version": "text",
"inference_timestamp": "text",
"device_id": "text",
"stream_id": "text",
"images": [
{
"file_id": "text",
"input_file_id": "text",
"label": "text",
"object_detections": [
{
"class": "text",
"x": 1,
"y": 1,
"width": 1,
"height": 1,
"confidence": 1
}
],
"classifications": [
{
"class": "text",
"confidence": 1
}
],
"instance_segmentations": [
{
"class": "text",
"x": 1,
"y": 1,
"width": 1,
"height": 1,
"confidence": 1,
"points": [
[
1
]
]
}
],
"keypoints": [
{
"class": "text",
"x": 1,
"y": 1,
"width": 1,
"height": 1,
"confidence": 1,
"keypoints": [
{
"id": 1,
"x": 1,
"y": 1,
"occluded": true
}
]
}
],
"metadata": {}
}
],
"videos": [
{
"file_id": "text",
"label": "text",
"content_type": "text",
"size_bytes": 1
}
],
"local_only_files": [
{
"file_id": "text",
"label": "text",
"content_type": "text",
"size_bytes": 1
}
],
"display_image_position": 1,
"event_schema": "text",
"event_data": {},
"custom_metadata": {},
"created_at": "text",
"api_version": "v2",
"original_file_count": 0,
"current_file_count": 0,
"draft": false,
"finalized_at": "text",
"auto_finalized_at": "text"
}
],
"count": 1,
"next_timestamp": "text"
}{
"detail": "text"
}{
"detail": "text"
}{
"detail": [
{
"loc": [
"anything"
],
"msg": "text",
"type": "text",
"input": "anything",
"ctx": {}
}
]
}{
"detail": "text"
}{
"detail": "text",
"error": "capacity_blocked"
}Get V2 Event By Id
Get a specific event by ID. Returns every stored event, including any written by an earlier version of the service.
200Successful Responseapplication/json
Show propertiesHide properties
Show propertiesHide properties
Center X of bounding box in absolute pixels
Center Y of bounding box in absolute pixels
Full width of bounding box in pixels
Full height of bounding box in pixels
Show propertiesHide properties
Show propertiesHide properties
Center X of bounding box in absolute pixels
Center Y of bounding box in absolute pixels
Full width of bounding box in pixels
Full height of bounding box in pixels
Polygon points as [[x, y], ...] in absolute pixels
Show propertiesHide properties
Center X of bounding box in absolute pixels
Center Y of bounding box in absolute pixels
Full width of bounding box in pixels
Full height of bounding box in pixels
Show propertiesHide properties
Files attached to this event that are stored on-device only and never uploaded to the cloud (e.g. inspection blobs, thumbnails, arbitrary JSON). Served via GET /local-only-files/{file_id}.
Show propertiesHide properties
v200True while the event is a draft: media may still be attached, and it is not yet uploaded. A draft is protected from cleanup only while cloud upload is enabled on the service. With cloud upload off, retention and capacity cleanup can delete an unfinished draft and its attachments.
falseWhen the event was finalized (null while draft)
Set when the event was force-finalized by the DRAFT_AUTO_FINALIZE_SECONDS sweep
401Missing or invalid `X-API-Key`. Only returned when API_KEY is set on the service; authentication is disabled by default.application/json
404Event not found.application/json
422Validation Errorapplication/json
Show propertiesHide properties
500Failed to retrieve the event.application/json
529Store is over its capacity limits and is waiting for uploads to drain (`capacity_blocked`). The request is rejected before any data is written.application/json
capacity_blockedGET /v2/events/{event_id} HTTP/1.1
Host: device-ip:8001
X-API-Key: YOUR_API_KEY
Accept: application/jsoncurl -L \
--request GET \
--url 'http://device-ip:8001/v2/events/{event_id}' \
--header 'X-API-Key: YOUR_API_KEY' \
--header 'Accept: application/json'const response = await fetch("http://device-ip:8001/v2/events/{event_id}", {
method: "GET",
headers: {
"X-API-Key": "YOUR_API_KEY",
"Accept": "application/json"
}
});
const data = await response.json();
console.log(data);import requests
url = "http://device-ip:8001/v2/events/{event_id}"
headers = {
"X-API-Key": "YOUR_API_KEY",
"Accept": "application/json"
}
response = requests.get(url, headers=headers)
print(response.json()){
"id": "text",
"solution": "text",
"workflow_id": "text",
"workflow_version": "text",
"inference_timestamp": "text",
"device_id": "text",
"stream_id": "text",
"images": [
{
"file_id": "text",
"input_file_id": "text",
"label": "text",
"object_detections": [
{
"class": "text",
"x": 1,
"y": 1,
"width": 1,
"height": 1,
"confidence": 1
}
],
"classifications": [
{
"class": "text",
"confidence": 1
}
],
"instance_segmentations": [
{
"class": "text",
"x": 1,
"y": 1,
"width": 1,
"height": 1,
"confidence": 1,
"points": [
[
1
]
]
}
],
"keypoints": [
{
"class": "text",
"x": 1,
"y": 1,
"width": 1,
"height": 1,
"confidence": 1,
"keypoints": [
{
"id": 1,
"x": 1,
"y": 1,
"occluded": true
}
]
}
],
"metadata": {}
}
],
"videos": [
{
"file_id": "text",
"label": "text",
"content_type": "text",
"size_bytes": 1
}
],
"local_only_files": [
{
"file_id": "text",
"label": "text",
"content_type": "text",
"size_bytes": 1
}
],
"display_image_position": 1,
"event_schema": "text",
"event_data": {},
"custom_metadata": {},
"created_at": "text",
"api_version": "v2",
"original_file_count": 0,
"current_file_count": 0,
"draft": false,
"finalized_at": "text",
"auto_finalized_at": "text"
}{
"detail": "text"
}{
"detail": "text"
}{
"detail": [
{
"loc": [
"anything"
],
"msg": "text",
"type": "text",
"input": "anything",
"ctx": {}
}
]
}{
"detail": "text"
}{
"detail": "text",
"error": "capacity_blocked"
}Get Latest V2 Events
Get the most recent events, no timestamp required. Returns every stored event, including any written by an earlier version of the service.
Maximum number of events to return
100Include draft (not yet finalized) events. Set false to see only finalized events.
true200Successful Responseapplication/json
Show propertiesHide properties
Show propertiesHide properties
Show propertiesHide properties
Files attached to this event that are stored on-device only and never uploaded to the cloud (e.g. inspection blobs, thumbnails, arbitrary JSON). Served via GET /local-only-files/{file_id}.
Show propertiesHide properties
v200True while the event is a draft: media may still be attached, and it is not yet uploaded. A draft is protected from cleanup only while cloud upload is enabled on the service. With cloud upload off, retention and capacity cleanup can delete an unfinished draft and its attachments.
falseWhen the event was finalized (null while draft)
Set when the event was force-finalized by the DRAFT_AUTO_FINALIZE_SECONDS sweep
401Missing or invalid `X-API-Key`. Only returned when API_KEY is set on the service; authentication is disabled by default.application/json
422Validation Errorapplication/json
Show propertiesHide properties
500Failed to retrieve events.application/json
529Store is over its capacity limits and is waiting for uploads to drain (`capacity_blocked`). The request is rejected before any data is written.application/json
capacity_blockedGET /v2/events/latest/query HTTP/1.1
Host: device-ip:8001
X-API-Key: YOUR_API_KEY
Accept: application/jsoncurl -L \
--request GET \
--url 'http://device-ip:8001/v2/events/latest/query' \
--header 'X-API-Key: YOUR_API_KEY' \
--header 'Accept: application/json'const response = await fetch("http://device-ip:8001/v2/events/latest/query", {
method: "GET",
headers: {
"X-API-Key": "YOUR_API_KEY",
"Accept": "application/json"
}
});
const data = await response.json();
console.log(data);import requests
url = "http://device-ip:8001/v2/events/latest/query"
headers = {
"X-API-Key": "YOUR_API_KEY",
"Accept": "application/json"
}
response = requests.get(url, headers=headers)
print(response.json()){
"events": [
{
"id": "text",
"solution": "text",
"workflow_id": "text",
"workflow_version": "text",
"inference_timestamp": "text",
"device_id": "text",
"stream_id": "text",
"images": [
{
"file_id": "text",
"input_file_id": "text",
"label": "text",
"object_detections": [
{
"class": "text",
"x": 1,
"y": 1,
"width": 1,
"height": 1,
"confidence": 1
}
],
"classifications": [
{
"class": "text",
"confidence": 1
}
],
"instance_segmentations": [
{
"class": "text",
"x": 1,
"y": 1,
"width": 1,
"height": 1,
"confidence": 1,
"points": [
[
1
]
]
}
],
"keypoints": [
{
"class": "text",
"x": 1,
"y": 1,
"width": 1,
"height": 1,
"confidence": 1,
"keypoints": [
{
"id": 1,
"x": 1,
"y": 1,
"occluded": true
}
]
}
],
"metadata": {}
}
],
"videos": [
{
"file_id": "text",
"label": "text",
"content_type": "text",
"size_bytes": 1
}
],
"local_only_files": [
{
"file_id": "text",
"label": "text",
"content_type": "text",
"size_bytes": 1
}
],
"display_image_position": 1,
"event_schema": "text",
"event_data": {},
"custom_metadata": {},
"created_at": "text",
"api_version": "v2",
"original_file_count": 0,
"current_file_count": 0,
"draft": false,
"finalized_at": "text",
"auto_finalized_at": "text"
}
],
"count": 1,
"next_timestamp": "text"
}{
"detail": "text"
}{
"detail": [
{
"loc": [
"anything"
],
"msg": "text",
"type": "text",
"input": "anything",
"ctx": {}
}
]
}{
"detail": "text"
}{
"detail": "text",
"error": "capacity_blocked"
}Get Event Count
Get event count and statistics
Filter by device_id
Filter by event_schema
Filter by workflow_id
200Successful Responseapplication/json
Total number of events
Number of events matching filters
Timestamp of oldest event (ISO8601)
Timestamp of newest event (ISO8601)
401Missing or invalid `X-API-Key`. Only returned when API_KEY is set on the service; authentication is disabled by default.application/json
422Validation Errorapplication/json
Show propertiesHide properties
500Failed to get the event count.application/json
529Store is over its capacity limits and is waiting for uploads to drain (`capacity_blocked`). The request is rejected before any data is written.application/json
capacity_blockedGET /events/count/stats HTTP/1.1
Host: device-ip:8001
X-API-Key: YOUR_API_KEY
Accept: application/jsoncurl -L \
--request GET \
--url 'http://device-ip:8001/events/count/stats' \
--header 'X-API-Key: YOUR_API_KEY' \
--header 'Accept: application/json'const response = await fetch("http://device-ip:8001/events/count/stats", {
method: "GET",
headers: {
"X-API-Key": "YOUR_API_KEY",
"Accept": "application/json"
}
});
const data = await response.json();
console.log(data);import requests
url = "http://device-ip:8001/events/count/stats"
headers = {
"X-API-Key": "YOUR_API_KEY",
"Accept": "application/json"
}
response = requests.get(url, headers=headers)
print(response.json()){
"total_count": 1,
"filtered_count": 1,
"oldest_timestamp": "text",
"newest_timestamp": "text"
}{
"detail": "text"
}{
"detail": [
{
"loc": [
"anything"
],
"msg": "text",
"type": "text",
"input": "anything",
"ctx": {}
}
]
}{
"detail": "text"
}{
"detail": "text",
"error": "capacity_blocked"
}Draft Lifecycle
A producer that needs to attach a video encoded after the pass/fail decision creates the event as a draft, uploads the file when it is ready, then finalizes:
EVENT_ID=$(curl -s -X POST http://<device-ip>:8001/v2/events \
-H "Content-Type: application/json" \
-d '{"inference_timestamp":"2025-01-30T14:30:00Z","event_schema":"quality_check","event_data":{"result":"pass"},"solution":"a1b2c3d4e5f67890","draft":true}' \
| jq -r '.id')
curl -X POST "http://<device-ip>:8001/v2/events/$EVENT_ID/videos" -F "file=@clip.mp4"
curl -X POST "http://<device-ip>:8001/v2/events/$EVENT_ID/finalize"Until an event is finalized it is skipped by cloud upload. It is also protected from cleanup, but only while cloud upload is enabled on the service. With cloud upload off, a draft is as deletable as any other record, so retention and capacity cleanup can remove one that is still being assembled.
A draft whose producer never calls finalize is force-closed after DRAFT_AUTO_FINALIZE_SECONDS. Both finalized_at and auto_finalized_at are set in that case, so read auto_finalized_at to tell a force-closed event from one the producer finalized itself.
Attachment routes add bytes, so unlike finalize they are subject to capacity backpressure: when the store is over its limits they return 529 and the upload is not accepted.
Upload Video To Event
Attach a video to a draft event.
The event must have been created with draft=true and not yet finalized - finalized events may already be in the cloud upload queue, so a late-attached video would silently never be backed up (409). The upload is multipart/form-data (no base64 overhead), parsed as a stream: the body is written straight to a staging file with MAX_VIDEO_UPLOAD_BYTES enforced per chunk, so an oversized (or misdirected) upload is rejected without ever spooling the full body to disk or memory, and the draft check runs before the body is consumed at all. The file must be a recognized video format (detected from content, not the declared content type).
Attached videos are served locally via GET /videos/{file_id} and appear
in the event's videos array on the v2 GET endpoints.
Video file
Label for the video (e.g. 'camera_1_video')
video201Successful Responseapplication/json
Video attached successfully400Malformed multipart body, or a missing, empty, or duplicate `file` part.application/json
401Missing or invalid `X-API-Key`. Only returned when API_KEY is set on the service; authentication is disabled by default.application/json
404Event not found.application/json
409Event is already finalized. Videos attach only to drafts.application/json
413Video exceeds MAX_VIDEO_UPLOAD_BYTES.application/json
415Content is not a supported video format. The format is detected from the bytes, not the declared type.application/json
422Validation Errorapplication/json
Show propertiesHide properties
Error raised by the service. detail is a string here, unlike HTTPValidationError where it is an array.
Show propertiesHide properties
Show propertiesHide properties
500Failed to store the video.application/json
529Store is over its capacity limits and is waiting for uploads to drain (`capacity_blocked`). The request is rejected before any data is written.application/json
capacity_blockedPOST /v2/events/{event_id}/videos HTTP/1.1
Host: device-ip:8001
X-API-Key: YOUR_API_KEY
Content-Type: multipart/form-data
Accept: application/json
{
"file": "binary",
"label": "video"
}curl -L \
--request POST \
--url 'http://device-ip:8001/v2/events/{event_id}/videos' \
--header 'X-API-Key: YOUR_API_KEY' \
--header 'Content-Type: multipart/form-data' \
--header 'Accept: application/json' \
--data '{
"file": "binary",
"label": "video"
}'const response = await fetch("http://device-ip:8001/v2/events/{event_id}/videos", {
method: "POST",
headers: {
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "multipart/form-data",
"Accept": "application/json"
},
body: JSON.stringify({
"file": "binary",
"label": "video"
})
});
const data = await response.json();
console.log(data);import requests
url = "http://device-ip:8001/v2/events/{event_id}/videos"
headers = {
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "multipart/form-data",
"Accept": "application/json"
}
payload = {
"file": "binary",
"label": "video"
}
response = requests.post(url, headers=headers, json=payload)
print(response.json()){
"file_id": "text",
"event_id": "text",
"label": "text",
"content_type": "text",
"size_bytes": 1,
"message": "Video attached successfully"
}{
"detail": "text"
}{
"detail": "text"
}{
"detail": "text"
}{
"detail": "text"
}{
"detail": "text"
}{
"detail": "text"
}{
"detail": "text"
}{
"detail": "text"
}{
"detail": "text",
"error": "capacity_blocked"
}Upload Local Only File To Event
Attach a local-only file to a draft event.
Local-only files are stored on-device and are never uploaded to the cloud - regardless of content type (they may be inspection blobs, JSON, or thumbnails). This is the explicit, first-class alternative to smuggling large non-queryable payloads through queryable metadata fields.
Like video attach, the event must have been created with draft=true and not yet finalized (409 otherwise), and the body is streamed to a staging file with max_local_only_file_upload_bytes enforced per chunk so an oversized upload is rejected without ever spooling the full body to memory or disk. Unlike video attach, no content type is enforced; the client may declare a content_type or let it be sniffed from the bytes.
Attached files are served locally via GET /local-only-files/{file_id} and
appear in the event's local_only_files array on the v2 GET endpoints.
Arbitrary file to store on-device only (never backed up)
Label for the file (e.g. 'inspection_blob')
fileOptional MIME type to store and serve the file with (e.g. 'application/json'). If omitted, the type is sniffed from the file content.
201Successful Responseapplication/json
Local-only file attached successfully400Malformed or incomplete multipart body, missing/empty/duplicate 'file' partapplication/json
401Missing or invalid `X-API-Key`. Only returned when API_KEY is set on the service; authentication is disabled by default.application/json
404Event not foundapplication/json
409Event is already finalized (local-only files attach to drafts only)application/json
413File exceeds the maximum upload sizeapplication/json
422Invalid label or content_typeapplication/json
Show propertiesHide properties
Error raised by the service. detail is a string here, unlike HTTPValidationError where it is an array.
Show propertiesHide properties
Show propertiesHide properties
500Failed to store the file.application/json
529Store is over its capacity limits and is waiting for uploads to drain (`capacity_blocked`). The request is rejected before any data is written.application/json
capacity_blockedPOST /v2/events/{event_id}/local-only-files HTTP/1.1
Host: device-ip:8001
X-API-Key: YOUR_API_KEY
Content-Type: multipart/form-data
Accept: application/json
{
"file": "binary",
"label": "file",
"content_type": "text"
}curl -L \
--request POST \
--url 'http://device-ip:8001/v2/events/{event_id}/local-only-files' \
--header 'X-API-Key: YOUR_API_KEY' \
--header 'Content-Type: multipart/form-data' \
--header 'Accept: application/json' \
--data '{
"file": "binary",
"label": "file",
"content_type": "text"
}'const response = await fetch("http://device-ip:8001/v2/events/{event_id}/local-only-files", {
method: "POST",
headers: {
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "multipart/form-data",
"Accept": "application/json"
},
body: JSON.stringify({
"file": "binary",
"label": "file",
"content_type": "text"
})
});
const data = await response.json();
console.log(data);import requests
url = "http://device-ip:8001/v2/events/{event_id}/local-only-files"
headers = {
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "multipart/form-data",
"Accept": "application/json"
}
payload = {
"file": "binary",
"label": "file",
"content_type": "text"
}
response = requests.post(url, headers=headers, json=payload)
print(response.json()){
"file_id": "text",
"event_id": "text",
"label": "text",
"content_type": "text",
"size_bytes": 1,
"message": "Local-only file attached successfully"
}{
"detail": "text"
}{
"detail": "text"
}{
"detail": "text"
}{
"detail": "text"
}{
"detail": "text"
}{
"detail": "text"
}{
"detail": "text"
}{
"detail": "text",
"error": "capacity_blocked"
}Finalize V2 Event
Finalize a draft event so it enters the upload/cleanup lifecycle.
Idempotent: finalizing an already-finalized event is a no-op that returns the existing state (already_finalized=true). If the event was already force-closed by the DRAFT_AUTO_FINALIZE_SECONDS sweep, auto_finalized_at is set in the response.
This endpoint stays available while the device is capacity-blocked (529) because finalizing drafts is how a draft-saturated store starts draining.
200Successful Responseapplication/json
True when the event was already finalized before this call (no-op)
Set when the event had already been force-finalized by the auto-finalize sweep
Event finalized401Missing or invalid `X-API-Key`. Only returned when API_KEY is set on the service; authentication is disabled by default.application/json
404Event not found.application/json
422Validation Errorapplication/json
Show propertiesHide properties
500Failed to finalize the event.application/json
POST /v2/events/{event_id}/finalize HTTP/1.1
Host: device-ip:8001
X-API-Key: YOUR_API_KEY
Accept: application/jsoncurl -L \
--request POST \
--url 'http://device-ip:8001/v2/events/{event_id}/finalize' \
--header 'X-API-Key: YOUR_API_KEY' \
--header 'Accept: application/json'const response = await fetch("http://device-ip:8001/v2/events/{event_id}/finalize", {
method: "POST",
headers: {
"X-API-Key": "YOUR_API_KEY",
"Accept": "application/json"
}
});
const data = await response.json();
console.log(data);import requests
url = "http://device-ip:8001/v2/events/{event_id}/finalize"
headers = {
"X-API-Key": "YOUR_API_KEY",
"Accept": "application/json"
}
response = requests.post(url, headers=headers)
print(response.json()){
"id": "text",
"finalized_at": "text",
"already_finalized": true,
"auto_finalized_at": "text",
"message": "Event finalized"
}{
"detail": "text"
}{
"detail": "text"
}{
"detail": [
{
"loc": [
"anything"
],
"msg": "text",
"type": "text",
"input": "anything",
"ctx": {}
}
]
}{
"detail": "text"
}Event Schemas
event_schema selects the structure of event_data. Each schema forbids fields it does not define, and every field accepts both its camelCase and snake_case spelling.
The two fields fail differently. A bad event_schema returns 422. An event_data payload that does not conform to the named schema returns 400, with a string detail naming the schema.
| Field | Type | Required | Constraint |
|---|---|---|---|
result | "pass" or "fail" | Yes | |
externalId | string | No | Up to 1000 characters |
{ "result": "pass", "externalId": "SKU-12345" }| Field | Type | Required | Constraint |
|---|---|---|---|
location | string | No | Up to 1000 characters |
itemCount | integer | No | 0 or greater |
itemType | string | No | Up to 1000 characters |
externalId | string | No | Up to 1000 characters |
{ "location": "warehouse-A", "itemCount": 42, "itemType": "widgets" }| Field | Type | Required | Constraint |
|---|---|---|---|
alertType | string | No | Up to 256 characters, letters, numbers, underscores, spaces, and hyphens only |
severity | "low", "medium", or "high" | No | |
description | string | No | Up to 10000 characters |
externalId | string | No | Up to 1000 characters |
{ "alertType": "no_ppe", "severity": "high", "description": "Worker entered area without hard hat" }| Field | Type | Required | Constraint |
|---|---|---|---|
relatedEventId | string | Yes | ID of the event being rated |
feedback | "correct", "incorrect", or "inconclusive" | Yes |
{ "relatedEventId": "550e8400-e29b-41d4-a716-446655440000", "feedback": "correct" }Query these back with the related_event_id filter on GET /v2/events.
| Field | Type | Required | Constraint |
|---|---|---|---|
externalId | string | No | Up to 1000 characters |
value | string | No | Up to 10000 characters |
{ "externalId": "sensor-123", "value": "temperature:72.5" }For structured data that does not fit these fields, use custom_metadata on the event, which is queryable, or per-image metadata, which is not.
Download Files
Image IDs are ephemeral. Cleanup can remove a file at any time, so handle 404 and do not cache IDs beyond a single session. Compare current_file_count against original_file_count on an event to tell whether its files were cleaned up.
Get Image
Get an image or video by ID. Supports HTTP Range requests for efficient video streaming.
Byte range to request. Supports formats: bytes=start-end, bytes=start-, bytes=-suffix
200Full content returnedapplication/json
206Partial content returned (response to Range request)image/*
401Missing or invalid `X-API-Key`. Only returned when API_KEY is set on the service; authentication is disabled by default.application/json
404File not foundapplication/json
416Range not satisfiableapplication/json
422Validation Errorapplication/json
Show propertiesHide properties
529Store is over its capacity limits and is waiting for uploads to drain (`capacity_blocked`). The request is rejected before any data is written.application/json
capacity_blockedGET /images/{image_id} HTTP/1.1
Host: device-ip:8001
X-API-Key: YOUR_API_KEY
Accept: application/jsoncurl -L \
--request GET \
--url 'http://device-ip:8001/images/{image_id}' \
--header 'X-API-Key: YOUR_API_KEY' \
--header 'Accept: application/json'const response = await fetch("http://device-ip:8001/images/{image_id}", {
method: "GET",
headers: {
"X-API-Key": "YOUR_API_KEY",
"Accept": "application/json"
}
});
const data = await response.json();
console.log(data);import requests
url = "http://device-ip:8001/images/{image_id}"
headers = {
"X-API-Key": "YOUR_API_KEY",
"Accept": "application/json"
}
response = requests.get(url, headers=headers)
print(response.json())"anything"binary{
"detail": "text"
}{
"detail": "text"
}{
"detail": "text"
}{
"detail": [
{
"loc": [
"anything"
],
"msg": "text",
"type": "text",
"input": "anything",
"ctx": {}
}
]
}{
"detail": "text",
"error": "capacity_blocked"
}Get Video
Get a video by ID. Supports HTTP Range requests for efficient streaming.
Returns 404 if the file exists but is not a video.
Byte range to request. Supports formats: bytes=start-end, bytes=start-, bytes=-suffix
200Full content returnedapplication/json
206Partial content returned (response to Range request)video/*
401Missing or invalid `X-API-Key`. Only returned when API_KEY is set on the service; authentication is disabled by default.application/json
404Video not foundapplication/json
416Range not satisfiableapplication/json
422Validation Errorapplication/json
Show propertiesHide properties
529Store is over its capacity limits and is waiting for uploads to drain (`capacity_blocked`). The request is rejected before any data is written.application/json
capacity_blockedGET /videos/{video_id} HTTP/1.1
Host: device-ip:8001
X-API-Key: YOUR_API_KEY
Accept: application/jsoncurl -L \
--request GET \
--url 'http://device-ip:8001/videos/{video_id}' \
--header 'X-API-Key: YOUR_API_KEY' \
--header 'Accept: application/json'const response = await fetch("http://device-ip:8001/videos/{video_id}", {
method: "GET",
headers: {
"X-API-Key": "YOUR_API_KEY",
"Accept": "application/json"
}
});
const data = await response.json();
console.log(data);import requests
url = "http://device-ip:8001/videos/{video_id}"
headers = {
"X-API-Key": "YOUR_API_KEY",
"Accept": "application/json"
}
response = requests.get(url, headers=headers)
print(response.json())"anything"binary{
"detail": "text"
}{
"detail": "text"
}{
"detail": "text"
}{
"detail": [
{
"loc": [
"anything"
],
"msg": "text",
"type": "text",
"input": "anything",
"ctx": {}
}
]
}{
"detail": "text",
"error": "capacity_blocked"
}Get Local Only File
Get a local-only file by ID. Supports HTTP Range requests.
Local-only files are attached to a draft event via POST /v2/events/{event_id}/local-only-files and are stored on-device only - they are never uploaded to the cloud. Returns 404 if the file exists but is not a local-only file, so this route cannot be used to fetch ordinary images or videos.
Byte range to request. Supports formats: bytes=start-end, bytes=start-, bytes=-suffix
200Full content returnedapplication/json
206Partial content returned (response to Range request)application/octet-stream
401Missing or invalid `X-API-Key`. Only returned when API_KEY is set on the service; authentication is disabled by default.application/json
404Local-only file not foundapplication/json
416Range not satisfiableapplication/json
422Validation Errorapplication/json
Show propertiesHide properties
529Store is over its capacity limits and is waiting for uploads to drain (`capacity_blocked`). The request is rejected before any data is written.application/json
capacity_blockedGET /local-only-files/{file_id} HTTP/1.1
Host: device-ip:8001
X-API-Key: YOUR_API_KEY
Accept: application/jsoncurl -L \
--request GET \
--url 'http://device-ip:8001/local-only-files/{file_id}' \
--header 'X-API-Key: YOUR_API_KEY' \
--header 'Accept: application/json'const response = await fetch("http://device-ip:8001/local-only-files/{file_id}", {
method: "GET",
headers: {
"X-API-Key": "YOUR_API_KEY",
"Accept": "application/json"
}
});
const data = await response.json();
console.log(data);import requests
url = "http://device-ip:8001/local-only-files/{file_id}"
headers = {
"X-API-Key": "YOUR_API_KEY",
"Accept": "application/json"
}
response = requests.get(url, headers=headers)
print(response.json())"anything"binary{
"detail": "text"
}{
"detail": "text"
}{
"detail": "text"
}{
"detail": [
{
"loc": [
"anything"
],
"msg": "text",
"type": "text",
"input": "anything",
"ctx": {}
}
]
}{
"detail": "text",
"error": "capacity_blocked"
}Statistics and Health
/stats reports current usage, the active configuration, capacity against each limit, and what the next cleanup pass will delete. Alert on capacity.storage.percent_used and capacity.records.percent_used above 80%.
Get Stats
Get comprehensive statistics about events and images including capacity and cleanup predictions
200Successful Responseapplication/json
Current state of the system
Show propertiesHide properties
Number of events stored
Number of image files stored
Total bytes used by images
Total storage in human-readable format (binary units)
Timestamp of oldest event (ISO8601)
Timestamp of newest event (ISO8601)
Time range of stored data in days
Human-readable time until oldest data is deleted
Number of draft events awaiting finalization
0Age of the oldest draft event in seconds (None when no drafts)
Current ENV configuration values
Show propertiesHide properties
Data directory path
Number of days to retain data before deletion
Maximum number of event records allowed
Maximum size for a single event record
Maximum record size in human-readable format
Maximum total storage for image files
Maximum storage in human-readable format
How often cleanup runs (in seconds)
Utilization metrics
Show propertiesHide properties
Record count capacity metrics
Show propertiesHide properties
Number of records currently stored
Maximum number of records allowed
Percentage of record capacity used
Storage capacity metrics
Show propertiesHide properties
Total bytes currently used
Bytes used in human-readable format
Maximum bytes allowed
Bytes limit in human-readable format
Percentage of storage capacity used
Average metrics
Show propertiesHide properties
Average size of a record in bytes
Average record size in human-readable format
Average number of images per event
Predictions for next cleanup run
Show propertiesHide properties
Data older than this will be deleted (ISO8601)
Number of records past retention period that cleanup can delete (excludes drafts while cloud upload is enabled)
Number of files past retention period
Bytes that will be freed from old files
Bytes to be freed in human-readable format
Records over the max_records limit
Bytes over the max_storage_bytes limit
Excess bytes in human-readable format
401Missing or invalid `X-API-Key`. Only returned when API_KEY is set on the service; authentication is disabled by default.application/json
500Failed to get stats.application/json
GET /stats HTTP/1.1
Host: device-ip:8001
X-API-Key: YOUR_API_KEY
Accept: application/jsoncurl -L \
--request GET \
--url 'http://device-ip:8001/stats' \
--header 'X-API-Key: YOUR_API_KEY' \
--header 'Accept: application/json'const response = await fetch("http://device-ip:8001/stats", {
method: "GET",
headers: {
"X-API-Key": "YOUR_API_KEY",
"Accept": "application/json"
}
});
const data = await response.json();
console.log(data);import requests
url = "http://device-ip:8001/stats"
headers = {
"X-API-Key": "YOUR_API_KEY",
"Accept": "application/json"
}
response = requests.get(url, headers=headers)
print(response.json()){
"current": {
"total_events": 1,
"total_images": 1,
"total_storage_bytes": 1,
"total_storage_formatted": "text",
"oldest_event_timestamp": "text",
"newest_event_timestamp": "text",
"days_of_data_stored": 1,
"time_until_oldest_data_deleted": "text",
"draft_events": 0,
"oldest_draft_age_seconds": 1
},
"configuration": {
"data_dir": "text",
"retention_days": 1,
"max_records": 1,
"max_record_size_bytes": 1,
"max_record_size_formatted": "text",
"max_storage_bytes": 1,
"max_storage_formatted": "text",
"cleanup_interval_seconds": 1
},
"capacity": {
"records": {
"used": 1,
"limit": 1,
"percent_used": 1
},
"storage": {
"bytes_used": 1,
"bytes_used_formatted": "text",
"bytes_limit": 1,
"bytes_limit_formatted": "text",
"percent_used": 1
},
"averages": {
"record_size_bytes": 1,
"record_size_formatted": "text",
"images_per_event": 1
}
},
"next_cleanup_will_delete": {
"retention_cutoff_timestamp": "text",
"records_past_retention": 1,
"files_past_retention": 1,
"bytes_past_retention": 1,
"bytes_past_retention_formatted": "text",
"excess_records_over_limit": 1,
"excess_bytes_over_limit": 1,
"excess_bytes_formatted": "text"
}
}{
"detail": "text"
}{
"detail": "text"
}Health Check
200Successful Responseapplication/json
Overall health status
Datastore health status
Error message if unhealthy
GET /health HTTP/1.1
Host: device-ip:8001
Accept: application/jsoncurl -L \
--request GET \
--url 'http://device-ip:8001/health' \
--header 'Accept: application/json'const response = await fetch("http://device-ip:8001/health", {
method: "GET",
headers: {
"Accept": "application/json"
}
});
const data = await response.json();
console.log(data);import requests
url = "http://device-ip:8001/health"
headers = {
"Accept": "application/json"
}
response = requests.get(url, headers=headers)
print(response.json()){
"status": "text",
"datastore": "text",
"error": "text"
}Administration
Manual Cleanup
Manually trigger cleanup process (bypasses normal schedule)
This endpoint allows operators to manually trigger data cleanup based on retention policies and storage limits. Useful for: - Freeing storage space immediately instead of waiting for scheduled cleanup - Testing cleanup behavior - Emergency capacity management
The cleanup process will: 1. Delete records older than retention_days 2. Delete oldest records if total exceeds max_records 3. Delete oldest files if total storage exceeds max_storage_bytes
Returns detailed metrics about what was deleted and current storage state.
200Successful Responseapplication/json
How cleanup was triggered (MANUAL or AUTOMATIC)
How long cleanup took to run
Counts of deleted items
Show propertiesHide properties
Total items deleted
Items deleted due to retention policy
Items deleted due to being over limit
Files deleted due to storage limits (files_deleted only)
Counts of deleted items
Show propertiesHide properties
Total items deleted
Items deleted due to retention policy
Items deleted due to being over limit
Files deleted due to storage limits (files_deleted only)
Total bytes freed by cleanup
State counts before or after cleanup
Show propertiesHide properties
Number of records
Number of files
Total bytes used
State counts before or after cleanup
Show propertiesHide properties
Number of records
Number of files
Total bytes used
Consistency check results
Show propertiesHide properties
Whether consistency check ran this cleanup
DB records removed because file was missing from disk
Disk files removed because not in DB
Human-readable summary message
401Missing or invalid `X-API-Key`. Only returned when API_KEY is set on the service; authentication is disabled by default.application/json
500Cleanup failed.application/json
POST /admin/cleanup HTTP/1.1
Host: device-ip:8001
X-API-Key: YOUR_API_KEY
Accept: application/jsoncurl -L \
--request POST \
--url 'http://device-ip:8001/admin/cleanup' \
--header 'X-API-Key: YOUR_API_KEY' \
--header 'Accept: application/json'const response = await fetch("http://device-ip:8001/admin/cleanup", {
method: "POST",
headers: {
"X-API-Key": "YOUR_API_KEY",
"Accept": "application/json"
}
});
const data = await response.json();
console.log(data);import requests
url = "http://device-ip:8001/admin/cleanup"
headers = {
"X-API-Key": "YOUR_API_KEY",
"Accept": "application/json"
}
response = requests.post(url, headers=headers)
print(response.json()){
"trigger": "text",
"duration_seconds": 1,
"records_deleted": {
"total": 1,
"retention": 1,
"overlimit": 1,
"storage": 1
},
"files_deleted": {
"total": 1,
"retention": 1,
"overlimit": 1,
"storage": 1
},
"bytes_freed": 1,
"before": {
"records": 1,
"files": 1,
"bytes": 1
},
"after": {
"records": 1,
"files": 1,
"bytes": 1
},
"consistency": {
"ran": true,
"dangling_db_records_removed": 1,
"orphaned_disk_files_removed": 1
},
"message": "text"
}{
"detail": "text"
}{
"detail": "text"
}Resetting takes two calls so it cannot happen by accident. /reset/request returns a single-use token valid for 60 seconds, and /reset/confirm performs the deletion.
A confirmed reset permanently deletes every event and file in the store. It cannot be undone.
Reset Request
Request a reset token (step 1 of 2)
200Successful Responseapplication/json
Token to use for reset confirmation
Number of seconds until token expires
Instructions for using the token
401Missing or invalid `X-API-Key`. Only returned when API_KEY is set on the service; authentication is disabled by default.application/json
POST /reset/request HTTP/1.1
Host: device-ip:8001
X-API-Key: YOUR_API_KEY
Accept: application/jsoncurl -L \
--request POST \
--url 'http://device-ip:8001/reset/request' \
--header 'X-API-Key: YOUR_API_KEY' \
--header 'Accept: application/json'const response = await fetch("http://device-ip:8001/reset/request", {
method: "POST",
headers: {
"X-API-Key": "YOUR_API_KEY",
"Accept": "application/json"
}
});
const data = await response.json();
console.log(data);import requests
url = "http://device-ip:8001/reset/request"
headers = {
"X-API-Key": "YOUR_API_KEY",
"Accept": "application/json"
}
response = requests.post(url, headers=headers)
print(response.json()){
"reset_token": "text",
"expires_in_seconds": 1,
"message": "text"
}{
"detail": "text"
}Reset Confirm
Confirm reset and delete all data (step 2 of 2)
200Successful Responseapplication/json
Status of the reset operation
Confirmation message
400Missing, invalid, or expired reset token.application/json
401Missing or invalid `X-API-Key`. Only returned when API_KEY is set on the service; authentication is disabled by default.application/json
422Validation Errorapplication/json
Show propertiesHide properties
500Reset failed.application/json
POST /reset/confirm HTTP/1.1
Host: device-ip:8001
X-API-Key: YOUR_API_KEY
Content-Type: application/json
Accept: application/json
{
"reset_token": "text"
}curl -L \
--request POST \
--url 'http://device-ip:8001/reset/confirm' \
--header 'X-API-Key: YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data '{
"reset_token": "text"
}'const response = await fetch("http://device-ip:8001/reset/confirm", {
method: "POST",
headers: {
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json",
"Accept": "application/json"
},
body: JSON.stringify({
"reset_token": "text"
})
});
const data = await response.json();
console.log(data);import requests
url = "http://device-ip:8001/reset/confirm"
headers = {
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json",
"Accept": "application/json"
}
payload = {
"reset_token": "text"
}
response = requests.post(url, headers=headers, json=payload)
print(response.json()){
"status": "text",
"message": "text"
}{
"detail": "text"
}{
"detail": "text"
}{
"detail": [
{
"loc": [
"anything"
],
"msg": "text",
"type": "text",
"input": "anything",
"ctx": {}
}
]
}{
"detail": "text"
}