Practical examples of creating RESTful APIs with Flask in 2025

If you’re hunting for clear, real-world examples of creating RESTful APIs with Flask, you’re in the right place. Instead of vague theory, this guide walks through concrete projects you could actually ship, from a to‑do API to token‑secured microservices. Along the way, you’ll see examples of how to structure routes, handle JSON, manage errors, and plug in authentication the way teams are doing it in 2024–2025. Flask remains one of the most popular Python microframeworks for building APIs because it stays out of your way: you bring the architecture, Flask brings the routing and request/response plumbing. In the sections below, we’ll walk through several examples of creating RESTful APIs with Flask that mirror real production scenarios: CRUD APIs, pagination, background tasks, JWT auth, and more. These examples include code you can paste into a project today, plus pointers to standards and best practices from authoritative sources.
Written by
Jamie
Published
Updated

Fast-start example of a minimal Flask REST API

Let’s start with the smallest possible example of creating RESTful APIs with Flask that still looks like something you’d use in a real codebase. This is a tiny notes API with in‑memory storage:

from flask import Flask, request, jsonify, abort

app = Flask(__name__)

notes = []  # in-memory store

@app.route("/notes", methods=["GET"])
def list_notes():
    return jsonify(notes), 200

@app.route("/notes", methods=["POST"])
def create_note():
    data = request.get_json() or {}
    if "text" not in data:
        abort(400, description="'text' field is required")

    note = {"id": len(notes) + 1, "text": data["text"]}
    notes.append(note)
    return jsonify(note), 201

if __name__ == "__main__":
    app.run(debug=True)

This tiny snippet already shows the core pattern behind many examples of creating RESTful APIs with Flask:

  • Use @app.route with HTTP methods to define resources.
  • Accept and validate JSON with request.get_json().
  • Return JSON consistently via jsonify and proper HTTP status codes.

From here, every other example of a Flask REST API is just layering on structure: blueprints, databases, authentication, background jobs, and rate limiting.


Real examples of creating RESTful APIs with Flask for CRUD data

Most developers start with a simple CRUD API. Here’s a more realistic example of a task manager API using SQLAlchemy and blueprints. This is one of the best examples of how people actually structure Flask projects in 2024.

from flask import Flask, Blueprint, request, jsonify, abort
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///tasks.db"
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False

db = SQLAlchemy(app)

tasks_bp = Blueprint("tasks", __name__, url_prefix="/api/tasks")

class Task(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(120), nullable=False)
    done = db.Column(db.Boolean, default=False)

    def to_dict(self):
        return {"id": self.id, "title": self.title, "done": self.done}

@tasks_bp.route("", methods=["GET"])
def get_tasks():
    tasks = Task.query.all()
    return jsonify([t.to_dict() for t in tasks]), 200

@tasks_bp.route("", methods=["POST"])
def create_task():
    data = request.get_json() or {}
    title = data.get("title")
    if not title:
        abort(400, description="'title' is required")

    task = Task(title=title)
    db.session.add(task)
    db.session.commit()
    return jsonify(task.to_dict()), 201

@tasks_bp.route("/<int:task_id>", methods=["PATCH"])
def update_task(task_id):
    task = Task.query.get_or_404(task_id)
    data = request.get_json() or {}

    if "title" in data:
        task.title = data["title"]
    if "done" in data:
        task.done = bool(data["done"])

    db.session.commit()
    return jsonify(task.to_dict()), 200

@tasks_bp.route("/<int:task_id>", methods=["DELETE"])
def delete_task(task_id):
    task = Task.query.get_or_404(task_id)
    db.session.delete(task)
    db.session.commit()
    return "", 204

app.register_blueprint(tasks_bp)

if __name__ == "__main__":
    with app.app_context():
        db.create_all()
    app.run(debug=True)

This example of a CRUD API covers patterns you’ll re‑use constantly:

  • Blueprints for modular routing (/api/tasks).
  • SQLAlchemy models with to_dict() methods.
  • PATCH for partial updates, which aligns with API design guidance from organizations like the U.S. Digital Service.

When people ask for real examples of creating RESTful APIs with Flask, this kind of endpoint set is usually what they mean.


Examples include pagination and filtering for real-world datasets

Once your API handles more than a few dozen records, pagination and filtering stop being optional. Here’s a focused example of adding pagination to the tasks API:

from flask import request, jsonify

