Overview

AudioPod AI supports multiple authentication methods with advanced security features:
  • JWT Authentication: Session-based authentication with device tracking
  • API Key Authentication: Server-to-server integration with scoped permissions
  • OAuth Integration: Google and GitHub single sign-on with account linking
  • Session Management: Multi-device session tracking and management
  • Security Features: CAPTCHA protection, rate limiting, and abuse prevention
  • Phone Verification: SMS-based phone number verification
  • Device Management: Trust and security management for user devices
All authenticated endpoints require either a valid JWT token in the Authorization: Bearer {token} header or an API key in the X-API-Key:{" "} {api_key} header.

JWT Authentication

Login

Authenticate with email/password to receive JWT tokens.
POST /api/v1/auth/token
Content-Type: application/x-www-form-urlencoded

username=user@example.com&password=secure_password
Response:
{
  "user": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "email": "user@example.com",
    "full_name": "John Doe",
    "is_active": true,
    "is_verified": true,
    "created_at": "2024-01-15T10:30:00Z",
    "updated_at": "2024-01-15T10:30:00Z",
    "image": null,
    "phone_number": null,
    "phone_verified": false,
    "user_type": null,
    "audio_usage": null,
    "credits": {
      "credits_balance": 1500,
      "payg_balance": 500,
      "total_available_credits": 2000,
      "credits_used_today": 0,
      "daily_limit": 10000,
      "last_reset_at": "2024-01-15T00:00:00Z"
    },
    "subscription": {
      "plan_id": "price_free",
      "plan_name": "Free",
      "is_free_plan": true,
      "status": "active",
      "current_period_start": "2024-01-15T10:30:00Z",
      "current_period_end": "2024-02-15T10:30:00Z",
      "cancel_at": null
    },
    "is_eligible_for_first_time_discount": true,
    "first_time_discount_active": true
  },
  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "token_type": "bearer",
  "expires_in": 3600
}

Refresh Token

Refresh an expired access token using the refresh token.
POST /api/v1/auth/refresh
Content-Type: application/json

{
  "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}

Logout

Invalidate current tokens and end the session.
POST /api/v1/auth/logout
Authorization: Bearer {access_token}

OAuth Authentication

Google OAuth

Authenticate or register using Google account. This endpoint handles both new user registration and existing user login.
POST /api/v1/auth/oauth/google
Content-Type: application/json

{
  "profile": {
    "email": "user@example.com",
    "name": "John Doe",
    "picture": "https://lh3.googleusercontent.com/a/..."
  },
  "account": {
    "id_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6...",
    "access_token": "ya29.a0AfH6SMC...",
    "providerAccountId": "1234567890",
    "type": "oauth",
    "expires_at": 1640995200
  },
  "browser_fingerprint": "optional-fingerprint-string"
}

GitHub OAuth

Authenticate or register using GitHub account. Same response format as Google OAuth.
POST /api/v1/auth/oauth/github
Content-Type: application/json

{
  "profile": {
    "email": "user@example.com",
    "name": "John Doe",
    "picture": "https://avatars.githubusercontent.com/u/..."
  },
  "account": {
    "access_token": "ghp_abcdef1234567890",
    "providerAccountId": "987654321",
    "type": "oauth"
  }
}
OAuth Response (for both Google and GitHub): Returns the same format as login - complete user object with tokens:
{
  "user": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "email": "user@example.com",
    "full_name": "John Doe",
    "image": "https://lh3.googleusercontent.com/a/...",
    "is_active": true,
    "is_verified": true,
    "created_at": "2024-01-15T10:30:00Z",
    "credits": {
      "credits_balance": 5000,
      "payg_balance": 0,
      "total_available_credits": 5000
    },
    "subscription": {
      "plan_name": "Free",
      "is_free_plan": true,
      "status": "active"
    }
  },
  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "token_type": "bearer",
  "expires_in": 3600
}

API Key Authentication

Generate API Key

Create a new API key for programmatic access.
POST /api/v1/auth/api-keys
Authorization: Bearer {access_token}
Content-Type: application/json

{
  "name": "Production API Key",
  "scopes": ["voice:read", "voice:write"]
}
Response:
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "name": "Production API Key",
  "api_key": "ap_live_sk_1234567890abcdef",
  "description": "API key for production environment",
  "status": "active",
  "created_at": "2024-01-15T10:30:00Z",
  "last_used_at": null,
  "revoked_at": null
}

List API Keys

Get all API keys for the authenticated user.
GET /api/v1/auth/api-keys?status=active
Authorization: Bearer {access_token}

Revoke API Key

Disable an API key permanently.
DELETE /api/v1/auth/api-keys/{key_id}
Authorization: Bearer {access_token}

User Registration

Step 1: Initiate Registration

Start the registration process and receive verification code.
POST /api/v1/auth/initiate-registration
Content-Type: application/json

