> ## Documentation Index
> Fetch the complete documentation index at: https://docs.akool.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Analyze Frames

> Face analysis for single or multiple images with automatic person deduplication

<Info>
  Analyze faces in one or more images, returning a `persons` format optimized for face swap. Automatically deduplicates faces across multiple frames.
</Info>

## Request Parameters

| Parameter      | Type   | Required | Default          | Description                         |
| -------------- | ------ | -------- | ---------------- | ----------------------------------- |
| `frame_urls`   | array  | Yes      | -                | List of image URLs to analyze       |
| `timestamps`   | array  | No       | \[0.0, 1.0, ...] | Timestamps for each frame (seconds) |
| `expand_ratio` | number | No       | 0.3              | Face crop expansion ratio (0-1)     |

<Note>
  **Single Image**: Each face becomes a separate person (no deduplication).
  **Multiple Images**: Same person across frames is merged into one entry.
</Note>

## Response Format

```json theme={null}
{
  "success": true,
  "frame_count": 3,
  "persons": [
    {
      "person_id": "person_0",
      "index": 0,
      "face_url": "https://s3.example.com/faces/face_abc123.jpg",
      "bbox": [100, 50, 200, 180],
      "confidence": 0.95,
      "appearances": [
        {"timestamp": 0.0, "frame_idx": 0, "bbox": [100, 50, 200, 180]},
        {"timestamp": 1.0, "frame_idx": 1, "bbox": [105, 52, 205, 182]}
      ],
      "first_seen": 0.0,
      "last_seen": 1.0
    }
  ]
}
```

### Response Fields

| Field         | Type    | Description                |
| ------------- | ------- | -------------------------- |
| `success`     | boolean | Whether analysis succeeded |
| `frame_count` | integer | Number of frames analyzed  |
| `persons`     | array   | List of detected persons   |

### Person Object

| Field         | Type    | Description                                                |
| ------------- | ------- | ---------------------------------------------------------- |
| `person_id`   | string  | Unique identifier (e.g., "person\_0")                      |
| `index`       | integer | Sort index (left to right by x-coordinate)                 |
| `face_url`    | string  | Cropped face image URL                                     |
| `bbox`        | array   | Bounding box `[x1, y1, x2, y2]` from first appearance      |
| `confidence`  | number  | Detection confidence (0-1)                                 |
| `appearances` | array   | List of frame appearances with timestamp, frame\_idx, bbox |
| `first_seen`  | number  | First appearance timestamp                                 |
| `last_seen`   | number  | Last appearance timestamp                                  |

## Examples

### Example 1: Single Image Analysis

**Request:**

```json theme={null}
{
  "frame_urls": ["https://example.com/group_photo.jpg"]
}
```

**Response:**

```json theme={null}
{
  "success": true,
  "frame_count": 1,
  "persons": [
    {
      "person_id": "person_0",
      "index": 0,
      "face_url": "https://s3.example.com/faces/face_a1b2c3.jpg",
      "bbox": [100, 50, 200, 180],
      "confidence": 0.96,
      "appearances": [
        {"timestamp": 0.0, "frame_idx": 0, "bbox": [100, 50, 200, 180]}
      ],
      "first_seen": 0.0,
      "last_seen": 0.0
    },
    {
      "person_id": "person_1",
      "index": 1,
      "face_url": "https://s3.example.com/faces/face_d4e5f6.jpg",
      "bbox": [300, 60, 400, 190],
      "confidence": 0.94,
      "appearances": [
        {"timestamp": 0.0, "frame_idx": 0, "bbox": [300, 60, 400, 190]}
      ],
      "first_seen": 0.0,
      "last_seen": 0.0
    }
  ]
}
```

### Example 2: Multi-Frame Analysis (Video Frames)

**Request:**

```json theme={null}
{
  "frame_urls": [
    "https://example.com/frame_0.jpg",
    "https://example.com/frame_1.jpg",
    "https://example.com/frame_2.jpg"
  ],
  "timestamps": [0.0, 1.0, 2.0]
}
```

**Response:**

```json theme={null}
{
  "success": true,
  "frame_count": 3,
  "persons": [
    {
      "person_id": "person_0",
      "index": 0,
      "face_url": "https://s3.example.com/faces/face_abc123.jpg",
      "bbox": [100, 50, 200, 180],
      "confidence": 0.95,
      "appearances": [
        {"timestamp": 0.0, "frame_idx": 0, "bbox": [100, 50, 200, 180]},
        {"timestamp": 1.0, "frame_idx": 1, "bbox": [105, 52, 205, 182]},
        {"timestamp": 2.0, "frame_idx": 2, "bbox": [110, 55, 210, 185]}
      ],
      "first_seen": 0.0,
      "last_seen": 2.0
    }
  ]
}
```

