Accept the values your endpoint needs.

Use Python types and defaults to describe a request.

Suppose you want a user endpoint with a page number and an active-user filter. Add it to your application:

@app.get(path="/users/{user_id}", methods=["GET"])
async def user(user_id: int, page: int = 1, active: bool = True):
    return f"User {user_id} · page={page} · active={active}"

A request to /users/42?page=2&active=false produces:

User 42 · page=2 · active=False

Karak gives your function an integer for user_id, an integer for page, and a boolean for active. You can use those values directly in your Python code.

Decide where a value comes from

If a parameter’s name appears in a path placeholder, it comes from that part of the URL. Other parameters come from the query string after ?.

In the example, user_id comes from /users/42. The query string supplies page and active.

Set a default or require a value

A default such as page: int = 1 is used when the caller omits that query key. Without a default, a value is required. For example:

@app.get(path="/search", methods=["GET"])
async def search(term: str):
    return f"Searching for {term}"

/search?term=python works. /search produces HTTP 422 because term is missing. A present empty string is a supplied value: term= is valid for a string, while page= fails integer conversion.

Accept several values

Use a list when the caller should be able to repeat a query key:

@app.get(path="/tags", methods=["GET"])
async def tags(tag: list[str]):
    return ", ".join(tag)

/tags?tag=python&tag=web produces python, web. Lists are available for query values only. Repeating a key for a single value, such as page=1&page=2, returns HTTP 422.

Limit the choices

from typing import Literal


@app.get(path="/products", methods=["GET"])
async def products(sort: Literal["price", "newest"] = "newest"):
    return f"Sort by {sort}"

/products?sort=price works. A value outside those two choices is rejected.

Choose a supported type

What you want Python type Example input
Text str name=karak
A whole number int page=2
A fractional number float ratio=0.5
A yes/no option bool active=true
An identifier UUID from uuid A valid UUID string
A date date from datetime day=2026-09-25
A date and time datetime from datetime at=2026-09-25T12:30:00Z
A decimal value Decimal from decimal amount=19.99
One of your enum members An Enum subclass A member’s value
A fixed choice Literal from typing sort=price
Several values list[T] id=1&id=2 for list[int]

Boolean input accepts true/false, 1/0, yes/no, and on/off, without case sensitivity. Import types such as UUID, date, and Literal before using them in your function signature.

Handle invalid input

A missing required value or a failed conversion returns HTTP 422. The response identifies the parameter that needs attention, and your function is not called.

Use supported types for every parameter. Types such as str | None, nested lists, dictionaries, and body models are not supported in the main framework yet. An unsupported annotation prevents the endpoint from being added.

Type to find a page.