{
  "email": "newuser@example.com",
  "password": "secure_password123",
  "full_name": "Jane Doe"
}
Response:
{
  "message": "Verification code sent to email",
  "email": "newuser@example.com"
}

Step 2: Verify Registration

Complete registration with verification code from email.
POST /api/v1/auth/verify-registration
Content-Type: application/json

{
  "email": "newuser@example.com",
  "verification_code": "123456"
}
Response:
{
  "user": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "email": "newuser@example.com",
    "full_name": "Jane Doe",
    "image": null,
    "phone_number": null,
    "phone_verified": false,
    "is_active": true,
    "is_verified": true,
    "created_at": "2024-01-15T10:30:00Z",
    "updated_at": "2024-01-15T10:30:00Z",
    "credits": {
      "credits_balance": 5000,
      "payg_balance": 0,
      "total_available_credits": 5000,
      "credits_used_today": 0,
      "daily_limit": 10000,
      "last_reset_at": "2024-01-15T00:00:00Z"
    },
    "subscription": {
      "plan_id": "price_free",
      "plan_name": "Free",
      "is_free_plan": true,
      "status": "active",
      "current_period_start": "2024-01-15T10:30:00Z",
      "current_period_end": "2024-02-15T10:30:00Z",
      "cancel_at": null
    },
    "is_eligible_for_first_time_discount": true,
    "first_time_discount_active": true
  },
  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "token_type": "bearer",
  "expires_in": 3600
}

Password Reset

Request and confirm password reset.
POST /api/v1/auth/forgot-password
Content-Type: application/json

{
  "email": "user@example.com"
}

User Profile Management

Get Current User

Retrieve complete information about the authenticated user including credits, subscription, and security settings.
GET /api/v1/auth/me
Authorization: Bearer {access_token}
Response:
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "email": "user@example.com",
  "full_name": "John Doe",
  "image": "https://lh3.googleusercontent.com/a/...",
  "phone_number": "+1234567890",
  "phone_verified": true,
  "user_type": "individual",
  "audio_usage": "personal",
  "is_active": true,
  "is_verified": true,
  "created_at": "2024-01-15T10:30:00Z",
  "updated_at": "2024-01-15T11:00:00Z",
  "credits": {
    "credits_balance": 1500,
    "payg_balance": 500,
    "total_available_credits": 2000,
    "credits_used_today": 150,
    "daily_limit": 10000,
    "last_reset_at": "2024-01-15T00:00:00Z"
  },
  "subscription": {
    "plan_id": "price_pro_monthly",
    "plan_name": "Pro",
    "is_free_plan": false,
    "status": "active",
    "current_period_start": "2024-01-15T00:00:00Z",
    "current_period_end": "2024-02-15T00:00:00Z",
    "cancel_at": null
  },
  "is_eligible_for_first_time_discount": false,
  "first_time_discount_active": false
}

Update Profile

Update user profile information.
PATCH /api/v1/auth/me
Authorization: Bearer {access_token}
Content-Type: application/json

{
  "full_name": "Updated Name",
  "user_type": "individual",
  "audio_usage": "personal",
  "phone_number": "+1234567890",
  "country_code": "US"
}
Updating phone number will reset phone verification status. You’ll need to verify the new number using the phone verification endpoints.

Session Management

Validate Current Session

Check if the current session is valid and get detailed session information.
GET /api/v1/auth/session/validate
Authorization: Bearer {access_token}
Response:
{
  "is_valid": true,
  "session_info": {
    "session_id": "sess_abc123",
    "user_id": "550e8400-e29b-41d4-a716-446655440000",
    "device_info": "Chrome on Windows",
    "ip_address": "192.168.1.1",
    "created_at": "2024-01-15T10:30:00Z",
    "last_active": "2024-01-15T11:00:00Z",
    "expires_at": "2024-01-15T16:30:00Z",
    "is_current": true
  },
  "user": { /* Complete user object */ },
  "expires_in": 18000,
  "needs_refresh": false
}

List Active Sessions

View and manage all your active sessions across devices.
GET /api/v1/auth/sessions
Authorization: Bearer {access_token}
Response:
[
  {
    "session_id": "sess_abc123",
    "user_id": "550e8400-e29b-41d4-a716-446655440000",
    "device_info": "Chrome on Windows",
    "ip_address": "192.168.1.1",
    "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
    "created_at": "2024-01-15T10:30:00Z",
    "last_active": "2024-01-15T11:00:00Z",
    "expires_at": "2024-01-15T16:30:00Z",
    "is_current": true
  },
  {
    "session_id": "sess_def456",
    "user_id": "550e8400-e29b-41d4-a716-446655440000",
    "device_info": "Safari on iPhone",
    "ip_address": "10.0.0.1",
    "created_at": "2024-01-14T09:15:00Z",
    "last_active": "2024-01-14T22:45:00Z",
    "expires_at": "2024-01-15T04:15:00Z",
    "is_current": false
  }
]

