Skip to main content

Authentication

The Leezy API uses OAuth 2.0 for authentication. This guide covers the authorization flow and token management.

Overview

Leezy implements the OAuth 2.0 Authorization Code flow with optional PKCE (Proof Key for Code Exchange) for enhanced security.

┌──────────┐                               ┌───────────┐
│ Client │ │ Leezy │
└────┬─────┘ └─────┬─────┘
│ 1. Redirect to /api/oauth/authorize │
│──────────────────────────────────────────>│
│ │
│ 2. User logs in and authorizes │
│<──────────────────────────────────────────│
│ │
│ 3. Redirect with authorization code │
│<──────────────────────────────────────────│
│ │
│ 4. POST /api/oauth/token │
│──────────────────────────────────────────>│
│ │
│ 5. Return access_token + refresh_token │
│<──────────────────────────────────────────│

OAuth Endpoints

EndpointMethodDescription
/api/oauth/authorizeGETAuthorization page
/api/oauth/tokenPOSTToken exchange

Step 1: Authorization Request

Redirect the user to the authorization endpoint:

https://app.leezy.ai/api/oauth/authorize?
client_id=YOUR_CLIENT_ID&
redirect_uri=https://yourapp.com/callback&
response_type=code&
scope=leads:read%20webhooks:manage&
state=random_state_string

Parameters

ParameterRequiredDescription
client_idYesYour application's client ID
redirect_uriYesURL to redirect after authorization
response_typeYesMust be code
scopeYesSpace-separated list of scopes
stateRecommendedRandom string for CSRF protection
code_challengeOptionalPKCE code challenge (recommended)
code_challenge_methodOptionalMust be S256 if using PKCE

Step 2: Token Exchange

After authorization, exchange the code for tokens:

curl -X POST "https://app.leezy.ai/api/oauth/token" \
-H "Content-Type: application/json" \
-d '{
"grant_type": "authorization_code",
"code": "AUTHORIZATION_CODE",
"redirect_uri": "https://yourapp.com/callback",
"client_id": "YOUR_CLIENT_ID",
"client_secret": "YOUR_CLIENT_SECRET",
"code_verifier": "OPTIONAL_PKCE_VERIFIER"
}'

Response

{
"access_token": "lzy_at_abc123...",
"refresh_token": "lzy_rt_xyz789...",
"token_type": "Bearer",
"expires_in": 3600,
"scope": "leads:read webhooks:manage",
"api_base_url": "https://app.leezy.ai"
}

Step 3: Using Access Tokens

Include the access token in API requests:

curl -X GET "https://app.leezy.ai/api/v1/leads" \
-H "Authorization: Bearer lzy_at_abc123..."

Refreshing Tokens

Access tokens expire after 1 hour. Use the refresh token to get a new access token:

curl -X POST "https://app.leezy.ai/api/oauth/token" \
-H "Content-Type: application/json" \
-d '{
"grant_type": "refresh_token",
"refresh_token": "lzy_rt_xyz789...",
"client_id": "YOUR_CLIENT_ID",
"client_secret": "YOUR_CLIENT_SECRET"
}'

Token Lifecycle

TokenPrefixLifetime
Access Tokenlzy_at_1 hour
Refresh Tokenlzy_rt_30 days
Token Prefixes

Leezy tokens use prefixes to help identify token types. Access tokens start with lzy_at_ and refresh tokens with lzy_rt_.

Available Scopes

ScopeDescription
leads:readRead qualification leads
leads:writeCreate and update leads
conversations:readRead chat conversations
conversations:writeWrite to conversations
tickets:readRead support tickets
tickets:writeCreate and update tickets
meetings:readRead scheduled meetings
webhooks:manageCreate and manage webhooks

For enhanced security, use PKCE:

// 1. Generate code_verifier (random 43-128 char string)
const code_verifier = generateRandomString(64);

// 2. Create code_challenge
const code_challenge = base64url(sha256(code_verifier));

// 3. Include in authorization URL
// ?code_challenge=ABC123&code_challenge_method=S256

// 4. Include code_verifier in token exchange
// "code_verifier": "your_code_verifier"

Error Codes

ErrorDescription
invalid_requestMissing required parameter
invalid_clientInvalid client_id or client_secret
invalid_grantExpired or invalid authorization code
unsupported_grant_typeGrant type not supported
invalid_scopeRequested scope is invalid

Next Steps