HTTP API

Upload, download, and manage files over plain HTTP. No account, no keys for uploads. Just curl.

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

POST/upload

Send a multipart/form-data body with one or more files[] fields (a single file field also works). Options are query parameters:

ParamTypeDescription
expiredurationLifetime, e.g. 6h, 90m, 3600. Capped at 24h; default 24h.
max_downloadsintegerAuto-delete after this many downloads.
outputenumResponse 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 are chunk_size bytes.
  • PATCH /upload/resumable/{id}. One slot's raw bytes with header Upload-Offset: <byte>. The offset must be a slot boundary (a multiple of chunk_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

GET/f/{name}

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)

GET/f/{name}/meta

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/delete/{name}

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

GET/api/info

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

GET/openapi.json

A full OpenAPI 3.1 description of every endpoint (including the admin API), for generating clients and tooling.

08Report abuse

POST/report

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."
}
codeMeaning
file_too_largeExceeds the upload size cap
empty_fileZero-byte upload
filetype_blockedExtension, MIME, or executable rejected
rate_limitedToo many uploads; wait and retry
storage_fullServer is low on disk
checksum_mismatchResumable finish hash didn't match
not_foundNo such file or session
forbiddenWrong or missing delete token

10Limits & policy

  • Files expire after at most 24 hours.
  • Size and rate limits are available at /api/info.
  • Executables and a few risky types are rejected; see the FAQ for the content policy.
  • Downloads and visits are not logged.