---
document_type: "reference_doc"
service: "MOMENTRY_CORE"
title: "Momentry Core API Reference"
date: "2026-04-25"
version: "V1.0"
status: "active"
owner: "Warren"
created_by: "OpenCode"
tags:
  - "reference"
  - "momentry"
  - "core"
ai_query_hints:
  - "查詢 Momentry Core API Reference 的內容"
  - "Momentry Core API Reference 的主要目的是什麼？"
  - "如何操作或實施 Momentry Core API Reference？"
---

# Momentry Core API Reference

> **Version**: 1.0 | **Source**: Generated from actual Rust code (`src/api/`)
> **Server**: Port 3002 (production) | 3003 (playground)
> **Auth**: Bearer token via `X-API-Key` header (required for most endpoints)

---

## 📋 Table of Contents

1. [Health & Stats (Public)](#health--stats)
2. [Core Asset Management](#core-asset-management)
3. [Processing Pipeline](#processing-pipeline)
4. [Search APIs](#search-apis)
5. [Visual Chunk Search](#visual-chunk-search)
6. [Face Recognition](#face-recognition)
7. [Person Identity](#person-identity)
8. [Global Identities](#global-identities)
9. [Identity Binding](#identity-binding)
10. [Configuration](#configuration)

---

## Health & Stats

| Method | Endpoint | Auth | Description |
|--------|----------|------|-------------|
| GET | `/health` | No | Basic health check |
| GET | `/health/detailed` | No | Detailed health (all services) |
| GET | `/api/v1/stats/ingest` | No | Ingest statistics |
| GET | `/api/v1/stats/sftpgo` | No | SFTPGo service status |
| GET | `/api/v1/stats/inference` | No | Inference service health |

### Example

```bash
curl http://localhost:3002/health
# Response: {"status": "ok"}
```

---

## Core Asset Management

| Method | Endpoint | Auth | Description |
|--------|----------|------|-------------|
| POST | `/api/v1/register` | Yes | Register a new video |
| POST | `/api/v1/unregister` | Yes | Delete a video and all data |
| GET | `/api/v1/videos` | Yes | List all videos |
| GET | `/api/v1/videos/:uuid/details` | Yes | Get video details with chunks |
| GET | `/api/v1/lookup` | Yes | Lookup video by path or UUID |
| GET | `/api/v1/progress/:uuid` | Yes | Get processing progress |

### Register Video

```bash
curl -X POST http://localhost:3002/api/v1/register \
  -H "X-API-Key: $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"path": "./demo/video.mp4"}'
```

### Video Details

```bash
curl http://localhost:3002/api/v1/videos/$UUID/details \
  -H "X-API-Key: $API_KEY"
```

---

## Processing Pipeline

| Method | Endpoint | Auth | Description |
|--------|----------|------|-------------|
| POST | `/api/v1/probe` | Yes | Probe video metadata |
| GET | `/api/v1/assets/:uuid/probe` | Yes | Get probe result by UUID |
| POST | `/api/v1/assets/:uuid/process` | Yes | Trigger processing pipeline |
| GET | `/api/v1/assets/:uuid/status` | Yes | Get asset processing status |
| GET | `/api/v1/jobs/:job_id` | Yes | Get job status by ID |
| GET | `/api/v1/jobs` | Yes | List all jobs |
| GET | `/api/v1/rules/:rule/status` | Yes | Get rule processing status |

### Trigger Processing

```bash
curl -X POST http://localhost:3002/api/v1/assets/$UUID/process \
  -H "X-API-Key: $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"rules": ["rule1"], "processors": ["asr", "yolo", "face"]}'
```

---

## Search APIs

### Vector Search

| Method | Endpoint | Auth | Description |
|--------|----------|------|-------------|
| POST | `/api/v1/search` | Yes | Vector/semantic search |
| POST | `/api/v1/search/hybrid` | Yes | Hybrid search (vector + BM25) |
| POST | `/api/v1/search/bm25` | Yes | BM25 text search |

### N8N Search (Library Functions)

| Method | Endpoint | Auth | Description |
|--------|----------|------|-------------|
| POST | `/api/v1/n8n/search` | Yes | N8N vector search |
| POST | `/api/v1/n8n/search/bm25` | Yes | N8N BM25 search |
| POST | `/api/v1/n8n/search/hybrid` | Yes | N8N hybrid search |
| POST | `/api/v1/n8n/search/smart` | Yes | N8N smart search |

### Search Request Body

```json
{
  "query": "男女主角見面的場景",
  "uuid": "optional-video-uuid",
  "types": ["chunk", "frame", "person"],
  "time_range": [0.0, 60.0],
  "filters": {
    "min_confidence": 0.8,
    "required_object_classes": ["person"],
    "speaker_id": "speaker_1"
  },
  "limit": 20,
  "offset": 0
}
```

---

## Visual Chunk Search

| Method | Endpoint | Auth | Description |
|--------|----------|------|-------------|
| POST | `/api/v1/search/visual` | Yes | Visual chunk search |
| POST | `/api/v1/search/visual/class` | Yes | Search by object class |
| POST | `/api/v1/search/visual/density` | Yes | Search by spatial density |
| POST | `/api/v1/search/visual/stats` | Yes | Get visual statistics |
| POST | `/api/v1/search/visual/combination` | Yes | Search by object combination |

### Visual Search Request

```bash
curl -X POST http://localhost:3002/api/v1/search/visual \
  -H "X-API-Key: $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "uuid": "abc123",
    "criteria": {
      "min_avg_confidence": 0.8,
      "required_classes": ["person", "car"],
      "min_spatial_density": 0.5
    }
  }'
```

### Search by Class

```bash
curl -X POST http://localhost:3002/api/v1/search/visual/class \
  -H "X-API-Key: $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "uuid": "abc123",
    "object_class": "person",
    "min_count": 5,
    "max_count": 20
  }'
```

---

## Face Recognition

| Method | Endpoint | Auth | Description |
|--------|----------|------|-------------|
| POST | `/api/v1/face/recognize` | Yes | Recognize faces in video |
| POST | `/api/v1/face/register` | Yes | Register a face |
| POST | `/api/v1/face/search` | Yes | Search similar faces |
| GET | `/api/v1/face/list` | Yes | List all faces |
| GET | `/api/v1/face/:face_id` | Yes | Get face details |
| DELETE | `/api/v1/face/:face_id` | Yes | Delete a face |
| GET | `/api/v1/face/results/:file_uuid` | Yes | Get recognition results |

---

## Person Identity

| Method | Endpoint | Auth | Description |
|--------|----------|------|-------------|
| POST | `/api/v1/person/identify` | Yes | Identify persons in video |
| POST | `/api/v1/person/auto-identify` | Yes | Auto-identify persons |
| POST | `/api/v1/person/suggest` | Yes | Get person suggestions |
| GET | `/api/v1/person/list` | Yes | List all persons |
| GET | `/api/v1/person/:person_id` | Yes | Get person details |
| PATCH | `/api/v1/person/:person_id` | Yes | Update person identity |
| GET | `/api/v1/person/:person_id/timeline` | Yes | Get person timeline |
| GET | `/api/v1/person/:person_id/appearances` | Yes | Get person appearances |
| GET | `/api/v1/person/:person_id/thumbnail` | Yes | Get person thumbnail |
| POST | `/api/v1/person/merge` | Yes | Merge two persons |
| POST | `/api/v1/person/merge/undo` | Yes | Undo merge |
| GET | `/api/v1/person/merge/history` | Yes | Get merge history |
| POST | `/api/v1/person/:person_id/split` | Yes | Split a person |
| GET | `/api/v1/person/:person_id/similar` | Yes | Get similar persons |
| PATCH | `/api/v1/person/:person_id/confirm` | Yes | Confirm suggestion |
| POST | `/api/v1/person/:person_id/unbind-speaker` | Yes | Unbind speaker |
| POST | `/api/v1/person/:person_id/reassign-speaker` | Yes | Reassign speaker |
| POST | `/api/v1/person/:person_id/remove-appearance` | Yes | Remove appearance |
| POST | `/api/v1/person/:person_id/reassign-appearance` | Yes | Reassign appearance |
| POST | `/api/v1/person/:person_id/register` | Yes | Register identity |
| GET | `/api/v1/chunks/:chunk_id/persons` | Yes | Get chunk persons |

---

## Global Identities

| Method | Endpoint | Auth | Description |
|--------|----------|------|-------------|
| POST | `/api/v1/identities/from-person` | Yes | Register from person |
| GET | `/api/v1/identities` | Yes | List all identities |
| GET | `/api/v1/identities/:identity_id/videos` | Yes | Get identity videos |
| GET | `/api/v1/identities/:identity_id/faces` | Yes | Get identity faces |
| POST | `/api/v1/identities/search` | Yes | Search identities |
| GET | `/api/v1/videos/:uuid/faces` | Yes | Get video faces |

---

## Identity Binding

| Method | Endpoint | Auth | Description |
|--------|----------|------|-------------|
| POST | `/api/v1/identities/bind` | Yes | Bind identity |
| POST | `/api/v1/identities/unbind` | Yes | Unbind identity |
| GET | `/api/v1/identity/:binding_type/:binding_value` | Yes | Get identity info |
| GET | `/api/v1/signals/unbound` | Yes | List unbound signals |
| GET | `/api/v1/signals/:uuid/:binding_type/:binding_value/timeline` | Yes | Get signal timeline |
| POST | `/api/v1/identities/suggest-av` | Yes | Suggest AV bindings |

---

## Configuration

| Method | Endpoint | Auth | Description |
|--------|----------|------|-------------|
| POST | `/api/v1/config/cache` | Yes | Toggle cache |

### Toggle Cache

```bash
curl -X POST http://localhost:3002/api/v1/config/cache \
  -H "X-API-Key: $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"enabled": false}'
```

---

## Authentication

All endpoints except `/health` and `/health/detailed` require an API key:

```bash
export API_KEY="muser_xxx"
curl -H "X-API-Key: $API_KEY" http://localhost:3002/api/v1/videos
```

---

## ⚠️ Notable Notes

1. **Universal Search routes** (`/api/v1/search/universal`, `/api/v1/search/frames`, `/api/v1/search/persons`) are defined in `universal_search.rs` but **NOT MOUNTED** in `server.rs`.

2. **Who routes** (`/api/v1/who`, `/api/v1/who/candidates`) are defined in `who.rs` but **NOT MOUNTED** in `server.rs`.

3. **Total endpoints**: 71 reachable + 6 unreachable = 77 defined.

---

## 📁 Related Documents

| Document | Location |
|----------|----------|
| API Examples | `IMPLEMENTATION/API_EXAMPLES.md` |
| cURL Examples | `IMPLEMENTATION/API_CURL_EXAMPLES.md` |
| WordPress Guide | `IMPLEMENTATION/API_WORDPRESS_GUIDE.md` |
| n8n Guide | `IMPLEMENTATION/API_N8N_GUIDE.md` |
| API Key Design | `REFERENCE/API_KEY_DESIGN.md` |
| API Key Architecture | `ARCHITECTURE/API_KEY_ARCHITECTURE.md` |
