# Momentry Identity Management API Guide

> Version: 4.0 | Updated: 2026-04-28
> Architecture: Two-layer (Face → Identity)
> Terminology: file_uuid, identity_uuid

---

## Overview

This guide demonstrates the complete workflow for:
- Choosing a video file
- Analyzing faces (unregistered candidates)
- Registering global identities
- Managing identity ↔ file relationships

---

## Terminology

| Term | Scope | Example |
|------|-------|---------|
| **file_uuid** | Video file identifier | `384b0ff44aaaa1f14cb2cd63b3fea966` |
| **identity_uuid** | Global identity identifier | `a9a90105-6d6b-...` |
| **face_id** | Single face detection | `face_100` |
| **trace_id** | Face tracking ID | `2` |

**Note**: `person_id` (video-local identifier) is deprecated. Use direct Face → Identity binding.

---

## 1. List Files

**Endpoint**: `GET /api/v1/files`

```bash
curl -s "http://127.0.0.1:3003/api/v1/files" \
  -H "X-API-Key: YOUR_API_KEY" | jq .
```

**Response**:
```json
{
  "success": true,
  "data": {
    "files": [
      {
        "file_uuid": "384b0ff44aaaa1f14cb2cd63b3fea966",
        "file_name": "Charade_1963.mp4",
        "duration": 6879.33,
        "status": "completed"
      }
    ]
  }
}
```

---

## 2. List Unregistered Faces (Candidates)

**Endpoint**: `GET /api/v1/faces/candidates`

Query faces that have not been bound to any identity.

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| `file_uuid` | UUID | No | - | Filter by file |
| `min_confidence` | float | No | 0.5 | Minimum confidence |
| `pose_angle` | string | No | - | Filter by pose (frontal/profile) |
| `page` | int | No | 1 | Page number |
| `page_size` | int | No | 15 | Items per page |
| `limit` | int | No | 100 | Total limit |

```bash
curl -s "http://127.0.0.1:3003/api/v1/faces/candidates?min_confidence=0.8" \
  -H "X-API-Key: YOUR_API_KEY" | jq .
```

**Response**:
```json
{
  "success": true,
  "data": {
    "candidates": [
      {
        "face_id": "face_100",
        "file_uuid": "384b0ff44aaaa1f14cb2cd63b3fea966",
        "frame": 100,
        "timestamp": 5.2,
        "pose_angle": "frontal",
        "confidence": 0.92,
        "trace_id": 2,
        "embedding_quality": 0.88
      }
    ],
    "statistics": {
      "total_candidates": 78,
      "pose_distribution": {
        "frontal": 20,
        "profile_right": 30,
        "three_quarter": 18
      }
    },
    "pagination": {
      "page": 1,
      "page_size": 15,
      "total": 78,
      "total_pages": 6
    }
  }
}
```

---

## 3. AI Suggest Clustering

**Endpoint**: `POST /api/v1/agents/suggest/clustering`

AI Agent analyzes unregistered faces and suggests clustering.

```bash
curl -s -X POST "http://127.0.0.1:3003/api/v1/agents/suggest/clustering" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: YOUR_API_KEY" \
  -d '{
    "min_confidence": 0.8,
    "pose_angles": ["frontal"],
    "max_suggestions": 5
  }' | jq .
```

**Response**:
```json
{
  "success": true,
  "data": {
    "suggestions": [
      {
        "suggestion_id": "suggest_1",
        "cluster_type": "high_confidence",
        "confidence": 0.92,
        "recommended_faces": [
          {
            "face_id": "face_100",
            "pose_angle": "frontal",
            "confidence": 0.95,
            "is_primary": true
          },
          {
            "face_id": "face_150",
            "pose_angle": "frontal",
            "confidence": 0.91
          }
        ],
        "cluster_stats": {
          "total_faces": 50,
          "avg_similarity": 0.89,
          "trace_ids": [2, 3]
        },
        "reason": "High confidence frontal faces from same trace",
        "action": "register"
      }
    ]
  }
}
```

---

## 4. Register Identity from Faces

**Endpoint**: `POST /api/v1/identities/register`

Register a new global identity from face candidates.

```bash
curl -s -X POST "http://127.0.0.1:3003/api/v1/identities/register" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: YOUR_API_KEY" \
  -d '{
    "face_ids": ["face_100", "face_150", "face_200"],
    "name": "Audrey Hepburn",
    "source": "manual",
    "auto_bind_chunks": true
  }' | jq .
```

**Response**:
```json
{
  "success": true,
  "data": {
    "identity_uuid": "a9a90105-6d6b-46ff-92da-0c3c1a57dff4",
    "name": "Audrey Hepburn",
    "faces_bound": 3,
    "chunks_bound": 10,
    "speaker_ids": ["SPEAKER_0"],
    "reference_vectors": {
      "total": 3,
      "angles": ["frontal", "three_quarter"]
    }
  }
}
```

---

## 5. Query Identity → Files

**Endpoint**: `GET /api/v1/identities/:identity_uuid/files`

List all files where this identity appears.

```bash
curl -s "http://127.0.0.1:3003/api/v1/identities/a9a90105.../files" \
  -H "X-API-Key: YOUR_API_KEY" | jq .
```

