Auth & user management
Every method for creating an end user, signing them in, verifying their email, resetting their password, and reading or deleting their account. All arguments are keyword-only.
The session lives on the client
login_user() stores a cookie on the client's requests.Session, and every later call on that client acts as that user. In a script that is exactly what you want. In a web server it is a serious bug: one shared client would hand the first visitor's session to the next.
In a web application, either construct a short-lived publishable client per request, or use a secret-key client and pass user_id explicitly.
signup_userSession cookie
POST /api/users/signup
authix.signup_user(
*, name: str, email: str, password: str,
username: str | None = None,
phone: str | None = None,
address: str | None = None,
) -> dict| Param | Type | Required | Description |
|---|---|---|---|
| name | str | Yes | Display name. |
| str | Yes | Unique within this app. The same address can exist in another app. | |
| password | str | Yes | Sent over HTTPS and stored as a bcrypt hash. Never stored in plaintext. |
| username | str | No | Optional handle, usable with get_user(). |
| phone | str | No | Optional. |
| address | str | No | Optional. |
Returns: dict — the created user
1user = authix.signup_user(
2 name="Ada Lovelace",
3 email="[email protected]",
4 password="a-long-passphrase",
5)
6
7print(user["user"]["id"])Throws: ValidationError on a malformed payload; AuthixAPIError (409) if the email already exists in this app.
Signing up does not verify the email. Call request_email_verification_otp() next if your app requires a verified address.
login_userSession cookie
POST /api/users/login
authix.login_user(*, email: str, password: str) -> dict
| Param | Type | Required | Description |
|---|---|---|---|
| str | Yes | The user's email. | |
| password | str | Yes | Their password. |
Returns: dict — the signed-in user
1result = authix.login_user(email="[email protected]", password="…")
2
3# The cookie is now on this client. Subsequent calls act as Ada.
4print(result["user"]["id"])Throws: AuthenticationError (401) on a wrong password or unknown email — deliberately indistinguishable, so the response cannot be used to enumerate accounts.
logout_userSession cookie
POST /api/users/logout
authix.logout_user() -> dict
Returns: dict
1authix.logout_user()
2
3authix.check_user_session()
4# {"authenticated": False}Clears the cookie both server-side and on the local session, so the client is genuinely signed out rather than merely appearing to be.
check_user_sessionSession cookie
GET /api/users/session
authix.check_user_session() -> dict
Returns: dict — {"authenticated": bool, "user": dict | None}
1session = authix.check_user_session()
2
3if session["authenticated"]:
4 print(session["user"]["email"])
5else:
6 prompt_login()Never raises for a missing or expired session — the server answers 200 with authenticated: False, because 'not signed in' is an answer rather than a failure. Safe to call on every request without a try/except.
change_passwordSession cookie
POST /api/users/change-password
authix.change_password(
*, user_id: str, current_password: str, new_password: str,
) -> dict| Param | Type | Required | Description |
|---|---|---|---|
| user_id | str | Yes | Whose password to change. |
| current_password | str | Yes | Verified before the change is applied. |
| new_password | str | Yes | The replacement. |
Returns: dict
1authix.change_password(
2 user_id=user_id,
3 current_password=old,
4 new_password=new,
5)
6# Every session for this user is now invalid, including this one.Throws: AuthenticationError (401) if current_password is wrong.
Bumps the user's token version, which invalidates every session they have anywhere. The device that made the change must sign in again too — that is the correct trade, because it is also what stops a stolen session surviving a password change.
request_email_verification_otpSession cookie
POST /api/users/request-verification
authix.request_email_verification_otp(*, user_id: str, email: str) -> dict
| Param | Type | Required | Description |
|---|---|---|---|
| user_id | str | Yes | The user to verify. |
| str | Yes | Where to send the code. |
Returns: dict
1authix.request_email_verification_otp(user_id=user_id, email=email)The code is stored hashed and expires shortly after it is issued.
verify_emailSession cookie
POST /api/users/verify-email
authix.verify_email(*, email: str, otp: str) -> dict
| Param | Type | Required | Description |
|---|---|---|---|
| str | Yes | The address being confirmed. | |
| otp | str | Yes | The code from the email. |
Returns: dict
1authix.verify_email(email=email, otp=code)Throws: ValidationError (400) if the code is wrong or has expired.
request_reset_user_password_otpSession cookie
POST /api/users/request-password-reset
authix.request_reset_user_password_otp(*, email: str) -> dict
| Param | Type | Required | Description |
|---|---|---|---|
| str | Yes | Where to send the reset code. |
Returns: dict
1authix.request_reset_user_password_otp(email="[email protected]")Succeeds whether or not the address exists, so the response cannot be used to discover which emails are registered. Show the same confirmation either way.
reset_user_passwordSession cookie
POST /api/users/reset-password
authix.reset_user_password(
*, email: str, otp: str, new_password: str,
) -> dict| Param | Type | Required | Description |
|---|---|---|---|
| str | Yes | The account being reset. | |
| otp | str | Yes | The emailed code. |
| new_password | str | Yes | The new password. |
Returns: dict
1authix.reset_user_password(
2 email=email,
3 otp=code,
4 new_password=new_password,
5)Throws: ValidationError (400) if the code is wrong or expired.
Also invalidates every existing session for that user — which is the point, since a reset usually means the account may have been compromised.
get_user_profileSession cookie
GET /api/users/:id/profile
authix.get_user_profile(*, user_id: str) -> dict
| Param | Type | Required | Description |
|---|---|---|---|
| user_id | str | Yes | Whose profile to read. |
Returns: dict
1profile = authix.get_user_profile(user_id=user_id)With a publishable key the server pins this to the signed-in user, so passing someone else's id returns their own record rather than the other person's.
get_userAPI key only
GET /api/users/lookup
authix.get_user(
*, id: str | None = None, username: str | None = None,
) -> dict| Param | Type | Required | Description |
|---|---|---|---|
| id | str | No | Look up by id. Pass this or username. |
| username | str | No | Look up by handle. |
Returns: dict
1user = authix.get_user(username="ada")Throws: InsufficientScopeError (403) with a publishable key; NotFoundError (404) if no such user exists in this app.
Requires a secret key — it can read any user on the account.
update_userSession cookie
PUT /api/users/:id
authix.update_user(*, user_id: str, **fields) -> dict
| Param | Type | Required | Description |
|---|---|---|---|
| user_id | str | Yes | Who to update. |
| **fields | Any | Yes | Profile fields to change: name, username, phone, address, avatar_url. |
Returns: dict
1authix.update_user(user_id=user_id, name="Ada L.", phone="+44…")Profile fields only. Passwords go through change_password, and email changes go through the verification flow.
delete_userSession cookie
DELETE /api/users/:id
authix.delete_user(*, user_id: str) -> dict
| Param | Type | Required | Description |
|---|---|---|---|
| user_id | str | Yes | Who to delete. |
Returns: dict
1authix.delete_user(user_id=user_id)Throws: NotFoundError (404) if the user does not exist in this app.
Deletes the user and every record they own, permanently. There is no recycle bin and no undo — export first if the data matters.
check_if_user_existsAPI key only
GET /api/users/:id/exists
authix.check_if_user_exists(user_id: str) -> dict
| Param | Type | Required | Description |
|---|---|---|---|
| user_id | str | Yes | Positional, unlike the rest of the SDK. |
Returns: dict
1if authix.check_if_user_exists(user_id)["exists"]:
2 ...Throws: InsufficientScopeError (403) with a publishable key.
The one method taking a positional argument. Requires a secret key.
Do not build your own authorisation on these
A successful check_user_session() tells you who someone is. It does not tell you what they may do. Ownership is enforced by the API on every request, and your own rules — which screens, which records, which actions — belong in your code.
Related