## Global Identities ### `GET /api/v1/identities` **Auth**: Required **Scope**: identity-level List all registered identities with pagination. #### Example ```bash curl -s "$API/api/v1/identities?page=1&page_size=20" -H "X-API-Key: $KEY" | jq '{count, identities: [.identities[] | {name}]}' ``` --- ### `GET /api/v1/identity/:identity_uuid` **Auth**: Required **Scope**: identity-level Get detailed information for a specific identity, including metadata and TMDb references. #### Example ```bash curl -s "$API/api/v1/identity/$IDENTITY_UUID" -H "X-API-Key: $KEY" ``` #### Response (200) ```json { "success": true, "identity_uuid": "a9a901056d6b46ff92da0c3c1a57dff4", "name": "Cary Grant", "identity_type": "people", "source": "tmdb", "status": "confirmed", "tmdb_id": 112, "tmdb_profile": "{output}/identities/{identity_uuid}/profile.jpg", "metadata": {}, "reference_data": {}, "created_at": "2026-05-16T12:00:00Z", "updated_at": null } ``` | Field | Type | Description | |-------|------|-------------| | `identity_uuid` | string | Identity identifier | | `name` | string | Identity name | | `identity_type` | string | `"people"` or null | | `source` | string | `.json`, `auto`, `tmdb`, `user_defined`, or `merged` | | `status` | string | `"confirmed"`, `"pending"`, or `"inactive"` | | `tmdb_id` | integer | TMDb person ID (only if source = tmdb) | | `tmdb_profile` | string | Local profile image path (`{output}/identities/{uuid}/profile.jpg`) | | `metadata` | object | Metadata JSON (tmdb_character, cast_order, etc.) | | `created_at` | string | Creation timestamp | --- ### `DELETE /api/v1/identity/:identity_uuid` **Auth**: Required **Scope**: identity-level Delete an identity permanently. --- ### `PATCH /api/v1/identity/:identity_uuid` **Auth**: Required **Scope**: identity-level Partially update an identity. Only provided fields are modified. The `name` field is a display label and may repeat across identities. Aliases for multilingual display are stored in `metadata.aliases` (see BCP 47 reference below). #### Request (JSON, all fields optional) | Field | Type | Description | |-------|------|-------------| | `name` | string | New display name | | `metadata` | object | Merged into existing metadata. Use `"aliases"` key for locale-tagged names | | `status` | string | `"confirmed"`, `"pending"`, or `"skipped"` | | `identity_type` | string | `"people"`, `"brand"`, `"object"`, `"concept"`, etc. | #### Example ```bash curl -s -X PATCH "$API/api/v1/identity/$IDENTITY_UUID" \ -H "X-API-Key: $KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "John Smith", "metadata": { "aliases": [ {"locale": "en", "name": "John Smith"}, {"locale": "zh-TW", "name": "約翰·史密斯"}, {"locale": "ja", "name": "ジョン・スミス"} ] } }' ``` #### Response (200) ```json { "success": true, "identity_uuid": "a9a901056d6b46ff92da0c3c1a57dff4", "updated_fields": ["name", "metadata"] } ``` #### Error Responses | HTTP | When | |------|------| | `400` | No fields to update or invalid UUID format | | `404` | Identity not found | --- ### `GET /api/v1/identity/:identity_uuid/files` **Auth**: Required **Scope**: identity-level Get all files where this identity appears. Returns per-file summary including face count, confidence, and appearance time range. #### Example ```bash curl -s "$API/api/v1/identity/$IDENTITY_UUID/files" -H "X-API-Key: $KEY" ``` #### Response (200) ```json { "success": true, "identity_uuid": "c3545906c82d4b66aa1d150bc02decce", "total": 1, "page": 1, "page_size": 20, "data": [ { "file_uuid": "aeed71342a899fe4b4c57b7d41bcb692", "file_name": "Charade (1963) Cary Grant & Audrey Hepburn.mp4", "file_path": "/path/to/videos/Charade.mp4", "status": "completed", "face_count": 19695, "speaker_count": 0, "first_appearance": 206.76, "last_appearance": 6756.68, "confidence": 0.803 } ] } ``` #### Response Fields | Field | Type | Description | |-------|------|-------------| | `file_uuid` | string | File identifier (full 32-char hex) | | `file_name` | string | Video file name | | `file_path` | string | Absolute path to video file | | `status` | string | Video processing status (`"completed"`, `"processing"`, etc.) | | `face_count` | int | Total face detections for this identity in this file | | `speaker_count` | int | Speaker segments (reserved, always `0`) | | `first_appearance` | float | First appearance time in seconds (computed from `frame_number / fps`) | | `last_appearance` | float | Last appearance time in seconds | | `confidence` | float | Average detection confidence | --- ### `GET /api/v1/identity/:identity_uuid/faces` **Auth**: Required **Scope**: identity-level Get all face detection records associated with this identity. #### Example ```bash curl -s "$API/api/v1/identity/$IDENTITY_UUID/faces?page=1&page_size=20" -H "X-API-Key: $KEY" ``` #### Response (200) ```json { "success": true, "identity_uuid": "c3545906c82d4b66aa1d150bc02decce", "total": 19695, "page": 1, "page_size": 20, "data": [ { "id": 655704, "file_uuid": "aeed71342a899fe4b4c57b7d41bcb692", "frame_number": 5169, "timestamp_secs": 206.76, "face_id": "5169_0", "bbox": { "x": 706, "y": 469, "width": 618, "height": 618 }, "confidence": 0.855 } ] } ``` #### Response Fields | Field | Type | Description | |-------|------|-------------| | `id` | int64 | Face detection record ID | | `file_uuid` | string | File where face was detected | | `frame_number` | int64 | Frame number (primary coordinate) | | `timestamp_secs` | float | Time in seconds (computed as `frame_number / fps`) | | `face_id` | string | Face ID (format: `{frame_number}_{detection_index}`) | | `bbox` | object | Bounding box | | `bbox.x` | float | Left coordinate | | `bbox.y` | float | Top coordinate | | `bbox.width` | float | Width in pixels | | `bbox.height` | float | Height in pixels | | `confidence` | float | Detection confidence (0.0–1.0) | --- ### `GET /api/v1/identity/:identity_uuid/chunks` **Auth**: Required **Scope**: identity-level Get all text chunks (sentences) spoken while this identity's face was on screen. Useful for finding what a person said. #### Example ```bash curl -s "$API/api/v1/identity/$IDENTITY_UUID/chunks" -H "X-API-Key: $KEY" ``` #### Response (200) ```json { "success": true, "identity_uuid": "a9a901056d6b46ff92da0c3c1a57dff4", "data": [ { "id": 0, "file_uuid": "bd80fec92b0b6963d177a2c55bf713e2", "chunk_id": "bd80fec92b0b6963d177a2c55bf713e2_2", "chunk_type": "sentence", "start_frame": 5103, "end_frame": 5127, "fps": 24.0, "start_time": 212.64, "end_time": 213.64, "text_content": "[213s-214s] Cary Grant: \"Olá!\"" } ] } ``` | Field | Type | Description | |-------|------|-------------| | `file_uuid` | string | File identifier | | `chunk_id` | string | Sentence chunk identifier | | `start_frame` | integer | Frame-accurate start position | | `end_frame` | integer | Frame-accurate end position | | `fps` | float | Frames per second | | `start_time` | float | Start time in seconds | | `end_time` | float | End time in seconds | | `text_content` | string | Spoken text content | --- ### `POST /api/v1/identity/:identity_uuid/bind` **Auth**: Required **Scope**: identity-level Bind a face detection to an identity. Associates the face trace with the identity for future search and recognition. #### Request Parameters | Field | Type | Required | Description | |-------|------|----------|-------------| | `file_uuid` | string | Yes | File where face is detected | | `face_id` | string | Yes | Face ID (format: `{frame}_{idx}`) | #### Example ```bash curl -s -X POST "$API/api/v1/identity/$IDENTITY_UUID/bind" \ -H "X-API-Key: $KEY" \ -H "Content-Type: application/json" \ -d '{"file_uuid": "'"$FILE_UUID"'", "face_id": "1_5"}' ``` --- ### `POST /api/v1/identity/:identity_uuid/unbind` **Auth**: Required **Scope**: identity-level Unbind a face detection from an identity. Removes the identity association from the face record. --- ### `GET /api/v1/identities/search` **Auth**: Required **Scope**: identity-level Search identities by name (ILIKE search). Returns matching identity records. #### Example ```bash curl -s "$API/api/v1/identities/search?q=Cary" -H "X-API-Key: $KEY" ``` | Field | Type | Description | |-------|------|-------------| | `name` | string | Identity name | | `source` | string | Identity source | | `tmdb_id` | integer | TMDb ID (if source = tmdb) | | `file_uuid` | string | Associated file | --- --- ### `POST /api/v1/identity/upload` **Auth**: Required **Scope**: identity-level Upload an identity.json file to create or update an identity. Accepts the same format as the identity.json files stored on disk. If an identity with the same `identity_uuid` already exists, it will be updated with the new values. #### Request The request body is an `IdentityFile` object: | Field | Type | Required | Description | |-------|------|----------|-------------| | `identity_uuid` | string | Yes | Identity identifier | | `name` | string | Yes | Identity display name | | `identity_type` | string | No | `"people"` or null | | `source` | string | No | `.json`, `auto`, `tmdb`, `user_defined`, or `merged` | | `status` | string | No | `"confirmed"`, `"pending"`, or `"inactive"` | | `tmdb_id` | integer | No | TMDb person ID | | `tmdb_profile` | string | No | TMDb profile image URL | | `metadata` | object | No | Arbitrary metadata JSON | | `file_bindings` | array | No | Array of `{ file_uuid, trace_ids, face_count }` (informational) | #### Example ```bash curl -s -X POST "$API/api/v1/identity/upload" \ -H "X-API-Key: $KEY" \ -H "Content-Type: application/json" \ -d '{ "version": 1, "identity_uuid": "a9a901056d6b46ff92da0c3c1a57dff4", "name": "Cary Grant", "identity_type": "people", "source": ".json", "status": "confirmed", "metadata": {}, "file_bindings": [] }' ``` #### Response (200) ```json { "success": true, "identity_uuid": "a9a901056d6b46ff92da0c3c1a57dff4", "name": "Cary Grant", "message": "Identity uploaded successfully" } ``` --- --- ### `POST /api/v1/identity/:identity_uuid/profile-image` **Auth**: Required **Scope**: identity-level Upload a profile image (JPEG or PNG) for an identity. The image is saved to `{output}/identities/{uuid}/profile.{ext}`. Uses `multipart/form-data` with field name `image`. #### Example ```bash curl -s -X POST "$API/api/v1/identity/$IDENTITY_UUID/profile-image" \ -H "X-API-Key: $KEY" \ -F "image=@/path/to/photo.jpg" ``` #### Response (200) ```json { "success": true, "identity_uuid": "a9a901056d6b46ff92da0c3c1a57dff4", "path": "/path/to/output/identities/.../profile.jpg", "message": "Profile image saved: profile.jpg" } ``` #### Error Responses | HTTP | When | |------|------| | `400` | Missing image field or unsupported format | | `404` | Identity not found | | `415` | Unsupported image type (use JPEG or PNG) | --- ### `GET /api/v1/identity/:identity_uuid/profile-image` **Auth**: Required **Scope**: identity-level Retrieve the profile image for an identity. Returns the raw image data with appropriate Content-Type header. ```bash curl -s "$API/api/v1/identity/$IDENTITY_UUID/profile-image" \ -H "X-API-Key: $KEY" -o profile.jpg ``` | Response Header | Value | |----------------|-------| | `content-type` | `image/jpeg` or `image/png` | --- ## Alias System (BCP 47 Locale Tags) Identity aliases support multilingual display names. Aliases are stored in `metadata.aliases` as an array of `{locale, name}` objects. ### BCP 47 Locale Tags Reference | Locale | Tag | Example | |--------|-----|---------| | English | `en` | John Smith | | Traditional Chinese | `zh-TW` | 約翰·史密斯 | | Simplified Chinese | `zh-CN` | 约翰·史密斯 | | Japanese | `ja` | ジョン・スミス | | Korean | `ko` | 존 스미스 | | Cantonese | `yue` | 約翰·史密夫 | | French | `fr` | John Smith (French spelling) | | Spanish | `es` | Juan Smith | | Arabic | `ar` | جون سميث | | Russian | `ru` | Джон Смит | | Thai | `th` | จอห์น สมิธ | BCP 47 is the IETF standard for language tags. Format: `language` (e.g. `en`, `ja`) or `language-Region` (e.g. `zh-TW`, `zh-CN`). ### Frontend Display Logic ```javascript function getDisplayName(identity, preferredLocale) { const match = identity.metadata?.aliases?.find(a => a.locale === preferredLocale); if (match) return match.name; const lang = preferredLocale.split('-')[0]; const langMatch = identity.metadata?.aliases?.find(a => a.locale.startsWith(lang)); if (langMatch) return langMatch.name; return identity.name; } ``` ### Updating Aliases via PATCH ```json PATCH /api/v1/identity/:identity_uuid { "metadata": { "aliases": [ {"locale": "en", "name": "John Smith"}, {"locale": "zh-TW", "name": "約翰·史密斯"} ] } } ``` --- *Updated: 2026-05-22*