01Quick start
POST a file as multipart, get JSON back with the URL:
curl -F 'files[]=@photo.png' https://un.vault.moe/upload
{
"success": true,
"files": [
{
"hash": "5c3f1a2b9d4e6f70",
"filename": "AbCd1234.png",
"url": "https://un.vault.moe/f/AbCd1234.png",
"size": 18244,
"dupe": false,
"expires_at": 1780000000,
"delete_token": "Hq3...keep-this-secret",
"delete_url": "https://un.vault.moe/delete/AbCd1234.png?token=Hq3..."
}
]
}
All files expire within 24 hours (or sooner; see options). Save the delete_token to delete manually.
02Endpoints
- POST/uploadUpload one or more files
- POST/upload/resumableStart a resumable (chunked) upload
- GET/f/{name}Download a file (supports Range)
- GET/f/{name}/metaFile metadata, without counting a download
- DELETE/delete/{name}Delete a file (delete token)
- GET/api/infoServer limits & policy (JSON)
- POST/reportReport a file for abuse
- GET/openapi.jsonOpenAPI 3.1 spec (all endpoints)
03Upload
Send a multipart/form-data body with one or more files[] fields (a single file field also works). Options are query parameters:
| Param | Type | Description |
|---|---|---|
expire | duration | Lifetime, e.g. 6h, 90m, 3600. Capped at 24h; default 24h. |
max_downloads | integer | Auto-delete after this many downloads. |
output | enum | Response format: json (default), csv, text, html, gyazo. |
curl -F 'files[]=@clip.mp4' \
'https://un.vault.moe/upload?expire=6h&max_downloads=3&output=text'
output=text returns just the URL(s), one per line. Handy for scripts and ShareX.
04Resumable uploads
For large files or unreliable connections, use chunked uploads. The file is split into fixed-size slots that may be sent in parallel and out of order; on interrupt, resume the slots that are still missing.
- POST /upload/resumable. Send JSON
{"filename","size","chunk_size?","expire?","max_downloads?"}and get back{session_id, chunk_size, ...}. Slots arechunk_sizebytes. - PATCH /upload/resumable/{id}. One slot's raw bytes with header
Upload-Offset: <byte>. The offset must be a slot boundary (a multiple ofchunk_size) and the body must exactly fill the slot (the last slot is the remainder). Re-sending a committed slot is a no-op. - GET /upload/resumable/{id}. Returns
{chunk_size, total_size, received_slots, complete}so you know which slots are missing. - HEAD /upload/resumable/{id}. Returns the contiguous
Upload-Offset(simple sequential resume). - POST /upload/resumable/{id}/finish. Send JSON
{"xxh3"}(required). The server verifies the whole-file hash and publishes (422 on mismatch). - DELETE /upload/resumable/{id}. Abort and discard.
The vault-upload CLI does all of this automatically for large files, uploading slots over several parallel connections (upload_streams).
05Download
Downloads support Range headers. Unsafe content types are forced to attachment + nosniff; images, video, audio, PDF, and plain text render inline.
curl -O https://un.vault.moe/f/AbCd1234.png
Metadata (no download count)
Read file metadata. Does not count against max_downloads:
curl https://un.vault.moe/f/AbCd1234.png/meta
{
"filename": "AbCd1234.png",
"size": 18244,
"mime": "image/png",
"expires_at": 1780000000,
"download_count": 1,
"downloads_remaining": 2,
"available": true
}
06Delete
Delete a file with the delete_token from its upload response, via the X-Delete-Token header, a ?token= query param, or a form field:
curl -X DELETE -H 'X-Delete-Token: Hq3...' \
https://un.vault.moe/delete/AbCd1234.png
A wrong or missing token always gives 403, so you can't probe whether a file exists.
07Discovery
Server limits and policy (JSON). For programmatic clients:
curl https://un.vault.moe/api/info
{
"version": "...",
"max_upload_bytes": 53687091200,
"max_expiry_seconds": 86400,
"chunk_size": 16777216,
"rate_limit": { "enabled": true, "files": 100, "window_seconds": 60 },
"blocked_extensions": ["exe", "svg", "php", "..."]
}
OpenAPI
A full OpenAPI 3.1 description of every endpoint (including the admin API), for generating clients and tooling.
08Report abuse
Report a file for abuse. No authentication is required. Send the file URL (or name) and an optional reason:
curl -H 'Content-Type: application/json' \
-d '{"url":"https://un.vault.moe/f/AbCd1234.png","reason":"..."}' \
https://un.vault.moe/report
Reports are queued for an operator to review. The vault-upload report <url> CLI does the same.
09Errors
Errors: HTTP status + JSON with a machine-readable code:
{
"success": false,
"errorcode": 415,
"code": "filetype_blocked",
"description": "Filetype not allowed."
}
| code | Meaning |
|---|---|
file_too_large | Exceeds the upload size cap |
empty_file | Zero-byte upload |
filetype_blocked | Extension, MIME, or executable rejected |
rate_limited | Too many uploads; wait and retry |
storage_full | Server is low on disk |
checksum_mismatch | Resumable finish hash didn't match |
not_found | No such file or session |
forbidden | Wrong or missing delete token |