GenuineAIGenuineAI
For usersFor developers
  • Overview
  • Guides
  • How-to
  • API reference
Documentation
  • Quickstart
  • Authentication
  • Errors
  • Rate limits
  • API reference
Platform
  • Platform overview
  • Solutions
  • Pricing
  • Sign in
Company
  • Status
  • Trust Center
  • Contact
  • Terms of Service
  • Privacy Policy

© 2026 GenuineAI Ventures LLC

support@genuinehq.com
Media library
Uploading filesOrganizing and finding assetsDelivering assetsPublishing assets
AI
AI enrichmentPeople and facesAgents and conversations
Knowledge
Knowledge basesHow agents use knowledge
Automation
Autonomous AIExternal dataExtensions
Creating and deploying
Generating contentDeployed AI
Operations
Usage and credits
How-to

People and faces

Beta

The People endpoints are marked beta: they may change on 30 days notice rather than the usual 90. See versioning.

Face recognition here is deliberately not automatic end to end. Detection is automatic, but identity is a decision a person makes, and the API is shaped around that:

Code
detection → suggestion → a human confirms → the person's index improves

The middle step is the important one. A suggestion is the matcher proposing a probable match. It is not an assignment, and nothing is attributed to anyone until it is confirmed.

Detections

Faces are found during analysis. GET /files/{id}/faces lists what was found in one photo, most confident first, each with the person it was matched to if any:

Code
{ "data": [ { "fd_id": "3f2a9c1e-…", "fd_file": "8a1b6e5c-…", "fd_person": "7b444c0d-…", "fd_low_quality": false, "fd_box": { "x": 0.31, "y": 0.12, "width": 0.09, "height": 0.14 } } ] }

fd_low_quality marks a face too blurry to match reliably. These detections still exist and still display, but they are excluded from matching and from face counts, which is why a photo with six blurry people in the background does not report six faces.

The photo's file_metadata.faceCount is the countable total, and has_faces=true on the media library filters on it.

People

A person is a cluster of faces, with or without a name attached. A face detected in twelve photos that nobody has named is still a person, just an unnamed one.

Code
GET /people

Most-photographed first, each with counts:

Code
{ "data": [ { "fp_id": "7b444c0d-…", "fp_name": "Dana Reyes", "face_count": 47, "manual_count": 6, "suggestion_count": 3 } ] }
face_countFaces assigned to this person.
manual_countHow many of those a human confirmed. These are the references the matcher trusts most.
suggestion_countFaces waiting for review.

Two filters exist for the two queues worth working through: unnamed=true for clusters nobody has named, and needs_review=true for people with suggestions pending.

GET /people/{id}/photos lists the photos someone appears in and applies each file's own access rules, so two callers asking about the same person can legitimately get different photos back.

Assign a face to a person

POST /people/assign assigns one detection. Omit fp_id and a new person is created for it, which is how someone is named for the first time:

POST /people/unassign reverses it. PUT /people/{id} renames, POST /people/{id}/set-cover chooses the face shown as their thumbnail, and DELETE /people/{id} removes the person while leaving the underlying detections alone.

Each confirmed assignment improves the next match. Manual assignments are the references the matcher ranks first, so naming a handful of clear photos of someone early is worth more than correcting fifty later.

The review queue

Code
GET /people/suggestions

Faces the matcher believes belong to someone already named, closest first. Filter to one person with fp_id. Resolve them one at a time with POST /people/suggestions/{id}/confirm or /reject, or in bulk:

TerminalCode
curl -X POST https://api.genuineai.app/api/v1/people/suggestions/actions/resolve \ -H "X-Api-Key: gai_…" -H "X-Tenant-Id: <workspace-id>" \ -H "Content-Type: application/json" \ -d '{"action": "confirm", "fd_ids": ["3f2a9c1e-…", "8a1b6e5c-…"]}'
Code
{ "confirmed": 12, "rejected": 0, "skipped": 2 }

