Skip to main content

Endpoint reference

Base URL https://fileshub.zaions.com/api/v1, header X-API-Key: fh_live_…, JSON in and out. Every route needs a key with a password scope (own or admin) and the ability listed. Which entries a key reaches is explained in Access and scopes. The machine-readable version is in the OpenAPI document under the Passwords tag.

MethodPathAbilityPurpose
GET/passwordslistSearch and list entries
POST/passwordscreateSave a new entry
GET/passwords/{id}listOne entry's details
PATCH/passwords/{id}updateChange any field
POST/passwords/{id}/revealrevealThe password, current code and history
DELETE/passwords/{id}deleteTo Recently Deleted, or remove for good
POST/passwords/{id}/restoredeleteBack from Recently Deleted
POST/passwords/generatecreate or updateA strong password (stores nothing)

The entry object​

Every answer except reveal and generate returns this shape. It never contains the password, the setup key or the history.

{
"id": "01m5mjhqhzm44rckzkca0anxf0",
"project_id": 1,
"title": "Domain registrar",
"websites": ["https://registrar.example.com", "https://registrar.example.com/login"],
"username": "ops@acme.test",
"notes": "Renews every March.",
"tags": ["domains", "billing"],
"is_favorite": true,
"has_verification_code": true,
"strength": { "score": 4, "label": "very strong" },
"reused": false,
"owner_scope": "admin",
"created_via": "api",
"password_changed_at": "2026-10-23T14:27:28+00:00",
"last_revealed_at": null,
"created_at": "2026-10-23T14:27:28+00:00",
"updated_at": "2026-10-23T14:27:28+00:00",
"deleted_at": null
}

Field meanings: Overview → What an entry holds. reused is null in lists and restore answers; ask for one entry to get it.

List​

GET /passwords — the entries this key can reach, favourites first, then by title.

QueryMeaning
qText in the title, username or websites.
websiteA host or URL; matches entries saved for that host (registrar.example.com).
tagEntries carrying this tag.
favorite1 for favourites only, 0 for the rest.
trashedonly lists Recently Deleted instead.
project_idEvery-project admin keys only: one project. Ignored for other keys.
page, per_pagePaging: default 20, maximum 50 (pagination).
curl -s "https://fileshub.zaions.com/api/v1/passwords?q=registrar&per_page=20" -H "X-API-Key: $FILESHUB_KEY"
{
"success": true,
"data": [ { "id": "01m5mjhqhzm44rckzkca0anxf0", "title": "Domain registrar", "...": "the entry object" } ],
"meta": { "current_page": 1, "per_page": 20, "total": 1, "last_page": 1, "has_more": false, "next_page": null },
"message": "Showing 1-1 of 1 (page 1 of 1). This is the last page."
}

Create​

POST /passwords → 201 with the entry.

Body fieldRules
titleRequired. String, ≤ 191.
passwordRequired. String, ≤ 1,024.
websitesList of up to 20 strings (example.com, https://example.com/login).
usernameString, ≤ 191.
totp_secretBase32 setup key (at least 16 characters, spaces allowed) or an otpauth://totp/…?secret=… link.
notesString, ≤ 10,000.
tagsList of up to 20 strings, each ≤ 40.
is_favoriteBoolean.
project_idEvery-project admin keys only: store it in another project (its numeric id). Any other key may send only its own project's id.

The new entry's owner follows the key: an own key's entries are owner_scope: "own", an admin key's are "admin".

curl -s https://fileshub.zaions.com/api/v1/passwords \
-H "X-API-Key: $FILESHUB_KEY" -H "Content-Type: application/json" \
-d '{"title": "Domain registrar", "websites": ["registrar.example.com"], "username": "ops@acme.test", "password": "vKpqzt-mbw4hd-Xenfra"}'

Get​

GET /passwords/{id} → 200 with the entry, including reused.

Update​

PATCH /passwords/{id} → 200 with the entry. Send only what changes; every create field except project_id is accepted. Send "totp_secret": null to remove a setup key.

A new password moves the current one into the history (the last 10 are kept), re-scores the strength and sets password_changed_at. Sending the same password again changes nothing.

curl -s -X PATCH https://fileshub.zaions.com/api/v1/passwords/01m5mjhqhzm44rckzkca0anxf0 \
-H "X-API-Key: $FILESHUB_KEY" -H "Content-Type: application/json" \
-d '{"password": "Hqtrnw-5fmzky-pobcse", "tags": ["domains"]}'

Reveal​

POST /passwords/{id}/reveal → 200. Body (optional): {"history": true} adds the earlier passwords. Sets last_revealed_at and writes an audit-log row.

{
"data": {
"id": "01m5mjhqhzm44rckzkca0anxf0",
"username": "ops@acme.test",
"password": "Hqtrnw-5fmzky-pobcse",
"unreadable": false,
"verification_code": { "code": "626093", "expires_in": 21 },
"password_history": [
{ "password": "vKpqzt-mbw4hd-Xenfra", "replaced_at": "2026-10-23T14:27:28+00:00" }
]
}
}
  • verification_code is null when no setup key is stored. Codes are the standard 30-second, 6-digit (RFC 6238, SHA-1) codes; expires_in is the seconds left. Ask again for the next one.
  • password_history is null unless history was requested; newest first.
  • unreadable: true with password: null means the stored value can no longer be decrypted.

Delete​

DELETE /passwords/{id} → 200 {"data": {"id": "…", "deleted": true}}. The entry moves to Recently Deleted: it disappears from lists and lookups, and GET /passwords?trashed=only shows it.

DELETE /passwords/{id}?permanent=1 on an entry already in Recently Deleted removes it for good → 200 {"data": {"id": "…", "purged": true}}. On a live entry it answers 409 and changes nothing:

{ "message": "Delete the password first; only a deleted password can be removed for good." }

Restore​

POST /passwords/{id}/restore → 200 with the entry, back in place. Restoring a live entry is a no-op.

Generate​

POST /passwords/generate → 200. Stores nothing.

Body fieldMeaning
stylegrouped (default): three groups of six, one digit and one capital, like Fneuht-fguhgh-s3bitk. random: random characters.
lengthrandom only: 8–128, default 20.
symbols, numbers, uppercaserandom only: booleans, default true.
{ "data": { "password": "W4_zyv24KafLFlUu<zIo4epC", "strength": "very strong" } }

Errors​

Errors answer {"message": "…"}; validation errors add errors.

StatusWhenExample message
401No key, a wrong key or a disabled keyAPI key missing · Invalid API key · API key is inactive
402An external project with no plan for the password managerThis project has no active plan for passwords. See https://fileshub.zaions.com/pricing to request it.
403The key has no password scopeInsufficient permissions. Required scope: passwords
403The scope lacks the abilityThis key lacks the password ability: reveal.
403Creating in another project without every-project reachThis key can only store passwords in its own project.
404The id does not exist or the key cannot reach itNot found
409Permanent removal of a live entryDelete the password first; only a deleted password can be removed for good.
422Invalid inputThe password field is required. · The verification code setup key must be a base32 key or an otpauth:// link.
429The key's rate limit (default 60 requests a minute)See errors and limits