---
title: "Mark an upload complete"
method: POST
path: "/files/{file_id}:complete"
tags: ["Files"]
---

# Mark an upload complete

`POST /files/{file_id}:complete`

## Request

- Base URL: `https://api.axilio.ai/api/v1`
- URL: `https://api.axilio.ai/api/v1/files/{file_id}:complete`
- Auth: API key in header `X-Axilio-Api-Key`
- TypeScript: <https://skmtc.dev/axilioai/apis/axilio-api-2/docs/files/:file_id:complete/post.ts> (a function with typed inputs; its response is checked against the schema)

Call after PUTting the bytes to the upload URL. Verifies the object landed at the declared size and type, checks the content really is the media it claims to be, and moves the file to ready so it can be delivered. Idempotent: completing an already-ready file just returns it. Applies to source=upload files; a captured file finalizes on its own from the phone's report.

## Path parameters

- `file_id` string, uuid, required: file identifier to finalize

## Response `200`

OK

- CompleteFileOutputBody
  - `file` FileSummary, required: One file in the org's library.
    - `attachment_url` string: Short-lived signed URL that downloads the file as an attachment under its name. Present only for ready files.
    - `bytes_transferred` integer: Bytes moved so far for an in-flight phone transfer. Absent until the phone reports progress.
    - `capture_error` string: Reason the phone's upload failed, when it did. Present for captures and message attachments.
    - `capture_state` 'detected' | 'uploading' | 'ready' | 'skipped_size' | 'skipped_quota' | 'skipped_type' | 'dropped_teardown' | 'failed': Upload lifecycle of a file the phone sends itself: detected/uploading while in flight, ready when usable, or a terminal skip/failure with its reason. Present for captures and message attachments.
    - `checksum` string: SHA-256 of the bytes, computed on the phone while uploading. Present for captures and message attachments.
    - `created_at` string, date-time, required: When the file was registered: upload registration, or capture detection.
    - `display_url` string: Short-lived signed URL for a full-resolution JPEG of a HEIC or HEIF original, for display where a browser cannot draw the original. Absent for other types and until generated.
    - `download_url` string: Short-lived signed URL to read the file's bytes. Present only for ready files; re-list to refresh an expired one.
    - `duration_seconds` integer: Video duration in seconds.
    - `filename` string, required: Original filename; used as the display name when the file lands on a phone.
    - `height` integer: Intrinsic pixel height of the source.
    - `id` string, required: File identifier. Unique across the whole library; deliverable to a phone regardless of source.
    - `message_id` string: The message this file was attached to. Present for message attachments once the message is stored; a file whose message never arrived still names its phone.
    - `mime_type` string, required: Declared MIME type, pinned by the presigned upload.
    - `on_phone_count` integer, required: Distinct phones currently holding or receiving a delivered copy. Informational: deleting the file from the library does not remove these.
    - `phone_id` string: The phone that received the message this file was attached to. Present for message attachments.
    - `preview_state` 'processing' | 'ready' | 'unavailable', required: Whether the preview exists, is still being generated, or will never be available for this format.
    - `reel_url` string: Short-lived signed URL for the animated hover preview. Videos only; absent until generated.
    - `session_id` string: Session that produced the file. Present only for captures.
    - `size_bytes` integer, required: Declared size in bytes, pinned by the presigned upload.
    - `source` 'upload' | 'capture' | 'message', required: How the file entered the library: upload (put in directly), capture (lifted off a session), or message (attached to a message one of the org's dedicated phones received).
    - `status` 'uploading' | 'ready', required: uploading until the object is verified in storage, then ready. For a capture, read capture_state for the fuller lifecycle.
    - `surface` 'phone': Which surface a capture or message attachment came off (phone today). Absent for a direct upload.
    - `thumbnail_url` string: Short-lived signed URL for the generated preview image. Absent while generation is pending, and permanently absent for formats without a preview.
    - `width` integer: Intrinsic pixel width of the source.

## Other responses

- `400`: Bad Request
- `404`: Not Found
- `422`: Unprocessable Entity
- `500`: Internal Server Error

## Changes

- **2026-10-24** `ecca093572e0`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/axilioai/apis/axilio-api-2/changes/files/:file_id:complete/post.md)

---

[API](https://skmtc.dev/axilioai/apis/axilio-api-2.md) - [All operations](https://skmtc.dev/axilioai/apis/axilio-api-2/llms.txt) - [OpenAPI document](https://skmtc.dev/axilioai/apis/axilio-api-2/revisions/62aa324803a7?raw)
