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

# Files

> Call /{consumer}/v1/files to upload, list, retrieve, delete, and download content. TrustGate routes only to registries that expose a Files store.

Clients send the same OpenAI Files requests they would send to OpenAI. Auth and the
consumer slug are the same as [chat](/trustgate/getting-started/quickstart#call-from-your-application).

```bash theme={null}
curl -X POST "https://<gateway-host>/<consumer-slug>/v1/files" \
  -H "X-AG-API-Key: <your-api-key>" \
  -F purpose=assistants \
  -F file=@notes.txt
```

List, retrieve, download, and delete use the same host and key:

```bash theme={null}
curl "https://<gateway-host>/<consumer-slug>/v1/files?purpose=assistants" \
  -H "X-AG-API-Key: <your-api-key>"

curl "https://<gateway-host>/<consumer-slug>/v1/files/<file-id>" \
  -H "X-AG-API-Key: <your-api-key>"

curl "https://<gateway-host>/<consumer-slug>/v1/files/<file-id>/content" \
  -H "X-AG-API-Key: <your-api-key>"

curl -X DELETE "https://<gateway-host>/<consumer-slug>/v1/files/<file-id>" \
  -H "X-AG-API-Key: <your-api-key>"
```

On a Private data plane, add `X-AG-Gateway-Slug` as in the chat snippets.

| Method   | Path                     | Result                                                  |
| -------- | ------------------------ | ------------------------------------------------------- |
| `POST`   | `/v1/files`              | Multipart upload, forwarded as-is                       |
| `GET`    | `/v1/files`              | List (query string passed through, including `purpose`) |
| `GET`    | `/v1/files/{id}`         | Retrieve metadata                                       |
| `GET`    | `/v1/files/{id}/content` | Download bytes; upstream `Content-Type` is kept         |
| `DELETE` | `/v1/files/{id}`         | Delete                                                  |

Wrong methods are **400**. Extra path tails (`/files/{id}/other`) are **404**.

TrustGate does **not** rewrite the multipart body and does not own file identity or
retention — upstream file IDs are returned as-is.

OpenAI SDKs use the same consumer base URL: `client.files.create()`, `list()`,
`retrieve()`, `content()`, and `delete()`.

## Providers

| Registry         | Upstream                                                                                          |
| ---------------- | ------------------------------------------------------------------------------------------------- |
| **OpenAI**       | `{base_url or https://api.openai.com/v1}/files…`                                                  |
| **Azure OpenAI** | `{endpoint}/openai/files…?api-version=…` (not deployment-scoped)                                  |
| **OpenRouter**   | `https://openrouter.ai/api/v1/files` (query passthrough, including `provider=`)                   |
| **xAI**          | `https://api.x.ai/v1/files`                                                                       |
| **Mistral**      | `{base_url or https://api.mistral.ai/v1}/files`                                                   |
| **Anthropic**    | `{base_url or https://api.anthropic.com/v1}/files` (`x-api-key`, `anthropic-version: 2023-06-01`) |

Custom / OpenAI-compatible, Groq, Gemini / Vertex, Bedrock, Cohere, and other chat-only
providers do not expose a Files store. They are left out of the candidate pool.

Anthropic Files is GA on the Claude API — TrustGate does not send the old
`files-api-2025-04-14` beta header. The response is Anthropic-shaped (`type`, `mime_type`,
`size_bytes`); it is not rewritten to OpenAI `object` / `purpose`. `purpose` is optional.
Claude Files is **not** available on Bedrock or Vertex.

Gemini `files.upload` uses a different wire format and is out of scope.

A JSON `model` field (including `@provider/model`) is used only to pin a registry. Upload
itself is multipart and has no model rewrite.

## Routing

1. The consumer's registries are filtered to those that advertise files.
2. [Model resolution](/trustgate/routing/model-resolution) and
   [load balancing](/trustgate/routing/load-balancing) run on that pool.
3. Pinning a registry that cannot store files is a **400**, not a failover.
4. An empty capable pool is a **503**.

Attach at least one files-capable registry to the consumer. A mixed chat + files pool is
fine: chat still uses every chat-capable member; files skip the rest.

## Related

* [Registries](/trustgate/concepts/registries)
* [Consumers](/trustgate/concepts/consumers) — Connect tab
* [Models](/trustgate/routing/models) — discovery does not list file ids
* [Images](/trustgate/routing/images)
* [Quickstart](/trustgate/getting-started/quickstart)
