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/meReturns 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/statsThe numbers on the dashboard's home page. Each section is null when the
caller lacks its scope:
filesneedsfiles: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.apiKeysneedsapi-keys:manageand 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.hostingneedsfiles:read. It is the public hosting traffic over the last 30 UTC days and the five files requested most in that time.usersneedsusers: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:
requestscounts responses that served a file:200,206for a byte range, and304when the caller's cached copy is still current. A video that seeks sends several range requests, so each one counts.bytescounts 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.notFoundcounts 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.
| Type | Fields | When |
|---|---|---|
storage-low | available, capacity | Less than a tenth of the volume is free. Needs files:read. |
uploads-failed | count, latest | Your own uploads failed in the last seven days. Signed-in sessions only. |
deletes-failed | count, latest | Your own file or folder deletes failed in the last seven days. Signed-in sessions only. |
keys-expired | count | Your keys are past their expiry date. Needs api-keys:manage. |
keys-expiring | count | Your keys expire within seven days. Needs api-keys:manage. |
keys-unused | count | Your 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.
| Status | Meaning |
|---|---|
400 | Neither field sent, or one of them is empty |
409 | Another 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/sessionsReturns { "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.
Vaze