FR
Copied
API

Authentication

Session cookie issuance, credential management, email verification, and GDPR self-service endpoints under /api/auth.

Authentication

The Authentication API issues and revokes session cookies, manages credentials, verifies email ownership, and exposes the GDPR self-service endpoints. All routes are mounted under /api/auth and respond with JSON unless noted.

Successful signup, login, and password/change calls set an outsend_session cookie:

Attribute Value
Name outsend_session
TTL 7 days (SESSION_DURATION_DAYS = 7)
HttpOnly true
Secure true (production)
SameSite Lax
Path /

The cookie is a signed token bound to a row in sessions. Revoking a session (logout, password change, account delete) deletes the row server-side even if the cookie is replayed.

Rate limits and errors

Each endpoint applies per-IP and per-identity windows (see Limits). Exhaustion returns 429 Too Many Requests with a French message containing the retry-after delay in seconds.

All errors follow FastAPI's { "detail": "<message>" } shape. Generic codes: 400 (invalid payload, expired token, wrong current password, captcha failure), 401 (bad credentials or missing session on protected routes), 429 (rate limit). Endpoint-specific detail messages are listed inline below.


POST /api/auth/signup

Creates a user, sends the welcome + verification email, and opens a session. No auth. Rate limit: 3 / hour / IP.

Request body

Field Type Notes
email string (email) Required.
password string 8 to 128 chars, must contain a letter AND a digit/symbol.
invitation_code string 1 to 64 chars. Alpha is invite-only.
accept_responsibility boolean Must be true.
hcaptcha_token string or null Required when HCAPTCHA_SECRET is configured.
{
  "email": "ada@example.com",
  "password": "lovelace-1843",
  "invitation_code": "ALPHA-7K2",
  "accept_responsibility": true,
  "hcaptcha_token": "10000000-aaaa-bbbb-cccc-000000000001"
}

Response — 200 OK

{
  "ok": true,
  "user": {
    "id": 42,
    "email": "ada@example.com",
    "is_admin": false,
    "is_active": true,
    "email_verified": false,
    "created_at": "2026-05-27T09:14:00Z"
  }
}

Sets the outsend_session cookie.

Specific errors

Status Detail
400 Captcha invalide. Réessaie.
400 Code invitation invalide
400 Email existe déjà

POST /api/auth/login

Validates credentials and opens a session. No auth. Rate limit: 5 / 15 min / IP and 5 / 15 min / email.

Request body

Field Type Notes
email string (email) Required.
password string 1 to 128 chars.
{ "email": "ada@example.com", "password": "lovelace-1843" }

Response — 200 OK

{ "ok": true, "user": { "id": 42, "email": "ada@example.com", "is_admin": false, "is_active": true, "email_verified": true, "created_at": "2026-05-27T09:14:00Z" } }

Sets the outsend_session cookie.

Specific errors

Status Detail
401 Email ou mot de passe incorrect
401 Compte désactivé

POST /api/auth/logout

Revokes the current session and clears the cookie. Auth optional. Empty body. Response: 200 OK { "ok": true }.


GET /api/auth/me

Returns the currently authenticated user.

{
  "id": 42,
  "email": "ada@example.com",
  "is_admin": false,
  "is_active": true,
  "email_verified": true,
  "created_at": "2026-05-27T09:14:00Z"
}

POST /api/auth/password/reset-request

Sends a reset link to the email if (and only if) it matches an active user. The response is identical in every case to prevent account enumeration. No auth. Rate limit: 3 / hour / IP and 3 / hour / email (silent when exhausted).

Request body

{ "email": "ada@example.com" }

Response — 200 OK

{ "ok": true }

POST /api/auth/password/reset-confirm

Consumes a single-use reset token and sets the new password. Revokes every existing session for the user. No auth (the token is the credential).

Request body

Field Type Notes
token string 10 to 256 chars, delivered by email.
new_password string 8 to 128 chars, letter + digit/symbol.
{ "token": "eyJ...", "new_password": "babbage-1822" }

Response — 200 OK

{ "ok": true }

Specific errors

Status Detail
400 Lien invalide ou expiré
422 Password complexity rejected by validator.

POST /api/auth/password/change

Rotates the password for a logged-in user. Requires the current password, revokes other sessions, issues a fresh cookie. Rate limit: 5 / hour / user.

Request body

Field Type Notes
current_password string 1 to 200 chars.
new_password string 8 to 200 chars, must differ from current.
{ "current_password": "lovelace-1843", "new_password": "babbage-1822" }

Response — 200 OK

{ "ok": true }

Sets a refreshed outsend_session cookie.

Specific errors

Status Detail
400 Mot de passe actuel incorrect
400 Le nouveau mot de passe doit être différent de l'actuel

POST /api/auth/email/verify

Consumes a single-use verification token and flips email_verified to true. No auth.

Request body

{ "token": "eyJ..." }

Response — 200 OK

{ "ok": true }

Specific error: 400 Lien de vérification invalide ou expiré.


POST /api/auth/email/resend-verify

Re-sends the verification email to the authenticated user. Idempotent when the address is already verified. Empty body. Rate limit: 3 / hour / user.

Response — 200 OK

{ "ok": true }

or, if already verified:

{ "ok": true, "already_verified": true }

DELETE /api/auth/me

Permanently deletes the account and every owned record (jobs, pipelines, surveillances, sessions, tokens). Job files on disk are purged after the cascading DB delete. Feedback threads are anonymised rather than removed.

Request body

Field Type Notes
confirm_email string Must equal the user's email (case-insensitive).
{ "confirm_email": "ada@example.com" }

Response — 204 No Content

Empty body. Clears the outsend_session cookie.

Specific error: 400 Confirmation email incorrecte.


GET /api/auth/me/export

GDPR portability endpoint. Streams a ZIP archive containing every record owned by the user.

Response — 200 OK

Content-Type: application/zip Content-Disposition: attachment; filename="outsend-export-<local>-<YYYY-MM-DD>.zip"

Archive layout:

Entry Contents
account.json Account metadata, no secrets.
jobs.json All jobs with metadata.
jobs/<job_id>/* CSV/JSON outputs for every done job.
pipelines.json Pipeline definitions.
veille.json recurring_scraps + run history.
manifest.txt Human-readable summary.