AcqStore Server API v2 contract¶
This document is the written HTTP contract for thin clients. The machine-readable contract is available from a running server at:
http://127.0.0.1:8767/openapi.json
Interactive Swagger documentation is available at:
http://127.0.0.1:8767/docs
For a complete JavaScript implementation, see JavaScript client guide.
Base URLs¶
const SERVER = 'http://127.0.0.1:8767';
const API = `${SERVER}/api/v2`;
The server binds to localhost by default. A thin client always requires a running AcqStore Server instance, either the packaged desktop app or a source-based Python process.
Client lifecycle¶
A complete client normally follows this sequence:
GET /api/v2/health
GET /api/v2/capabilities
POST /api/v2/pick-and-open or POST /api/v2/open
GET returned channel dataUrl values
GET /api/v2/sessions/{sessionId}
DELETE /api/v2/sessions/{sessionId}
Discovery¶
GET /api/v2¶
Returns links to the maintained v2 resources.
GET /api/v2/health¶
Example response:
{
"ok": true,
"api_version": "v2",
"server_version": "0.2.0"
}
api_version is the HTTP contract (v2). server_version is the installed AcqStore Server package version. Use this as the lightest check that the local server and v2 router are available.
Health JSON uses snake_case field names. Other API v2 JSON payloads remain camelCase.
GET /api/v2/capabilities¶
Example response shape:
{
"ok": true,
"apiVersion": "v2",
"supportedImportExtensions": [".tif", ".oir"],
"allowedImportExtensions": [".tif", ".oir"],
"binary": {
"servedDtype": "float32",
"encoding": "raw-f32-le",
"layout": "row-major",
"mediaType": "application/octet-stream"
},
"sessionTtlSeconds": 300.0
}
The extension lists are runtime values sourced from AcqStore. Clients should not hard-code them.
Open an acquisition¶
POST /api/v2/pick-and-open¶
Use the native file picker on the machine running AcqStore Server.
Minimal request:
{}
Optional channel and extension selection:
{
"channelIndices": [0, 1],
"extensions": [".oir", ".czi", ".tif"]
}
Cancelling the dialog is not an HTTP failure. It returns HTTP 200 with:
{
"ok": false,
"error": "cancelled",
"message": "User cancelled file dialog"
}
POST /api/v2/open¶
Use an absolute path visible to the server process:
{
"path": "/absolute/path/to/acquisition.oir",
"channelIndices": [0, 1]
}
Omit channelIndices to load all channels. Requested channel order is preserved.
Successful open response¶
Both open endpoints return the same contract:
{
"ok": true,
"apiVersion": "v2",
"sessionId": "example-session-id",
"source": {
"path": "/absolute/path/to/acquisition.oir",
"name": "acquisition.oir",
"format": "oir",
"sourceDtype": "uint16",
"numChannels": 2
},
"header": {
"shape": [2, 30000, 24],
"dims": ["C", "Y", "X"],
"sizes": {"C": 2, "Y": 30000, "X": 24},
"dtype": "uint16",
"numChannels": 2,
"physicalUnits": [1.0, 0.000535, 0.011414],
"physicalUnitsLabels": ["Channels", "seconds", "micrometer"],
"date": "",
"time": "",
"fileSize": ""
},
"plane": {
"shape": [30000, 24],
"axes": [
{"arrayDimension": 0, "name": "Y", "size": 30000, "step": 0.000535, "unit": "seconds"},
{"arrayDimension": 1, "name": "X", "size": 24, "step": 0.011414, "unit": "micrometer"}
],
"servedDtype": "float32",
"encoding": "raw-f32-le",
"layout": "row-major",
"mediaType": "application/octet-stream"
},
"channels": [
{
"index": 0,
"name": "Channel 0",
"byteLength": 2880000,
"dataUrl": "/api/v2/sessions/example-session-id/channels/0/data"
}
],
"reference": null
}
Field values above are illustrative. Clients must use the values returned by the running server.
header is normalized AcqStore acquisition metadata. plane describes the two-dimensional arrays served for the selected source channels.
Binary source planes¶
GET /api/v2/sessions/{sessionId}/channels/{channelIndex}/data¶
The response body is raw binary:
Content-Type: application/octet-stream
Cache-Control: no-store
Decode it as little-endian float32. Validate:
response byte count == channel.byteLength
float32 sample count == plane.shape[0] * plane.shape[1]
The payload is row-major and has not been transposed by the server.
Reference image¶
When present, reference contains its own plane, channels, optional lineRoi, and optional scanPath. Either geometry field may be null or omitted when the acquisition has no reference line metadata.
Reference binary URL:
GET /api/v2/sessions/{sessionId}/reference/channels/{channelIndex}/data
Decode and validate it using reference.plane and the selected reference channel's byteLength.
lineRoi and scanPath examples¶
Coordinates are in the reference plane's AcqStore pixel space before any client display transpose:
xaligns with array dimension 1 (columns)yaligns with array dimension 0 (rows)
lineRoi is a four-number segment [x0, y0, x1, y1] (start → end):
"lineRoi": [12.0, 40.0, 210.5, 40.0]
scanPath is a polyline as parallel x / y arrays of equal length:
"scanPath": {
"x": [12.0, 80.0, 210.5],
"y": [40.0, 42.5, 40.0]
}
Illustrative reference object (numbers are examples only):
"reference": {
"plane": {
"shape": [512, 512],
"axes": [
{"arrayDimension": 0, "name": "Y", "size": 512, "step": 0.2, "unit": "micrometer"},
{"arrayDimension": 1, "name": "X", "size": 512, "step": 0.2, "unit": "micrometer"}
],
"servedDtype": "float32",
"encoding": "raw-f32-le",
"layout": "row-major",
"mediaType": "application/octet-stream"
},
"channels": [
{
"index": 0,
"byteLength": 1048576,
"dataUrl": "/api/v2/sessions/example-session-id/reference/channels/0/data"
}
],
"lineRoi": [12.0, 40.0, 210.5, 40.0],
"scanPath": {
"x": [12.0, 80.0, 210.5],
"y": [40.0, 42.5, 40.0]
}
}
Prefer scanPath when both are present. A simple point list for drawing:
function referencePathPoints(scanPath, lineRoi) {
if (
scanPath &&
Array.isArray(scanPath.x) &&
Array.isArray(scanPath.y) &&
scanPath.x.length > 0 &&
scanPath.x.length === scanPath.y.length
) {
return scanPath.x.map((x, index) => [x, scanPath.y[index]]);
}
if (Array.isArray(lineRoi) && lineRoi.length === 4) {
return [
[lineRoi[0], lineRoi[1]],
[lineRoi[2], lineRoi[3]],
];
}
return [];
}
If the client transposes the reference plane for display (swap rows/columns), apply the same swap to overlay points: plot (y, x) in the transposed image so the path stays aligned with the pixels.
Session lifecycle¶
GET /api/v2/sessions/{sessionId}¶
Example response:
{
"ok": true,
"sessionId": "example-session-id",
"ttlSecondsRemaining": 294.2,
"channelIndices": [0, 1],
"referenceChannelIndices": [0],
"totalBytes": 5764096
}
DELETE /api/v2/sessions/{sessionId}¶
Example response:
{
"ok": true,
"sessionId": "example-session-id",
"deleted": true
}
Clients should explicitly delete sessions when finished.
Stable errors¶
All v2 JSON errors use:
{
"ok": false,
"error": "stable_machine_code",
"message": "Human-readable summary",
"details": null
}
Request-validation errors include details. Clients should branch on error, not on message text.
Common codes include:
cancelled
path_not_found
unsupported_format
invalid_channel_indices
channel_out_of_range
channel_not_found
reference_channel_not_found
session_not_found
load_timeout
decode_failed
Maintained reference client¶
The maintained v2 client is the built-in demo. When the server is running:
http://127.0.0.1:8767/demo/v2/
Match its behavior from the live page and from Demo; application source code is not required.