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

# Uploading files

> Hand Concord a brief, a media plan, or a creative with prepareUpload and attachUpload.

Two tools give Concord a file. The bytes go straight to storage and never through the MCP transport, so a large video does not pass through your model's context.

## The three steps

<Steps>
  <Step title="prepareUpload">
    Pass `filename`, `contentType`, and the exact `size` in bytes.

    ```json theme={null}
    { "filename": "q3-creatives.xlsx", "contentType": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "size": 48213 }
    ```

    You get an `upload` handle, an `uploadUrl`, the `headers` to send, and an `expiresAt`.
  </Step>

  <Step title="PUT the bytes">
    Send the raw file to `uploadUrl` with an HTTP `PUT`, passing the returned headers verbatim. Do not base64-encode. This request goes to storage, not to Concord.
  </Step>

  <Step title="attachUpload">
    Pass the `upload` handle from step 1. Add a `chatId` to attach the file to that conversation, so a following `askConcord` can work on it.

    ```json theme={null}
    { "upload": "<handle>", "chatId": "4f2c1a9e-…" }
    ```

    You get back the `fileId`, `name`, and `type` of the new Concord file.
  </Step>
</Steps>

Once attached, the file behaves like any [upload in the web app](/features/files/files-overview): Concord reads briefs, works spreadsheets sheet by sheet, and previews creatives.

## Constraints

|                           |                                                                                                        |
| ------------------------- | ------------------------------------------------------------------------------------------------------ |
| Maximum size              | 500 MB per file                                                                                        |
| Upload URL lifetime       | 5 minutes after `prepareUpload`                                                                        |
| Files per `prepareUpload` | One                                                                                                    |
| `size`                    | Must be the exact byte count. It is signed into the URL, so storage refuses a PUT of any other length. |
| `contentType`             | The MIME type stored with the file, e.g. `image/png`.                                                  |

## If something fails

* **The PUT is refused.** Almost always a `size` that does not match the bytes sent. Recompute the size and start again from `prepareUpload`.
* **`attachUpload` says the bytes never arrived or differ in size.** The PUT failed or was truncated. Run `prepareUpload` again and re-upload.
* **`attachUpload` says storage could not be reached.** The bytes may well be there. Call `attachUpload` again rather than re-uploading.
* **`attachUpload` called twice for the same upload** returns the same file rather than creating a duplicate.

## Related

[Ask Concord](/developers/mcp/ask-concord) · [Files in Concord](/features/files/files-overview)
