docs: add PATCH identity endpoint doc + BCP 47 alias reference
This commit is contained in:
516
deliverable_v1.1.0/modules/07_identity.md
Normal file
516
deliverable_v1.1.0/modules/07_identity.md
Normal file
@@ -0,0 +1,516 @@
|
||||
<!-- module: identity -->
|
||||
<!-- description: Global identities — CRUD, detail, files, faces, bind, unbind, search -->
|
||||
<!-- depends: 01_auth -->
|
||||
|
||||
## 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*
|
||||
|
||||
|
||||
@@ -74,6 +74,66 @@ 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 (removed UNIQUE constraint). 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
|
||||
# Update name and add aliases
|
||||
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": "ジョン・スミス"}
|
||||
]
|
||||
}
|
||||
}'
|
||||
|
||||
# Update status only
|
||||
curl -s -X PATCH "$API/api/v1/identity/$IDENTITY_UUID" \
|
||||
-H "X-API-Key: $KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"status": "confirmed"}'
|
||||
```
|
||||
|
||||
#### 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
|
||||
@@ -225,7 +285,7 @@ curl -s "$API/api/v1/identities/search?q=Cary" -H "X-API-Key: $KEY"
|
||||
|
||||
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 `name` already exists, it will be updated with the new values.
|
||||
If an identity with the same `identity_uuid` already exists, it will be updated with the new values.
|
||||
|
||||
#### Request
|
||||
|
||||
@@ -330,7 +390,63 @@ curl -s "$API/api/v1/identity/$IDENTITY_UUID/profile-image" \
|
||||
|----------------|-------|
|
||||
| `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`). Region suffix distinguishes regional variants.
|
||||
|
||||
### Frontend Display Logic
|
||||
|
||||
```javascript
|
||||
function getDisplayName(identity, preferredLocale) {
|
||||
// 1. Exact locale match
|
||||
const match = identity.metadata?.aliases?.find(a => a.locale === preferredLocale);
|
||||
if (match) return match.name;
|
||||
|
||||
// 2. Language-only match (zh-TW → zh)
|
||||
const lang = preferredLocale.split('-')[0];
|
||||
const langMatch = identity.metadata?.aliases?.find(a => a.locale.startsWith(lang));
|
||||
if (langMatch) return langMatch.name;
|
||||
|
||||
// 3. Fallback to identity.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": "約翰·史密斯"}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This **replaces** the entire `aliases` array. To add to existing aliases, include all existing entries in the request.
|
||||
|
||||
---
|
||||
*Updated: 2026-05-19 12:49:24*
|
||||
*Updated: 2026-05-22
|
||||
|
||||
@@ -225,7 +225,7 @@ curl -s "$API/api/v1/identities/search?q=Cary" -H "X-API-Key: $KEY"
|
||||
|
||||
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 `name` already exists, it will be updated with the new values.
|
||||
If an identity with the same `identity_uuid` already exists, it will be updated with the new values.
|
||||
|
||||
#### Request
|
||||
|
||||
|
||||
Reference in New Issue
Block a user