<Note>
  The same person appearing in all 3 frames is merged into a single person entry with multiple appearances.
</Note>

### Example 3: Custom Expand Ratio

**Request:**

```json theme={null}
{
  "frame_urls": ["https://example.com/photo.jpg"],
  "expand_ratio": 0.5
}
```

## Error Responses

| success | error                                         | Description         |
| ------- | --------------------------------------------- | ------------------- |
| false   | frame\_urls is required and must not be empty | Missing frame\_urls |
| false   | Failed to download image from URL             | Download failed     |
| true    | (empty persons array)                         | No faces detected   |

## Integration with Face Swap

```python theme={null}
import requests

# Analyze frames
response = requests.post(
    "https://openapi.akool.com/interface/detect-api/faceswap/analyze_frames",
    json={"frame_urls": ["https://example.com/target.jpg"]},
    headers={"x-api-key": "YOUR_API_KEY"}
)

result = response.json()
if result["success"]:
    for person in result["persons"]:
        face_url = person["face_url"]
        print(f"Person {person['person_id']}: {face_url}")
        # Use face_url directly in Face Swap API
```

## Best Practices

* **URL Requirements**: Use HTTPS, ensure publicly accessible
* **Multi-Frame**: Use 3-10 frames for typical video clips
* **Expand Ratio**: Use 0.5 for more facial context in face swap


## OpenAPI

````yaml POST /faceswap/analyze_frames
openapi: 3.0.3
info:
  title: Face Detection API
  description: >
    API for detecting faces in images and videos with bounding boxes and 6-point
    landmarks.


    This API provides:

    - Unified face detection for both images and videos

    - Face tracking across video frames

    - 6-point facial landmarks detection

    - Bounding box coordinates for each detected face

    - Cropped face image URLs with landmarks (optional)

    - Single face mode for returning only the largest face

    - Multi-frame face analysis with person deduplication
  version: 1.0.0
servers:
  - url: https://openapi.akool.com/interface/detect-api
    description: Face detection server
security:
  - ApiKeyAuth: []
  - BearerAuth: []
paths:
  /faceswap/analyze_frames:
    post:
      tags:
        - Face Detection
      summary: Analyze Frames for Face Swap
      description: >
        Unified face analysis endpoint for single or multiple frame images.
        Returns a `persons` format optimized for face swap operations.


        **Key Features**:

        - Supports both single image and multiple frame images

        - Automatic person deduplication across frames (for multi-frame input)

        - Returns cropped face image URLs ready for face swap

        - Tracks person appearances across frames with timestamps


        **Behavior**:

        - **Single Image**: Each detected face is returned as a separate person
        (no deduplication)

        - **Multiple Images**: Faces are matched across frames using embeddings,
        same person appears once with all appearances listed


        **Use Cases**:

        - Prepare faces for Face Swap API

        - Analyze video frames for person tracking

        - Extract face thumbnails from images
      operationId: analyzeFrames
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AnalyzeFramesRequest'
            examples:
              single_image:
                summary: Single Image Analysis
                value:
                  frame_urls:
                    - https://example.com/image.jpg
              multiple_frames:
                summary: Multiple Frames Analysis
                value:
                  frame_urls:
                    - https://example.com/frame_0.jpg
                    - https://example.com/frame_1.jpg
                    - https://example.com/frame_2.jpg
                  timestamps:
                    - 0
                    - 1
                    - 2
              with_expand_ratio:
                summary: Custom Expand Ratio
                value:
                  frame_urls:
                    - https://example.com/image.jpg
                  expand_ratio: 0.5
      responses:
        '200':
          description: Face analysis completed successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AnalyzeFramesResponse'
              examples:
                single_image_success:
                  summary: Single Image with Two Faces
                  value:
                    success: true
                    frame_count: 1
                    persons:
                      - person_id: person_0
                        index: 0
                        face_url: https://s3.example.com/faces/face_abc123.jpg
                        bbox:
                          - 100
                          - 50
                          - 200
                          - 180
                        confidence: 0.95
                        appearances:
                          - timestamp: 0
                            frame_idx: 0
                            bbox:
                              - 100
                              - 50
                              - 200
                              - 180
                        first_seen: 0
                        last_seen: 0
                      - person_id: person_1
                        index: 1
                        face_url: https://s3.example.com/faces/face_def456.jpg
                        bbox:
                          - 300
                          - 60
                          - 400
                          - 190
                        confidence: 0.92
                        appearances:
                          - timestamp: 0
                            frame_idx: 0
                            bbox:
                              - 300
                              - 60
                              - 400
                              - 190
                        first_seen: 0
                        last_seen: 0
                multi_frame_success:
                  summary: Multiple Frames with Person Tracking
                  value:
                    success: true
                    frame_count: 3
                    persons:
                      - person_id: person_0
                        index: 0
                        face_url: https://s3.example.com/faces/face_abc123.jpg
                        bbox:
                          - 100
                          - 50
                          - 200
                          - 180
                        confidence: 0.95
                        appearances:
                          - timestamp: 0
                            frame_idx: 0
                            bbox:
                              - 100
                              - 50
                              - 200
                              - 180
                          - timestamp: 1
                            frame_idx: 1
                            bbox:
                              - 105
                              - 52
                              - 205
                              - 182
                          - timestamp: 2
                            frame_idx: 2
                            bbox:
                              - 110
                              - 55
                              - 210
                              - 185
                        first_seen: 0
                        last_seen: 2
        '400':
          description: Bad request - Invalid input parameters
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AnalyzeFramesErrorResponse'
              example:
                success: false
                error: frame_urls is required and must not be empty
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AnalyzeFramesErrorResponse'
              example:
                success: false
                error: Failed to process frames
