---
title: Send Query, Header, and Body Parameters
slug: send-query-header-and-body-parameters
type: how-to
plugin: huxx-connect
summary: Configure query, header, and body parameters at the API and endpoint level, and understand which value wins when the same key is set in more than one place.
keywords: [query parameters, headers, body parameters, precedence, overrides]
version_added: 1.2.5
version_updated: 1.2.5
level: intermediate
related: [choose-a-body-format, use-path-variables, authenticate-with-an-api-key, debug-api-requests]
---

Every request HuxxConnect sends can carry three kinds of parameters: query parameters (in the URL), headers, and body parameters (POST/PUT/PATCH only). Each kind can be set at the [API](/docs/connect/explanation/glossary/#api) level, at the [endpoint](/docs/connect/explanation/glossary/#endpoint) level, and at runtime — with a fixed precedence when they collide.

> **Quick version:**
> 1. API screen → **Default Headers** / **Default Query Parameters** / **Default Body Parameters**: sent with every request to that API.
> 2. Endpoint editor → **Headers** / **Query Parameters** / **Body Parameters**: sent for that endpoint; same key overrides the API-level default.
> 3. Runtime overrides beat both: `query_variables`, `header_variables`, `body_variables` in PHP args; `query_variables`, `body_variables`, `body_json` shortcode attributes.
> 4. Precedence, lowest → highest: **API → endpoint → runtime** (verified in `src/Http/RequestBuilder.php`).

## Where each parameter lives

**API level** — on the API detail screen, three collapsible sections apply to every endpoint of the API: **Default Headers**, **Default Query Parameters**, and **Default Body Parameters**. Use these for values every request needs, such as a version header or a `format=json` query key. Default body parameters are included only in POST, PUT, and PATCH requests and ignored for GET and DELETE.

**Endpoint level** — each endpoint has its own **Headers**, **Query Parameters**, and **Body Parameters** sections. The Body Parameters section appears only when the endpoint's method is POST, PUT, or PATCH.

**Runtime** — a shortcode or PHP call can override individual keys for that one request without touching the saved configuration.

<!-- screenshot-todo: api-detail--endpoint-query-params--two-rows | alt: Endpoint Query Parameters repeater with limit and select rows filled in for the DummyJSON products endpoint -->

:::novice
Query parameters are the `?limit=5&skip=10` part of a URL, headers are metadata sent alongside the request, and the body is the data payload of a write request. [Understanding authentication](/docs/connect/explanation/understanding-authentication/) covers why credentials usually travel in headers.
:::

## Override precedence

For each parameter kind, values merge in this order — later entries win on key collision:

1. API-level defaults
2. Endpoint-level parameters
3. Runtime overrides (`query_variables` / `header_variables` / `body_variables`)

So an endpoint that sets `limit=10` overrides an API default of `limit=30`, and a shortcode passing `query_variables="limit=2"` overrides both. Keys that don't collide combine.

One exception: when an endpoint's body format is **Nested JSON**, API-level Default Body Parameters are not merged in at all — a nested JSON document has no clean merge with flat key-value pairs. Runtime `body_variables` still apply, merged at the top level of the document. See [Choose a body format](/docs/connect/how-to/choose-a-body-format/).

## Example: override a configured query parameter

Configure the demo API's `get_products` endpoint with a Query Parameter row `limit` = `30`, then override it for one placement.

Shortcode:

```
[huxx_api api_id="demo_api" endpoint_id="get_products" query_variables="limit=2,skip=10" keys="total"]
```

Output:

```
194
```

PHP:

```php
$data = huxx_api( 'demo_api', 'get_products', array(
    'query_variables' => array(
        'limit' => 2,
        'skip'  => 10,
    ),
) );

echo count( $data['products'] ) . ' of ' . $data['total'];
```

Output:

```
2 of 194
```

The request URL was `https://dummyjson.com/products?limit=2&skip=10` — the runtime `limit=2` replaced the configured `limit=30`, and `skip=10` was added alongside it.

Runtime headers are PHP-only: pass `'header_variables' => array( 'X-Request-Source' => 'newsletter' )` in the args array. There is deliberately no shortcode attribute for headers — headers commonly carry credentials, and post content is not a trusted place for them.

## Advanced

### Values are type-coerced before sending

Parameter values are stored as strings in the admin UI, but HuxxConnect coerces recognizable patterns to native types so the wire format is correct: `true`/`false` become booleans, `null` becomes null, `42` and `3.14` become numbers, and `["a","b"]` becomes an array. Round-trip checks prevent surprises — `007` stays the string `"007"`, and JSON *objects* (`{"a":1}`) are left as strings.

### Array query parameters

A query value coerced to an array is encoded as repeated keys: `fields` = `["title","price"]` produces `fields[]=title&fields[]=price`. If you name the key `fields[]` yourself (the convention some APIs document), HuxxConnect strips the extra brackets so you still get single-bracket output. A `null` value produces a valueless parameter (`?key` with no `=`).

### Headers vs authentication

Auth [credentials](/docs/connect/explanation/glossary/#credentials) sit outside the precedence chain above. Your configured headers (API → endpoint → runtime) are assembled first, and *then* the auth type applies its credential as an ordinary header or query parameter, overwriting any same-named entry (`src/Http/RequestBuilder.php`). An endpoint header named `Authorization` therefore loses: the auth type's value is what gets sent. To give one endpoint different credentials, use the endpoint's **Authentication Override** section instead of a header row.

The endpoint editor shows a warning on such rows — "This header will override the API authorization." — but the behavior is actually the reverse of what that tooltip says: the auth type wins. Treat a same-named header row as a configuration mistake either way. (The header row does take effect when the API's auth type is None, since there is then no credential to overwrite it.)

## If it didn't work

**Your parameter is sent, but with the wrong value.** Something higher in the precedence chain overrides it. Check runtime attributes first, then the endpoint section, then the API defaults — and confirm the final URL and headers with [Debug API requests](/docs/connect/how-to/debug-api-requests/).

**Body parameters never arrive.** Body parameters are only sent for POST, PUT, and PATCH. If the endpoint's method is GET or DELETE, the body — including API-level Default Body Parameters — is skipped entirely.

**A default body parameter is missing from one endpoint's requests.** If that endpoint uses the Nested JSON body format, API-level Default Body Parameters are intentionally not merged. Add the key to the endpoint's JSON document instead.
