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