Skip to main content

Authentication

The Accountability API uses session-based authentication with bearer tokens. The API supports multiple authentication providers including local email/password, OAuth providers, and SAML.

Authentication Flow

1. List Available Providers

First, discover which authentication providers are enabled:
curl -X GET https://your-instance.accountability.app/api/auth/providers
providers
array
Array of enabled authentication providers

2. Register New User (Local Provider)

For local email/password authentication:
curl -X POST https://your-instance.accountability.app/api/auth/register \
  -H "Content-Type: application/json" \
  -d '{
    "email": "[email protected]",
    "password": "SecurePassword123!",
    "displayName": "John Doe"
  }'
email
string
required
User’s email address
password
string
required
Password (minimum 8 characters)
displayName
string
required
User’s display name
user
AuthUser
Created user details
identities
array
Array of linked authentication provider identities

3. Login

Local Provider Login:
curl -X POST https://your-instance.accountability.app/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{
    "provider": "local",
    "credentials": {
      "email": "[email protected]",
      "password": "SecurePassword123!"
    }
  }'
token
string
Session token (UUID) - use this for authenticated requests
user
AuthUser
Authenticated user details
provider
string
The provider used for authentication
expiresAt
string
Session expiration timestamp (ISO 8601)
OAuth Provider Login: For OAuth providers, use a two-step flow:
  1. Get authorization URL:
curl -X GET https://your-instance.accountability.app/api/auth/authorize/google
Response:
{
  "redirectUrl": "https://accounts.google.com/o/oauth2/v2/auth?client_id=...",
  "state": "random-csrf-token"
}
  1. Redirect user to redirectUrl. After authorization, the provider redirects back with a code.
  2. Exchange code for session:
curl -X POST https://your-instance.accountability.app/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{
    "provider": "google",
    "credentials": {
      "code": "authorization-code-from-provider",
      "state": "random-csrf-token"
    }
  }'

Using Session Tokens

Include the session token in the Authorization header with Bearer scheme:
curl -X GET https://your-instance.accountability.app/api/v1/accounts \
  -H "Authorization: Bearer your-session-token-here" \
  -H "Content-Type: application/json"

Session Management

Get Current User

Retrieve details for the authenticated user:
curl -X GET https://your-instance.accountability.app/api/auth/me \
  -H "Authorization: Bearer your-session-token"

Update Profile

Update the current user’s profile:
curl -X PUT https://your-instance.accountability.app/api/auth/me \
  -H "Authorization: Bearer your-session-token" \
  -H "Content-Type: application/json" \
  -d '{
    "displayName": "Jane Doe"
  }'

Refresh Session

Extend the session expiration:
curl -X POST https://your-instance.accountability.app/api/auth/refresh \
  -H "Authorization: Bearer your-session-token"
Response:
{
  "token": "new-session-token",
  "expiresAt": "2025-03-16T14:30:00Z"
}

Logout

Invalidate the current session:
curl -X POST https://your-instance.accountability.app/api/auth/logout \
  -H "Authorization: Bearer your-session-token"

Multi-Provider Identity Linking

Users can link multiple authentication providers to a single account.
  1. Initiate linking:
curl -X POST https://your-instance.accountability.app/api/auth/link/github \
  -H "Authorization: Bearer your-session-token"
Response:
{
  "redirectUrl": "https://github.com/login/oauth/authorize?client_id=...",
  "state": "random-csrf-token"
}
  1. User authorizes on the provider’s site and is redirected back.
  2. The callback automatically completes the linking process.
Remove a linked provider identity:
curl -X DELETE https://your-instance.accountability.app/api/auth/identities/{identityId} \
  -H "Authorization: Bearer your-session-token"
Users must maintain at least one linked identity. The API will reject attempts to unlink the last identity.

Change Password

For users with local authentication:
curl -X POST https://your-instance.accountability.app/api/auth/change-password \
  -H "Authorization: Bearer your-session-token" \
  -H "Content-Type: application/json" \
  -d '{
    "currentPassword": "OldPassword123!",
    "newPassword": "NewSecurePassword456!"
  }'
currentPassword
string
required
User’s current password for verification
newPassword
string
required
New password (minimum 8 characters)

Error Responses

Invalid Credentials (401)

{
  "_tag": "AuthUnauthorizedError",
  "message": "Invalid credentials or authentication required"
}

Session Expired (401)

{
  "_tag": "SessionInvalidError",
  "message": "Session is invalid or expired"
}

User Already Exists (409)

{
  "_tag": "UserExistsError",
  "email": "[email protected]",
  "message": "A user with this email already exists"
}

Weak Password (400)

{
  "_tag": "PasswordWeakError",
  "message": "Password does not meet requirements",
  "requirements": [
    "Minimum 8 characters",
    "At least one uppercase letter",
    "At least one number"
  ]
}

Security Best Practices

Never expose session tokens in client-side code, URLs, or logs. Use secure HTTP-only cookies when possible.
Refresh sessions before they expire to maintain uninterrupted access.
Always call the logout endpoint when users explicitly sign out to invalidate the session server-side.
Always use HTTPS in production to encrypt authentication credentials in transit.

Build docs developers (and LLMs) love