PrintHeritage uses the OAuth2 password flow for authentication. You exchange a user’s email address and password for a short-lived JWT access token, then attach that token to every subsequent request. This page explains how to obtain a token, how to use it, when it expires, and how to register new users and manage passwords through the API.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/joaomonteir0/printheritage/llms.txt
Use this file to discover all available pages before exploring further.
How Authentication Works
Submit credentials to POST /login
Send the user’s email and password as
application/x-www-form-urlencoded form fields. The API validates the credentials against the bcrypt-hashed password stored in the database.Receive a Bearer token
On success, the API returns a JSON object containing an
access_token string and token_type: "bearer". Store this token in your application’s memory or a secure storage mechanism.Attach the token to every request
Include the token in the
Authorization header as Bearer <access_token> for all protected endpoints.POST /login — Obtain a Token
The login endpoint follows the OAuth2 password grant. It expectsapplication/x-www-form-urlencoded — not JSON — because it uses FastAPI’s OAuth2PasswordRequestForm.
Request Fields
The user’s email address. Despite the field name
username (required by the OAuth2 spec), the API validates this value as an email and looks it up in the users table by the email column.The user’s plain-text password. The API verifies it against the bcrypt hash stored in the database using
bcrypt.checkpw.Response
On success the API returns HTTP200 with:
A signed HS256 JWT. The payload contains
sub (the user’s email) and exp (a UTC timestamp 60 minutes in the future).Always
"bearer".Curl Example
Using the Token
Include the access token in theAuthorization header on every protected request:
sub claim (email), and loads the corresponding user record from the database. If the token is missing, malformed, expired, or the user no longer exists, the API returns 401 Unauthorized.
JWT Payload Structure
| Claim | Description |
|---|---|
sub | The authenticated user’s email address |
exp | Unix timestamp after which the token is invalid (60 min from issue) |
GET /me — Current User Profile
Returns the full profile of the user identified by the Bearer token. Useful for bootstrapping a session after login.UserResponse Schema
The user’s unique identifier (UUID v4).
The user’s email address. Used as the login credential and as the JWT
sub claim.The user’s platform-wide role. One of:
SUPER_ADMIN, GENERAL_ADMIN, PROJECT_ADMIN, or VISUALIZER. Determines access to admin-only endpoints and implicit project permissions.The user’s display name. Optional; may be
null if not set during registration or profile update.ISO 8601 datetime. Optional; may be
null.URL to the user’s profile picture. Optional; may be
null.Whether the user’s profile is publicly visible to other platform members. Defaults to
true.POST /register — Create a New Account
Registers a new user. This endpoint does not require authentication, so it can be called before any token is obtained. If the email is already in use, the API returns400 Bad Request.
Request Fields
A valid email address. Must be unique across the platform. Used as the login credential.
The desired password. The API hashes it with bcrypt before storing it — the plain-text password is never persisted.
The role to assign to the new user. Must be one of:
SUPER_ADMIN, GENERAL_ADMIN, PROJECT_ADMIN, VISUALIZER.Optional display name for the user.
Optional birth date in ISO 8601 format (e.g.
"1990-06-15T00:00:00").Optional URL to a profile picture.
Whether the profile is publicly visible. Defaults to
true.Curl Example
Registration is logged to the audit trail as a
USER_CREATED action. The new user’s UUID and email are recorded in the audit_logs table.POST /change-password — Update Password
Allows an authenticated user to change their own password. The request must include the current password for verification before the new password is accepted.Request Fields
The user’s existing password. Verified against the stored bcrypt hash using
bcrypt.checkpw. Returns 400 Bad Request if it does not match.The replacement password. Immediately hashed with bcrypt and stored; the old hash is discarded.
Curl Example
Error Reference
| HTTP Status | Trigger |
|---|---|
400 Bad Request | Email already registered (POST /register), or wrong current_password (POST /change-password) |
401 Unauthorized | Invalid credentials (POST /login), missing, malformed, or expired Bearer token on any protected endpoint |
403 Forbidden | Valid token but insufficient role for the requested operation |