Documentation Index

Fetch the complete documentation index at: https://docs.supermetrics.com/llms.txt

Use this file to discover all available pages before exploring further.

Transforming response structure

Prev Next

Most APIs return JSON in a shape that maps directly to report fields. When an API returns data in a structure that doesn't, you can attach one or more data adapters to a report type's response to reshape the JSON in memory before fields are extracted from it. Common reasons to use such adapters include exploding nested arrays into separate rows, pulling a date key out of an object so it becomes a row value, or pivoting parallel arrays into per-row records.

Data adapters are configured under response.dataAdapters.items on a report type's request. Each entry runs in the order it appears in the array, and each one sees the output of the previous transformation, not the raw API response.

Configuration overview

A data adapter has a type (which adapter to run) and a config (its parameters). Adapters are listed under response.dataAdapters.items:

"response": {
  "dataRows": {
    "source": "jsonPath",
    "value": "$.data.*"
  },
  "dataAdapters": {
    "items": [
      {
        "type": "[adapter type]",
        "config": {
          "dataPath": "[JSONPath]",
          ...
        }
      }
    ]
  }
}

The dataRows JSONPath points at where the data rows are read from – but it is evaluated after all data adapters have run, so it must match the transformed structure, not the original response.

Note: Adapter dataPath, valuesPath, and similar properties always use JSONPath syntax ($.foo.*, $.results.items, etc.).

Available adapters

Adapter Use when
Flatten values The response has nested arrays inside each item that should become separate rows.
Append key The response is an object keyed by a value (commonly a date) that should appear as a field on each row.
Time series The response contains parallel metric arrays (one value per day) that should become one row per date.
Match values by keys The response has a series array and a values map keyed by series — and you need them pivoted into rows.
Combine keys with values The response splits column names and row values into separate arrays (header/row style).
Combine keys with nested values Same idea as combine_keys_with_values, but the adapted data must be merged into an existing row instead of replacing it.
Extract fields by path A field defined once in a metadata section (such as a currency code in headers) needs to be copied onto each row.
Concat value to keys Field names need to be namespaced with another field's value (for example, prefixing amount with charge_ or refund_).
Union nested arrays with key The response has per-category arrays nested under a single object, and you want a single flat report tagged with the category name.
Aggregate values The response has an array of per-segment objects, and you want a single row with totals rather than one row per segment.
Split to rows A single field holds multiple comma-separated values that should become one row each.

Chaining multiple adapters

A single response can be reshaped by several adapters at once — they run in the order they appear under dataAdapters.items, and each adapter sees the result of the previous one rather than the raw response. This means a dataPath that worked on the original JSON often needs to be different on the second or third adapter, because the structure has already changed.

Below you can find a short example. Suppose an API returns a single object with a nested array of items, and each item carries its own nested array of daily breakdowns:

{
  "report": {
    "items": [
      {
        "campaign": "Summer Sale",
        "daily": [
          {
            "date": "2026-05-01",
            "clicks": 12
          },
          {
            "date": "2026-05-02",
            "clicks": 18
          }
        ]
      }
    ]
  }
}

The goal is to produce one row per day, carrying the campaign name. Two adapters get this done — the first extracts the items into the response root, the second explodes the daily breakdowns:

"dataAdapters": {
  "items": [
    {
      "type": "flatten_values",
      "config": {
        "dataPath": "$",
        "valuesPath": "$.report.items.*"
      }
    },
    {
      "type": "flatten_values",
      "config": {
        "dataPath": "$.*",
        "valuesPath": "$.daily.*"
      }
    }
  ]