The Meta-Data Tag Generator uses JWT-based authentication to secure all API endpoints. This guide covers registration, login, token management, and authentication workflows.
Authentication Flow
Register an Account
Create a new user account with email and password. All API operations require authentication.
Log In
Authenticate with your credentials to receive access and refresh tokens.
Use Access Token
Include the access token in the Authorization header for all API requests.
Refresh Token
When your access token expires, use the refresh token to obtain a new access token without re-authentication.
Registration
Register a new user account to access the document processing API.
API Endpoint
Request Body
{
"email" : "[email protected] " ,
"password" : "SecurePassword123!" ,
"full_name" : "John Doe"
}
Response
{
"id" : "550e8400-e29b-41d4-a716-446655440000" ,
"email" : "[email protected] " ,
"full_name" : "John Doe" ,
"is_active" : true ,
"is_verified" : false ,
"created_at" : "2026-03-03T10:30:00Z"
}
Passwords must be at least 8 characters long. The system enforces secure password requirements.
Login
Authenticate with your credentials to receive JWT tokens.
API Endpoint
Request Body
Response
{
"user" : {
"id" : "550e8400-e29b-41d4-a716-446655440000" ,
"email" : "[email protected] " ,
"full_name" : "John Doe" ,
"is_active" : true ,
"is_verified" : false ,
"created_at" : "2026-03-03T10:30:00Z"
},
"tokens" : {
"access_token" : "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." ,
"refresh_token" : "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." ,
"token_type" : "bearer" ,
"expires_in" : 3600
}
}
Using Access Tokens
Include the access token in the Authorization header for all authenticated requests.
import requests
headers = {
"Authorization" : f "Bearer { access_token } "
}
# Example: Process a single PDF
response = requests.post(
"http://localhost:8000/api/single/process" ,
headers = headers,
files = { "pdf_file" : open ( "document.pdf" , "rb" )},
data = { "config" : json.dumps(config)}
)
Refreshing Tokens
Access tokens expire after a set period (default: 1 hour). Use the refresh token to obtain a new access token without requiring the user to log in again.
API Endpoint
Request Body
{
"refresh_token" : "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
Response
{
"access_token" : "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." ,
"refresh_token" : "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." ,
"token_type" : "bearer" ,
"expires_in" : 3600
}
import requests
def refresh_access_token ( refresh_token ):
url = "http://localhost:8000/api/auth/refresh"
payload = { "refresh_token" : refresh_token}
response = requests.post(url, json = payload)
tokens = response.json()
return tokens[ 'access_token' ], tokens[ 'refresh_token' ]
# Usage
new_access_token, new_refresh_token = refresh_access_token(refresh_token)
Get Current User
Retrieve information about the currently authenticated user.
API Endpoint
Example
import requests
headers = { "Authorization" : f "Bearer { access_token } " }
response = requests.get( "http://localhost:8000/api/auth/me" , headers = headers)
user_info = response.json()
print ( f "Logged in as: { user_info[ 'email' ] } " )
print ( f "User ID: { user_info[ 'id' ] } " )
Logout
Revoke a refresh token to log out the user.
API Endpoint
Request Body
{
"refresh_token" : "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
Response
{
"message" : "Successfully logged out" ,
"success" : true
}
import requests
url = "http://localhost:8000/api/auth/logout"
payload = { "refresh_token" : refresh_token}
response = requests.post(url, json = payload)
print (response.json()[ 'message' ]) # "Successfully logged out"
Error Handling
Cause : Invalid credentials or expired access token.Solution :
Check that email and password are correct
Refresh your access token using the refresh token
Re-authenticate if refresh token is also expired
{
"detail" : "Invalid email or password"
}
Cause : Invalid request format or missing required fields.Solution :
Ensure email is valid format
Password must be at least 8 characters
All required fields must be provided
{
"detail" : "Password must be at least 8 characters"
}
Cause : Account is inactive or not verified.Solution : Contact administrator to activate account.{
"detail" : "Account is inactive"
}
Best Practices
Secure Token Storage
Store tokens securely (e.g., encrypted storage, secure cookies)
Never expose tokens in URLs or logs
Clear tokens on logout
Token Refresh Strategy
Implement automatic token refresh before expiration
Handle 401 errors by attempting token refresh
Fall back to re-authentication if refresh fails
Session Management
Access tokens expire after 1 hour by default
Refresh tokens have longer lifetime
Implement logout functionality to revoke tokens
Error Recovery
Catch authentication errors gracefully
Provide clear error messages to users
Redirect to login on authentication failure
Implementation Example
Here’s a complete authentication flow implementation:
Complete Authentication Flow
import requests
from datetime import datetime, timedelta
class AuthClient :
def __init__ ( self , base_url = "http://localhost:8000" ):
self .base_url = base_url
self .access_token = None
self .refresh_token = None
self .token_expiry = None
def register ( self , email , password , full_name = None ):
"""Register a new user"""
url = f " { self .base_url } /api/auth/register"
payload = {
"email" : email,
"password" : password,
"full_name" : full_name
}
response = requests.post(url, json = payload)
response.raise_for_status()
return response.json()
def login ( self , email , password ):
"""Login and store tokens"""
url = f " { self .base_url } /api/auth/login"
payload = { "email" : email, "password" : password}
response = requests.post(url, json = payload)
response.raise_for_status()
data = response.json()
self .access_token = data[ 'tokens' ][ 'access_token' ]
self .refresh_token = data[ 'tokens' ][ 'refresh_token' ]
self .token_expiry = datetime.now() + timedelta( seconds = data[ 'tokens' ][ 'expires_in' ])
return data[ 'user' ]
def refresh_tokens ( self ):
"""Refresh access token"""
if not self .refresh_token:
raise ValueError ( "No refresh token available" )
url = f " { self .base_url } /api/auth/refresh"
payload = { "refresh_token" : self .refresh_token}
response = requests.post(url, json = payload)
response.raise_for_status()
data = response.json()
self .access_token = data[ 'access_token' ]
self .refresh_token = data[ 'refresh_token' ]
self .token_expiry = datetime.now() + timedelta( seconds = data[ 'expires_in' ])
def get_headers ( self ):
"""Get authorization headers, refreshing token if needed"""
# Refresh if token will expire in next 5 minutes
if self .token_expiry and datetime.now() >= self .token_expiry - timedelta( minutes = 5 ):
self .refresh_tokens()
return { "Authorization" : f "Bearer { self .access_token } " }
def logout ( self ):
"""Logout and clear tokens"""
if self .refresh_token:
url = f " { self .base_url } /api/auth/logout"
payload = { "refresh_token" : self .refresh_token}
requests.post(url, json = payload)
self .access_token = None
self .refresh_token = None
self .token_expiry = None
# Usage
auth = AuthClient()
# Register
auth.register( "[email protected] " , "SecurePass123!" , "John Doe" )
# Login
user = auth.login( "[email protected] " , "SecurePass123!" )
print ( f "Logged in as { user[ 'email' ] } " )
# Make authenticated requests
headers = auth.get_headers()
response = requests.post(
"http://localhost:8000/api/single/process" ,
headers = headers,
# ... other parameters
)
# Logout
auth.logout()
The authentication system tracks device information and IP addresses for security purposes. This data is automatically captured from request headers.