Using the Zero API
Using the Zero API (Advanced Usage)
Zero includes a small, local-only API for power users who want to script secure reads (e.g., fetch a decrypted password or download a file attached to a row). These endpoints work only on your machine and require an active, authenticated session.
Base URL: ZERO_HOST_URL
(defaults to http://127.0.0.1:6007/
). Use this placeholder in your scripts so you can change it in one place later.
Before you start
- Keep Zero running.
- Be logged in (the app writes a signed session cookie to a local file that the API reads).
- Know your
table
name and the row’sid
.
Authentication model: the API reads the saved, signed session from disk (no tokens, no headers required). If you log out, the session file is removed and the API returns 403
.
Endpoints in this version
1) GET /api/get-credentials
Return a single row with decrypted scalar fields. File fields are returned as downloadable links (no raw bytes in JSON).
Query parameters
table
(required): table namerow_id
(required): numeric row idonly_creds
(optional):true
to return just username/password if present
Notes
- Encrypted scalar fields are decrypted server-side for this response.
- File fields become URLs:
stored: "fs"
→url
points to/media/…
(works in the same browser session).alt_url
points to the API download endpoint and works for headless scripts.stored: "db"
→url
points to the API download endpoint.
- When
only_creds=true
, the API looks for common columns likeusername
/email
/login
andpassword
/pass
/pwd
/secret
. If none are found, you’ll get a friendly message instead of an error.
Example (Python)
# Example: only username/password
import requests
url = f"{'ZERO\_HOST\_URL'.rstrip('/')}/api/get-credentials"
params = {"table": "credentials", "row\_id": 42, "only\_creds": "true"}
r = requests.get(url, params=params)
print(r.status\_code)
print(r.json())
Example JSON responses
# only_creds = true (found):
{
"status": "ok",
"username_field": "username",
"password_field": "password",
"username": "alice",
"password": "s3cr3t",
"message": null
}
# only\_creds = true (not found):
{
"status": "ok",
"username\_field": null,
"password\_field": null,
"username": null,
"password": null,
"message": "No username/password-like columns found in this table."
}
# Full row (files are links; no raw bytes):
{
"id": 42,
"site": "[https://example.com](https://example.com)",
"username": "alice",
"password": "s3cr3t", # decrypted because this column is encrypted in schema
"notes": "2FA enabled for prod.",
"attachment": {
"stored": "fs",
"url": "ZERO\_HOST\_URL/media/credentials/42/contract.pdf",
"alt\_url": "ZERO\_HOST\_URL/api/file/download?table=credentials\&row\_id=42\&field=attachment",
"note": "Direct /media URL works in the same browser session. External clients should use 'alt\_url'."
},
"config\_file": {
"stored": "db",
"url": "ZERO\_HOST\_URL/api/file/download?table=credentials\&row\_id=42\&field=config\_file",
"note": "Use this API URL to download. Requires an authenticated saved session."
},
"created": "2025-01-10T13:25:51",
"updated": "2025-02-03T09:12:04",
"last\_used": "2025-02-10T08:01:00"
}
Common errors
400
— missing/invalid params or table name403
— no active session (log in to Zero and try again)404
— row not found
2) GET /api/file/download
Download a single file field from a row. Streams bytes (decrypted on the fly if needed).
Query parameters
table
(required): table namerow_id
(required): numeric row idfield
(required): the file column name
When to use this endpoint
- For files stored in the database (BLOB), this is the only way to fetch them.
- For files stored on disk (
/media
), use this endpoint when calling from scripts or different clients. It works with the saved session; the bare/media
URL only works in the same browser session.
Examples (Python)
# Download and save a file
import requests
url = f"{'ZERO\_HOST\_URL'.rstrip('/')}/api/file/download"
params = {"table": "credentials", "row\_id": 42, "field": "attachment"}
r = requests.get(url, params=params, stream=True)
if r.ok:
with open("attachment.bin", "wb") as f:
for chunk in r.iter\_content(chunk\_size=8192):
f.write(chunk)
else:
print(r.status\_code, r.text)
Common errors
400
— bad params or the field isn’t a file column403
— no active session404
— row/file not found500
— decrypt failed (e.g., corrupted value)
Tips & security notes
- The API is local-only. There are no remote tokens or public listeners.
- Scripts do not need to send cookies; the app reads the signed session file from disk.
/media/…
links work inside your current browser session. For headless clients, prefer the/api/file/download
URL.- Logging out will invalidate the saved session; API calls then return
403
.
Quick checklist if a call fails
- Is Zero running?
- Are you logged in (try the UI first)?
- Is the
table
name exact and therow_id
correct? - For files: is the column actually defined as a file field in the schema?