@app.route("/api/tasks-paged", methods=["GET"])
def get_tasks_paged():
    page = request.args.get("page", default=1, type=int)
    per_page = request.args.get("per_page", default=20, type=int)
    query = Task.query

#    # Optional filtering
    done = request.args.get("done")
    if done is not None:
        query = query.filter_by(done=(done.lower() == "true"))

    pagination = query.paginate(page=page, per_page=per_page, error_out=False)

    return jsonify({
        "items": [t.to_dict() for t in pagination.items],
        "page": pagination.page,
        "per_page": pagination.per_page,
        "total": pagination.total
    }), 200

This is a practical example of creating RESTful APIs with Flask that behave well under load. By returning page, per_page, and total, you make client‑side UI work much easier.

For API design standards and pagination patterns, the GSA API Standards are worth a read; they influence how many U.S. government APIs behave.


JWT authentication: a security-focused example of a Flask REST API

In 2024–2025, almost every serious API needs token‑based authentication. Here’s a compact example of using JSON Web Tokens (JWT) with Flask. This uses the flask-jwt-extended extension, which is still widely used.

from datetime import timedelta
from flask import Flask, request, jsonify
from flask_jwt_extended import (
    JWTManager, create_access_token,
    jwt_required, get_jwt_identity
)

app = Flask(__name__)
app.config["JWT_SECRET_KEY"] = "change-me-in-production"
app.config["JWT_ACCESS_TOKEN_EXPIRES"] = timedelta(hours=1)

jwt = JWTManager(app)

USERS = {"alice": "password123"}

@app.route("/auth/login", methods=["POST"])
def login():
    data = request.get_json() or {}
    username = data.get("username")
    password = data.get("password")

    if USERS.get(username) != password:
        return jsonify({"msg": "Bad username or password"}), 401

    token = create_access_token(identity=username)
    return jsonify(access_token=token), 200

@app.route("/auth/profile", methods=["GET"])
@jwt_required()
def profile():
    current_user = get_jwt_identity()
    return jsonify(user=current_user), 200

This example of a secure RESTful API endpoint with Flask shows how you can:

  • Issue short‑lived access tokens.
  • Protect routes with @jwt_required().
  • Attach user identity to requests without session cookies.

If you’re building health‑related APIs, you’ll also want to look at security guidance from sources like the Office for Civil Rights at HHS, since HIPAA‑aligned systems lean heavily on authenticated, auditable APIs.


Background jobs and async workflows: real examples of Flask APIs in production

Sometimes your API needs to kick off long‑running work: video processing, AI inference, or bulk data imports. A common pattern is to use Flask as the front door and Celery or RQ for background jobs.

Here’s a trimmed‑down example of creating RESTful APIs with Flask that trigger background tasks using RQ and Redis:

import time
import redis
from rq import Queue
from flask import Flask, jsonify

app = Flask(__name__)

redis_conn = redis.Redis(host="localhost", port=6379)
queue = Queue("default", connection=redis_conn)


def long_running_job(x):
    time.sleep(10)  # simulate heavy work
    return x * 2

@app.route("/jobs", methods=["POST"])
def create_job():
    job = queue.enqueue(long_running_job, 21)
    return jsonify({"job_id": job.get_id()}), 202

@app.route("/jobs/<job_id>", methods=["GET"])
def get_job(job_id):
    from rq.job import Job
    job = Job.fetch(job_id, connection=redis_conn)
    return jsonify({
        "id": job.get_id(),
        "status": job.get_status(),
        "result": job.result
    }), 200

This pattern shows up in many best examples of Flask APIs in production, because it keeps the HTTP layer fast and pushes heavy lifting into workers.


Versioning and blueprints: examples include multi-version APIs

Real APIs live for years. That means versioning. Here’s a small example of organizing v1 and v2 endpoints with blueprints:

from flask import Flask, Blueprint, jsonify

app = Flask(__name__)

v1 = Blueprint("v1", __name__, url_prefix="/api/v1")
v2 = Blueprint("v2", __name__, url_prefix="/api/v2")

@v1.route("/status")
def status_v1():
    return jsonify({"status": "ok", "version": 1}), 200

@v2.route("/status")
def status_v2():
    return jsonify({"status": "ok", "version": 2, "features": ["metrics"]}), 200

app.register_blueprint(v1)
app.register_blueprint(v2)

This example of API versioning with Flask is intentionally simple, but the pattern scales. As your API grows, you can split each version into its own package and migrate clients gradually.

