Dociya

Authentication

Every request except sign-up, sign-in, and a handful of public preview endpoints carries a bearer access token. Six independent entry paths mint one — pick whichever fits your client.

The header

Authorization: Bearer <accessToken>

The decoded payload carries userId, householdId, profileId, and sessionId — every household-scoped query in this API filters by the token's householdId, never a client-supplied one.

Token lifetimes

Access token
15 minutes
JWT_ACCESS_TTL
Refresh token
30 days
JWT_REFRESH_TTL
Anonymous session
24 hours
JWT_ANON_TTL_SECONDS
Step-up token
2 minutes (fixed)
STEP_UP_TTL_SECONDS

Sign up

POST/auth/signupno auth

Creates a new household and its first profile. Consent capture is mandatory in the same transaction — there is no account state that predates a recorded consent.

Parameters
emailstringrequired

Unique per account.

passwordstringrequired

Minimum 10 characters.

namestringrequired

Display name for the first profile.

regionstringrequired

ISO country code — selects the locale pack (doc types, lead times).

consentobjectrequired

{ version, locale } — captured in the same transaction as account creation.

claimTokenstringoptional

An anon session's access token — converts a pre-account session into this new account.

inviteTokenstringoptional

Join an existing household as a family member instead of creating a new one.

referralCodestringoptional

Credits both households once this account uploads its first document.

curl https://api.dociya.com/auth/signup \
  -H "Content-Type: application/json" \
  -d '{
    "email": "priya@example.com",
    "password": "correct-horse-battery-staple",
    "name": "Priya",
    "region": "us",
    "consent": { "version": "2026-01-01", "locale": "en" }
  }'

Log in

POST/auth/loginno auth

Password sign-in for an existing account.

Parameters
emailstringrequired

passwordstringrequired

curl https://api.dociya.com/auth/login \
  -H "Content-Type: application/json" \
  -d '{ "email": "priya@example.com", "password": "correct-horse-battery-staple" }'

Refresh a session

POST/auth/refreshno auth

Rotates both tokens — the old refresh token stops working the moment a new pair is issued. Web clients never see the refresh token in JS; it's set and read entirely via the httpOnly cookie, which this endpoint re-seats.

Parameters
refreshTokenstringoptional

Omit on web — the refresh token travels in an httpOnly cookie (dociya_rt, path /auth) instead.

curl https://api.dociya.com/auth/refresh \
  -H "Content-Type: application/json" \
  -d '{ "refreshToken": "8f2c1a9e..." }'

Step up for a sensitive reveal

POST/auth/step-up

Re-verifies the caller's password (or, via POST /auth/webauthn/assert/verify, a passkey) and mints a short-lived token required by the two field-reveal endpoints under /documents — the only routes in this API gated by more than a bearer token alone.

Response fields
stepUpTokenstringoptional

Pass as X-Step-Up-Token on the reveal endpoint.

expiresInnumberoptional

Always 120 (seconds).

curl https://api.dociya.com/auth/step-up \
  -H "Authorization: Bearer $DOCIYA_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "password": "correct-horse-battery-staple" }'

Other ways in

POST /auth/oauthSign in with an Apple or Google ID token, verified against the provider's JWKS.
POST /auth/phone-otp/request → verifySMS one-time code — off by default, feature-flagged per deployment.
POST /auth/anonMint a 24h provisional session before any account exists, so a first document can be captured pre-signup. Pass the resulting token back as claimToken on signup or login.
GET /auth/devices · DELETE /auth/devices/:idList or revoke sessions (device management).
POST /auth/logoutRevoke the current session and clear the refresh cookie.
Note
Every route on this page is rate-limited to 10 requests/minute per IP, independent of the per-household limits documented on other resources.