# Attachments

> Tracon documentation. Tracon is a .NET package family that adds a control
> plane on Microsoft Agent Framework, published as NuGet packages that run
> inside your own ASP.NET Core application.
>
> Page: https://tracon.dev/http-api/attachments/
> Summary: The attachments endpoints of the Tracon HTTP API — 4 operations.

4 operations. `{prefix}` is the route prefix passed to
`MapTracon`; the template uses `/tracon`.

## GET {prefix}/api/attachments

**Operation ID:** `TraconListAttachments`

**Lists attachments.**

Only descriptors are returned — file name, media type, size, and content hash — never the bytes; fetch those from the download endpoint. 'sessionId' narrows the list to one session, and attachments uploaded without a session are reachable only without that filter. Paging is offset based: 'skip' defaults to 0, 'take' to 50, and 'take' is clamped to 1..200 instead of being rejected. If a registered IRunAuthorizationHandler denies the caller, the response is 403 — the list is REJECTED, never silently filtered.

**Authorization:** bearer authentication; `Reader` role policy when that policy is registered; `RunsRead` API-key scope.

| Parameter | In | Required | Type | Description and rules |
|---|---|---|---|---|
| `sessionId` | query | no | `string` | — |
| `skip` | query | no | `integer (int32)` | pattern `^-?(?:0\\|[1-9]\d*)$` |
| `take` | query | no | `integer (int32)` | pattern `^-?(?:0\\|[1-9]\d*)$` |

| Response | Body | Headers |
|---|---|---|
| **200** OK | `application/json` → array of [`AttachmentDescriptor`](/http-api/schemas/attachmentdescriptor/) | — |
| **403** Forbidden | `application/problem+json` → [`ProblemDetails`](/http-api/schemas/problemdetails/) | — |

## POST {prefix}/api/attachments

**Operation ID:** `TraconUploadAttachment`

**Uploads a new attachment.**

The body must be 'multipart/form-data' and must carry a 'file' field. The type is validated by magic bytes, not by the Content-Type the client reports. If a registered IRunAuthorizationHandler denies the caller, the response is 403.

**Authorization:** bearer authentication; `Operator` role policy when that policy is registered; `RunsWrite` API-key scope.

| Parameter | In | Required | Type | Description and rules |
|---|---|---|---|---|
| `sessionId` | query | no | `string` | — |

**Request body** (required):

- `multipart/form-data` → `object`

| Response | Body | Headers |
|---|---|---|
| **201** Created | `application/json` → [`AttachmentDescriptor`](/http-api/schemas/attachmentdescriptor/) | — |
| **403** Forbidden | `application/problem+json` → [`ProblemDetails`](/http-api/schemas/problemdetails/) | — |

## GET {prefix}/api/attachments/{id}

**Operation ID:** `TraconDownloadAttachment`

**Streams the raw content of an attachment.**

The response carries the attachment's own stored media type, an ETag holding the content's SHA-256, and 'Content-Disposition: attachment' together with 'X-Content-Type-Options: nosniff' — a browser therefore downloads the bytes instead of rendering them, so uploaded HTML can never execute in the console's origin. The token travels in the Authorization header, so a browser cannot use this URL directly as an image or audio element source; fetch the bytes and wrap them in an object URL instead. If a registered IRunAuthorizationHandler denies the caller, the response is 404, identical to an attachment that does not exist.

**Authorization:** bearer authentication; `Reader` role policy when that policy is registered; `RunsRead` API-key scope.

| Parameter | In | Required | Type | Description and rules |
|---|---|---|---|---|
| `id` | path | yes | `string (uuid)` | — |

| Response | Body | Headers |
|---|---|---|
| **200** OK | `application/octet-stream` → [`Stream`](/http-api/schemas/stream/) | — |
| **404** Not Found | `application/problem+json` → [`ProblemDetails`](/http-api/schemas/problemdetails/) | — |

## DELETE {prefix}/api/attachments/{id}

**Operation ID:** `TraconDeleteAttachment`

**Deletes an attachment.**

The bytes are removed immediately; there is no soft delete. Messages that already reference the attachment keep the reference and it stops resolving, so delete an attachment only when its conversation no longer needs to be replayed. Deleting the owning session removes its attachments as well, which is usually the call to reach for. An unknown id returns 404, and so does a denial by a registered IRunAuthorizationHandler.

**Authorization:** bearer authentication; `Operator` role policy when that policy is registered; `RunsWrite` API-key scope.

| Parameter | In | Required | Type | Description and rules |
|---|---|---|---|---|
| `id` | path | yes | `string (uuid)` | — |

| Response | Body | Headers |
|---|---|---|
| **204** No Content | — | — |
