# Series

The workhorse endpoint. One call pattern covers every time series in the catalog: exchange rates, KIBOR, CPI, reserves, GDP, Raast, telecom and the rest.

## `GET /v1/series/{series_id}` (key required)

| Param | Type | Default | Notes |
|---|---|---|---|
| `from` | date | - | Earliest observation date, inclusive. On Free/Developer it is raised to your history floor |
| `to` | date | - | Latest observation date, inclusive |
| `dims` | string | - | Dimension filter `key:value`, comma-separated for several, e.g. `side:offer` or `city:karachi` |
| `limit` | int | 1000 | 1-10000 |
| `sort` | `asc`\|`desc` | `desc` | By date. With `desc` + `limit` you get the **most recent** N points |
| `format` | `json`\|`csv` | `json` | CSV is formula-injection-safe |
| `transform` | string | - | `yoy`, `mom`, `pct_change`, `3ma`, `index`, computed server-side ([Transforms](https://pakdatahub.com/docs/api-transforms.md)) |
| `vintage` | date | - | Pro/Business: values as first recorded on that date ([Vintages](https://pakdatahub.com/docs/api-vintages.md)) |

```bash
curl -H "X-API-Key: pk_live_xxx" \
  "https://api.pakdatahub.com/v1/series/rates.kibor.3m?dims=side:offer&limit=2"
```

```json
{
  "success": true,
  "series": "rates.kibor.3m",
  "meta": { "name": "KIBOR 3-Month", "unit": "percent", "frequency": "daily",
            "source": "SBP", "last_updated": "2026-09-24", "transform": null },
  "data": [
    { "date": "2026-09-24", "value": 11.75, "dims": { "side": "offer" } },
    { "date": "2026-09-23", "value": 11.75, "dims": { "side": "offer" } }
  ],
  "pagination": { "next_cursor": null, "count": 2 }
}
```

### Response fields

| Field | Type | Meaning |
|---|---|---|
| `series` | string | The requested id |
| `meta.name` | string | Human-readable name |
| `meta.unit` | string | Unit after any transform (e.g. `percent` for `yoy`) |
| `meta.frequency` | string | `daily`, `weekly`, `monthly`, `quarterly`, `half_yearly`, `annual`, `irregular` |
| `meta.source` | string | `SBP`, `PBS`, `PTA`, `MUFAP` |
| `meta.last_updated` | date | Date of the newest observation we hold |
| `meta.transform` | string\|null | Echo of the applied transform |
| `data[].date` | date | Observation date (month-end for monthly, quarter-end for quarterly) |
| `data[].value` | number\|null | The value; `null` where a transform has no partner point |
| `data[].dims` | object | Dimension tags, e.g. `{"side":"offer"}`, `{"city":"lahore"}` |
| `pagination.count` | int | Rows returned. `next_cursor` is always `null`; page by date with `from`/`to` |

### CSV

```bash
curl -H "X-API-Key: pk_live_xxx" \
  "https://api.pakdatahub.com/v1/series/fx.rate.avg.usd?format=csv&limit=3"
```

```
series,date,value,dims
fx.rate.avg.usd,2026-08-31,277.9187406,{}
fx.rate.avg.usd,2026-07-31,278.2380682,{}
fx.rate.avg.usd,2026-06-30,278.5795536,{}
```

The content type is `text/csv; charset=utf-8`. This works directly with `pandas.read_csv(url + "&api_key=...")`, Excel "From Web" and Google Sheets `IMPORTDATA`.

### Paging long histories

`limit` goes up to 10,000, which covers every monthly and quarterly series in one call. For long daily series, window by date:

```python
import httpx
key = {"X-API-Key": "pk_live_xxx"}
url = "https://api.pakdatahub.com/v1/series/rates.pkrv.10y"
rows = []
for year in range(2022, 2027):
    r = httpx.get(url, params={"from": f"{year}-01-01", "to": f"{year}-12-31",
                               "sort": "asc", "limit": 10000}, headers=key)
    rows += r.json()["data"]
```

## `GET /v1/series/{series_id}/latest` (key required)

The newest observation, and one row per dimension when the series has dimensions (e.g. both KIBOR bid and offer). It's cached server-side, so it's cheap and ideal for tickers and dashboards. It accepts `dims` (e.g. `dims=side:offer` for one row instead of every side) and `format=csv`.

```bash
curl -H "X-API-Key: pk_live_xxx" \
  "https://api.pakdatahub.com/v1/series/fx.rate.avg.usd/latest"
```

```json
{ "success": true, "series": "fx.rate.avg.usd",
  "meta": { "name": "Average Exchange rate of Pak Rupees per U.S. Dollar", "unit": "pkr",
            "frequency": "monthly", "source": "SBP", "last_updated": "2026-08-31", "transform": null },
  "data": [ { "date": "2026-08-31", "value": 277.9187406, "dims": {} } ],
  "pagination": { "next_cursor": null, "count": 1 } }
```

## Errors

- `404`: unknown series id. Check with [`/v1/search`](https://pakdatahub.com/docs/api-search.md).
- `422`: bad date, bad `dims` token (it must be `key:value`), unknown transform, or a transform that doesn't fit the frequency.
- `403`: `vintage` on a plan below Pro.

## Popular ids

`fx.rate.avg.usd` - `fx.effective.reer` - `rates.kibor.3m` - `rates.policy` - `rates.pkrv.10y` - `inflation.cpi.national.yoy` - `inflation.cpi.urban.food` - `remittances.total` - `reserves.total_sbp_reserves` - `banking.m2` - `industry.lsm.qim` - `payments.raast.total.value` - `telecom.subscribers.cellular.total` - `sme.npl_ratio`. See the [data dictionary](https://pakdatahub.com/docs/data-dictionary.md) for more.

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