POST /identify
Operator bearer token required. multipart/form-data.
string
required
Must be the literal string
"true". Missing or "false" is rejected before any dependency is called — the cheapest possible failure path.file
required
The probe face — no customer identifier of any kind.
searchNearest) — not a loop of 1:1 comparisons. Every call is logged to SearchLog regardless of outcome, with a latencyMs breakdown per stage (liveness, embed, search).
POST /identify/{referenceId}/escalate
Operator bearer token required.
200 OK
escalatedAt on the SearchLog row — a real, logged state, not just “the operator tried again.”
POST /verify/self
Consumer bearer token required. multipart/form-data, field image. Scoped to the caller’s own record — a single lookup against their own canonical embedding, not a database-wide search, so it stays responsive even under heavy /identify load.
200 OK — match
200 OK — no match
proofToken is only present on match — short-lived (PROOF_TOKEN_TTL_SECONDS, default 120s), single-use, and required to gate PATCH/DELETE /users/{id} (see Profile).
A high-confidence match also upserts the canonical embedding with this newer capture (the freshness rule from Epic 3, story 15) — the searchable record always reflects the most recent proven appearance, not whichever image was captured first.