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

# Upload a file

> Upload a text-based file for use in Sessions, tools, or Agent outputs.

`POST /api/v1/cloud/files`

Uploads a text-based file and returns a [File object](/cloud-agents/api/files/schemas#file-object).

## Headers

| Header          | Required | Description           |
| --------------- | -------- | --------------------- |
| `Authorization` | Yes      | `Bearer $QODER_PAT`   |
| `Content-Type`  | Yes      | `multipart/form-data` |

## Request body

| Field      | Type        | Required | Description                                                                                                                           |
| ---------- | ----------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| `file`     | file        | Yes      | Text-based file content. See [Supported upload file types](/cloud-agents/api/files/schemas#supported-upload-file-types)               |
| `name`     | string      | No       | Stored file name. Defaults to the uploaded file name. After server sanitization, length must be 1-255 bytes and cannot be `.` or `..` |
| `metadata` | JSON string | No       | Valid JSON encoded as a form field. Maximum raw length is 8 KB. Defaults to `{}`                                                      |

## Example request

```bash theme={null}
curl -X POST "https://api.qoder.com/api/v1/cloud/files" \
  -H "Authorization: Bearer $QODER_PAT" \
  -F "file=@./my-document.txt" \
  -F "name=my-document.txt" \
  -F 'metadata={"project":"demo"}'
```

## Example response

**HTTP 200 OK**

```json theme={null}
{
  "id": "file_019e3bb8c1387743bf4ef115aae5acb1",
  "type": "file",
  "filename": "my-document.txt",
  "mime_type": "text/plain",
  "size_bytes": 110,
  "downloadable": false,
  "scope": null,
  "metadata": {
    "project": "demo"
  },
  "created_at": "2026-05-18T15:33:44Z"
}
```

## Response fields

| Field          | Type           | Description                                                                                                           |
| -------------- | -------------- | --------------------------------------------------------------------------------------------------------------------- |
| `id`           | string         | File ID with the `file_` prefix                                                                                       |
| `type`         | string         | Always `"file"`                                                                                                       |
| `filename`     | string         | Stored file name                                                                                                      |
| `size_bytes`   | integer        | File size in bytes                                                                                                    |
| `mime_type`    | string         | MIME type supplied by the upload or detected from the file name                                                       |
| `downloadable` | boolean        | Whether this file can be downloaded through the `/content` endpoint                                                   |
| `scope`        | object \| null | Scope object when the file is associated with another resource, for example `{ "id": "sess_...", "type": "session" }` |
| `metadata`     | object         | Custom metadata object supplied on upload; defaults to `{}`                                                           |
| `created_at`   | string         | UTC creation time in RFC 3339 format                                                                                  |

## Notes

* The multipart request body is limited to about 5 MB of file content plus multipart overhead.
* Only text-based files are accepted. Binary document, image, audio, video, and archive files are rejected.
* The server sanitizes `name` by keeping the base file name and replacing path separators or null bytes with `_`.

## Errors

| HTTP | Type                    | Trigger                                                                                                                      |
| ---- | ----------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| 400  | `invalid_request_error` | Missing `file`, invalid multipart form, unsupported file type, invalid `name`, invalid `metadata`, or request body too large |
| 401  | `authentication_error`  | Missing or invalid authentication token                                                                                      |
| 500  | `api_error`             | File storage backend is unavailable                                                                                          |

See [Errors](/cloud-agents/api/conventions/errors) for the full error envelope.

## Related

<CardGroup cols={2}>
  <Card title="Attach and download files" icon="paperclip" href="/cloud-agents/files">
    Upload files to give your agent context, and download files it produces.
  </Card>
</CardGroup>
