---
title: "Extract Values with the keys Syntax"
slug: extract-values-with-keys
type: how-to
plugin: huxx-connect
summary: "Pull exactly the values you need out of an API response using dot paths, brace lists, and the [] wildcard — worked against a real DummyJSON response."
keywords: [keys, dot notation, extraction, wildcard, brace notation]
version_added: 1.2.5
version_updated: 1.2.5
level: intermediate
related: [keys-syntax, display-data-with-shortcodes, use-template-functions]
---

The `keys` syntax turns a whole API response into just the values you want to display. It works identically in the shortcode's `keys` attribute and in the `keys` runtime argument of [`huxx_api()`](/docs/connect/how-to/use-template-functions/) — with one exception: the `[]` wildcard is PHP-only, because WordPress ends a shortcode at the first `]`. This page works every pattern against the same live response; the formal rules are in the [keys Syntax Reference](/docs/connect/reference/keys-syntax/).

> **Quick version:**
>
> ```
> keys="products.0.title"                        → single value
> keys="{products.0.title},{products.0.price}"   → several values, keyed by path
> keys="products.[].title"                       → that value from every list item (PHP only)
> keys="products.[].reviews.[].rating"           → nested wildcards, flattened (PHP only)
> ```

## The response we're extracting from

All examples below run against the DummyJSON demo configuration (API `demo_api`, [endpoint](/docs/connect/explanation/glossary/#endpoint) `get_products`, GET `https://dummyjson.com/products`), which returns:

```json
{
    "products": [
        { "id": 1, "title": "Essence Mascara Lash Princess", "price": 9.99, "category": "beauty" },
        { "id": 2, "title": "Eyeshadow Palette with Mirror", "price": 19.99, "category": "beauty" }
    ],
    "total": 194,
    "skip": 0,
    "limit": 30
}
```

<details>
<summary><strong>New to APIs? Read this first</strong></summary>

JSON responses nest lists inside objects inside lists. A dot path is just directions for walking down that nesting, one level per dot. [How HuxxConnect Works](/docs/connect/explanation/how-huxxconnect-works/) explains the request-to-response flow.

</details>

## Extract one value with a dot path

Each dot moves one level deeper. List positions are numeric and start at `0`.

Shortcode:

```
[huxx_api api_id="demo_api" endpoint_id="get_products" keys="products.0.title"]
```

PHP:

```php
<?php
$title = huxx_api( 'demo_api', 'get_products', array( 'keys' => 'products.0.title' ) );
echo esc_html( $title );
```

Output:

```
Essence Mascara Lash Princess
```

A path that doesn't exist in the response returns `null` — the shortcode renders it as `null` inside the response `<pre>` block so you can see the miss.

## Extract several values with a brace list

Wrap each path in `{ }` and separate with commas. The result is an associative array keyed by the full dot path, so you always know which value came from where.

Shortcode:

```
[huxx_api api_id="demo_api" endpoint_id="get_products" keys="{products.0.title},{products.0.price}"]
```

PHP:

```php
<?php
$values = huxx_api( 'demo_api', 'get_products', array(
    'keys' => array( 'products.0.title', 'products.0.price' ),
) );
echo esc_html( $values['products.0.title'] );
```

Shortcode output:

```json
{
    "products.0.title": "Essence Mascara Lash Princess",
    "products.0.price": 9.99
}
```

Paths that resolve to `null` are omitted from a multi-key result rather than included as empty entries. Bare comma lists without braces (`keys="products.0.title,products.0.price"`) parse the same way; the brace form is preferred because it stays unambiguous.

## Extract from every list item with `[]`

A `[]` segment fans out across all items of a list, applies the rest of the path to each one, and flattens the results into a single array.

> **Warning:** `[]` cannot be used inside a shortcode attribute. WordPress ends a shortcode at the first `]` it finds, so `keys="products.[].title"` cuts the tag off mid-attribute and the keys path is never applied. Use the PHP `huxx_api()` function for wildcard paths.

PHP:

```php
<?php
$titles = huxx_api( 'demo_api', 'get_products', array( 'keys' => 'products.[].title' ) );
foreach ( $titles as $title ) {
    echo '<li>' . esc_html( $title ) . '</li>';
}
```

`$titles` (truncated):

```json
[
    "Essence Mascara Lash Princess",
    "Eyeshadow Palette with Mirror"
]
```

Wildcards nest: each product in the DummyJSON response carries a `reviews` list, so `products.[].reviews.[].rating` collects every rating from every product into one flat array. A `[]` only fans out over sequential lists — applying it to a keyed object returns `null`.

## Choose string or array form in PHP

In PHP, `keys` accepts either the same string the shortcode uses (braces and all) or a plain array of paths:

```php
<?php
// String form — parsed exactly like the shortcode attribute.
$one  = huxx_api( 'demo_api', 'get_products', array( 'keys' => '{products.0.title}' ) );

// Array form — no parsing; each entry is a dot path.
$many = huxx_api( 'demo_api', 'get_products', array( 'keys' => array( 'total', 'limit' ) ) );
```

Output:

```
$one  = "Essence Mascara Lash Princess"
$many = [ 'total' => 194, 'limit' => 30 ]
```

A single-entry array behaves like a single string path: it returns the raw value, not a one-entry array. Extraction only runs when the response is an array — endpoints whose Results Format is `JSON String` or `Raw` return text, and `keys` is skipped.

## If it didn't work

- **The result is `null`.** The path doesn't match the structure. Render the response without `keys` first, then rebuild the path level by level — remember list indexes are numeric and the wrapper key (here `products`) counts as a level.
- **A multi-key result is missing one of the paths.** That path resolved to `null` (missing key, or a key whose value is literally `null`) and was dropped. Check the spelling of that one path against the raw response.
- **`[]` returns `null` even though the data is there.** The segment before `[]` points at a keyed object, not a list. Move the `[]` to the level that is actually a sequential list (e.g. `products.[]`, not `[].products`).
