Basic Usage

Arguments are specified as a dictionary of name -> Field pairs.

from webargs import fields, validate

user_args = {
    # Required arguments
    "username": fields.Str(required=True),
    # Validation
    "password": fields.Str(validate=lambda p: len(p) >= 6),
    # OR use marshmallow's built-in validators
    "password": fields.Str(validate=validate.Length(min=6)),
    # Default value when argument is missing
    "display_per_page": fields.Int(missing=10),
    # Repeated parameter, e.g. "/?nickname=Fred&nickname=Freddie"
    "nickname": fields.List(fields.Str()),
    # Delimited list, e.g. "/?languages=python,javascript"
    "languages": fields.DelimitedList(fields.Str()),
    # When you know where an argument should be parsed from
    "active": fields.Bool(location="query"),
    # When value is keyed on a variable-unsafe name
    # or you want to rename a key
    "content_type": fields.Str(load_from="Content-Type", location="headers"),
    # OR, on marshmallow 3
    # "content_type": fields.Str(data_key="Content-Type", location="headers"),
    # File uploads
    "profile_image": fields.Field(
        location="files", validate=lambda f: f.mimetype in ["image/jpeg", "image/png"]


See the marshmallow.fields documentation for a full reference on available field types.

To parse request arguments, use the parse method of a Parser object.

from flask import request
from webargs.flaskparser import parser

@app.route("/register", methods=["POST"])
def register():
    args = parser.parse(user_args, request)
    return register_user(

Decorator API

As an alternative to Parser.parse, you can decorate your view with use_args or use_kwargs. The parsed arguments dictionary will be injected as a parameter of your view function or as keyword arguments, respectively.

from webargs.flaskparser import use_args, use_kwargs

@app.route("/register", methods=["POST"])
@use_args(user_args)  # Injects args dictionary
def register(args):
    return register_user(

@app.route("/settings", methods=["POST"])
@use_kwargs(user_args)  # Injects keyword arguments
def user_settings(username, password, fullname, display_per_page, nickname):
    return render_template("settings.html", username=username, nickname=nickname)


When using use_kwargs, any missing values will be omitted from the arguments. Use **kwargs to handle optional arguments.

from webargs import fields, missing

@use_kwargs({"name": fields.Str(required=True), "nickname": fields.Str(required=False)})
def myview(name, **kwargs):
    if "nickname" not in kwargs:
        # ...

Request “Locations”

By default, webargs will search for arguments from the URL query string (e.g. "/?name=foo"), form data, and JSON data (in that order). You can explicitly specify which locations to search, like so:

@use_args(user_args, locations=("json", "form"))
def register(args):
    return "registration page"

Available locations include:

  • 'querystring' (same as 'query')

  • 'json'

  • 'form'

  • 'headers'

  • 'cookies'

  • 'files'


Each Field object can be validated individually by passing the validate argument.

from webargs import fields

args = {"age": fields.Int(validate=lambda val: val > 0)}

The validator may return either a boolean or raise a ValidationError.

from webargs import fields, ValidationError

def must_exist_in_db(val):
    if not User.query.get(val):
        # Optionally pass a status_code
        raise ValidationError("User does not exist")

args = {"id": fields.Int(validate=must_exist_in_db)}


If a validator returns None, validation will pass. A validator must return False or raise a ValidationError for validation to fail.

There are a number of built-in validators from marshmallow.validate (re-exported as webargs.validate).

from webargs import fields, validate

args = {
    "name": fields.Str(required=True, validate=[validate.Length(min=1, max=9999)]),
    "age": fields.Int(validate=[validate.Range(min=1, max=999)]),

The full arguments dictionary can also be validated by passing validate to Parser.parse, Parser.use_args, Parser.use_kwargs.

from webargs import fields
from webargs.flaskparser import parser

argmap = {"age": fields.Int(), "years_employed": fields.Int()}

# ...
result = parser.parse(
    argmap, validate=lambda args: args["years_employed"] < args["age"]

Error Handling

Each parser has a default error handling method. To override the error handling callback, write a function that receives an error, the request, the marshmallow.Schema instance, status code, and headers. Then decorate that function with Parser.error_handler.

from webargs import flaskparser

parser = flaskparser.FlaskParser()

class CustomError(Exception):

def handle_error(error, req, schema, status_code, headers):
    raise CustomError(error.messages)

Parsing Lists in Query Strings

Use fields.DelimitedList to parse comma-separated lists in query parameters, e.g. /?permissions=read,write

from webargs import fields

args = {"permissions": fields.DelimitedList(fields.Str())}

If you expect repeated query parameters, e.g. /?repo=webargs&repo=marshmallow, use fields.List instead.

from webargs import fields

args = {"repo": fields.List(fields.Str())}

Nesting Fields

Field dictionaries can be nested within each other. This can be useful for validating nested data.

from webargs import fields

args = {
    "name": fields.Nested(
        {"first": fields.Str(required=True), "last": fields.Str(required=True)}


By default, webargs only parses nested fields using the json request location. You can, however, implement your own parser to add nested field functionality to the other locations.

Next Steps

  • Go on to Advanced Usage to learn how to add custom location handlers, use marshmallow Schemas, and more.

  • See the Framework Support page for framework-specific guides.

  • For example applications, check out the examples directory.