This guide explains how authentication works in the Transcript Create API.
Transcript Create uses OAuth 2.0 for user authentication with support for:
- Google OAuth
- Twitch OAuth
After successful authentication, the API uses session cookies to maintain user state.
Redirect users to the Google login endpoint:
GET /auth/login/google
This redirects to Google's OAuth consent screen where users authorize your application.
After user consent, Google redirects back to:
GET /auth/callback/google?code=...&state=...
The API automatically:
- Exchanges the authorization code for an access token
- Fetches user profile information
- Creates or updates the user in the database
- Creates a session and sets a cookie
- Redirects to the frontend application
The response sets a secure HTTP-only cookie:
Set-Cookie: tc_session=<token>; HttpOnly; Secure; SameSite=Lax; Max-Age=604800
This cookie is automatically sent with subsequent requests to authenticate the user.
The Twitch OAuth flow works identically to Google:
GET /auth/login/twitch
GET /auth/callback/twitch?code=...&state=...
Same automatic processing as Google OAuth.
Get information about the currently authenticated user:
curl https://api.example.com/auth/me \
-H "Cookie: tc_session=your_session_token"Response when authenticated:
{
"user": {
"id": "123e4567-e89b-12d3-a456-426614174000",
"email": "user@example.com",
"name": "John Doe",
"avatar_url": "https://example.com/avatar.jpg",
"plan": "free",
"searches_used_today": 5,
"search_limit": 100
}
}Response when not authenticated:
{
"user": null
}Invalidate the current session:
curl -X POST https://api.example.com/auth/logout \
-H "Cookie: tc_session=your_session_token"Response:
{
"ok": true
}This clears the session cookie and removes the session from the database.
Users have one of two plans:
- Limited daily searches (100 by default)
- Limited daily exports
- Full transcription access
- Unlimited searches
- Unlimited exports
- Priority processing
- Managed via Stripe subscription
Check plan details:
curl https://api.example.com/auth/meThe response includes:
plan: "free" or "pro"searches_used_today: Current daily usage (free only)search_limit: Daily quota (free only)
Configure OAuth providers with these environment variables:
# Google OAuth
OAUTH_GOOGLE_CLIENT_ID=your_google_client_id
OAUTH_GOOGLE_CLIENT_SECRET=your_google_client_secret
OAUTH_GOOGLE_REDIRECT_URI=https://api.example.com/auth/callback/google
# Twitch OAuth
OAUTH_TWITCH_CLIENT_ID=your_twitch_client_id
OAUTH_TWITCH_CLIENT_SECRET=your_twitch_client_secret
OAUTH_TWITCH_REDIRECT_URI=https://api.example.com/auth/callback/twitch
# Frontend
FRONTEND_ORIGIN=https://app.example.com- Go to Google Cloud Console
- Create a new project or select existing
- Enable Google+ API
- Create OAuth 2.0 credentials
- Add authorized redirect URI:
https://api.example.com/auth/callback/google - Copy Client ID and Client Secret to environment variables
- Go to Twitch Developer Console
- Register a new application
- Add OAuth redirect URL:
https://api.example.com/auth/callback/twitch - Set category to "Website Integration"
- Copy Client ID and Client Secret to environment variables
Session tokens are:
- 32-byte URL-safe random strings
- Stored securely in the database
- Expire after 7 days of inactivity
- HTTP-only cookies (not accessible via JavaScript)
- Secure flag (HTTPS only in production)
- SameSite=Lax to prevent CSRF
User information stored includes:
- OAuth provider (Google/Twitch)
- OAuth subject ID (unique user identifier from provider)
- Email address
- Display name
- Avatar URL
Sensitive data like OAuth tokens are not stored permanently.
The API restricts cross-origin requests to the configured frontend origin:
CORS_ORIGINS = [settings.FRONTEND_ORIGIN]401 Unauthorized - Authentication required
{
"error": "authentication_required",
"message": "You must be logged in to access this resource",
"details": {}
}403 Forbidden - Insufficient permissions
{
"error": "authorization_error",
"message": "You do not have permission to access this resource",
"details": {}
}503 Service Unavailable - OAuth library not configured
{
"error": "external_service_error",
"message": "OAuth authentication is not available",
"details": {
"service": "OAuth"
}
}500 Internal Server Error - OAuth flow failed
{
"error": "external_service_error",
"message": "Authentication failed with Google/Twitch",
"details": {
"service": "Google OAuth"
}
}In development, you can manually set session cookies:
# Create a session in the database manually
# Then use the token in requests:
curl https://api.example.com/auth/me \
-H "Cookie: tc_session=your_test_token"Use the test client with cookie support:
from fastapi.testclient import TestClient
client = TestClient(app)
response = client.post("/auth/login/google")
# Follow redirect, handle OAuth mock
response = client.get("/auth/me")
assert response.json()["user"] is not NoneAdmin users have additional privileges:
- Access to
/admin/*endpoints - View event analytics
- Manage user plans
- Export event data
Admin status is set via the is_admin flag in the users table.
- Getting Started - Basic API usage
- Webhooks - Stripe webhook authentication
- Examples - Code examples with authentication