Skip to main content

Authentication

Base URL: https://events.pana.space/api

The API supports two bearer-token schemes:

SchemeToken formatTypical use
JWTeyJ… (SimpleJWT)User login, web & mobile apps
PATpat_…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)​

codeWhen
ACCOUNT_ON_EVENTSThis email is already a Pana Events account, and the request is for Olai.
ACCOUNT_ON_OLAIThis email is already a Pana Olai account, and the request is for Events, and the company domain has no Events workspace.
REQUEST_ACCESSThis email is already a Pana Olai account, and the company domain already has an Events workspace. workspace_name is set.
EMAIL_ALREADY_EXISTSThis email already has an account on the same product, or the payload did not say which product.
DOMAIN_CLAIMEDThis 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 up
  • POST /api/v1/users/auth/domain-access/request/ — request access to existing workspace domain
  • POST /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.