> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ellomas.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Working with JSON

> JSONPath expressions for extraction and assertions in Replay workflows.

# Working with JSON

JSONPath is the query language used across Replay for extracting values from responses and targeting assertion paths.

## JSONPath Basics

JSONPath expressions navigate JSON structures:

```yaml theme={null}
extract:
  user_id: $.data.id
```

| Expression    | Description                   |
| ------------- | ----------------------------- |
| `$`           | Root object                   |
| `.field`      | Dot-notation child access     |
| `[n]`         | Array index                   |
| `[*]`         | Array wildcard (all elements) |
| `..`          | Deep scan (recursive descent) |
| `[start:end]` | Array slice                   |

## Shorthand Syntax

Replay accepts several shorthand forms:

```yaml theme={null}
# Full JSONPath
extract:
  token: $.data.token

# Without leading $
extract:
  token: data.token

# With res. prefix (matches HTTP response structure)
extract:
  status_code: res.status
```

## Common Patterns

### Nested Fields

```yaml theme={null}
extract:
  city: $.user.address.city
  org_name: $.data.organization.name
```

### Array Access

```yaml theme={null}
extract:
  first_item: $.data.items[0]
  third_item: $.data.items[2]
  last_item: $.data.items[-1]
```

### Array Wildcards

```yaml theme={null}
extract:
  all_names: $.data.users[*].name
  all_prices: $..price
```

### Array Slices

```yaml theme={null}
extract:
  first_two: $.data.items[0:2]
  from_third: $.data.items[2:]
```

## In HTTP Steps

The HTTP response is structured as:

```json theme={null}
{
  "status": 200,
  "data": { ... },
  "header": { ... }
}
```

Target each part:

```yaml theme={null}
extract:
  status_code: res.status               # HTTP status code
  response_body: $.data                 # Parsed JSON body
  content_type: res.header.Content-Type[0]  # Response header
```

## In Database Steps

PostgreSQL results are arrays of row objects:

```json theme={null}
[
  { "id": 1, "name": "Alice" },
  { "id": 2, "name": "Bob" }
]
```

```yaml theme={null}
extract:
  first_name: $[0].name
  all_ids: $[*].id
```

## In Shell Steps

Shell stdout is parsed as JSON if possible:

```yaml theme={null}
- name: generate
  type: shell
  command: 'echo "{\"result\": {\"id\": 42, \"status\": \"ok\"}}"'
  extract:
    item_id: $.result.id
```

If the output is not valid JSON, use `$` to grab the raw string:

```yaml theme={null}
extract:
  raw_output: $
```

## Assertions with JSONPath

```yaml theme={null}
assert:
  - ["$.status", "eq", 200]
  - ["$.data.email", "contains", "@"]
  - ["$.data.items", "not_null"]
  - ["$.data.count", "gt", 0]
  - ["$[0].name", "eq", "Alice"]
```

## Debugging JSONPath

Enable debug mode to see the full response structure:

```yaml theme={null}
config:
  http:
    debug: true
```

This prints the request and response to the terminal, making it easy to find the right path.

## What's Next?

* Integrate with [CI/CD pipelines](/replay/guides/ci-cd-integration)
* Explore [real-world use cases](/replay/guides/use-cases)
