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

# FastAPI and ASGI

> Scan prompts as requests reach a FastAPI or other ASGI app, before your route runs

`PromptGuardMiddleware` from `promptguard.integrations.fastapi` scans prompts as requests reach your app, before your route runs. Use it when your app accepts prompts but calls the LLM somewhere [auto-instrumentation](/integrations/auto-instrumentation) does not patch. With `promptguard.init()` also on, the same text is scanned twice.

It works with any ASGI app and needs no extra install:

```bash theme={"system"}
pip install promptguard-sdk
```

## Add the middleware

```python theme={"system"}
from fastapi import FastAPI
from promptguard.integrations.fastapi import PromptGuardMiddleware

app = FastAPI()
app.add_middleware(
    PromptGuardMiddleware,
    api_key="pg_live_xxxxxxxx",
    paths=["/v1/chat"],                  # omit to scan every path
    exclude_paths=["/v1/chat/feedback"],
)
```

## What it scans

It reads the fields named in `DEFAULT_PROMPT_FIELDS` (`messages`, `prompt`, `system` and the like) from any request body on the selected paths: JSON, `text/plain` and form bodies, in their declared charset, and gzip or deflate bodies once decompressed. Content blocks and tool calls go to the Guard API as they are. It scans them with the async Guard client and answers a block with `403` and the [error envelope](/api-reference/introduction#error-response-format) before your route runs; otherwise your route receives the body unchanged.

`paths` and `exclude_paths` match whole segments of the path your routes see, with any `root_path` removed, so they work in a mounted app: `/v1/chat` covers `/v1/chat/completions` but not `/v1/chatter`. A body larger than `DEFAULT_MAX_BODY_BYTES`, before or after decompression, is refused with `413`. So is a request the Guard API rejects as too large, in every mode, so padding a prompt cannot get it through.

<Warning>
  `multipart/form-data` bodies are not scanned. A prompt sent as a multipart form field reaches your route unscanned, so scan it in the route with the [Guard client](/guides/python-sdk#guard-client) if your app accepts prompts that way.
</Warning>

## When the Guard API cannot answer

If the Guard API cannot answer (a network error, a timeout, a `5xx` or a `429`), the request goes through unscanned and a `WARNING` is logged with `promptguard_event="guard_unavailable_fail_open"`; pass `fail_open=False` to answer `503` instead.

The [SDK README](https://github.com/acebot712/promptguard-python#fastapi--asgi-middleware) lists every field, body type and outcome.


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