Skip to main content
Experimental

IPA-129: Query Parameters

Query parameters can be appended to the request URI and are useful for providing optional parameter values in the request. These values can be used for filtering, sorting, searching and pagination. Query parameters can help clients retrieve only the items they are interested in, or format the response in a specified way.

Guidance

  1. API Producers may use query parameters for:

  2. Query parameters must not be used in place of request body fields for Create and Update Methods, i.e. when the value causes a side-effect.

    paths:
    /orders:
    post:
    operationId: createOrder
    requestBody:
    required: true
    content:
    application/json:
    schema:
    type: object
    properties:
    customerId:
    type: string
    total:
    type: number
    Why:

    The values that create the order live in the request body, so the side-effect is described by the payload rather than by the URI.

    paths:
    /orders:
    post:
    operationId: createOrder
    parameters:
    - name: customerId
    in: query
    required: true
    schema:
    type: string
    - name: total
    in: query
    required: true
    schema:
    type: number
    Why:

    The fields that mutate state are passed as query parameters. State-changing input belongs in the request body, where it is not exposed in URIs, logs, or browser history.

    1. Collect every POST (Create) and PUT/PATCH (Update) operation in the spec.

    2. For each, list its parameters where in: query.

    3. Determine whether any query parameter supplies a value that mutates resource state rather than shaping the response (such as filtering or pagination).

    4. Report any Create or Update operation that takes state-changing input through a query parameter instead of the request body.

  3. Query parameters must not be required.

    parameters:
    - name: status
    in: query
    required: false
    schema:
    type: string
    Why:

    The parameter is optional, so the request stays valid when the parameter is omitted.

    parameters:
    - name: status
    in: query
    required: true
    schema:
    type: string
    Why:

    A required query parameter forces every caller to supply it, turning an optional refinement into a mandatory part of the contract.

    1. Enumerate every parameter in the spec where in: query, both on path items and on individual operations.

    2. For each, read its required field.
    3. Report any query parameter whose required is true.

  4. API Producers should document the possible length of query parameter values.

    parameters:
    - name: tag
    in: query
    required: false
    description: A label to filter by. Up to 64 characters.
    schema:
    type: string
    maxLength: 64
    Why:

    The bound on the value is stated in the description and pinned with maxLength, so a consumer knows what the server will accept before sending a request.

    parameters:
    - name: tag
    in: query
    required: false
    schema:
    type: string
    Why:

    Nothing states how long the value may be, so a consumer cannot tell whether a long value will be accepted or rejected.

    1. Enumerate every parameter where in: query.
    2. For each, check whether the description or schema documents a bound on the value length.

    3. Report any query parameter whose value length is left undocumented.

  5. For string query parameters, API Producers should document the maximum allowed length of the value.

    parameters:
    - name: search
    in: query
    required: false
    schema:
    type: string
    maxLength: 256
    Why:

    maxLength makes the upper bound on a string value machine-readable, so validators and generated clients enforce it without prose.

    parameters:
    - name: search
    in: query
    required: false
    schema:
    type: string
    Why:

    A string query parameter with no maxLength declares no upper bound, so tooling cannot validate the size of the value.

    1. Enumerate every parameter where in: query whose schema.type is string.

    2. For each, check whether schema.maxLength is set.

    3. Report any string query parameter that omits maxLength.

  6. The number of distinct query parameters for a method must not exceed 10. A high number of query parameters can lead to performance issues, and some browsers and servers limit URI length.

    1. For each operation, collect its in: query parameters, including any inherited from the path item.

    2. Count the distinct parameter names.
    3. Report any operation whose count exceeds 10.

