Developer reference
vau API
Bring your media into the vault programmatically: import, organize, share.
Only the minimal Import & manage surface is published; the custody surface and low-level plumbing are deliberately absent.
Authentication
Every request is authenticated with a vau_ bearer token. Mint one in your
vault's Access page (/v/<your-vault>/access): give
it a name, choose read-only or read-write, set an
optional expiry. The secret is shown once; store it then. A token is scoped to a
single vault, is revocable in the same register at any time, and every action it takes is
attributed in the ledger as via {token name}.
Send it on the Authorization header of every call:
Authorization: Bearer vau_your_token_hereA first call that lists the media in a vault:
curl https://vau.ltd/api/vaults/$VAULT_ID/media \
-H "Authorization: Bearer $VAU_TOKEN"A read-only token receives a clear 403 on any write,
never a silent no-op. A viewer cannot mint a read-write token; a token's
permission is capped by the role of the member who created it.
Workflow
One job, three moves. The canonical loop the API and the MCP server are built around: import a project's photos, organize them into galleries, and share the result. Every call below carries the same vau_ token from the step above.
- 1
Import the project
Register each file, PUT its bytes to the storage URL you get back, then complete it, and files land straight in your library with an accession stamp. The response tells you whether a file takes a single PUT or presigned multipart parts.
curl -X POST https://vau.ltd/api/vaults/$VAULT_ID/files \ -H "Authorization: Bearer $VAU_TOKEN" \ -H "Content-Type: application/json" \ -d '{"name":"hero.jpg","size_bytes":4813204,"mime":"image/jpeg"}'Large uploads: for big videos,
registerreturns a presigned part-URL scheme: PUT each part, then callcomplete. The MCP'supload_filesandimport_projecttools do this for you, mapping top-level folders to galleries automatically. - 2
Organize into galleries
Create a gallery, then file media into it. Membership is a pointer; the original stays in the archive forever, so grouping (and regrouping) is always safe.
curl -X POST https://vau.ltd/api/vaults/$VAULT_ID/collections \ -H "Authorization: Bearer $VAU_TOKEN" \ -H "Content-Type: application/json" \ -d '{"name":"Summer 2026"}' # → returns { "id": "…", "slug": "summer-2026" }. Then file each media into it: curl -X POST https://vau.ltd/api/media/$MEDIA_ID/collections \ -H "Authorization: Bearer $VAU_TOKEN" \ -H "Content-Type: application/json" \ -d '{"collection_id":"$GALLERY_ID"}' - 3
Share it
Mint a scoped, revocable share link for the gallery. Hand the URL to a recipient; revoke it the moment it has done its job. (Deleting the gallery or the media itself stays with you; see below.)
curl -X POST https://vau.ltd/api/vaults/$VAULT_ID/shares \ -H "Authorization: Bearer $VAU_TOKEN" \ -H "Content-Type: application/json" \ -d '{"scope":"collection","collection_id":"$GALLERY_ID","recipient_email":"studio@example.com"}'
The same loop, one instruction
# With the MCP server wired up (see "For AI agents"), one instruction
# runs the whole loop: the agent calls import_project, create_gallery,
# add_to_gallery and create_share for you:
"Import ~/shoots/summer-2026 into my vault, group the hero frames into a
'Summer 2026' gallery, and share it with studio@example.com."Endpoints
Grouped by resource. Paths are relative to https://vau.ltd; every path parameter
is in: path and required. Send your token on each call.
Import & upload
3 endpointsBring a project’s assets into the vault: register a file, stream its bytes to storage with the presigned URL, then complete it. Small files take a single PUT; large videos use presigned multipart parts (see the large-uploads note). Files land straight in your library.
- POST
/api/vaults/{id}/filesOwner intake: register a file
Path parametersidcurl example
curl -X POST https://vau.ltd/api/vaults/$VAULT_ID/files \ -H "Authorization: Bearer $VAU_TOKEN" \ -H "Content-Type: application/json" \ -d '{"name":"hero.jpg","size_bytes":4813204,"mime":"image/jpeg"}' - POST
/api/vaults/{id}/files/{fileId}/completeOwner intake: complete a file
Path parametersidfileIdcurl example
curl -X POST https://vau.ltd/api/vaults/$VAULT_ID/files/$FILE_ID/complete \ -H "Authorization: Bearer $VAU_TOKEN" - GET
/api/vaults/{id}/files/{fileId}/part-urlOwner intake: presigned part URL
Path parametersidfileIdcurl example
curl https://vau.ltd/api/vaults/$VAULT_ID/files/$FILE_ID/part-url \ -H "Authorization: Bearer $VAU_TOKEN"
Media
3 endpointsList, inspect and download the files held in a vault. The archive is read-and-collect: a token fills galleries, it never empties the vault.
- GET
/api/media/{id}/originalDownload the original
Path parametersidcurl example
curl https://vau.ltd/api/media/$MEDIA_ID/original \ -H "Authorization: Bearer $VAU_TOKEN" - GET
/api/media/{id}/thumbMedia thumbnail
Path parametersidcurl example
curl https://vau.ltd/api/media/$MEDIA_ID/thumb \ -H "Authorization: Bearer $VAU_TOKEN" - GET
/api/vaults/{id}/mediaList media
Path parametersidcurl example
curl https://vau.ltd/api/vaults/$VAULT_ID/media \ -H "Authorization: Bearer $VAU_TOKEN"
Galleries
4 endpointsGroup media freely. Adding or removing an item is a membership change only: the original file stays in the archive forever. Deleting a gallery is a custody act and stays session-only.
- POST
/api/media/{id}/collectionsAdd media to a gallery
Path parametersidcurl example
curl -X POST https://vau.ltd/api/media/$MEDIA_ID/collections \ -H "Authorization: Bearer $VAU_TOKEN" \ -H "Content-Type: application/json" \ -d '{"collection_id":"$GALLERY_ID"}' - DELETE
/api/media/{id}/collections/{collectionId}Remove media from a gallery
Path parametersidcollectionIdcurl example
curl -X DELETE https://vau.ltd/api/media/$MEDIA_ID/collections/$GALLERY_ID \ -H "Authorization: Bearer $VAU_TOKEN" - GET
/api/vaults/{id}/collectionsList galleries
Path parametersidcurl example
curl https://vau.ltd/api/vaults/$VAULT_ID/collections \ -H "Authorization: Bearer $VAU_TOKEN" - POST
/api/vaults/{id}/collectionsCreate a gallery
Path parametersidcurl example
curl -X POST https://vau.ltd/api/vaults/$VAULT_ID/collections \ -H "Authorization: Bearer $VAU_TOKEN" \ -H "Content-Type: application/json" \ -d '{"name":"Summer 2026"}'
Posted
2 endpointsRecord where a piece of media went live, and unrecord it. The posted mark is how the vault remembers what has already been used.
- POST
/api/media/{id}/postsMark media posted
Path parametersidcurl example
curl -X POST https://vau.ltd/api/media/$MEDIA_ID/posts \ -H "Authorization: Bearer $VAU_TOKEN" \ -H "Content-Type: application/json" \ -d '{"url":"https://instagram.com/p/XXXX"}' - DELETE
/api/media/{id}/posts/{postId}Unmark a posted record
Path parametersidpostIdcurl example
curl -X DELETE https://vau.ltd/api/media/$MEDIA_ID/posts/$POST_ID \ -H "Authorization: Bearer $VAU_TOKEN"
For AI agents
vau is AI-compatible, never AI-managed. Your own agent (Claude Code, Claude Desktop, any MCP client) operates the vault with your permissions, through the same REST API a human uses. Point it at the machine-readable spec, or wire up the MCP server for a self-describing toolset.
/llms.txtis the curated, agent-first index of vau and where the docs live./api/public/openapi.jsonis the machine-readable OpenAPI 3.1 document (token-reachable surface only).
MCP setup
The MCP server (@vau/mcp, stdio) is a thin wrapper over the same API.
Configure it with VAU_API_URL and VAU_TOKEN.
Read-only and read-write tools mirror the token permission; there are no custody tools, because
the API forbids custody to tokens.
Claude Code
claude mcp add vau \
--env VAU_API_URL=https://vau.ltd \
--env VAU_TOKEN=vau_your_token_here \
-- node /absolute/path/to/vau/mcp/dist/index.jsClaude Desktop claude_desktop_config.json
{
"mcpServers": {
"vau": {
"command": "node",
"args": ["/absolute/path/to/vau/mcp/dist/index.js"],
"env": {
"VAU_API_URL": "https://vau.ltd",
"VAU_TOKEN": "vau_your_token_here"
}
}
}
}Manage everything with your AI's help. The AI never manages you.
Custody stays in your hands
A few operations are deliberately absent from this API and can never be performed with a token, only by you, signed in: accepting a delivery into the library, trashing media, deleting a gallery, adding or removing members, exporting everything, and minting or revoking tokens.
This is a feature, not a limitation. It draws a hard line around your vault's blast radius: a token that leaks can fill your galleries or make a share you can revoke; it can never empty the vault, grant itself permanence, or hand a human access. The AI builds your portfolio; custody stays with you.