Envelope
Every call to the Face API uses the same request envelope. The
verb is in the JSON body's action field, not the URL path. One
endpoint, one auth header, nine actions.
Endpoint
POST https://api.biofrq.com/v1/face/execute
Request
json
{
"action": "biofrq.detect",
"requestId": "optional-uuid-you-generate",
"params": {
"images": [
{
"kind": "image",
"bytes": "<base64-encoded image bytes>",
"contentType": "image/jpeg"
}
]
},
"debug": false
}
| Field | Type | Required | Notes |
|---|---|---|---|
action | string | yes | One of the nine actions in this reference. |
requestId | UUID | no | Server generates one if omitted. Returned on every response — capture it for reconciliation. |
params | object | yes | Shape varies per action. Image inputs always live under params.images[] (see below). |
debug | bool | no | Adds provider IDs and raw scores to the response. Off by default. |
Image inputs
Every action that takes an image takes it inside params.images[],
an array of ImageItem objects:
| Field | Type | Required | Notes |
|---|---|---|---|
kind | "image" | yes | Always the literal string "image". |
bytes | string | yes | Base64-encoded image bytes. |
contentType | "image/jpeg" | "image/jpg" | "image/png" | yes | Wire content-type of the encoded bytes. |
correlationId | string | no | Echoed back on the per-item result; useful for batch calls. |
Single-image actions (detect, liveness, enroll, analyze,
attributes) read params.images[0]. verify takes one or two
images[] depending on the comparison mode.
Headers
| Header | Required | Notes |
|---|---|---|
X-Api-Key | yes | Your bfq_live_… key. |
Content-Type | yes | application/json. |
X-Api-Version | no | Defaults to 1. The path already carries /v1/; this header is reserved for envelope-level revisions. |
Response — success
json
{
"ok": true,
"requestId": "2c3f8b1a-9ed3-7c4a-8a1b-...",
"action": "biofrq.detect",
"data": {
"results": [
{
"index": 0,
"correlationId": "auto-0",
"ok": true,
"value": { /* per-action payload */ }
}
]
},
"errors": []
}
ok: truemeans the action ran cleanly anddata.results[0].valuecarries the per-action payload (documented on each action's page).data.results[]is always an array — single-image actions return a one-element array; batch shapes can return more.errorsis empty on success.
Response — error
json
{
"ok": false,
"requestId": "2c3f8b1a-9ed3-7c4a-8a1b-...",
"action": "biofrq.detect",
"data": null,
"errors": [
{
"code": "RATE_LIMITED",
"message": "Project rate limit exceeded."
}
]
}
- Action-level failures still return HTTP 200 with
ok: false; branch on the top-levelokflag, not the HTTP status. - Auth + decode failures (
UNAUTHORIZED,INVALID_REQUESTfor malformed JSON,PAYLOAD_TOO_LARGE) return non-200 HTTP statuses with a{"detail": "..."}body — they don't go through the action envelope at all.
See Errors for the full catalog.
Idempotency
A client-supplied requestId replayed within the server's dedup
window returns the original response with the idempotencyReplay
flag set on the response meta block (when meta is populated).
A replay is not billed twice.