**Response**:
```json
{
  "success": true,
  "data": {
    "identity_uuid": "a9a90105...",
    "name": "Audrey Hepburn",
    "files": [
      {
        "file_uuid": "384b0ff44aaaa1f14cb2cd63b3fea966",
        "file_name": "Charade_1963.mp4",
        "face_count": 500,
        "speaker_count": 10,
        "first_appearance": 5.2,
        "last_appearance": 180.5,
        "confidence": 0.86
      },
      {
        "file_uuid": "9760d0820f0cf9a7",
        "file_name": "Breakfast_at_Tiffanys.mp4",
        "face_count": 300,
        "speaker_count": 5
      }
    ],
    "total_files": 2
  }
}
```

---

## 6. Query File → Identities

**Endpoint**: `GET /api/v1/files/:file_uuid/identities`

List all identities appearing in a file.

```bash
curl -s "http://127.0.0.1:3003/api/v1/files/384b0ff44aaaa1f14cb2cd63b3fea966/identities" \
  -H "X-API-Key: YOUR_API_KEY" | jq .
```

**Response**:
```json
{
  "success": true,
  "data": {
    "file_uuid": "384b0ff44aaaa1f14cb2cd63b3fea966",
    "file_name": "Charade_1963.mp4",
    "identities": [
      {
        "identity_uuid": "a9a90105...",
        "name": "Audrey Hepburn",
        "face_count": 500,
        "speaker_count": 10,
        "confidence": 0.86
      },
      {
        "identity_uuid": "b8b80206...",
        "name": "Cary Grant",
        "face_count": 450,
        "speaker_count": 8
      }
    ],
    "total_identities": 2
  }
}
```

---

## 7. Get Identity Detail

**Endpoint**: `GET /api/v1/identities/:identity_uuid`

```bash
curl -s "http://127.0.0.1:3003/api/v1/identities/a9a90105..." \
  -H "X-API-Key: YOUR_API_KEY" | jq .
```

**Response**:
```json
{
  "success": true,
  "data": {
    "identity_uuid": "a9a90105...",
    "name": "Audrey Hepburn",
    "source": "manual",
    "identity_type": "person",
    "global_stats": {
      "total_files": 3,
      "total_faces": 1500,
      "total_speaker_segments": 30
    },
    "reference_vectors": {
      "total": 4,
      "angles": ["frontal", "profile_right", "three_quarter"],
      "quality_avg": 0.875
    }
  }
}
```

---

## 8. Bind Additional Faces to Identity

**Endpoint**: `POST /api/v1/identities/:identity_uuid/bind`

Add more faces to an existing identity.

```bash
curl -s -X POST "http://127.0.0.1:3003/api/v1/identities/a9a90105.../bind" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: YOUR_API_KEY" \
  -d '{
    "face_ids": ["face_300", "face_400"],
    "auto_bind_chunks": true
  }' | jq .
```

**Response**:
```json
{
  "success": true,
  "data": {
    "identity_uuid": "a9a90105...",
    "faces_bound": 2,
    "chunks_bound": 5,
    "updated_stats": {
      "total_faces": 1502,
      "total_files": 3
    }
  }
}
```

---

## 9. Unbind Faces from Identity

**Endpoint**: `POST /api/v1/identities/:identity_uuid/unbind`

```bash
curl -s -X POST "http://127.0.0.1:3003/api/v1/identities/a9a90105.../unbind" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: YOUR_API_KEY" \
  -d '{
    "face_ids": ["face_400"]
  }' | jq .
```

---

## 10. Get Identity Thumbnail

**Endpoint**: `GET /api/v1/identities/:identity_uuid/thumbnail`

```bash
curl -s -o identity_thumbnail.jpg \
  "http://127.0.0.1:3003/api/v1/identities/a9a90105.../thumbnail" \
  -H "X-API-Key: YOUR_API_KEY"
```

---

## Complete Workflow Example

```
Step 1: List files → Choose Charade_1963.mp4
Step 2: List face candidates → Find high-confidence frontal faces
Step 3: AI suggest clustering → Get clustering recommendations
Step 4: Register identity → Create "Audrey Hepburn" with 3 faces
Step 5: Auto-bind chunks → 10 sentence chunks bound automatically
Step 6: Verify → Query identity → files (appears in 3 files)
```

---

## API Endpoints Summary

| Category | Endpoint | Description |
|----------|----------|-------------|
| **List** | `GET /api/v1/files` | List files |
| **List** | `GET /api/v1/identities` | List identities |
| **Candidates** | `GET /api/v1/faces/candidates` | Unregistered faces |
| **Suggest** | `POST /api/v1/agents/suggest/clustering` | AI clustering suggestions |
| **Register** | `POST /api/v1/identities/register` | Register new identity |
| **Bind** | `POST /api/v1/identities/:uuid/bind` | Bind faces to identity |
| **Detail** | `GET /api/v1/identities/:uuid` | Identity detail |
| **Relation** | `GET /api/v1/identities/:uuid/files` | Identity → Files (N:N) |
| **Relation** | `GET /api/v1/files/:uuid/identities` | File → Identities (N:N) |

---

## Changes from V3.x

| Change | V3.x | V4.0 |
|--------|------|------|
| **Architecture** | Face → Person → Identity | Face → Identity (2-layer) |
| **file_uuid** | file_uuid | file_uuid |
| **person_id** | 28 person API endpoints | Removed (deprecated) |
| **file_identities** | Not mentioned | Added (N:N relationship table) |
| **chunk candidates** | chunk candidates API | Removed (chunks auto-bind) |

---

## Version History

| Version | Date | Changes |
|---------|------|---------|
| V4.0 | 2026-04-28 | Two-layer architecture, file_uuid terminology |
| V3.5 | 2026-04-17 | Person-based workflow |
| V3.0 | 2026-04-10 | Initial identity management |
