Skip to main content
Prerequisites: Before you begin, ensure you have the following installed:
  • Python 3.9 or higher
  • pip or Poetry package manager
  • jq - Required for Auth0 CLI setup
  • Your preferred code editor
Flask Version Compatibility: This quickstart requires Flask 3.0 or higher for native async support.

Get Started

This guide demonstrates how to integrate Auth0 with any new or existing Python API built with Flask.
1

Create a new Flask project

Create a new directory for your Flask API:
Create a virtual environment and activate it:
2

Install dependencies

Create a requirements.txt file with the following dependencies:
requirements.txt
Install the dependencies:
3

Setup your Auth0 API

Next up, you need to create a new API on your Auth0 tenant and configure your application.You can choose to do this automatically by running a CLI command or do it manually via the Dashboard:
  1. Go to the Auth0 DashboardApplicationsAPIs
  2. Click Create API
  3. Enter your API details:
    • Name: My Flask API
    • Identifier: https://my-flask-api (this will be your audience)
    • Signing Algorithm: RS256
  4. Click Create
  5. Copy your Domain from the Dashboard (found under ApplicationsApplications[Your App]Settings)
  6. Copy the Identifier you just created (this is your audience)
Your Domain should not include https:// - use only the domain name (e.g., your-tenant.auth0.com).The Audience (API Identifier) is a unique identifier for your API and can be any valid URI.
4

Define API permissions

Configure permissions (scopes) for your API to control access to specific resources:
  1. In the Auth0 Dashboard, navigate to ApplicationsAPIs
  2. Select your API (My Flask API)
  3. Go to the Permissions tab
  4. Click Add Permission
  5. Add the following permission:
    • Permission (Scope): read:messages
    • Description: Read messages
  6. Click Add
Permissions define what actions can be performed on your API. You can add multiple permissions like write:messages, delete:messages, etc. The /api/private-scoped endpoint in this quickstart requires the read:messages permission.
5

Configure the Auth0 client

If you used the CLI method in Step 3, your .env file was automatically created. Skip to creating the app.py file below.
If you used the Dashboard method, create a .env file in your project root to store your Auth0 configuration:
.env
Replace your-tenant.us.auth0.com with your actual Auth0 domain and update the API_IDENTIFIER to match your API identifier from the dashboard.
Create an app.py file and configure the Auth0 API client:
app.py
5

Create protected routes

Add a decorator for protecting routes and create public and private endpoints:
app.py
6

Run your API

Start your Flask application:
Your API is now running on http://localhost:5000.
CheckpointYou should now have a fully functional Auth0-protected Flask API running on your localhost with three endpoints:
  • /api/public - Accessible without authentication
  • /api/private - Requires a valid Auth0 access token
  • /api/private-scoped - Requires authentication and the read:messages permission

Test Your API

To test your protected endpoints, you need an access token.

Get a test token

  1. Go to the Auth0 Dashboard
  2. Navigate to Applications → APIs
  3. Select your API
  4. Go to the Test tab
  5. Copy the access token

Make a request

Test the public endpoint (no token required):
Test the protected endpoint (token required):
Replace YOUR_ACCESS_TOKEN with the token you copied from the Auth0 Dashboard.

Advanced Usage

Require specific claims to be present in the access token:
For enhanced security, enable DPoP (Demonstrating Proof-of-Possession). DPoP enhances OAuth 2.0 by binding access tokens to cryptographic keys.
The verify_request() method automatically detects whether the request uses Bearer or DPoP authentication. When DPoP is used, it validates both the access token and the DPoP proof according to RFC 9449.
Create a decorator to check for specific scopes:
Implement comprehensive error handling with specific error types:
All authentication errors extend from BaseAuthError, which provides methods like get_status_code(), get_headers(), and get_error_code() for proper HTTP responses with WWW-Authenticate headers.
For applications where most endpoints require authentication, use Flask’s before_request to validate tokens globally:

Common Issues

Symptom: Getting 401 errors even with valid-looking tokensCause: The audience in your token doesn’t match the audience configured in your API clientSolution:
  1. Verify the AUTH0_AUDIENCE in your .env file matches your Auth0 API Identifier exactly
  2. The audience is case-sensitive
  3. Ensure the audience is a URL or URN format (e.g., https://my-api not my-api)
Symptom: Token validation fails with issuer mismatchCause: The domain configuration doesn’t match the token issuerSolution:
  1. Verify AUTH0_DOMAIN is correct (e.g., tenant.us.auth0.com)
  2. Don’t include https:// in the domain
  3. Don’t include a trailing slash
Symptom: None values or environment variable errorsCause: Environment variables not loaded or .env file not foundSolution:
  1. Ensure .env file exists in your project root
  2. Verify load_dotenv() is called before accessing os.getenv()
  3. Check that variable names match exactly (case-sensitive)
Symptom: RuntimeError: This event loop is already running or similar async errorsCause: Using async routes without Flask 3.0+ or mixing sync/async incorrectlySolution:
  1. Upgrade to Flask 3.0 or higher: pip install --upgrade flask
  2. Ensure all route handlers using api_client are declared as async def
  3. Don’t use asyncio.run() within route handlers
Symptom: VerifyAccessTokenError: Token is expiredCause: The access token has passed its expiration timeSolution:
  1. Request a new token from the Auth0 Dashboard Test tab
  2. Implement token refresh in your client application
  3. Tokens from the Dashboard are typically valid for 24 hours
Symptom: Missing or invalid authorization header errorCause: Request doesn’t include the Authorization header or uses incorrect formatSolution:
  1. Ensure the header is named Authorization (capital A)
  2. Use format: Authorization: Bearer YOUR_TOKEN
  3. Don’t include quotes around the token

Additional Resources

SDK Documentation

Complete SDK documentation and API reference

Flask Documentation

Official Flask framework documentation

Auth0 Dashboard

Manage your Auth0 tenant and APIs

API Authentication Guide

Learn about access tokens and API security

DPoP Documentation

Learn about proof-of-possession security

Community Forum

Get help from the Auth0 community

Next Steps

Check out the Auth0 Python API samples repository for complete working examples with Flask.