Formatting

  1. Query parameters must be provided in the URI. The query component starts with the first question mark (?) character and is terminated by the number sign (#) character, or by the end of the URI.

  2. Query parameters must be formatted as key-value pairs and separated with an ampersand (&).

    parameters:
    - name: name
    in: query
    schema:
    type: string
    - name: age
    in: query
    schema:
    type: integer
    Why:

    Each value has its own named key, which serializes to standard key=value pairs joined by & (?name=peter&age=25).

    parameters:
    - name: filter
    in: query
    schema:
    type: string
    description: A semicolon-delimited list such as "name:peter;age:25".
    Why:

    Packing several fields into one parameter with a custom delimiter abandons the standard key-value form, so generic tooling cannot parse the individual values.

    1. Enumerate every parameter where in: query.
    2. For each, check whether the description or schema relies on a custom delimiter to encode multiple values in a single parameter.

    3. Report any query parameter that bundles multiple fields instead of using one key-value pair per value.

Array Query Parameters

Array query parameters are query parameters that accept a list of values.

  1. Array query parameters must be provided by repeating the key and value of the parameter, for each value in the list.

    parameters:
    - name: name
    in: query
    explode: true
    style: form
    schema:
    type: array
    items:
    type: string
    Why:

    With style: form and explode: true, each item repeats the key (?name=peter&name=linda&name=sam), which is the standard array serialization.

    parameters:
    - name: name
    in: query
    explode: false
    style: form
    schema:
    type: array
    items:
    type: string
    Why:

    With explode: false the values collapse into one comma-joined key (?name=peter,linda,sam) instead of a repeated key per value.

    1. Enumerate every parameter where in: query whose schema.type is array.

    2. For each, check that style is form and explode is true (the default for form), so each value repeats the key.

    3. Report any array query parameter whose serialization collapses the values into a single key.

  2. API Producers must document which query parameters accept array values.

    parameters:
    - name: tag
    in: query
    description: Filters by one or more tags. Repeat the key for each tag.
    schema:
    type: array
    items:
    type: string
    Why:

    The schema declares type: array and the description states that the parameter takes multiple values, so the array nature is explicit.

    parameters:
    - name: tag
    in: query
    description: Filters by tag.
    schema:
    type: string
    Why:

    The parameter is meant to accept several tags, but it is typed as a single string with no mention of accepting a list, leaving the array behavior undocumented.

    1. Enumerate every parameter where in: query.
    2. Identify the parameters intended to accept multiple values, from the description, name, or example.

    3. Confirm each such parameter is declared with schema.type: array.

    4. Report any parameter that accepts a list of values but is not documented as an array.

  3. API Producers must document the maximum number of array items using the maxItems property.

    parameters:
    - name: tag
    in: query
    schema:
    type: array
    maxItems: 20
    items:
    type: string
    Why:

    maxItems makes the cap on the number of values machine-readable, so validators reject oversized lists without prose.

    parameters:
    - name: tag
    in: query
    schema:
    type: array
    items:
    type: string
    Why:

    The array parameter declares no maxItems, so there is no documented limit on how many values a caller may send.

  4. The maxItems property must not exceed 20.

  5. Empty arrays must be handled gracefully, i.e. not cause an error response.

    paths:
    /projects:
    get:
    operationId: listProjects
    parameters:
    - name: tag
    in: query
    schema:
    type: array
    items:
    type: string
    responses:
    "200":
    description: The full, unfiltered list when no tag is supplied.
    Why:

    An empty tag array is treated as "no filter" and returns a normal 200, so the caller is not penalized for sending an empty list.

    paths:
    /projects:
    get:
    operationId: listProjects
    parameters:
    - name: tag
    in: query
    schema:
    type: array
    items:
    type: string
    responses:
    "400":
    description: Returned when tag is present but empty.
    Why:

    An empty array triggers a 400, so a value that should be a harmless no-op becomes a client error.

    1. Identify the array query parameters on each operation.

    2. Inspect the handler source or runtime behavior to determine how an empty array is processed, since the spec alone does not capture it.

    3. Confirm that an empty array yields a successful response rather than a validation error.

    4. Report any operation that returns an error response when an array query parameter is empty.

Filtering & Searching

Query parameters can be used to filter or search responses by specific field values.

  1. Filtering should be implemented using query parameters, for example /projects?name=project1.

    paths:
    /projects:
    get:
    operationId: listProjects
    parameters:
    - name: name
    in: query
    schema:
    type: string
    Why:

    The filter is expressed as a query parameter on the collection, keeping the path a plain resource collection.

    paths:
    /projects/by-name/{name}:
    get:
    operationId: getProjectByName
    parameters:
    - name: name
    in: path
    required: true
    schema:
    type: string
    Why:

    Encoding the filter as a dedicated path segment invents a new endpoint per filter field, where a single query parameter on the collection would do.

    1. Identify the operations that filter a collection by field value.

    2. For each, check whether the filter is expressed as a query parameter rather than a dedicated path segment or a custom endpoint.

    3. Report any filtering behavior implemented through path segments instead of query parameters.

  2. Filtering and searching may be implemented for:

  3. Filtering and searching must not be implemented for Get, Create, Update, and Delete Methods.

    paths:
    /projects/{projectId}:
    get:
    operationId: getProject
    parameters:
    - name: projectId
    in: path
    required: true
    schema:
    type: string
    Why:

    A Get addresses one resource by its identifier and exposes no filtering or search parameters, which belong on list or retrieval custom methods.

    paths:
    /projects/{projectId}:
    get:
    operationId: getProject
    parameters:
    - name: projectId
    in: path
    required: true
    schema:
    type: string
    - name: status
    in: query
    schema:
    type: string
    Why:

    A Get targets a single resource, so a filtering parameter has nothing to filter and muddies the method's contract.

    1. Collect the Get, Create, Update, and Delete operations in the spec.

    2. For each, inspect its in: query parameters for any that filter or search results.

    3. Report any Get, Create, Update, or Delete operation that exposes a filtering or searching query parameter.

Further Reading