skipped counts suggestions already assigned or already resolved by someone else. The batch does not fail over them, which matters when two reviewers work the same queue. Read the counts to see what your call actually did.

What the queue does not show you

The suggestion list is filtered before you see it rather than after. Three checks withhold a suggestion rather than making you reject it:

  • Gender. A candidate with a confidently estimated gender that never appears among the person's confidently-gendered references is never suggested.
  • Age. A candidate more than 20 years from the person's median age is withheld.
  • A no_match verdict from the vision check below.

This is why the queue is usually shorter than the raw match count, and why an obviously wrong suggestion is worth reporting: it means one of these checks is not working.

Verify suggestions with vision

Code
POST /people/{id}/suggestions/verify

Runs one vision comparison of the person's reference faces against each unverified candidate and records match, no_match or unsure. It catches what face embeddings cannot: twins, siblings, and the same person at very different ages.

It decides nothing on its own. Verdicts come back through the suggestion list, and a no_match withholds that suggestion from the queue. It is idempotent and skips already-verified candidates, so calling it twice costs nothing. Run it before a review session so the queue you hand to a person is already filtered.

Merge and reindex

Two clusters representing the same person is the normal failure mode: someone photographed across a decade, or with and without glasses.

TerminalCode
curl -X POST https://api.genuineai.app/api/v1/people/merge \ -H "X-Api-Key: gai_…" -H "X-Tenant-Id: <workspace-id>" \ -H "Content-Type: application/json" \ -d '{"source_id": "3f2a9c1e-…", "target_id": "7b444c0d-…"}'

Every face moves from source_id onto target_id, and the source is retired. There is no unmerge, so confirm the direction before calling it.

POST /people/{id}/reindex rebuilds a person's face index from their current assignments. Run it after a large merge or a batch of corrections, so subsequent matching uses the improved reference set.

Search by face

Two options, answering different questions:

face_person=<fp_id> on GET /media-filesPhotos of someone you have named. Exact, cheap, no model call.
face_embedding=[…]Photos resembling a face you supply, named or not. See AI enrichment.

Use the first whenever the person already exists. It is a lookup rather than a search.

How matching works

Every face is reduced to a numeric descriptor, and matching compares the Euclidean distance between two of them. Three outcomes follow. Close enough, and the face is assigned automatically. In a middle band, it becomes a suggestion for someone to confirm or reject. Beyond that, it is not treated as a match at all.

That middle band is the entire review queue. Tightening the point where a match becomes automatic sends more faces to review and produces fewer mistakes; loosening it does the reverse. Faces below a minimum size are never matched automatically whatever the distance, because a small crop's descriptor is not reliable.

The thresholds are workspace-level tuning rather than per-request parameters, and the defaults are calibrated against the canonical cutoff for the descriptor in use.

Next steps

  • AI enrichment covers what detection runs alongside.
  • Organizing and finding assets shows the face filters in context.
  • Sharing and access explains why two people see different photos of the same person.
Last modified on October 8, 2026
AI enrichmentAgents and conversations
On this page
  • Detections
  • People
  • Assign a face to a person
  • The review queue
    • What the queue does not show you
    • Verify suggestions with vision
  • Merge and reindex
  • Search by face
  • How matching works
  • Next steps
JSON
JSON
# name a new person from a detected face curl -X POST https://api.genuineai.app/api/v1/people/assign \ -H "X-Api-Key: gai_…" -H "X-Tenant-Id: <workspace-id>" \ -H "Content-Type: application/json" \ -d '{"fd_id": "3f2a9c1e-…", "fp_name": "Dana Reyes"}' # add a face to someone who already exists curl -X POST https://api.genuineai.app/api/v1/people/assign \ -H "X-Api-Key: gai_…" -H "X-Tenant-Id: <workspace-id>" \ -H "Content-Type: application/json" \ -d '{"fd_id": "8a1b6e5c-…", "fp_id": "7b444c0d-…"}'
JSON