Engineering

How to Add License Key Validation to Your Flask Application

TOT
Traffic Orchestrator Team
Engineering
April 10, 2026 5 min read 507 words
Share

How to Add License Key Validation to Your Flask Application

Flask's lightweight, modular design makes it perfect for building APIs and microservices — but when you need to monetize your Flask application, you need license key validation. This guide shows you how to integrate Traffic Orchestrator into Flask with minimal boilerplate.

Why License Your Flask Application?

Flask powers REST APIs, webhook handlers, internal tools, and SaaS backends. License keys help you:

  • Monetize your API with tiered access levels
  • Enforce rate limits tied to license tiers
  • Track which customers are using which features
  • Prevent unauthorized access to premium endpoints

Step 1: Install the SDK

pip install traffic-orchestrator flask

Step 2: Initialize the Client

Create a shared client instance in your Flask application factory:

# app.py
from flask import Flask
from traffic_orchestrator import Client

to_client = Client( base_url="https://api.trafficorchestrator.com/api/v1", grace_period=True, grace_period_ttl=86400, )

def create_app(): app = Flask(__name__) app.config["TO_CLIENT"] = to_client return app ```

Step 3: Create a License Decorator

Flask decorators are the idiomatic way to protect routes:

# auth.py
from functools import wraps
from flask import request, jsonify, current_app

def require_license(feature=None): def decorator(f): @wraps(f) def decorated(args, *kwargs): key = request.headers.get("X-License-Key") if not key: return jsonify(error="License key required"), 401

client = current_app.config["TO_CLIENT"] result = client.validate_license( key=key, domain=request.host )

if not result["valid"]: return jsonify(error="Invalid license", reason=result.get("error")), 403

if feature and feature not in result.get("features", []): return jsonify(error=f"Feature '{feature}' not in your plan"), 403

request.license = result return f(args, *kwargs) return decorated return decorator ```

Step 4: Protect Your Routes

Apply the decorator to any Flask route:

# routes.py
from flask import Blueprint, jsonify, request
from .auth import require_license

api = Blueprint("api", __name__)

@api.route("/api/data") @require_license() def get_data(): return jsonify(data="Premium content", license=request.license["key"])

@api.route("/api/analytics") @require_license(feature="analytics") def get_analytics(): return jsonify(analytics={"views": 1234}, plan=request.license.get("plan"))

@api.route("/api/export") @require_license(feature="export") def export_data(): return jsonify(export="CSV data here") ```

Step 5: Add a License Validation Blueprint

Create a reusable blueprint to organize license-related endpoints:

# license_bp.py
from flask import Blueprint, request, jsonify, current_app
import hmac, hashlib, time

license_bp = Blueprint("license", __name__, url_prefix="/license")

@license_bp.route("/validate", methods=["POST"]) def validate(): data = request.get_json() client = current_app.config["TO_CLIENT"] result = client.validate_license( key=data.get("key", ""), domain=data.get("domain", request.host) ) return jsonify(result)

@license_bp.route("/webhook", methods=["POST"]) def webhook(): signature = request.headers.get("X-TO-Signature", "") timestamp = request.headers.get("X-TO-Timestamp", "0")

if time.time() - int(timestamp) > 300: return jsonify(error="Expired"), 401

body = request.get_data(as_text=True) expected = hmac.new( current_app.config["WEBHOOK_SECRET"].encode(), f"{timestamp}.{body}".encode(), hashlib.sha256 ).hexdigest()

if not hmac.compare_digest(signature, expected): return jsonify(error="Invalid signature"), 401

event = request.get_json() # Process event return jsonify(received=True) ```

Step 6: Error Handling and Grace Periods

Handle network failures gracefully:

# Production-ready validation with error handling
from traffic_orchestrator import Client

client = Client( base_url="https://api.trafficorchestrator.com/api/v1", grace_period=True, grace_period_ttl=86400, )

def validate_with_fallback(key, domain): try: result = client.validate_license(key=key, domain=domain) if result.get("from_cache"): print("Using cached validation (API unreachable)") return result except Exception as e: print(f"Validation error: {e}") return {"valid": False, "error": "Service unavailable"} ```

Next Steps

Traffic Orchestrator's edge-native architecture means license validation adds less than 10ms of latency to your Flask API responses — faster than a database query.

TOT
Traffic Orchestrator Team
Engineering

The engineering team behind Traffic Orchestrator, building enterprise-grade software licensing infrastructure used by developers worldwide.

Was this article helpful?
Get licensing insights delivered

Engineering deep-dives, security advisories, and product updates. Unsubscribe anytime.

Share this article
Free Plan Available

Ship licensing in your next release

5 licenses, 500 validations/month, full API access. Set up in under 5 minutes — no credit card required.

2-minute setup No credit card Cancel anytime