---
title: "Upload a file"
method: POST
path: "/v1/files"
tags: ["Files"]
---

# Upload a file

`POST /v1/files`

Upload a file into the session's uploads directory. By default the file is stored under `uploads/{filename}` within the session scope; pass `path` to push it to a custom object-storage-style key (e.g. `data/2024/report.pdf`), relative to the uploads mount (`/mnt/user-data/uploads/` inside the sandbox). The relative path is returned as the file ID. Uploading a file to an existing key overwrites it.

## Query parameters

- `scope_id` string, required — Session / container identifier (matches the `container` field in chat requests).
- `path` string, nullable — Object-storage-style key for the uploaded file, relative to the uploads mount. Defaults to `uploads/{filename}`. Nested keys are supported and parent directories are created automatically. May be prefixed with `uploads/` for convenience. Must be relative (no leading `/`), must not contain `..` components, and must not end with `/`.
- `namespace` string — Namespace for the file. Defaults to 'session'.

## Response `200`

Successful Response

- FileMetadata — Metadata for a file stored in a session (upload or sandbox output).
  - `id` string, required — Relative path of the file within the session, e.g. 'uploads/data.csv' or 'outputs/result.png'. Use this value as `file_id` in subsequent requests.
  - `created_at` string, date-time, required — ISO-8601 timestamp when the file was created or last modified.
  - `filename` string, required — Filename derived from the path.
  - `mime_type` string, required — MIME type detected from the file content.
  - `size_bytes` integer, required — File size in bytes.
  - `type` 'file' — Object type discriminator, always 'file'.
  - `downloadable` boolean, required — True for sandbox output files; False for uploaded input files.
  - `etag` string, nullable — Content checksum (MD5 hex or S3 ETag). Present after stat; None if unavailable.
  - `namespace` string — Namespace this file belongs to (e.g. 'session', 'skills', or a custom namespace).
  - `scope` FileScope, required — Scope that a file belongs to (always a session).
    - `id` string, required — Session / container identifier that owns this file.
    - `type` string — Namespace the file belongs to (e.g. 'session', 'skills', or a custom namespace).

## Other responses

- `401` — Unauthorized
- `422` — Validation Error

## Changes

- **2026-08-27** `4e828cf153c4` — 1 breaking, 4 info
  - the `type` response property const value `session` was removed for the status `200`
  - added the new optional `query` request parameter `namespace`
  - added the new optional `query` request parameter `path`
  - added the optional property `etag` to the response with the `200` status
  - …1 more
- **2026-07-06** `594fa71dfb90` — 1 info
  - endpoint added

[Change history](https://skmtc.dev/zylon-ai/apis/private-gpt-api/changes/v1/files/post.md)

---

[API](https://skmtc.dev/zylon-ai/apis/private-gpt-api.md) · [All operations](https://skmtc.dev/zylon-ai/apis/private-gpt-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/zylon-ai/private-gpt-api/revisions/4e828cf153c4/schema)
