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

# Upload Image

> Upload one or more images to your Private Image Library for indexing and search.

<Info>
  **Product**: Visual Search
  **Use case**: Upload videos and images, auto-index them, then search by natural language, image, or transcript phrase
  **Host**: `https://api.memories.ai/serve/api/v1`
  **Auth**: `Authorization: sk-mavi-...` (no `Bearer` prefix)
</Info>

Uploaded images go into your **Private Image Library** — this is a separate library from your Private Video Library. Use [Upload Video](/visual-search/upload-video-from-file) if you want to add videos.

Once uploaded, images are indexed automatically and become searchable via [Search Private Image Library](/visual-search/search-private-image).

## Prerequisites

* You have [created a memories.ai API key](/visual-search/create-your-key).
* **Supported formats**: `.jpg`, `.jpeg`, `.png`, `.gif`, `.bmp`, `.webp` (case-insensitive). The `Content-Type` of each file part must start with `image/`.
* **Max file size**: 20 MB per image.

## Endpoint

```
POST https://api.memories.ai/serve/api/v1/upload_img
```

<Note>This endpoint uses `multipart/form-data`. Repeat the `files` field once per image. All other parameters are sent as form fields.</Note>

## Authentication

```
Authorization: sk-mavi-...
```

## Request Example

```python theme={null}
import requests

headers = {"Authorization": "sk-mavi-..."}
files = [
    ("files", ("photo1.jpg", open("photo1.jpg", "rb"), "image/jpeg")),
    ("files", ("photo2.png", open("photo2.png", "rb"), "image/png")),
]
data = {
    "datetime_taken": "2025-09-07 22:52:00",
    "camera_model": "Canon EOS 5D",
    "latitude": "39.9042",
    "longitude": "116.4074",
    "tags": ["outdoor", "2025"]
}
response = requests.post(
    "https://api.memories.ai/serve/api/v1/upload_img",
    headers=headers,
    files=files,
    data=data
)
print(response.json())
```

## Request Parameters

<ParamField body="files" type="file[]" required>
  One or more image files. Each must have a supported extension and a `Content-Type` starting with `image/`. Maximum **20 MB** per file. If any file in the batch fails validation, the entire request is rejected.
</ParamField>

<ParamField body="datetime_taken" type="string">
  Capture time in `yyyy-MM-dd HH:mm:ss` format. Invalid formats are rejected.
</ParamField>

<ParamField body="camera_model" type="string">
  Camera or device model name. Maximum **200 characters**.
</ParamField>

<ParamField body="latitude" type="number">
  GPS latitude where the images were captured (decimal).
</ParamField>

<ParamField body="longitude" type="number">
  GPS longitude where the images were captured (decimal).
</ParamField>

<ParamField body="tags" type="array">
  User-defined tags. Maximum **50 tags** per request. An `api` tag is appended automatically.
</ParamField>

## Notes & Limits

* **Rate limiting**: Exceeding the per-account upload rate limit returns an error. See [Rate limits](/visual-search/rate-limits).
* **Billing**: Each upload deducts credits from your account. Insufficient balance causes the request to fail.
* **Batch validation**: If any file in the batch fails validation, the entire request is rejected — no files are uploaded.

## Response Example

```json theme={null}
{
    "code": "0000",
    "msg": "success",
    "data": [
        { "id": 568102998803353601 },
        { "id": 568102998803353602 }
    ],
    "success": true,
    "failed": false
}
```

## Response Fields

<ResponseField name="code" type="string">
  Business status code. `0000` indicates success.
</ResponseField>

<ResponseField name="msg" type="string">
  Human-readable status message.
</ResponseField>

<ResponseField name="data" type="array">
  Array of uploaded image entries, in the same order as the `files` parts in the request.
</ResponseField>

<ResponseField name="data[].id" type="integer">
  Unique numeric identifier for the uploaded image. Use this in subsequent search and retrieval operations.
</ResponseField>


## OpenAPI

````yaml POST /serve/api/v1/upload_img
openapi: 3.1.0
info:
  title: Memories Platform API (Docs Mapping)
  version: v1
  description: OpenAPI mapping used by Mintlify Try it for the platform docs.
servers:
  - url: https://api.memories.ai
security:
  - ApiKeyAuth: []
paths:
  /serve/api/v1/upload_img:
    post:
      summary: Upload Image from File
      operationId: upload_image_from_file
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/UploadImageRequest'
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UploadImageResponse'
components:
  schemas:
    UploadImageRequest:
      type: object
      properties:
        files:
          type: array
          items:
            type: string
            format: binary
          description: >-
            One or more image files. Allowed extensions: .jpg, .jpeg, .png,
            .gif, .bmp, .webp. Content-Type must start with image/. Max 20 MB
            per file. Batch size capped by server configuration.
        datetime_taken:
          type: string
          example: '2025-09-07 22:52:00'
          description: Capture time in format yyyy-MM-dd HH:mm:ss.
        camera_model:
          type: string
          maxLength: 200
          example: Canon EOS 5D
          description: Camera/device model. Max 200 characters.
        latitude:
          type: number
          format: double
          example: 39.9042
        longitude:
          type: number
          format: double
          example: 116.4074
        tags:
          type: array
          items:
            type: string
          maxItems: 50
          example:
            - test1
            - test2
          description: >-
            User-defined tags. Max 50. The server automatically appends an 'api'
            tag.
      required:
        - files
    UploadImageResponse:
      type: object
      properties:
        code:
          type: string
          example: '0000'
          description: Business status code. 0000 indicates success.
        msg:
          type: string
          example: success
        data:
          type: array
          items:
            type: object
            properties:
              id:
                type: integer
                format: int64
                example: 568102998803353600
                description: Unique numeric identifier of the uploaded image.
          example:
            - id: 568102998803353600
            - id: 568102998803353600
        success:
          type: boolean
          example: true
        failed:
          type: boolean
          example: false
      example:
        code: '0000'
        msg: success
        data:
          - id: 568102998803353600
          - id: 568102998803353600
        success: true
        failed: false
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: Authorization

````