Skip to content

Authentication

Butterbase provides a complete authentication service for your app’s end users. Each app has independent user accounts and tokens, scoped by app_id.

MethodPathRate Limit
POST/auth/{app_id}/signup5 requests per 15 minutes
{
"email": "user@example.com",
"password": "MyP@ssw0rd!",
"display_name": "Jane Doe"
}

Password requirements: At least 8 characters, must include uppercase, lowercase, a number, and a special character.

A verification email is sent automatically with a 6-digit code.

MethodPathRate Limit
POST/auth/{app_id}/login10 requests per 15 minutes
{
"email": "user@example.com",
"password": "MyP@ssw0rd!"
}

Response:

{
"access_token": "eyJhbGciOi...",
"refresh_token": "...",
"expires_in": 3600,
"token_type": "Bearer",
"user": {
"id": "uuid",
"email": "user@example.com",
"email_verified": true,
"display_name": "Jane Doe",
"avatar_url": null
}
}

The access token is what your frontend sends with API requests. The refresh token is used to get a new access token when the current one expires.

MethodPathRate Limit
POST/auth/{app_id}/refresh20 requests per 15 minutes

Exchange a refresh token for a new access token. The old refresh token is invalidated (token rotation).

{
"refresh_token": "your-refresh-token"
}
MethodPathAuth Required
POST/auth/{app_id}/logoutYes (Bearer token)

Revokes all refresh tokens. The user must log in again.

MethodPathRate Limit
POST/auth/{app_id}/verify-email10 requests per 15 minutes
{
"email": "user@example.com",
"code": "123456"
}

The code expires after 24 hours.

Step 1: Request a reset code

MethodPathRate Limit
POST/auth/{app_id}/forgot-password3 requests per 15 minutes

Always returns success regardless of whether the email exists (prevents user enumeration).

Step 2: Reset the password

MethodPathRate Limit
POST/auth/{app_id}/reset-password5 requests per 15 minutes
{
"email": "user@example.com",
"code": "123456",
"new_password": "NewP@ssw0rd!"
}

The reset code expires after 1 hour. All existing sessions are invalidated.

Configure a provider using the configure_oauth_provider MCP tool or the OAuth configuration API.

These only need client_id, client_secret, and redirect_uris — URLs and default scopes are auto-filled:

ProviderDefault Scopes
googleopenid, email, profile
githubuser:email
discordidentify, email
facebookemail, public_profile
linkedinopenid, profile, email
microsoftopenid, email, profile, User.Read
applename, email (requires provider_metadata)
xtweet.read, users.read (no email; synthetic email used)

Custom providers require authorization_url, token_url, and userinfo_url.

  1. Direct the user’s browser to /auth/{app_id}/oauth/{provider}?redirect_to=https://yourapp.com/callback
  2. The user signs in with the provider
  3. The provider redirects to the callback URL
  4. Tokens are returned as query parameters: ?access_token=...&refresh_token=...&expires_in=900
  • Google, LinkedIn, Apple: User info extracted from ID token via JWKS.
  • GitHub: If email is not public, it’s fetched from /user/emails automatically.
  • Apple: Uses POST callback (form_post). Requires provider_metadata with teamId, keyId, and privateKey. Only provides name on first authorization.
  • X (Twitter): Uses PKCE. No email provided — a synthetic email is generated.
MethodPathAuth Required
GET/auth/{app_id}/meYes

Returns the authenticated user’s profile.

MethodPathCache
GET/auth/{app_id}/.well-known/jwks.json5 minutes

Returns public keys for verifying access tokens in your own backend.

Include the access token when calling the data API:

GET /v1/{app_id}/posts
Authorization: Bearer {access_token}

With RLS enabled, the user only sees their own rows automatically.

Configurable per app using update_jwt_config:

  • Access token: Default 1 hour (options: “15m”, “30m”, “1h”, “2h”, “1d”)
  • Refresh token: Default 7 days (configurable in days)