---
title: "Step 3 of upload: confirm uploaded files"
method: POST
path: "/events/{id}/photos/confirm"
tags: ["Photos"]
---

# Step 3 of upload: confirm uploaded files

`POST /events/{id}/photos/confirm`

## Request

- Base URL: `https://findme.photo/api/v1`
- URL: `https://findme.photo/api/v1/events/{id}/photos/confirm`
- Auth: HTTP bearer

Confirms slots whose bytes you have PUT to S3 (up to 50 per call). For each id the server checks the file exists in S3, records its real size, and then:

- photos move to `indexing` and face indexing starts in the background (asynchronous; the photo becomes findable by selfie once indexing finishes);
- videos move straight to `completed`.

Results come back per photo in `confirmed[]` with HTTP 200 even when some items fail; check each `status`/`reason`. Failure reasons: `not_found`, `not_owned`, `already_processed` (status is then the current one), `s3_object_missing` (the PUT never landed), `upload_exceeds_size_limit` (over 100 MB for a photo or 1 GB for a video; the file is deleted), `video_storage_limit_exceeded`, `video_storage_check_failed`, `size_exceeds_album_quality: ...`, `db_update_failed: ...`.

Optional `dimensions`: send the rendered `width`/`height` per photo when you resized before upload. They are stored and checked against the album quality (long edge over the cap by more than 2 px fails with `size_exceeds_album_quality`). Without them the server reads the dimensions from the stored JPEG or PNG and applies no quality check. `original_size_bytes` (the file size before you resized it) is what the plan's storage meter counts, never less than the stored size.

## Request body

- ConfirmPhotoUploadsRequest
  - `photo_ids` string[], required
  - `dimensions` object[]: Optional rendered dimensions per photo, for uploaders that resize before upload.
    - `photo_id` string, uuid, required
    - `width` integer, required
    - `height` integer, required
    - `original_long_edge` integer: Accepted; not currently used.
    - `size_bytes` integer: Accepted; the server uses the size measured in S3 instead.
    - `original_size_bytes` integer: File size before the uploader resized it. Photos only.

## Response `200`

Per-photo confirmation results.

- object
  - `data` PhotoConfirmBatch, required
    - `confirmed` object[], required: One result per requested photo id.
      - `photo_id` string, required
      - `status` string, required: `indexing` (photo accepted, face indexing started), `completed` (video accepted), `error`, or with `already_processed` the row's current status.
      - `reason` string: Present when the item was not accepted. See the operation description for values.
  - `meta` Meta, required
    - `request_id` string, required

## Other responses

- `400`: `invalid_request`: invalid id, query parameter, cursor or body. Validation failures list `details.issues`.
- `401`: `missing_or_invalid_token` (no or malformed `Authorization: Bearer fm_live_...` header) or `invalid_token` (unknown or revoked key).
- `403`: `tier_not_eligible`: the plan does not include API access (includes `upgrade_url`), or does not include the feature this endpoint needs.
- `404`: `not_found`: no such resource, or it is not yours, or (for albums) it is deleted.
- `429`: `rate_limited` (per-minute limit; `retry_after_seconds`) or `quota_exceeded` (monthly quota; `retry_after_seconds`, `resets_at`).
- `500`: `internal_error`: something failed on our side. Safe to retry reads; include `request_id` when reporting.

---

[API](https://skmtc.dev/findme/apis/findme-photo-api.md) · [All operations](https://skmtc.dev/findme/apis/findme-photo-api/llms.txt) · [OpenAPI document](https://skmtc.dev/findme/apis/findme-photo-api/revisions/b68670b742a9?raw)
