Authentication
Base URL: https://events.pana.space/api
The API supports two bearer-token schemes:
| Scheme | Token format | Typical use |
|---|---|---|
| JWT | eyJ… (SimpleJWT) | User login, web & mobile apps |
| PAT | pat_… | Workspace access tokens for automation |
Authorization: Bearer <token>
Sign up
POST /api/v1/users/auth/signup/
Content-Type: application/json
Request body
{
"first_name": "Jane",
"last_name": "Doe",
"company": "Acme Corp",
"email": "jane@example.com",
"password": "your-secure-password"
}
Send product (olai or events) or plan_segment (individual or team) so a duplicate email returns a code the site can branch on. product wins when both are sent. Olai signup (product: "olai" or plan_segment: "individual") blocks a company domain only when an Events workspace has already claimed it. A domain with no Events workspace stays open, including for coworkers.
Error codes (409 Conflict)
code | When |
|---|---|
ACCOUNT_ON_EVENTS | This email is already a Pana Events account, and the request is for Olai. |
ACCOUNT_ON_OLAI | This email is already a Pana Olai account, and the request is for Events, and the company domain has no Events workspace. |
REQUEST_ACCESS | This email is already a Pana Olai account, and the company domain already has an Events workspace. workspace_name is set. |
EMAIL_ALREADY_EXISTS | This email already has an account on the same product, or the payload did not say which product. |
DOMAIN_CLAIMED | This company domain is already claimed by an Events workspace. Applies to Events signup, and to Olai signup of a new email on that domain. workspace_name is set. |
Each of these responses includes code, error, detail, name, and workspace_name.
POST /api/v1/users/auth/login/ and POST /api/v1/users/auth/google/ use the same code values when the payload includes product, plan_segment, or plan. POST /api/v1/users/auth/signup/eligibility/ returns the same code with "allowed": false.
Response (201 Created)
{
"access": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9…",
"refresh": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9…",
"user": {
"id": "660e8400-e29b-41d4-a716-446655440001",
"email": "jane@example.com",
"name": "Jane Doe",
"active_workspace": {
"id": "aa0e8400-e29b-41d4-a716-446655440005",
"name": "Acme Corp"
}
}
}
Related:
POST /api/v1/users/auth/signup/eligibility/— check if email/domain can sign upPOST /api/v1/users/auth/domain-access/request/— request access to existing workspace domainPOST /api/v1/users/auth/domain-access/respond/— approve/decline domain access
Log in
POST /api/v1/users/auth/login/
Content-Type: application/json
Request body
{
"email": "jane@example.com",
"password": "your-secure-password"
}
Response (200 OK)
{
"access": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9…",
"refresh": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9…",
"user": {
"id": "660e8400-e29b-41d4-a716-446655440001",
"email": "jane@example.com",
"name": "Jane Doe"
}
}
Google sign-in
POST /api/v1/users/auth/google/
POST /api/v1/users/auth/google/mobile/
OTP
POST /api/v1/users/auth/otp/request/
POST /api/v1/users/auth/otp/verify/
Password reset
POST /api/v1/users/auth/password-reset/request/
POST /api/v1/users/auth/password-reset/confirm/
Refresh token
POST /api/v1/users/auth/token/refresh/
Content-Type: application/json
Request body
{
"refresh": "<refresh_token>"
}
Response (200 OK)
{
"access": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9…"
}
Log out
POST /api/v1/users/auth/logout/
Authorization: Bearer <access_token>
Current user & profile
GET /api/v1/users/users/
PUT /api/v1/users/users/
PATCH /api/v1/users/users/
Authorization: Bearer <access_token>
Returns profile and active_workspace.
Profile picture upload
POST /api/v1/users/users/profile-picture/presigned-url/
Account deletion
GET /api/v1/users/users/me/delete/eligibility/
POST /api/v1/users/users/me/delete/initiate/
POST /api/v1/users/users/me/delete/confirm/
POST /api/v1/users/users/me/delete/cancel/
Team invitations
GET /api/v1/users/auth/invite/details/
POST /api/v1/users/auth/invite/accept/
POST /api/v1/users/auth/invite/signup/
Personal access tokens (PAT)
Create tokens in Settings → Developers → Access tokens (workspace admin only).
Use the token on any workspace-scoped API:
GET /api/v1/{workspace_id}/events/
Authorization: Bearer pat_a1b2c3d4e5f6…
Rules:
- Token must start with
pat_ - Token is shown once at creation — store it securely
- Token is scoped to the workspace where it was created
- Token owner must remain an active workspace member
- Revoked tokens return
401 Invalid or revoked access token
Full CRUD: Access tokens
Legacy paths
Some auth routes are also mounted at /api/auth/… (without /v1/users/) for backwards compatibility. Prefer /api/v1/users/auth/… for new integrations.