POST /v1/action
Run one VLA action step (unit-billed, per call)
Robot action route (route_type: action; task #37). Single-shot VLA turn: camera frame(s) + instruction + robot state in, an action-chunk JSON out. Multipart/form-data ONLY; the body crosses to the card VERBATIM (original boundary included — byte integrity is the contract; the dial is POST <lane-base>/action). Accepted form fields — model (required), instruction (REQUIRED non-empty on every row, uniformly — a model whose adapter ignores it still receives it; required→optional is additive later, the reverse breaking), state (required: a JSON-encoded array of numbers; the empty array [] is the legal stateless embodiment; anything else is 400 invalid_param/state), and one or more image FILE parts (the composite payload's own slot name — vision's single-kind payload stays file). Chunk length/horizon is the MODEL's own property, not a request param — horizon, chunk_size, or any other field/query is 400 unknown_param naming it. The 25 MiB multipart family cap applies (413, refused before any connection is made). Metering: unit_type='calls' — ONE billed call per SERVED (2xx) request, request-stamped (never model-reported); usage on every answer is OUR {calls, cost} at 6dp. The response's normalization block — the per-embodiment normalization statistics the card applied — is ROUTE CONTRACT and crosses byte-intact (its content is the card's artifact). An unparseable 2xx body relays verbatim (the row already billed the call). Lane saturation at the provider relays as CLIENT 429 rate_limited (never a 502) with the card's Retry-After forwarded when present, non-rotating, the turn unbilled. Idempotency-Key: accepted and logged, NO replay semantics (§8 route-scope — the multipart family; a retrying client pays twice, documented). The robot models ship UNLISTED at launch (task #37): absent from /v1/models and a plain 404 here until each model's serving lane comes online.
Request
The body is multipart/form-data — one part per field below; the sample sends it
with curl -F legs (curl owns the boundary — no Content-Type header).
Request body fields for runAction | Field | Type | Required | Description |
| model | string | yes | An IronStratum alias whose route_type is action. |
| instruction | string | yes | Required non-empty on every row (uniform law — models whose adapters ignore it still require the field). |
| state | string | yes | A JSON-encoded array of numbers (multipart has no native array type); "[]" is the legal stateless embodiment. |
| image | array of string (binary) | yes | One or more camera frames (1-3 in practice; the body cap bounds the count). |
Responses
200 The action chunk
200 response fields for runAction | Field | Type | Required | Description |
| actions | array of array of number | no | The action chunk — arrays of actuator deltas, the card's own shape. |
| normalization | object | no | The per-embodiment normalization statistics the card applied — route CONTRACT, passed through byte-intact (the stats content is the card's artifact). |
| usage | object | no | OUR count and OUR retail cost — the card's token-shaped usage block never crosses. |
400 400
400 response fields for runAction | Field | Type | Required | Description |
| error | object | yes | — |
401 401
401 response fields for runAction | Field | Type | Required | Description |
| error | object | yes | — |
402 402
402 response fields for runAction | Field | Type | Required | Description |
| error | object | yes | — |
403 403
403 response fields for runAction | Field | Type | Required | Description |
| error | object | yes | — |
404 404
404 response fields for runAction | Field | Type | Required | Description |
| error | object | yes | — |
413 413
413 response fields for runAction | Field | Type | Required | Description |
| error | object | yes | — |
429 429
429 response fields for runAction | Field | Type | Required | Description |
| error | object | yes | — |
500 500
500 response fields for runAction | Field | Type | Required | Description |
| error | object | yes | — |
502 502
502 response fields for runAction | Field | Type | Required | Description |
| error | object | yes | — |
503 503
503 response fields for runAction | Field | Type | Required | Description |
| error | object | yes | — |
Example
curl -X POST https://api.ironstratum.com/v1/action \
-H "Authorization: Bearer $IRONSTRATUM_API_KEY" \
-F model=<model>
-F instruction=<instruction>
-F state=<state>
-F image=@<image>
All operations ·
interactive reference ·
openapi.yaml