Use query parameters when the request is a read operation and the filter is part of the resource lookup, such as fetching a user by id. Use the request body when the client is sending data to create, update, or delete records. That separation keeps handlers easier to test, aligns with HTTP semantics, and reduces ambiguity in how the endpoint should behave.
Why the split between query parameters and request bodies matters
API shape is not just a syntax choice, it defines how a client and server communicate intent. Query parameters work best when they refine a retrieval, because they make the lookup visible in the URI and fit naturally with caching, bookmarking, and observability. Request bodies are better when the client is submitting state changes or structured payloads that are too large or complex for the URI.
That distinction also reduces accidental ambiguity for maintainers. When a handler accepts read filters in the query string and write data in the body, it becomes easier to tell which inputs are part of selection logic and which are part of business state. The result is fewer edge cases around validation, routing, and whether an endpoint is truly safe to repeat.
For security and reliability work, this clarity matters because the input location often affects how proxies, gateways, logs, and middleware treat the request. A query string is commonly exposed in access logs and monitoring tools, so sensitive data should not be placed there by default. A body is usually the better home for data that should not be indexed as part of the request target or reused as a lookup hint.
Where query parameters are the better fit
Use query parameters when the client is asking the server to narrow or shape a retrieval, not when it is changing the underlying resource. Common examples include pagination, sorting, field selection, date ranges, and resource lookup by an identifier. That keeps the endpoint aligned with HTTP semantics and makes the resource address easier to reason about.
Query parameters are also valuable when the parameter belongs to the concept of retrieval itself. If the question is “which records match these conditions?”, the query string is usually the most natural place to express that filter. This is especially useful when the same endpoint serves multiple read variants and the differences are about selection, not payload content.
They are less suitable when the data is large, nested, or semantically part of an object you are creating or updating. At that point, the body communicates the shape of the submitted state much more clearly, and it avoids URI length limits and awkward encoding rules.
Where the request body is the better fit
Use the request body when the client is sending a representation of data to create, update, or delete records. The body is the right place for structured content, complex nested objects, and fields that belong to the state transition rather than the lookup key. That separation is what lets an endpoint express intent cleanly instead of mixing selection and mutation in the same surface.
The body also gives you more room for validation and schema enforcement. If the endpoint accepts write data, the server can validate required fields, types, and business rules against a coherent payload instead of reconstructing meaning from multiple query values. That is easier to test and much easier to document.
As a practical matter, teams should avoid putting secrets or high-sensitivity data into query parameters. Query strings are more likely to appear in browser history, reverse-proxy logs, analytics tooling, and shared traces. When the data is meant to be submitted, not used as part of a bookmarkable lookup, the body is normally the safer default.
Standards & Framework Alignment
This section maps relevant standards and security frameworks to the operational risks and controls described in this guidance.
CIS Controls v8 and NIST CSF 2.0 set the governance and control requirements practitioners need to meet.
| Framework | Control / Reference | Relevance |
|---|---|---|
| CIS Controls v8 | CIS 13 — Data Protection | Query strings can expose sensitive data in logs and telemetry. |
| Recommendation — Keep sensitive request data out of URLs and apply data protection controls to API inputs. | ||
| NIST CSF 2.0 | PR.DS — Data Security | Separating lookup data from body payloads reduces accidental disclosure and handling ambiguity. |
| Recommendation — Classify and handle request data by sensitivity before deciding where it belongs. | ||
Practitioner Guidance
What to prioritise: Decide first whether the endpoint is performing lookup or mutation. If the parameter changes which resource is selected, put it in the query string; if it changes the resource itself, put it in the body. That rule prevents most API design drift before it starts.
What to verify: Check that the chosen location matches how the endpoint will be cached, logged, retried, and documented. If a field could expose sensitive information or create confusion when replayed, it usually does not belong in the query string.
Common mistake: Teams often move data into the query string because it is convenient for debugging or because the endpoint “still works” that way. Convenience is not a good design rule for mutable data, especially once clients, gateways, and audit tooling start depending on the shape of the request.
Practitioner takeaway: Use the URI to identify or filter the thing you want, and use the body to describe the thing you want to create or change. That keeps API contracts predictable, testable, and less likely to leak or misclassify data.
Related resources from NHI Mgmt Group
- How should teams reduce risk from API endpoints tied to identity data?
- When should teams prioritise identity data cleanup over new IAM features?
- When should teams prioritise request-path controls over more AI dashboards?
- How should teams govern API access when regulated data is exposed through endpoints?