---
title: "Complete an attachment upload session"
method: POST
path: "/v3/grants/{grant_id}/attachment-uploads/{attachment_id}/complete"
tags: ["Attachments"]
---

# Complete an attachment upload session

`POST /v3/grants/{grant_id}/attachment-uploads/{attachment_id}/complete`

Finalize an attachment upload session after the file has been uploaded to the pre-signed URL.
Nylas verifies that the upload succeeded in storage and, if `size` was declared on session
creation, that the uploaded byte count matches the declared size.

After completion, reference the attachment in a [send](/docs/reference/api/messages/send-message/)
or [draft](/docs/reference/api/drafts/put-drafts-id/) request by passing
`{ "id": "<attachment_id>" }` in the `attachments` array.

**Retention note:** By default, the uploaded file is deleted from storage when `expires_at`
passes (one hour after session creation). Plan your send to occur inside this window. The
attachment metadata row is retained for 60 days for observability.

For the full upload flow, see
[Send large attachments](/docs/v3/email/send-large-attachments/).

## Path parameters

- `grant_id` string, required
- `attachment_id` string, required

## Response `200`

Upload session completed successfully. The attachment is now ready to use in a send or draft.

- object
  - `request_id` string
  - `data` object
    - `attachment_id` string — The attachment ID. Pass this value as `{ "id": "<attachment_id>" }` in the `attachments` array of a send or draft request.
    - `grant_id` string
    - `status` 'ready' — Upload session status. Always `ready` on success.

## Other responses

- `401` — Unauthorized
- `404` — The `attachment_id` does not exist.
- `409` — The upload session has already been completed (`status: ready`) or has failed (`status: failed`).
- `410` — The upload session has expired. Returned when the session was previously marked `expired` by the cleanup job, or when `expires_at` has already passed at the time `/complete` is called.
- `422` — Upload verification failed. Returned when the file is not found in storage, when the uploaded size does not match the `size` declared on session creation, or when no `size` was declared and the uploaded object is empty.
- `500` — Internal error. Returned on storage or database failures during verification.

---

[API](https://skmtc.dev/nylas/apis/nylas-api.md) · [All operations](https://skmtc.dev/nylas/apis/nylas-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/nylas/nylas-api/revisions/51c2c1b4ecff/schema)
