profile API
Profile Management¶
Endpoints for managing trace profiles (face track metadata stored in TKG) and file profiles (video metadata stored in PostgreSQL).
Terminology¶
Core Concepts¶
| Term | Definition | Identifier | Display Format |
|---|---|---|---|
| Face | A single human face detection on one frame | face_id |
Usually not displayed |
| Face Sequence (Trace) | A collection of faces across multiple frames representing the same person | trace_id |
FS#233 |
| Face Group | A collection of traces sharing the same name/label | label (string) |
"Person A" |
Data Model Hierarchy¶
Video
└── Frame (F#233, F#234, ...) ← Single frame number
└── Face ← Single detection (bbox + confidence)
└── Face Sequence / Trace ← Same person across frames (FS#233)
└── Face Group ← Multiple traces with same name
Example¶
Video: "interview.mp4"
├── Frame F#100
│ └── Face (bbox: {100, 200, 50, 50}, confidence: 0.95)
├── Frame F#105
│ └── Face (bbox: {110, 205, 48, 48}, confidence: 0.92)
├── Frame F#110
│ └── Face (bbox: {115, 210, 52, 52}, confidence: 0.88)
...
Face Sequence FS#233 = [Face@F#100, Face@F#105, Face@F#110, ...]
↓
Face Group "Person A" = [FS#233, FS#234, FS#235]
Storage¶
| Entity | Storage | Table/Collection |
|---|---|---|
| Face | Qdrant | _faces collection |
| Face Sequence / Trace | PostgreSQL (TKG) | tkg_nodes where node_type='face_track' |
| Face Group | PostgreSQL (TKG) | tkg_nodes.label field |
Operations¶
| Operation | Level | API |
|---|---|---|
| View faces | Face | Internal (embedded in trace data) |
| Merge traces | Trace | POST /api/v1/trace/:file_uuid/merge |
| Rename group | Group | PUT /api/v1/trace-profile/group |
| Merge groups | Group | POST /api/v1/file/:file_uuid/groups/merge |
Naming Convention¶
- Frame:
F#{number}— e.g.,F#233 - Face Sequence / Trace:
FS#{number}— e.g.,FS#233 - Face Group: String name — e.g.,
"Person A","Speaker 1"
GET /api/v1/trace-profile¶
Auth: Required Scope: file-level
Read a single face trace's profile including name, key frame, key face, and multi-language aliases.
Request Parameters¶
| Field | Type | Required | Description |
|---|---|---|---|
file_uuid |
string | Yes | File UUID |
trace_id |
integer | Yes | Trace ID (numeric) |
Example¶
Response (200)¶
{
"file_uuid": "9f6a9cd55a5809f977f5a6589b9045c5",
"trace_id": 7,
"name": "John Doe",
"key_frame": 640,
"key_face": "face_12345",
"aliases": {
"en": "John Doe",
"zh": "約翰"
},
"properties": {
"status": "bound",
"avg_bbox": {"x": 899, "y": 212, "width": 342, "height": 342},
"start_frame": 624,
"end_frame": 669,
"frame_count": 5
}
}
| Field | Type | Description |
|---|---|---|
file_uuid |
string | File UUID |
trace_id |
integer | Trace ID |
name |
string | Display name (from tkg_nodes.label) |
key_frame |
integer | Representative frame number, or null |
key_face |
string | Representative face ID, or null |
aliases |
object | Multi-language name aliases |
properties |
object | Full TKG node properties (bbox, frames, etc.) |
Error Responses¶
| HTTP | When |
|---|---|
404 |
Trace not found |
401 |
Missing or invalid API key |
PUT /api/v1/trace-profile¶
Auth: Required Scope: file-level
Update a single face trace's profile fields. Only provided fields are updated; others remain unchanged.
Request Body¶
| Field | Type | Required | Description |
|---|---|---|---|
file_uuid |
string | Yes | File UUID |
trace_id |
integer | Yes | Trace ID to update |
name |
string | No | New display name |
key_frame |
integer | No | Representative frame number |
key_face |
string | No | Representative face ID |
aliases |
object | No | Multi-language aliases {"en": "...", "zh": "..."} |
properties |
object | No | Additional properties to merge into existing JSONB |
Example¶
curl -s -X PUT "$API/api/v1/trace-profile" \
-H "X-API-Key: $KEY" \
-H "Content-Type: application/json" \
-d '{
"file_uuid": "9f6a9cd55a5809f977f5a6589b9045c5",
"trace_id": 7,
"name": "John Doe",
"key_frame": 640,
"key_face": "face_12345",
"aliases": {"en": "John Doe", "zh": "約翰"}
}'
Response (200)¶
{
"success": true,
"message": "Trace profile updated",
"file_uuid": "9f6a9cd55a5809f977f5a6589b9045c5",
"trace_id": 7
}
PUT /api/v1/trace-profile/group¶
Auth: Required Scope: file-level
Batch update the name (label) for multiple traces in a face group. Used when renaming a group.
Request Body¶
| Field | Type | Required | Description |
|---|---|---|---|
file_uuid |
string | Yes | File UUID |
trace_ids |
integer[] | Yes | List of trace IDs to update |
name |
string | Yes | New group name for all traces |
Example¶
curl -s -X PUT "$API/api/v1/trace-profile/group" \
-H "X-API-Key: $KEY" \
-H "Content-Type: application/json" \
-d '{
"file_uuid": "9f6a9cd55a5809f977f5a6589b9045c5",
"trace_ids": [7, 2, 13],
"name": "Group A"
}'
Response (200)¶
{
"success": true,
"message": "Updated 3 traces in group",
"file_uuid": "9f6a9cd55a5809f977f5a6589b9045c5",
"updated_count": 3
}
POST /api/v1/file/:file_uuid/groups/merge¶
Auth: Required Scope: file-level
Merge multiple face groups into one target group. All traces from source groups are reassigned to the target group name.
Request Body¶
| Field | Type | Required | Description |
|---|---|---|---|
file_uuid |
string | Yes | File UUID |
source_groups |
string[] | Yes | List of group names to merge from |
target_group_name |
string | Yes | Target group name to merge into |
Examples¶
Merge 2 groups:
curl -s -X POST "$API/api/v1/file/$FILE_UUID/groups/merge" \
-H "X-API-Key: $KEY" \
-H "Content-Type: application/json" \
-d '{
"file_uuid": "c36f35685177c981aa139b66bbbccc5b",
"source_groups": ["Person A"],
"target_group_name": "Person B"
}'
Merge 4 groups:
curl -s -X POST "$API/api/v1/file/$FILE_UUID/groups/merge" \
-H "X-API-Key: $KEY" \
-H "Content-Type: application/json" \
-d '{
"file_uuid": "c36f35685177c981aa139b66bbbccc5b",
"source_groups": ["Person A", "Person C", "Person D"],
"target_group_name": "Person B"
}'
Response (200)¶
{
"success": true,
"file_uuid": "c36f35685177c981aa139b66bbbccc5b",
"source_groups": ["Person A", "Person C", "Person D"],
"target_group_name": "Person B",
"traces_merged": 12,
"message": "Merged 3 group(s) into 'Person B'"
}
Error Responses¶
| HTTP | Condition |
|---|---|
400 |
Target group in source_groups list |
400 |
Empty source_groups array |
500 |
Database error |
Behavior¶
- Find all traces with
label IN (source_groups) - Update their labels to
target_group_name - All source groups disappear (no traces left)
- Target group contains all traces from merged groups
Merging Groups: Two Methods¶
Method 1: Use Merge Groups API (Recommended)¶
POST /api/v1/file/:file_uuid/groups/merge
{
"file_uuid": "...",
"source_groups": ["Person A", "Person C"],
"target_group_name": "Person B"
}
Pros: Simple, only requires group names, supports multi-group merge Cons: New API (requires backend update)
Method 2: Use Batch Update API (Existing)¶
PUT /api/v1/trace-profile/group
{
"file_uuid": "...",
"trace_ids": [13, 14, 15, 43, 44],
"name": "Person B"
}
Pros: Works with existing API Cons: Frontend must collect all trace_ids from both groups
Example: Merge Group A and C into Group B¶
Before:
Method 1 (Recommended):
curl -X POST "$API/api/v1/file/$FILE_UUID/groups/merge" \
-H "X-API-Key: $KEY" \
-H "Content-Type: application/json" \
-d '{
"file_uuid": "c36f35685177c981aa139b66bbbccc5b",
"source_groups": ["Person A", "Person C"],
"target_group_name": "Person B"
}'
Method 2 (Existing API):
curl -X PUT "$API/api/v1/trace-profile/group" \
-H "X-API-Key: $KEY" \
-H "Content-Type: application/json" \
-d '{
"file_uuid": "c36f35685177c981aa139b66bbbccc5b",
"trace_ids": [13, 14, 15, 43, 44, 67, 68],
"name": "Person B"
}'
After:
GET /api/v1/file-profile¶
Auth: Required Scope: file-level
Read a file's metadata including path, name, status, and technical details.
Request Parameters¶
| Field | Type | Required | Description |
|---|---|---|---|
file_uuid |
string | Yes | File UUID |
Example¶
Response (200)¶
{
"file_uuid": "49884ce1c341953d1ad7bf67a77c30cc",
"file_name": "Dedicatoria.mp4",
"file_path": "/Users/accusys/momentry/var/sftpgo/data/demo/Dedicatoria.mp4",
"status": "completed",
"duration": 93.33,
"width": 1280,
"height": 720,
"fps": 30.0,
"total_frames": 0
}
| Field | Type | Description |
|---|---|---|
file_uuid |
string | File UUID |
file_name |
string | File name |
file_path |
string | Full filesystem path |
status |
string | pending, processing, completed, failed |
duration |
float | Duration in seconds |
width |
integer | Video width in pixels |
height |
integer | Video height in pixels |
fps |
float | Frames per second |
total_frames |
integer | Total frame count |
PUT /api/v1/file-profile¶
Auth: Required Scope: file-level
Update file metadata, typically used when a file is moved to a new location.
Request Body¶
| Field | Type | Required | Description |
|---|---|---|---|
file_uuid |
string | Yes | File UUID |
file_path |
string | No | New filesystem path |
file_name |
string | No | New file name |
Example¶
curl -s -X PUT "$API/api/v1/file-profile" \
-H "X-API-Key: $KEY" \
-H "Content-Type: application/json" \
-d '{
"file_uuid": "49884ce1c341953d1ad7bf67a77c30cc",
"file_path": "/new/location/Dedicatoria.mp4"
}'
Response (200)¶
{
"success": true,
"message": "File profile updated",
"file_uuid": "49884ce1c341953d1ad7bf67a77c30cc"
}
Data Storage¶
| Profile Type | Storage | Table |
|---|---|---|
| trace_profile | PostgreSQL (TKG) | tkg_nodes where node_type='face_track' |
| file_profile | PostgreSQL | videos |
Trace Profile Fields¶
| Field | TKG Column | Description |
|---|---|---|
name |
label |
Display name for the trace |
key_frame |
properties->'key_frame' |
Representative frame number |
key_face |
properties->'key_face' |
Representative face ID |
aliases |
properties->'aliases' |
Multi-language name aliases |
Updated: 2026-07-25 — Added Merge Groups API (POST /groups/merge), added Terminology section (Face, Face Sequence, Face Group) Updated: 2026-07-21 — Fixed external_id matching (trace_N + face_track_N formats), fixed parameter ordering in UPDATE query Updated: 2026-07-18 — New profile module: trace-profile (GET, PUT, PUT group) and file-profile (GET, PUT)
Version History¶
| Version | Date | Changes |
|---|---|---|
| 1.0 | 2026-10-24 | Initial documentation |