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

# Download Models

> Request and response models for the original photo download API

## Overview

This page documents the request and response models for [Download Original Photos](/api-reference/download-original-photos): the JSON request body, the per-item presigned URL shapes (success and failure), and the top-level response envelope.

## DownloadOriginalPhotosRequest

Sent in the JSON body of [Download Original Photos](/api-reference/download-original-photos). The shape of `identifier` depends on `method`.

```json theme={null}
{
  "method": "selfie",
  "identifier": "ddc661a7-8861-4793-9437-af42a82d12f8"
}
```

```json theme={null}
{
  "method": "image_id",
  "identifier": "a4402318-0cf4-4e1e-b8e8-ac8e8f2fc244"
}
```

```json theme={null}
{
  "method": "image_ids",
  "identifier": [
    "a4402318-0cf4-4e1e-b8e8-ac8e8f2fc244",
    "f6cb3c08-2c7a-4ff7-8c1b-71b6f7d4d932"
  ]
}
```

| Field        | Type                      | Description                                                                                                                                                                                             |
| ------------ | ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `method`     | string                    | Download method: `bib`, `selfie`, `image_id`, or `image_ids`.                                                                                                                                           |
| `identifier` | string \| array of string | The value to look up. A **string** when `method` is `bib` (BIB number), `selfie` (selfie `request_id`), or `image_id` (single image ID). A non-empty **array of strings** when `method` is `image_ids`. |

## PresignedUrlItem

Each entry inside `presigned_urls[]`.

```json theme={null}
{
  "url": "https://...",
  "filename": "a4402318-0cf4-4e1e-b8e8-ac8e8f2fc244.jpg"
}
```

| Field      | Type   | Description                                                       |
| ---------- | ------ | ----------------------------------------------------------------- |
| `url`      | string | Presigned URL for downloading the image. Time-limited (\~1 hour). |
| `filename` | string | Suggested filename for download.                                  |

## FailedUrlItem

Each entry inside `failed_urls[]` when one or more URLs could not be generated.

```json theme={null}
{
  "image_id": "a4402318-0cf4-4e1e-b8e8-ac8e8f2fc244",
  "error": "Failed to generate URL",
  "path": "imgs/456/large/a4402318-0cf4-4e1e-b8e8-ac8e8f2fc244.jpg"
}
```

| Field      | Type           | Description                   |
| ---------- | -------------- | ----------------------------- |
| `image_id` | string         | Image ID that failed.         |
| `error`    | string         | Human-readable error message. |
| `path`     | string \| null | Object path if available.     |

## DownloadOriginalPhotosResponse

Top-level response. It uses the standard envelope from [Conventions](/api-reference/conventions#response-envelope); the download payload lives in `data`. When no images are available the API still returns `200 OK` with empty arrays and a descriptive `message` (for example `"No images found for selfie identifier ..."`).

`data.identifier` is the value echoed from the request:

* For `method` = `bib` / `selfie` / `image_id`, it is the single string that was sent.
* For `method` = `image_ids`, it is `null` (the request supplied a list).

If `method` is `image_id` and the image does not exist, or `method` is `image_ids` and **every** requested ID is invalid, the API instead responds with `400 Bad Request` and the standard error envelope (`data` is `null`) — see [Download Originals](/api-reference/download-original-photos#error-responses).

```json theme={null}
{
  "responseType": "success",
  "message": "Generated 47 presigned URLs for download.",
  "data": {
    "presigned_urls": [
      {
        "url": "https://...",
        "filename": "a4402318-0cf4-4e1e-b8e8-ac8e8f2fc244.jpg"
      }
    ],
    "failed_urls": [],
    "total_images": 47,
    "successful_count": 47,
    "failed_count": 0,
    "identifier": "ddc661a7-8861-4793-9437-af42a82d12f8",
    "pagination": {
      "total": 47,
      "currentPage": 1,
      "totalPages": 2,
      "hasNextPage": true,
      "hasPreviousPage": false,
      "page_size": 30
    }
  }
}
```

| Field                   | Type           | Description                                                                                                                                                                         |
| ----------------------- | -------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `responseType`          | string         | Always `"success"` for 2xx responses. See [Conventions](/api-reference/conventions#response-envelope).                                                                              |
| `message`               | string         | Human-readable status message describing the result.                                                                                                                                |
| `data.presigned_urls`   | array          | List of <a href="#presignedurlitem">PresignedUrlItem</a> download links.                                                                                                            |
| `data.failed_urls`      | array          | List of <a href="#failedurlitem">FailedUrlItem</a> failures.                                                                                                                        |
| `data.total_images`     | number         | Total number of images matched: for `bib` / `selfie`, the number of images that matched the identifier; for `image_id`, always `1`; for `image_ids`, the size of the supplied list. |
| `data.successful_count` | number         | Number of successfully generated URLs in this page.                                                                                                                                 |
| `data.failed_count`     | number         | Number of failed URL generations in this page.                                                                                                                                      |
| `data.identifier`       | string \| null | BIB number, selfie `request_id`, or single `image_id` echoed from the request. `null` when `method` is `image_ids` (since a list was supplied).                                     |
| `data.pagination`       | object \| null | <a href="/api-reference/models/pagination">PaginationInfo</a> metadata. `null` when there were no images to paginate.                                                               |

## Used By

<CardGroup cols={1}>
  <Card title="Download Originals" icon="cloud-arrow-down" href="/api-reference/download-original-photos">
    Request body and response envelope for presigned downloads.
  </Card>
</CardGroup>
