---
title: "Upload File"
method: POST
path: "/api/v1/upload"
tags: ["public-api"]
---

# Upload File

`POST /api/v1/upload`

## Request

- Base URL: `https://ndi-api.nace.ai` (the document declares no server; this is the origin it was published from)
- URL: `https://ndi-api.nace.ai/api/v1/upload`
- Auth: API key in header `X-API-Key`
- TypeScript: <https://skmtc.dev/nace/apis/ndi-service/docs/api/v1/upload/post.ts> (a function with typed inputs; its response is checked against the schema)

Stage a document and return an opaque ``file_id``.

Pass ``ndi://file/<file_id>`` as ``source_url`` on any action endpoint.
Upload once, reuse across parse → categorize / ground.

Ordinary uploads have no expiry and stay until explicit deletion.

## Request body `multipart/form-data`

- BodyUploadFileApiV1UploadPost
  - `file` string, binary, required: The document to stage for later parse/categorize/ground.

## Response `200`

Successful Response

- NdiServiceAppSchemasPublicUploadResponse: Returned by ``POST /upload``: an opaque handle for later job starts.
  - `file_id` string, uuid, required
  - `file_name` string, required
  - `expires_at` string, date-time, nullable, required

## Other responses

- `400`: Bad Request
- `401`: Unauthorized
- `402`: Payment Required
- `403`: Forbidden
- `404`: Not Found
- `409`: Conflict
- `413`: Upload exceeds NDI_MAX_UPLOAD_BYTES.
- `422`: Unprocessable Entity
- `500`: Internal Server Error
- `503`: Service Unavailable

---

[API](https://skmtc.dev/nace/apis/ndi-service.md) - [All operations](https://skmtc.dev/nace/apis/ndi-service/llms.txt) - [OpenAPI document](https://skmtc.dev/nace/apis/ndi-service/revisions/d9d1f8ec2207?raw)