Standards like the NIST Secure Software Development Framework emphasize lifecycle thinking; versioned APIs are one practical way to apply that mindset.


JSON schema validation: examples of safer input handling

Another pattern that shows up in better examples of creating RESTful APIs with Flask is explicit input validation. Instead of manually checking every field, you can use marshmallow or similar libraries.

Here’s a short example using marshmallow to validate a user signup payload:

from flask import Flask, request, jsonify
from marshmallow import Schema, fields, ValidationError

app = Flask(__name__)

class SignupSchema(Schema):
    email = fields.Email(required=True)
    password = fields.Str(required=True, validate=lambda p: len(p) >= 8)

signup_schema = SignupSchema()

@app.errorhandler(ValidationError)
def handle_validation_error(err):
    return jsonify({"errors": err.messages}), 400

@app.route("/auth/signup", methods=["POST"])
def signup():
    data = request.get_json() or {}
    valid = signup_schema.load(data)
#    # create user here
    return jsonify({"email": valid["email"]}), 201

This style of validation makes your API behavior easier to reason about, and it’s the kind of detail that separates toy examples of Flask APIs from code you’d trust in production.


OpenAPI and documentation: an example of self-describing Flask APIs

By 2025, clients expect well-documented APIs with machine‑readable specs. Flask plays nicely with tools that generate OpenAPI (Swagger) definitions.

Here’s a minimal example using flask-smorest to auto‑generate OpenAPI docs:

from flask import Flask
from flask_smorest import Api, Blueprint

app = Flask(__name__)
app.config["API_TITLE"] = "Books API"
app.config["API_VERSION"] = "v1"
app.config["OPENAPI_VERSION"] = "3.0.3"

api = Api(app)

blp = Blueprint("books", "books", url_prefix="/books", description="Books operations")

@blp.route("")
class BooksResource:
    @blp.response(200)
    def get(self):
        """List books"""
        return []

api.register_blueprint(blp)

Run this, and you’ll get interactive documentation at /swagger-ui (or similar, depending on configuration). Among all the examples of creating RESTful APIs with Flask, this is one that pays off immediately: developers can explore and test endpoints without reading your source code.


Looking across these examples of creating RESTful APIs with Flask, a few trends stand out in current projects:

  • Microservices and containers: Teams often run multiple small Flask APIs in Docker, fronted by an API gateway.
  • Typed Python: More codebases use type hints plus tools like mypy to catch API contract issues early.
  • Security hardening: JWTs, OAuth2, rate limiting, and strict CORS settings are now standard rather than nice‑to‑have.
  • Observability: Logging, tracing, and metrics (via tools like OpenTelemetry) are wired into APIs from day one.

If you’re building anything that touches regulated data (health, finance, education), it’s worth skimming guidance from places like HealthIT.gov or your country’s digital service for expectations around API reliability and privacy.

The bottom line: the best examples of creating RESTful APIs with Flask in 2025 don’t just show @app.route and jsonify. They show structure, validation, authentication, and documentation—exactly the patterns you’ve seen in the examples above.


FAQ: examples of common questions about Flask REST APIs

Q: What is a simple example of creating RESTful APIs with Flask for beginners?
A straightforward starting point is a single‑file app that exposes a /items endpoint with GET and POST, stores data in memory, and returns JSON using jsonify. The first code sample in this article is exactly that style of beginner‑friendly example.

Q: How do I secure a Flask REST API with tokens?
Use a library like flask-jwt-extended to issue JWT access tokens on login, then protect sensitive routes with @jwt_required(). The JWT example of a Flask API above shows the core pattern, including token expiration and identity lookup.

Q: Are there production-grade examples of Flask APIs using databases?
Yes. Many teams pair Flask with SQLAlchemy or PostgreSQL clients. The task manager example in this guide demonstrates a realistic CRUD pattern with a Task model, migrations via db.create_all(), and HTTP verbs mapped to database operations.

Q: Can Flask handle real-time or high-traffic APIs?
Flask itself is synchronous, but it runs well behind WSGI servers like Gunicorn or uWSGI and can scale horizontally with load balancers. For heavy workloads or real‑time features, teams often combine Flask with message queues, background workers, or async services for the hottest paths.

Q: Where can I find more examples of well-designed REST APIs?
You can study public government and research APIs, which often publish standards and example implementations. The GSA API Standards and related U.S. government API guidelines are good references, even if you’re not building civic tech.

Explore More Flask Code Snippets

Discover more examples and insights in this category.

View All Flask Code Snippets