API reference
Base: https://api.rempar.org/v1. JSON everywhere. Successful responses are wrapped in {"data": ...}, errors in {"error": {"code": "...", "message": "..."}}. Authentication by a Bearer token specific to each device.
The API is zero-knowledge: it never receives a password or any content in plain text. Third-party clients are welcome as long as they follow protocol v1.
Health
GET /v1/health
→ { "data": { "status": "ok", "release": "1.1.0" } }
Authentication
| Method | Route | Body | Response |
|---|---|---|---|
| POST | /auth/prelogin |
{email} |
{kdf, kdf_salt}. Deterministic dummy salt if the e-mail address is unknown. |
| POST | /auth/register |
{email, auth_key, kdf, kdf_salt, device} |
201 {status: "verification_sent"}. A six-digit code is sent by e-mail. |
| POST | /auth/verify-email |
{email, code} |
{} |
| POST | /auth/login |
{email, auth_key, device, totp?, code?} |
{tokens, device_id, vault_key_sealed?}. Error totp_required (403) if 2FA is active and the code is missing. Then email_code_required (403): a six-digit code is e-mailed and must be sent back in code to obtain the tokens (10 min, 5 attempts). |
| POST | /auth/refresh |
{refresh_token} |
{access_token, refresh_token, ...}. Rotation; a replay revokes the device. |
| POST | /auth/logout |
Revokes the current device. | |
| POST | /auth/recover |
{email, recovery_auth, totp?} |
Proof of the recovery kit: returns {vault_key_recovery, recovery_token} (15 min). totp_required when 2FA is on. |
| POST | /auth/recover/complete |
{email, recovery_token, auth_key, kdf, kdf_salt, vault_key_sealed, device} |
New master password: replaces the authentication key and the resealed vault key, revokes every other device, signs this one in ({tokens, device_id, vault_key_sealed}). |
device: {name, platform, client_id} where client_id is a UUID chosen by the client, stable for this device.
kdf: {"algo": "argon2id", "m": 65536, "t": 3, "p": 4}. Clients refuse parameters weaker than m=19456, t=2, p=1.
Account
| Method | Route | Description |
|---|---|---|
| GET | /account |
E-mail address, 2FA status, vault revision, subscription {plan, active, until}. |
| GET | /account/subscription |
Subscription only. |
| POST | /account/password |
Replaces auth_key after a master password change. The client first re-publishes the re-sealed vault key. |
| GET | /account/devices |
Active devices. |
| DELETE | /account/devices/{id} |
Revokes a device. |
| POST | /account/totp/setup |
Generates a secret and returns {secret, otpauth_url}. |
| POST | /account/totp/enable |
{code}: enables 2FA. |
| POST | /account/totp/disable |
{code}: disables 2FA. |
Vault
| Method | Route | Description |
|---|---|---|
| PUT | /vault/key |
{vault_key_sealed, vault_key_recovery?}: sealed blobs only, replaced atomically. Always allowed (restoration). |
| GET | /vault/items?since=<revision>&limit=500 |
{items: [{id, revision, deleted, blob, updated_at}], revision}. Requires an active subscription. |
| POST | /vault/items |
{base_revision, items: [{id, blob|null}]} → {revision, conflicts: []}. blob: null deletes (tombstone). If base_revision is stale, the server returns newer_items instead of writing. Maximum 500 items per upload. Requires an active subscription. |
Subscription
Every account starts in trial for 30 days. Sync routes respond 402 subscription_required once it expires; the sealed vault key remains readable to allow a restoration. The client shows "Pending" and continues in local mode.
Error codes
| Code | HTTP | Meaning |
|---|---|---|
invalid_credentials |
401 | Incorrect e-mail address, key or code. |
unauthenticated |
401 | Token missing, expired, or device revoked. |
email_unverified |
403 | E-mail code not entered. |
totp_required |
403 | Provide totp. |
subscription_required |
402 | Cloud subscription expired. |
email_taken |
409 | An account is already verified with this e-mail address. |
stale_revision |
409 | Pull the returned newer_items first. |
token_reused |
401 | Replay detected, device revoked. |
Rate limits
Pre-login 30/min, registration and verification 10/min, login 15/min, refresh 30/min, authenticated routes 240/min per device.
Example
curl -s https://api.rempar.org/v1/auth/prelogin \
-H 'Content-Type: application/json' \
-d '{"email":"vous@example.org"}'
A question not answered here? support@rempar.org