Vaze
API Reference

Account

The caller's account, profile, password, devices and dashboard stats

GET /api/me and GET /api/stats accept an API key or a signed-in session and need no particular scope. What they return depends on what the caller may do.

The endpoints that change the account (profile, password and devices) need a signed-in session and no scope, so every role can use them. A request made with an API key gets a 403.

Current account

GET /api/me

Returns the account behind the request and the scopes it can use. For an API key, scopes holds only what both the key and its owner's role allow, so a client can hide actions that would fail.

curl https://files.example.com/api/me \
  -H "API-Key: your-api-key"
{
  "data": {
    "user": {
      "id": "mYaNkYgtuFD3p3Z5N3Na2cNjqR1ytOMu",
      "name": "Dana",
      "email": "[email protected]",
      "image": null,
      "role": "editor"
    },
    "scopes": ["files:read", "files:write", "files:delete", "api-keys:manage"]
  },
  "error": null
}

Stats

GET /api/stats

The numbers on the dashboard's home page. Each section is null when the caller lacks its scope:

  • files needs files:read. It covers the whole instance: totals, used and free storage and the size of the volume, usage per MIME type, files and bytes per visibility, files added per day over the last 30 UTC days, and the five largest and five most recent files.
  • apiKeys needs api-keys:manage and a signed-in session, since an API key never carries that scope. It counts the user's own keys, their requests over the last seven UTC days, oldest first, and each key's share of that week.
  • hosting needs files:read. It is the public hosting traffic over the last 30 UTC days and the five files requested most in that time.
  • users needs users:manage, so only admins get it: how many accounts exist, how many are disabled, and how many devices are signed in across all of them.

alerts is always present and lists what needs attention, or nothing.

{
  "data": {
    "files": {
      "total": 128,
      "folders": 12,
      "storage": {
        "used": 734003200,
        "available": 96636764160,
        "capacity": 107374182400
      },
      "types": [{ "mimeType": "image/png", "size": 524288000, "count": 96 }],
      "largest": [ ... ],
      "recent": [ ... ],
      "visibility": {
        "public": { "count": 120, "size": 712003200 },
        "private": { "count": 8, "size": 22000000 }
      },
      "added": [
        { "date": "2026-09-19", "count": 0, "size": 0 },
        ...
        { "date": "2026-10-18", "count": 4, "size": 2352400 }
      ]
    },
    "apiKeys": {
      "total": 2,
      "requests": [
        { "date": "2026-10-12", "count": 14 },
        { "date": "2026-10-13", "count": 0 },
        ...
      ],
      "keys": [
        {
          "id": "bcc37b14-15f5-4934-8076-408484a87147",
          "name": "website",
          "requests": 14,
          "lastUsed": "2026-10-18T13:39:23.980Z",
          "expiresAt": null
        }
      ]
    },
    "hosting": {
      "days": [
        { "date": "2026-09-19", "requests": 0, "bytes": 0, "notFound": 0 },
        ...
        { "date": "2026-10-18", "requests": 212, "bytes": 48203776, "notFound": 3 }
      ],
      "top": [{ "file": { ... }, "requests": 96, "bytes": 31457280 }]
    },
    "users": { "total": 3, "disabled": 1, "sessions": 4 },
    "alerts": [
      { "type": "uploads-failed", "count": 2, "latest": "2026-10-18 13:39:08" },
      { "type": "keys-expiring", "count": 1 }
    ]
  },
  "error": null
}

largest, recent and each file in hosting.top are file objects, the same shape the files endpoints return. folders includes the root folder. added only counts files that are still stored, so deleting a file takes it off its day. Every daily list holds one entry per day, zeros included, oldest first.

storage.capacity is the usable size of the volume that holds Vaze's data, which other data on the same disk may share, so capacity - available - used is roughly what everything else takes up.

In apiKeys.keys, keys are ordered by requests, busiest first. Requests made with a key that has since been deleted still count in requests, but belong to no key in keys.

Hosting traffic

Vaze keeps a count per UTC day of what the public hosting endpoint serves:

  • requests counts responses that served a file: 200, 206 for a byte range, and 304 when the caller's cached copy is still current. A video that seeks sends several range requests, so each one counts.
  • bytes counts body bytes as they are sent. A download cut short counts what was sent before it stopped, which can include data already buffered on the way to the client.
  • notFound counts requests that found nothing, such as a broken link or a private file asked for without a signed link or a key.

Requests that carry a dashboard or mobile app session aren't counted, so browsing your own files doesn't look like traffic. HEAD requests aren't counted either. Requests made with an API key or a signed link are. Counts are gathered in memory and saved every minute, and before each read of this endpoint. Per-file counts are kept for 30 days and daily totals for a year.

Alerts

Each alert has a type, plus the fields below. New types may be added, so skip any you don't recognize.

TypeFieldsWhen
storage-lowavailable, capacityLess than a tenth of the volume is free. Needs files:read.
uploads-failedcount, latestYour own uploads failed in the last seven days. Signed-in sessions only.
deletes-failedcount, latestYour own file or folder deletes failed in the last seven days. Signed-in sessions only.
keys-expiredcountYour keys are past their expiry date. Needs api-keys:manage.
keys-expiringcountYour keys expire within seven days. Needs api-keys:manage.
keys-unusedcountYour keys haven't been used for 30 days, counting from when they were made if never used.

latest is when the most recent failure happened, as stored in activity. Clearing those entries from your activity clears the alert.

capacity, visibility, added, keys, hosting, users and alerts were added after this endpoint first shipped. Servers that predate them leave them out, so a client that talks to several servers should check before reading them.

Update your profile

PUT /api/me
{ "name": "Dana Scully", "email": "[email protected]" }

Send name, email or both; a field left out keeps its value. A new email is the one you sign in with from then on, and applies right away. The response is the updated account, the same shape GET /api/me returns.

StatusMeaning
400Neither field sent, or one of them is empty
409Another account already uses that email

Change your password

PUT /api/me/password
{
  "currentPassword": "old-password",
  "newPassword": "new-password",
  "revokeOtherSessions": true
}

newPassword needs at least 8 characters. With revokeOtherSessions, every other device is signed out and the session making the request stays signed in. A wrong currentPassword responds 400.

Devices

Each device signed in to the account is a session:

{
  "id": "Xb1x2Qm0...",
  "ipAddress": "203.0.113.7",
  "userAgent": "Vaze/1.0.0 (Android 16)",
  "createdAt": "2026-10-14T09:12:44.000Z",
  "current": true
}

current marks the session making the request. Session tokens are never returned, only their ids.

List devices

GET /api/me/sessions

Returns { "sessions": [ ... ] }, the current session first, then the most recently used.

Sign out a device

DELETE /api/me/sessions
// one device
{ "id": "<session-id>" }

// every device but this one
{ "others": true }

The current session can't be ended here, which responds 400; sign out instead. A session that isn't the caller's responds 404.

On this page