DKBSignDocs

Get started

Authentication

The gateway uses a Bearer token issued by login. The same token is forwarded to every upstream service.

Bearer token

Call POST /api/v1/login with a company account. Read data.access_token and send it on protected routes:

http
Authorization: Bearer 1|abcdefghijklmnopqrstuvwxyz

There is no gateway API key, HMAC, or OAuth client-credentials flow. Social login is available as POST /api/v1/social-auth (provider is google or facebook plus the provider access_token).

Login responses

Send email and password. Two success shapes exist:

json
{
  "status": "success",
  "message": "Logged in successfully",
  "data": {
    "user": { "id": 4, "role": "user", "email": "user@acme.test", "locale": "fr" },
    "access_token": "1|abcdefghijklmnopqrstuvwxyz",
    "mfa_setup_required": false
  }
}

If the account has a usable MFA method, no token is issued:

json
{
  "status": "success",
  "message": "MFA required",
  "data": {
    "mfa_required": true,
    "challenge_token": "opaque-challenge",
    "methods": ["email", "totp"],
    "email_hint": "u***@acme.test"
  }
}

Complete the challenge with POST /api/v1/login/mfa/verify (challenge_token, method = email or totp, code). For WebAuthn, call .../webauthn/options then .../webauthn/verify with the browser assertion. Wrong credentials always return 401 Invalid email or password (no user enumeration).

When company policy requires MFA but nothing is enrolled, login still succeeds and mfa_setup_required is true. Enroll factors on /api/v1/mfa/....

Register

POST /api/v1/register creates an account and returns 201. No access token is issued — the user must log in. Required fields: first_name, last_name, email, card_id_number, phone_number (E.164, starts with +), address, city, country, password (min 8, mixed case, number, symbol).

Company roles

Only admin (company administrator) and user (employee) may use this API. The gateway checks the role at login and again on every protected request.

RoleAccess
adminAllowed. Company settings, users, certificates, license, audit, vault purge.
userAllowed. Day-to-day signing, workflows, contacts, vault (ACL-limited).
Any other role403 — API gateway is restricted to company admin and user roles

Fine-grained permissions (workflow roles, EDM ACLs, and so on) are enforced by upstream services. The gateway only applies this binary company-user gate. A license in read-only grace returns 403 LICENSE_READONLY on writes; an expired license returns 403 LICENSE_EXPIRED on introspection.

Public routes

These paths do not require a Bearer token:

  • Login, register, social login, password reset, login MFA, email verification
  • External-identity self-service under /api/v1/public/external-identity (uses X-Identity-Token after the code is verified)
  • Public signing session under /api/v4/public/envelopes/{signer_uuid}
  • Vault share links: GET /api/edm/shared/{token}
  • GET /api/v1/certificates/{certificate}/download
  • GET /api/v4/documents/{uuid}/download
  • GET /api/v4/verify/{uuid}
  • GET /api/v4/attachments/{att_uuid}/download

Everything else requires a valid company-user token.

MFA

Two separate MFA surfaces exist:

  1. Login MFA — public, authenticated by challenge_token only: /api/v1/login/mfa/email/send, .../verify, .../webauthn/options, .../webauthn/verify.
  2. Account enrollment — Bearer required: GET /api/v1/mfa/status, then email / TOTP / WebAuthn enroll and disable routes. Disabling a method requires the account password.

Company admins configure policy on PUT /api/v1/companies/{company}/security-settings (mfa_enforced, allowed_methods, min_signature_level, …) and can reset an employee with POST /api/v1/users/{user}/mfa/reset.

POST /api/v1/2fa/send and .../verify are a legacy step-up OTP tied to the current Bearer token — not the login challenge.

External identity

External signers manage verified identities without a company account:

  1. POST /api/v1/public/external-identity/code with email — always 202 (anti-enumeration)
  2. POST /api/v1/public/external-identity/verify with email + 6-digit code → { "access_token": "…" }
  3. Send that value as X-Identity-Token (not Bearer) on GET /api/v1/public/external-identity and POST .../{identity}/revoke

Statuses: pending, verified, rejected, revoked, expired. Face capture for a signing session lives on the public envelope identity routes.

Profile

Self-service only — {user} must be the authenticated user. PATCH /api/v1/profile/{user}/update is a partial update. Use multipart/form-data when uploading seal (png/jpg, max 20 MB).

  • job_title — shown under the signature (max 120)
  • locale — fr, en, or null to reset (emails fall back to the request locale, then French)
  • signature_mentions — { enabled, frame, mentions[] }. mentions is a closed list of at most 4: fullName, jobTitle, company, email, signedAt, provider

Password change uses old_password and new_password (not current_password). Availability uses is_available, optional unavailable_until (Y-m-d), and interim_user_ids (0–2 colleagues).

Headers

HeaderWhen
Authorization: Bearer {token}All protected routes
Content-Type: application/jsonJSON request bodies
Content-Type: multipart/form-dataFile uploads (envelopes, workflows, vault, identity, seals)
Accept: application/jsonRecommended on every call
Accept-LanguageOptional; forwarded upstream. Profile locale also controls email language.
X-Identity-TokenPublic external-identity routes after POST /api/v1/public/external-identity/verify