> ## Documentation Index
> Fetch the complete documentation index at: https://rydantic.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Axum and Tokio

> Validated JSON requests and responses for asynchronous Rust APIs.

Turn a JSON request into a validated Rust model before it reaches your handler. The same model validates the response on the way out.

JSON requestModel validationTyped handler

## Install the integration

Enable the `axum` feature to use Axum 0.8 adapters:

```toml Cargo.toml theme={"system"}
[dependencies]
rydantic = { version = "=0.7.0", features = ["axum"] }
tokio = { version = "1", features = ["macros", "rt-multi-thread", "net"] }
```

## Create a validated endpoint

```rust src/main.rs theme={"system"}
use rydantic::{Model, axum::{Json, Router, routing::post}};

#[derive(Model)]
struct User {
    #[model(trim, min_length = 2)]
    name: String,
    #[model(ge = 18)]
    age: u8,
}

async fn create_user(Json(user): Json<User>) -> Json<User> {
    Json(user)
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let app = Router::new().route("/users", post(create_user));
    let listener = tokio::net::TcpListener::bind("127.0.0.1:3000").await?;
    rydantic::axum::framework::serve(listener, app).await?;
    Ok(())
}
```

`rydantic::axum::Json<T>` reads raw JSON and applies model normalization and validation. It also supports collections such as `Json<Vec<User>>`. Responses revalidate the model, apply output aliases and exclusions, and set `Content-Type: application/json`. The complete Axum API is re-exported through `rydantic::axum::framework`; `Router` and `routing` are also available directly.

## Handle validation errors

| Failure | HTTP status |
| - | - |
| Invalid JSON syntax | 400 |
| Missing or unsupported JSON content type | 415 |
| Request body over Axum's configured limit | 413 |
| Input type or model constraint errors | 422 |
| Invalid model returned by a handler | 500 |

Error bodies use `{"detail": [ValidationError, ...]}` and preserve field paths, codes, stages, and constraint parameters. Axum's `DefaultBodyLimit` applies, and `application/*+json` content types are supported.

## Use asynchronous validators

For asynchronous validators, extract `AsyncJson<T>` and await output validation explicitly:

```rust theme={"system"}
use rydantic::axum::{AsyncJson, Rejection, framework::response::Response};

async fn create_account(
    AsyncJson(account): AsyncJson<Account>,
) -> Result<Response, Rejection> {
    AsyncJson(account).response().await
}
```

Here `Account` is a model with asynchronous validators, as shown in the [asynchronous validation guide](/models/async). Tokio provides the asynchronous runtime; Axum supplies the HTTP routing and extraction layer.

## Keep building

> **[Build a CRUD API](/tutorials/http-api)**
>
> Follow a complete SQLite project with requests and expected responses.

> **[Run service examples](/examples/services)**
>
> Try the same model with three SQL backends.

> **[Add a database](/integrations/http-database)**
>
> Connect this endpoint to validated SQL models.

> **[Write async validators](/models/async)**
>
> Check application rules at asynchronous boundaries.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.