Developer reference

vau API

Bring your media into the vault programmatically: import, organize, share.

Spec /api/public/openapi.json

Base URL
https://vau.ltd
OpenAPI
3.1
Version
1.13
Endpoints
14

Only the minimal Import & manage surface is published; the custody surface and low-level plumbing are deliberately absent.

01

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:

http
Authorization: Bearer vau_your_token_here

A first call that lists the media in a vault:

curl
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.

02

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. 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
    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, register returns a presigned part-URL scheme: PUT each part, then call complete. The MCP's upload_files and import_project tools do this for you, mapping top-level folders to galleries automatically.

  2. 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
    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. 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
    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

agent
# 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."
03

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 endpoints

Bring 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}/files

    Owner intake: register a file

    Path parameters
    id string · required
    curl example
    curl
    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}/complete

    Owner intake: complete a file

    Path parameters
    id string · required
    fileId string · required
    curl example
    curl
    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-url

    Owner intake: presigned part URL

    Path parameters
    id string · required
    fileId string · required
    curl example
    curl
    curl https://vau.ltd/api/vaults/$VAULT_ID/files/$FILE_ID/part-url \
      -H "Authorization: Bearer $VAU_TOKEN"

Media

3 endpoints

List, 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}/original

    Download the original

    Path parameters
    id string · required
    curl example
    curl
    curl https://vau.ltd/api/media/$MEDIA_ID/original \
      -H "Authorization: Bearer $VAU_TOKEN"
  • GET /api/media/{id}/thumb

    Media thumbnail

    Path parameters
    id string · required
    curl example
    curl
    curl https://vau.ltd/api/media/$MEDIA_ID/thumb \
      -H "Authorization: Bearer $VAU_TOKEN"
  • GET /api/vaults/{id}/media

    List media

    Path parameters
    id string · required
    curl example
    curl
    curl https://vau.ltd/api/vaults/$VAULT_ID/media \
      -H "Authorization: Bearer $VAU_TOKEN"

Galleries

4 endpoints

Group 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}/collections

    Add media to a gallery

    Path parameters
    id string · required
    curl example
    curl
    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 parameters
    id string · required
    collectionId string · required
    curl example
    curl
    curl -X DELETE https://vau.ltd/api/media/$MEDIA_ID/collections/$GALLERY_ID \
      -H "Authorization: Bearer $VAU_TOKEN"
  • GET /api/vaults/{id}/collections

    List galleries

    Path parameters
    id string · required
    curl example
    curl
    curl https://vau.ltd/api/vaults/$VAULT_ID/collections \
      -H "Authorization: Bearer $VAU_TOKEN"
  • POST /api/vaults/{id}/collections

    Create a gallery

    Path parameters
    id string · required
    curl example
    curl
    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"}'

Shares

2 endpoints

Prepare a delivery link for a recipient, then revoke it the moment it has done its job. A share is a capability URL: powerful but scoped, and always revocable.

  • POST /api/shares/{id}/revoke

    Revoke a share

    Path parameters
    id string · required
    curl example
    curl
    curl -X POST https://vau.ltd/api/shares/$VAULT_ID/revoke \
      -H "Authorization: Bearer $VAU_TOKEN"
  • POST /api/vaults/{id}/shares

    Create a share

    Path parameters
    id string · required
    curl example
    curl
    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"}'

Posted

2 endpoints

Record 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}/posts

    Mark media posted

    Path parameters
    id string · required
    curl example
    curl
    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 parameters
    id string · required
    postId string · required
    curl example
    curl
    curl -X DELETE https://vau.ltd/api/media/$MEDIA_ID/posts/$POST_ID \
      -H "Authorization: Bearer $VAU_TOKEN"
04

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.

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

bash
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.js

Claude Desktop claude_desktop_config.json

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.

05

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.