# Transforms

Add `?transform=` to [`/v1/series/{id}`](https://pakdatahub.com/docs/api-series.md) and the API computes the transform for you. Your numbers then match everyone else's, and you don't have to fetch extra history to do it yourself.

| `transform` | Meaning | Allowed frequencies | Output unit |
|---|---|---|---|
| `yoy` | Year-over-year % change: value vs the same date one year earlier | daily, weekly, monthly, quarterly | `percent` |
| `mom` | Month-over-month % change | monthly only | `percent` |
| `pct_change` | % change vs the previous observation | any | `percent` |
| `3ma` | Trailing 3-period moving average | any | source unit |
| `index` | Rebased to 100 at the first observation **in your window** | any | `index` |

```bash
curl -H "X-API-Key: pk_live_xxx" \
  "https://api.pakdatahub.com/v1/series/inflation.cpi.national?transform=yoy&limit=2"
```

```json
{ "success": true, "series": "inflation.cpi.national",
  "meta": { "name": "CPI National", "unit": "percent", "frequency": "monthly",
            "source": "PBS", "last_updated": "2026-06-30", "transform": "yoy" },
  "data": [ { "date": "2026-06-30", "value": 11.090083270249806, "dims": {} },
            { "date": "2026-05-31", "value": 11.64643399089529, "dims": {} } ],
  "pagination": { "next_cursor": null, "count": 2 } }
```

## Rules

- **Partners are fetched for you.** `yoy`, `mom`, `pct_change` and `3ma` look back before your `from` date and outside your `limit`, so every returned point has its partner. A point is `null` only where no earlier observation exists at all (e.g. the first year of a series).
- **Per dimension.** Transforms run separately for each `dims` group (KIBOR bid and offer, each SPI city).
- **`index` uses your window.** It rebases to 100 at the first point you get back, so pick `from` deliberately:

```bash
# Rupee depreciation since 2018, as an index
curl -H "X-API-Key: pk_live_xxx" \
  "https://api.pakdatahub.com/v1/series/fx.rate.avg.usd?from=2018-01-01&transform=index&sort=asc"
```

- **Mismatches fail loudly.** `mom` on a quarterly series, or `yoy` on an annual one, returns `422 invalid_params` with a message suggesting `pct_change`.
- Transforms combine with `vintage`, `dims`, `format=csv` and `sort`.

## Recipes

| Question | Call |
|---|---|
| Headline inflation from the index | `/v1/series/inflation.cpi.national?transform=yoy` |
| Monthly change in FX reserves | `/v1/series/reserves.total_sbp_reserves?transform=mom` |
| Remittance growth vs a year ago | `/v1/series/remittances.total?transform=yoy` |
| Smoothed LSM | `/v1/series/industry.lsm.qim?transform=3ma` |
| Compare currencies on one axis | `fx.rate.avg.usd`, `fx.rate.avg.eur` with `transform=index&from=2015-01-01` |
| Raast quarter-on-quarter growth | `/v1/series/payments.raast.total.value?transform=pct_change` |

---
Source: https://pakdatahub.com/docs/api-transforms - PakDataHub docs index: https://pakdatahub.com/docs/llms.txt