components:
  schemas:
    AnalyzeFramesRequest:
      type: object
      required:
        - frame_urls
      properties:
        frame_urls:
          type: array
          items:
            type: string
            format: uri
          description: |
            List of image URLs to analyze. Must be publicly accessible.
            - Single URL: Returns each face as a separate person
            - Multiple URLs: Automatically deduplicates faces across frames
          example:
            - https://example.com/image.jpg
        timestamps:
          type: array
          items:
            type: number
            format: float
          description: >
            Optional timestamps for each frame (in seconds).

            If not provided, sequential indices (0.0, 1.0, 2.0, ...) will be
            used.

            Length should match `frame_urls` length.
          example:
            - 0
            - 1
            - 2
        expand_ratio:
          type: number
          format: float
          default: 0.3
          minimum: 0
          maximum: 1
          description: >
            Expansion ratio for face cropping. The face bounding box is expanded
            by this ratio 

            on all sides before cropping. Higher values include more context
            around the face.
          example: 0.3
    AnalyzeFramesResponse:
      type: object
      required:
        - success
        - frame_count
        - persons
      properties:
        success:
          type: boolean
          description: Whether the analysis was successful
          example: true
        frame_count:
          type: integer
          description: Number of frames that were analyzed
          example: 3
        persons:
          type: array
          items:
            $ref: '#/components/schemas/PersonInfo'
          description: |
            List of detected persons. Each person contains:
            - Unique ID and index
            - Cropped face image URL
            - Bounding box and confidence
            - All appearances across frames
            - First and last seen timestamps
    AnalyzeFramesErrorResponse:
      type: object
      required:
        - success
        - error
      properties:
        success:
          type: boolean
          example: false
        error:
          type: string
          description: Error message describing what went wrong
          example: Failed to download image from URL
    PersonInfo:
      type: object
      required:
        - person_id
        - index
        - face_url
        - bbox
        - confidence
        - appearances
        - first_seen
        - last_seen
      properties:
        person_id:
          type: string
          description: Unique identifier for this person (e.g., "person_0", "person_1")
          example: person_0
        index:
          type: integer
          description: Sort index based on x-coordinate (left to right ordering)
          example: 0
        face_url:
          type: string
          format: uri
          description: URL of the cropped face image stored in cloud storage
          example: https://s3.example.com/faces/face_abc123.jpg
        bbox:
          type: array
          items:
            type: integer
          minItems: 4
          maxItems: 4
          description: Face bounding box coordinates [x1, y1, x2, y2] from first appearance
          example:
            - 100
            - 50
            - 200
            - 180
        confidence:
          type: number
          format: float
          minimum: 0
          maximum: 1
          description: Detection confidence score (0-1)
          example: 0.95
        appearances:
          type: array
          items:
            $ref: '#/components/schemas/PersonAppearance'
          description: List of all appearances of this person across frames
        first_seen:
          type: number
          format: float
          description: Timestamp of first appearance (in seconds)
          example: 0
        last_seen:
          type: number
          format: float
          description: Timestamp of last appearance (in seconds)
          example: 2
    PersonAppearance:
      type: object
      required:
        - timestamp
        - frame_idx
        - bbox
      properties:
        timestamp:
          type: number
          format: float
          description: Timestamp when this appearance was detected (in seconds)
          example: 0
        frame_idx:
          type: integer
          description: Frame index where this appearance was detected
          example: 0
        bbox:
          type: array
          items:
            type: integer
          minItems: 4
          maxItems: 4
          description: Bounding box coordinates [x1, y1, x2, y2]
          example:
            - 100
            - 50
            - 200
            - 180
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key
      description: >-
        Your API Key used for request authorization. If both Authorization and
        x-api-key have values, Authorization will be used first and x-api-key
        will be discarded.
    BearerAuth:
      type: http
      scheme: bearer
      description: >-
        Your API Key used for request authorization. Get Token from
        authentication/usage#get-the-token

````