---
title: "Import an encrypted asset (exact bytes)"
method: POST
path: "/v1/vault/assets"
tags: ["Vault"]
---

# Import an encrypted asset (exact bytes)

`POST /v1/vault/assets`

## Request

- Base URL: `http://localhost:9998`
- URL: `http://localhost:9998/v1/vault/assets`
- Auth: HTTP bearer

Imports the raw request body as an encrypted vault asset — a pasted or
dropped image stored bit-for-bit (no transcoding, no metadata
stripping), sealed as a multi-chunk blob under the asset-subkey. The
asset id is the `sha256:<hex>` of the exact plaintext, so identical
bytes dedup to one blob; the on-disk filename is an unrelated random
UUID. The request's `Content-Type` becomes the asset's recorded MIME
type. 413 past the per-asset ceiling (512 MiB at the service layer;
the server's global transport cap binds first over real HTTP).

## Response `200`

The imported (or dedup-matched) asset identity

- WireVaultAssetImportResponse: An imported (or dedup-matched) vault asset's identity. The id is the `sha256:<hex>` of the exact plaintext bytes (content-addressed); embed tokens serialize as `vault://asset/<id>`.
  - `id` string, required: Content id (`sha256:<hex>`) of the exact bytes.
  - `mimeType` string, required
  - `byteLength` integer, required: Exact plaintext byte count.

## Other responses

- `400`: Invalid request
- `413`: The asset exceeds the per-asset size ceiling
- `423`: The vault is locked (no VMK loaded). Unlock natively in ToolPiper — there is no unlock route. The body is the standard nested error envelope with type `vault_locked`.
- `503`: Vault service unavailable

---

[API](https://skmtc.dev/modelpiper/apis/toolpiper-api.md) · [All operations](https://skmtc.dev/modelpiper/apis/toolpiper-api/llms.txt) · [OpenAPI document](https://skmtc.dev/modelpiper/apis/toolpiper-api/revisions/6722bf56385c?raw)