Revoke Sessions

Revoke specific sessions or all other sessions for security.
POST /api/v1/auth/sessions/revoke
Authorization: Bearer {access_token}
Content-Type: application/json

{
  "session_id": "sess_def456",
  "revoke_all_others": false
}

Enhanced Token Refresh

Refresh access token with complete user data (alternative to basic refresh).
POST /api/v1/auth/refresh-enhanced
Content-Type: application/json

{
  "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}

Check Token Health

Check token validity and expiration status without full validation.
GET /api/v1/auth/token-health
Authorization: Bearer {access_token}
Response:
{
  "valid": true,
  "expired": false,
  "expires_in_seconds": 1800,
  "expires_in_minutes": 30,
  "should_refresh": false,
  "user_id": "550e8400-e29b-41d4-a716-446655440000"
}

Device Management

List User Devices

Get all devices and browsers the user has logged in from.
GET /api/v1/auth/devices?include_inactive=true
Authorization: Bearer {access_token}
Response:
{
  "devices": [
    {
      "id": "dev_abc123",
      "device_fingerprint": "fp_xyz789",
      "display_name": "Chrome on Windows",
      "browser": "Chrome",
      "os": "Windows",
      "device_type": "desktop",
      "ip_address": "192.168.1.1",
      "location": "New York, NY, US",
      "timezone": "America/New_York",
      "first_seen": "2024-01-10T10:00:00Z",
      "last_seen": "2024-01-15T11:00:00Z",
      "last_login_method": "password",
      "login_count": 15,
      "is_active": true,
      "is_current_session": true,
      "is_trusted": true,
      "is_blocked": false,
      "current_session_id": "sess_abc123"
    }
  ],
  "total_count": 3,
  "active_count": 2,
  "current_device": { /* Current device object */ },
  "trusted_count": 2
}

Security Features

CAPTCHA Protection

CAPTCHA challenges are automatically required based on IP reputation and activity patterns.

Check if CAPTCHA is Required

GET /api/v1/auth/captcha/required

Generate CAPTCHA Challenge

GET /api/v1/auth/captcha/generate
Response:
{
  "captcha_id": "capt_abc123",
  "question": "What is 7 + 15?",
  "expires_in": 300
}

Verify CAPTCHA Response

POST /api/v1/auth/captcha/verify
Content-Type: application/json

{
  "captcha_id": "capt_abc123",
  "answer": "22"
}

Phone Verification

Send Phone Verification Code

Send SMS verification code to user’s phone number.
POST /api/v1/auth/send-phone-verification
Authorization: Bearer {access_token}
Content-Type: application/json

{
  "phone_number": "+1234567890",
  "country_code": "US"
}

Verify Phone Number

Verify phone number with received OTP code.
POST /api/v1/auth/verify-phone
Authorization: Bearer {access_token}
Content-Type: application/json

{
  "phone_number": "+1234567890",
  "otp_code": "123456"
}

Password Management

Change Password

Change user password (requires current password).
POST /api/v1/auth/change-password
Authorization: Bearer {access_token}
Content-Type: application/json

{
  "current_password": "current_password123",
  "new_password": "new_secure_password456"
}
Password changes automatically log out all other active sessions for security.

OAuth Account Management

Link additional OAuth providers to your account.
POST /api/v1/auth/account-providers
Authorization: Bearer {access_token}
Content-Type: application/json

{
  "provider": "google",
  "provider_account_id": "1234567890",
  "type": "oauth",
  "access_token": "ya29.a0AfH6SMC...",
  "id_token": "eyJhbGciOiJSUzI1NiIs..."
}

List Linked Providers

GET /api/v1/auth/account-providers
Authorization: Bearer {access_token}
DELETE /api/v1/auth/account-providers/{provider}
Authorization: Bearer {access_token}

Rate Limiting

Authentication endpoints have specific rate limits to prevent abuse:
EndpointRate LimitWindowNotes
/auth/initiate-registration5 requests1 minutePrevents spam registrations
/auth/verify-registration10 requests1 minutePrevents code brute force
/auth/forgot-password3 requests1 hourPrevents email flooding
/auth/reset-password5 requests1 hourPrevents token brute force
Additional Security:
  • CAPTCHA required after suspicious activity
  • Maximum 3 signups per device/IP combination
  • Email flood protection across all users
  • Automatic account flagging for review
Rate Limit Headers:
X-RateLimit-Limit: 5
X-RateLimit-Remaining: 4
X-RateLimit-Reset: 1640995200
Retry-After: 60

Error Handling

Authentication Error Responses

Registration Error Responses

OAuth Error Responses

Security Error Responses

Rate Limiting and System Errors

Error Response Headers

Authentication endpoints may include additional headers:
HeaderDescriptionExample
X-Captcha-RequiredCAPTCHA verification needed"true"
X-RateLimit-LimitRequest limit per window5
X-RateLimit-RemainingRemaining requests in window4
X-RateLimit-ResetWindow reset timestamp1640995200
Retry-AfterSeconds to wait when rate limited60

Scopes and Permissions

Available Scopes

API keys can be granted specific scopes to limit access:
ScopeDescription
voice:readList and read voice data
voice:writeCreate and modify voices
voice:generateGenerate speech with voices
music:readAccess music generation data
music:generateGenerate music content
translation:useUse translation services
account:readRead account information
account:writeModify account settings
credits:readView credit balance
admin:*Administrative access

Scope Inheritance

Some scopes include others:
  • voice:write includes voice:read
  • admin:* includes all scopes
  • account:write includes account:read

Integration Examples

Web Application (React)

// React authentication hook
import { useState, useEffect } from "react";

export function useAuth() {
  const [user, setUser] = useState(null);
  const [loading, setLoading] = useState(true);

  const login = async (email, password) => {
    const response = await fetch("/api/v1/auth/token", {
      method: "POST",
      headers: { "Content-Type": "application/x-www-form-urlencoded" },
      body: new URLSearchParams({ username: email, password }),
    });

    if (response.ok) {
      const data = await response.json();
      localStorage.setItem("access_token", data.access_token);
      localStorage.setItem("refresh_token", data.refresh_token);
      setUser(data.user);
      return true;
    }
    return false;
  };

  const logout = async () => {
    await fetch("/api/v1/auth/logout", {
      method: "POST",
      headers: {
        Authorization: `Bearer ${localStorage.getItem("access_token")}`,
      },
    });

    localStorage.removeItem("access_token");
    localStorage.removeItem("refresh_token");
    setUser(null);
  };

  return { user, login, logout, loading };
}

Server-to-Server (Python)

# Python client with API key authentication
import requests

class AudioPodClient:
    def __init__(self, api_key):
        self.api_key = api_key
        self.base_url = "https://api.audiopod.ai/api/v1"
        self.session = requests.Session()
        self.session.headers.update({
            "X-API-Key": api_key,
            "User-Agent": "AudioPod-Python-Client/1.0"
        })

    def generate_speech(self, text, voice_id="aura-en-female"):
        response = self.session.post(
            f"{self.base_url}/voice/clone/",
            json={
                "input_text": text,
                "voice_id": voice_id
            }
        )
        response.raise_for_status()
        return response.json()

# Usage
client = AudioPodClient("ap_live_sk_your_api_key")
result = client.generate_speech("Hello, world!")

Best Practices

Security Recommendations

  1. Store tokens securely: Use secure storage for refresh tokens
  2. Implement token rotation: Regularly refresh access tokens
  3. Use HTTPS only: Never send tokens over unencrypted connections
  4. Validate tokens server-side: Always verify tokens on your backend
  5. Implement logout: Properly invalidate tokens when users log out
  6. Use minimal scopes: Grant only necessary permissions to API keys
  7. Monitor usage: Track API key usage and revoke suspicious keys

Error Handling

# Robust error handling example
import requests
from requests.exceptions import RequestException

def handle_auth_request(func, *args, **kwargs):
    try:
        response = func(*args, **kwargs)
        response.raise_for_status()
        return response.json()
    except requests.exceptions.Timeout:
        raise AuthError("Request timed out")
    except requests.exceptions.ConnectionError:
        raise AuthError("Connection failed")
    except requests.exceptions.HTTPError as e:
        if e.response.status_code == 401:
            raise AuthError("Invalid credentials")
        elif e.response.status_code == 429:
            raise AuthError("Rate limit exceeded")
        else:
            raise AuthError(f"HTTP error: {e.response.status_code}")
    except RequestException:
        raise AuthError("Unexpected error occurred")

Token Management

# Automatic token refresh implementation
import time
import jwt

class TokenManager:
    def __init__(self, access_token, refresh_token):
        self.access_token = access_token
        self.refresh_token = refresh_token

    def get_valid_token(self):
        if self._is_token_expired(self.access_token):
            self._refresh_access_token()
        return self.access_token

    def _is_token_expired(self, token):
        try:
            payload = jwt.decode(token, options={"verify_signature": False})
            return payload['exp'] < time.time() + 60  # Refresh 1 min before expiry
        except:
            return True

    def _refresh_access_token(self):
        response = requests.post(
            "https://api.audiopod.ai/api/v1/auth/refresh",
            json={"refresh_token": self.refresh_token}
        )

        if response.status_code == 200:
            data = response.json()
            self.access_token = data["access_token"]
        else:
            raise AuthError("Failed to refresh token")