Setting up Airtable OAuth authentication using Python

I’m trying to set up OAuth authentication for Airtable using Python. I have working Google OAuth code that uses google_auth_oauthlib.flow.InstalledAppFlow.from_client_secrets_file to handle the browser flow and token storage:

from google_auth_oauthlib.flow import InstalledAppFlow

def authenticate_user():
    user_creds = None
    # Check if token file exists with stored credentials
    if os.path.exists(AUTH_TOKEN_FILE):
        user_creds = Credentials.from_authorized_user_file(AUTH_TOKEN_FILE, API_SCOPES)
    
    # Handle credential validation and refresh
    if not user_creds or not user_creds.valid:
        if user_creds and user_creds.expired and user_creds.refresh_token:
            user_creds.refresh(Request())
        else:
            auth_flow = InstalledAppFlow.from_client_secrets_file(CLIENT_CONFIG_FILE, API_SCOPES)
            user_creds = auth_flow.run_local_server(port=0)
        
        # Store credentials for future use
        with open(AUTH_TOKEN_FILE, 'w') as token_file:
            token_file.write(user_creds.to_json())
    
    return user_creds

The CLIENT_CONFIG_FILE contains JSON credentials downloaded from Google’s OAuth console. However, Airtable doesn’t provide a similar downloadable file, so I manually created one with these parameters:

{"installed":
    {"client_id":"****",
     "auth_uri":"https://airtable.com/oauth2/v1/authorize",
     "token_uri":"https://oauth2.googleapis.com/token",
     "auth_provider_x509_cert_url":"https://www.googleapis.com/oauth2/v1/certs",
     "client_secret":"*****",
     "redirect_uris":["http://localhost"]}}

This gives me an error about the client ID being invalid, even though it’s correct. The issue seems to be with the redirect URI configuration.

I also tried using a different OAuth library with PKCE:

from oauthlib.oauth2 import WebApplicationClient
from requests_oauthlib import OAuth2Session
import secrets
import base64
import hashlib

def create_pkce_codes():
    """ Create code_verifier and code_challenge for PKCE authentication. """
    verifier = base64.urlsafe_b64encode(secrets.token_bytes(32)).rstrip(b"=").decode('utf-8')
    challenge = base64.urlsafe_b64encode(hashlib.sha256(verifier.encode('utf-8')).digest()).rstrip(b"=").decode('utf-8')
    return verifier, challenge

def setup_oauth():
    app_id = '****'
    callback_url = 'https://localhost:8080/'
    permissions = ['schema.bases:read']

    # Create PKCE pair
    verifier_code, challenge_code = create_pkce_codes()

    # Setup OAuth client
    oauth_client = WebApplicationClient(app_id)
    session = OAuth2Session(client=oauth_client, redirect_uri=callback_url, scope=permissions)

    # Build authorization URL
    auth_url, session_state = session.authorization_url(
        url='https://airtable.com/oauth2/v1/authorize',
        code_challenge_method="S256",
        code_challenge=challenge_code
    )

    print("Visit this URL to authorize:", auth_url)

    # Manual callback handling
    callback_response = input('Enter the complete redirect URL: ')

    # Get access token
    token_endpoint = "https://api.airtable.com/oauth/token"
    access_token = session.fetch_token(
        token_url=token_endpoint,
        authorization_response=callback_response,
        client_secret=None,
        code_verifier=verifier_code)

    print("Retrieved token:", access_token)

This approach gets further but fails with INVALID_API_VERSION error when trying to exchange the authorization code for a token. I need help with either fixing the redirect URI configuration or specifying the correct API version for the OAuth flow.

Your redirect URI mismatch happens because you’re using http://localhost but Airtable wants the exact URI you registered. Check your Airtable developer console - the redirect URI needs to match exactly, including the port. For the Google OAuth library issue: you’re mixing Google’s token endpoint with Airtable’s auth endpoint. Switch your JSON config to use Airtable’s token endpoint: https://airtable.com/oauth2/v1/token. I ran into the same problems when switching from Google OAuth patterns. Here’s the key difference - Airtable requires PKCE for public clients, so your second approach is actually correct. Just fix that token endpoint URL and make sure your OAuth app’s redirect URI matches your callback_url parameter exactly.

I’ve hit this Airtable OAuth nightmare too. You’re trying to use Google OAuth when Airtable works completely differently.

Ditch the Google OAuth library - it won’t work. Airtable has different response structure and needs PKCE.

Your second approach is close but needs fixes:

  1. Use http://127.0.0.1:8080/callback as redirect URI (not localhost, include /callback)
  2. Set your Airtable app as “Public” client in developer console
  3. Add state parameter for security

This worked for me:

from requests_oauthlib import OAuth2Session
import secrets

def get_airtable_token():
    client_id = 'your_client_id'
    redirect_uri = 'http://127.0.0.1:8080/callback'
    scope = ['data.records:read', 'schema.bases:read']
    
    # Generate state for security
    state = secrets.token_urlsafe(32)
    
    session = OAuth2Session(
        client_id=client_id,
        redirect_uri=redirect_uri,
        scope=scope,
        state=state
    )
    
    # Your PKCE code generation looks fine, keep that
    verifier, challenge = create_pkce_codes()
    
    auth_url, state = session.authorization_url(
        'https://airtable.com/oauth2/v1/authorize',
        code_challenge=challenge,
        code_challenge_method='S256'
    )
    
    print(f"Go to: {auth_url}")
    callback = input("Paste the callback URL: ")
    
    token = session.fetch_token(
        'https://airtable.com/oauth2/v1/token',
        authorization_response=callback,
        code_verifier=verifier
    )
    
    return token

Make sure your redirect URI in code matches exactly what’s in the Airtable developer console.

your token endpoint URL is wrong in the second attempt. use https://airtable.com/oauth2/v1/token instead of https://api.airtable.com/oauth/token. airtable’s oauth endpoints are different from their api ones - that’s what’s causing your invalid api version error.

Had this exact problem last month! The issue is Airtable’s OAuth doesn’t play nice with Google’s OAuth library. InstalledAppFlow is built for Google’s flow and expects response formats that Airtable just doesn’t give you. Your PKCE approach is the way to go. Fix the token endpoint to https://airtable.com/oauth2/v1/token and make sure your Airtable OAuth app is set as “public client” instead of “confidential client” in the developer console. That invalid client ID error? Usually means wrong app type. One more thing - Airtable’s OAuth hates localhost redirects. Try http://127.0.0.1:8080 instead. Your PKCE flow looks good otherwise, just needs those tweaks.