TidyURLs
Go to Tools
BLOG
The TidyURLsJournal

Practical guides, tutorials, and insights about URLs, SEO, web development, and online marketing. Learn, troubleshoot, and get the most of the web.

Back to the Journal
TidyURLs Journal

How to Represent Arrays in API Query Parameters

Practical insights, clear explanations, and useful ideas for understanding the web.

October 28, 20266 min read5 topics
How to Represent Arrays in API Query Parameters
Explore the details
#API design#OpenAPI#HTTP#query parameters#backend development
October 28, 20266 min read

APIs commonly represent a list in a query string using repeated keys, comma-separated values, or bracketed names. Each can work, but clients and server parsers do not always interpret them the same way. This guide compares the formats, explains how OpenAPI describes common serialization styles, and highlights edge cases to settle in your API contract.

Key Takeaways

  • Repeated keys, such as tag=red&tag=blue, are usually the clearest choice when values can contain commas.
  • Comma-separated values, such as tag=red,blue, are compact but require an explicit rule for commas inside values.
  • Bracketed names, such as tag[]=red&tag[]=blue, are a parser convention, not a universal array format.
  • Specify what an omitted parameter and an empty list mean, how duplicates and order work, and how values are encoded.
  • OpenAPI can describe repeated-key and comma-separated arrays; confirm that your framework and generated clients implement the contract as intended.

Three common array query formats

Suppose an endpoint accepts a list of tags. Here are three ways to request the same two values:

GET /articles?tag=red&tag=blue
GET /articles?tag=red,blue
GET /articles?tag[]=red&tag[]=blue

Repeated keys

With repeated keys, each value gets its own occurrence of the parameter:

?tag=red&tag=blue

This format maps naturally to an ordered list of query pairs. It avoids using a comma as a special delimiter, so it is a good default when values might themselves contain commas. The server still needs to use a parser that preserves repeated values; some APIs or application layers instead keep only one value or reject duplicates.

Comma-separated values

A comma-separated representation puts the list into one parameter value:

?tag=red,blue

It is compact and familiar, but the contract must define how to distinguish a list separator from a comma that belongs to a value. For example, a value of north,east could mean one item or two unless escaping and decoding rules are clear.

Percent-encoding a comma as %2C may help only if both sides agree on the order of splitting and decoding. A parser that decodes the whole parameter before splitting can turn an encoded comma into a separator. Test the actual client and server combination rather than assuming that encoding alone removes the ambiguity.

Bracketed names

Some parsers use bracketed parameter names to signal arrays:

?tag[]=red&tag[]=blue

This is a convention rather than a universal query-string rule. Other implementations may treat tag[] as the literal parameter name, or require a different bracketed form. If you choose it, document the exact parameter name and check support in client generators, gateways, and server parsers.

How OpenAPI describes array serialization

OpenAPI query parameters use a serialization style and an explode setting to describe how values are represented. For a query array, the commonly used form style with explode: true represents separate values as repeated keys. With explode: false, values are joined with commas.

For example, an OpenAPI 3.x parameter can describe repeated keys like this:

parameters:
  - name: tag
    in: query
    required: false
    style: form
    explode: true
    schema:
      type: array
      items:
        type: string

For comma-separated values, set explode: false instead:

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

For form parameters, OpenAPI's default for explode is true, but spelling it out makes the intended wire format easier to review. OpenAPI can describe serialization; it does not guarantee that every framework, gateway, or generated client will parse or produce it identically. Bracketed naming should not be assumed to follow the same behavior: document it explicitly if your API uses it.

Documentation limitation: Live retrieval of the OpenAPI specification and framework documentation was not available while preparing this article. The examples describe common OpenAPI serialization conventions, but check the specification and documentation for the exact versions of the tools in your stack before relying on their defaults.

Edge cases to define in the contract

CaseWhat can go wrongA useful contract decision
Empty arrayNo parameter occurrence is indistinguishable from an omitted parameter in common formats.Say whether omission means an empty list, no filter, or a default. If clients must distinguish these states, define an explicit representation or use a request body.
Empty value?tag= may mean one empty string, a missing value, or invalid input—not necessarily an empty list.Define whether empty items are accepted, ignored, or rejected.
Comma inside a valueA CSV parser may mistake it for a list separator.Prefer repeated keys, or specify escaping and the exact split/decode behavior.
Repeated valuesA parser might preserve all occurrences, keep only one, or reject duplicates.Specify whether duplicates are meaningful and test the deployed parser.
OrderingQuery parameters are often treated as unordered, while repeated values may arrive in a particular sequence.State whether array order matters. If it does, require clients and intermediaries to preserve repeated-value order.

A practical check with the platform URLSearchParams API illustrates why repeated values need an explicit multi-value read:

const params = new URLSearchParams("tag=red&tag=blue");

console.log(params.get("tag"));    // "red" — gets one value
console.log(params.getAll("tag")); // ["red", "blue"] — gets every occurrence

Do not assume that every framework exposes the same interface or defaults. Verify how your chosen framework parses duplicate keys, bracketed names, empty values, and percent-encoded characters. Include those cases in integration tests against the actual HTTP stack, not just a hand-written parsing helper.

Choosing a format

For most list-valued filters, repeated keys are a good starting point:

GET /products?category=books&category=games

They make each value visible and avoid delimiter collisions. Choose comma-separated values when compactness or compatibility with an existing API matters and your contract defines how embedded commas are handled. Choose bracketed names only when your framework ecosystem already expects that convention and the API description makes it unambiguous.

Before publishing an endpoint, write down examples for one value, multiple values, no values, an empty value, duplicate values, and a value containing a reserved or delimiter character. Check that your OpenAPI description, server parser, generated clients, and documentation all agree on those examples.

Common Mistakes

  • Treating bracket notation as a standard that every server understands.
  • Assuming ?tag= represents an empty array.
  • Splitting on commas without defining how a comma inside an item is represented.
  • Reading only one value from a repeated parameter when the endpoint expects a list.
  • Assuming list order or duplicate handling without specifying it.
  • Documenting one serialization style in OpenAPI while implementing another in the server.

Best Practices

  • Pick one representation per parameter and document it with concrete request URLs.
  • Prefer repeated keys when values can contain the proposed delimiter.
  • Define omission, empty values, duplicates, and ordering explicitly.
  • Test parsing and encoding through the complete client-to-server path, including any gateway or proxy that may normalize query strings.
  • Keep the API description and implementation aligned; do not rely on undocumented framework defaults.

Conclusion

There is no single query-array format that every API stack interprets identically. Repeated keys are often the least ambiguous choice, while CSV and bracket notation can be appropriate when their parsing rules are part of a clear, tested contract.