---
title: "Upload a local file or archive"
method: POST
path: "/v1/assets/upload"
tags: ["Assets"]
---

# Upload a local file or archive

`POST /v1/assets/upload`

## Request

- Base URL: `/` (relative, and the document was published on a file host, not at the API’s origin)
- URL: `/v1/assets/upload`
- Auth: HTTP bearer

Send raw file bytes, not multipart form data. The server packages a file or extracts a supported archive. Read max_import_bytes and upload_idempotency from GET /v1/assets first. When upload_idempotency is true, send a stable Idempotency-Key and X-Nodus-SHA256 for verified replay of the same bytes and name. An in-progress, failed or deleted keyed upload returns an actionable conflict without creating a replacement. Unkeyed uploads retain their existing behavior. After an uncertain unkeyed response, inspect the asset list before repeating the request.

## Query parameters

- `name` string

## Headers

- `Idempotency-Key` string
- `X-Nodus-SHA256` string

## Request body `application/octet-stream`

- string, binary

## Response `201`

Upload complete and asset ready

- Asset
  - `id` string
  - `kind` string: Includes workspace_source for a generated workspace project revision. These copies use their separate included source pool.
  - `name` string
  - `state` string: Current asset state: importing, ready, failed, deleting or deleted.
  - `revision` string
  - `sha256` string
  - `stored_bytes` integer
  - `imported_bytes` integer
  - `created_at` string, date-time
  - `ready_at` string, date-time, nullable
  - `deleted_at` string, date-time, nullable
  - `export` ConnectionExport
    - `id` string
    - `connection_id` string
    - `asset_id` string
    - `query_hash` string
    - `branch` string
    - `format` 'parquet' | 'csv'
    - `row_count` integer
    - `bytes` integer
    - `created_at` string, date-time
    - `state` 'pending' | 'running' | 'cleanup' | 'ready': Durable export state. Failed exports release this record after object cleanup.
  - `error` string: Value-free terminal query export error. Failed assets remain observable after cleanup, with zero stored bytes once their reservation is released.
  - `workspace_source` WorkspaceSourceAlias
    - `source_id` string, required
    - `workspace_id` string, required
    - `source_revision` string, required
    - `exporter_version` string, required
    - `state` string, required
    - `removable` boolean, required: Whether this alias can currently be removed. Active workloads protect their source.
    - `shared_alias_count` integer, required: References sharing this physical source copy. Deleting one alias need not release bytes.

## Other responses

- `400`: Invalid file, archive or size limit
- `409`: Storage quota reached or two imports already in progress
- `500`: Asset staging or commit failed
- `502`: Object storage unavailable
- `default`: Error. The JSON error and message fields are stable. Additional fields may provide details. Authentication, rate limits, and transient failures apply to all operations.

---

[API](https://skmtc.dev/nodus-compute/apis/nodus-infrastructure-execution-api.md) - [All operations](https://skmtc.dev/nodus-compute/apis/nodus-infrastructure-execution-api/llms.txt) - [OpenAPI document](https://skmtc.dev/nodus-compute/apis/nodus-infrastructure-execution-api/revisions/a59210899d95?raw)
