<!-- https://developers.silktide.com/v1/analytics/audience/get-regions | Analytics / Audience -->

# List the regions within countries that visitors came from

`GET /v1/results/analytics/regions`

Lists the regions within countries that visits came from, such as states, provinces or the nations of the United Kingdom, with each region's visitors and page views, most visitors first. It is a [table](https://developers.silktide.com/v1/concepts/tables.md): choose its columns, sort it, search it by region name, and page through it.

A region code is only unique within its country, so identify a row by `countryCode` and `regionCode` together. To list one country's regions, filter with `filters[countryCode]=is:GB`.

Visits whose region could not be worked out are left out, so the rows can add up to less than [Get countries](https://developers.silktide.com/v1/analytics/audience/get-countries.md) shows for the same country.

With `columns`, a row holds only the columns you name, without its codes unless you name them too. Send `sort` with `columns`, naming one of them. `previousPeriod=1` adds the period before, as it does for countries.

## Request

### Query parameters

- `view` (string, optional, matches `^(all|[1-9]\d*)$`): The analytics view to read: its id, the number after `/analytics/` in its address in Silktide, or `all` for all of the account's analytics. Send this or `websiteId`.
- `websiteId` (integer, optional, at least 1): Instead of `view`, a website whose analytics to read. The website must have Analytics set up.
- `sectionId` (integer, optional): With `websiteId`, a section of the website. Defaults to `0`, the whole website.
- `period` (string, optional): The date range. Defaults to `all`. The spaced forms (`-7 days`, `month to date`) are older names that keep working. `custom` needs `from` and `to`. One of: `all`, `today`, `last-7-days`, `last-30-days`, `last-90-days`, `month-to-date`, `last-month`, `year-to-date`, `last-12-months`, `custom`, `-7 days`, `-30 days`, `-90 days`, `-1 month`, `month to date`, `year to date`, `-12 months`.
- `from` (string, optional): With `period=custom`, the first day, such as `2026-10-01`.
- `to` (string, optional): With `period=custom`, the last day.
- `timezone` (string, optional): The IANA time zone days are read in, such as `America/New_York`. Defaults to `UTC`.
- `filters` (map of strings, optional): Only visits matching every filter, keyed by what is filtered: `filters[url]=contains:/blog`. Each value is `{operator}:{value}`, with operator `is`, `not`, `contains`, `starts`, `gt` or `lt`. Keys include `url`, `hostName`, `entryUrl`, `exitUrl`, `event`, `outgoingUrl`, `referrer`, `source`, `medium`, `campaign`, `content`, `term`, `countryCode`, `regionCode`, `language`, `deviceType` (`desktop`, `tablet` or `mobile`), `operatingSystem` and `browser`.
- `columns` (string, optional): The columns to return, comma-separated, such as `url,pageViews`. Left out, the table's default columns. Send a string even in a JSON body: an array is ignored.
- `sort` (string, optional): The column to sort by, then `:a` for ascending or `:d` for descending, such as `pageViews:d`. Left out, the table's own order.
- `search` (string, optional): Only rows matching this text. What it searches depends on the table, most often the URL or title.
- `page` (integer, optional, at least 1): The page of rows to return, from `1`. Defaults to `1`.
- `rowsPerPage` (integer, optional, at least 1): How many rows a page holds. Defaults to `100`.
- `previousPeriod` (string, optional): `1` to add the figures of the period before, the same length and ending where this one starts, as `previous…` fields. Left out or `0`, none. Needs a `period` with a start: with `all`, nothing is added. One of: `0`, `1`.

## Response

Status `200`.

- `result` (object, required): The answer.
  - `page` (integer, required, at least 1): The page returned. Not always the page asked for, when that was out of range.
  - `minPage` (integer, required, at least 1): The first page. Always `1`.
  - `maxPage` (integer, required): The last page at this `rowsPerPage`. With no rows, `0` or `1` depending on the table.
  - `numRows` (integer, required): How many rows there are across every page.
  - `rowsPerPage` (integer, required, at least 1): How many rows a page holds.
  - `rows` (list of objects, required): The rows on this page.
    - `countryCode` (string, optional): The region's country, as its two-letter ISO 3166 code, such as `GB`. Absent when `columns` leaves it out.
    - `countryName` (string, optional): The country's name in English. The code when Silktide has no name for it. Absent when `columns` leaves it out.
    - `regionCode` (string, optional): The region within its country, as the ISO 3166-2 subdivision code without the country, such as `SCT` for Scotland. Unique only together with `countryCode`. Absent when `columns` leaves it out.
    - `regionName` (string, optional): The region's name in English. Currently the text `regionCode in countryCode`, word for word, when Silktide has no name for it. Absent when `columns` leaves it out.
    - `visitors` (integer, optional): Unique visitors from the region. Absent when `columns` leaves it out.
    - `pageViews` (integer, optional): Page views from the region. Absent when `columns` leaves it out.
    - `previousVisitors` (integer, optional): Unique visitors from the region in the period before. Only with `previousPeriod=1` and a period other than `all`. With `columns`, only when named there.
    - `previousPageViews` (integer, optional): Page views from the region in the period before. Only with `previousPeriod=1` and a period other than `all`. With `columns`, only when named there.
- `selector` (string, required): The query that answered, as its path: `/v1/results/scores`.
- `duration` (number, required): Seconds Silktide took to answer.

## Errors

| Status | Type | When |
| --- | --- | --- |
| 404 | `ModelNotFound` | No view or website with that id exists in the account, or the API key's user cannot see it. |
| 403 | `AccessDenied` | The API key's user cannot read that analytics view. |
| 200 | `ModelNotFound` | The website has no Analytics set up. The body is an error despite the status. |
| 200 | `InvalidRequest` | Neither `view` nor `websiteId` was sent. The error's own `status` is `400` and `properties.field` is `view`. The body is an error despite the status. |
| 200 | `InvalidArgument` | A filter names a key or operator Analytics does not know. The body is an error despite the status. |
| 200 | `InvalidArgument` | `period` is not one of its values, or is `custom` without both `from` and `to`. The body is an error despite the status. |
| 401 | `NotLoggedIn` | No API key was sent, or it is not a key for this region. |
| 429 | `TooManyRequests` | Too many requests to this path in five seconds. Retry after the number of seconds in the `Retry-After` header, which `properties.retryAfter` repeats. |
| 503 | - | Silktide is busy. Retry after the number of seconds in the `Retry-After` header. |

## Access

- Permission: View analytics view (View all analytics for `view=all`)
- Plan feature: none
- Edition: Silktide 4 and Silktide 5
- Cost: free
- Stability: stable, since 1.0.0

## Example: The top regions

```bash
curl "https://api.eu.silktide.com/v1/results/analytics/regions?view=all&rowsPerPage=3" \
  -H "Authorization: silktide token=$SILKTIDE_API_KEY"
```

Response:

```json
{
  "result": {
    "page": 1,
    "minPage": 1,
    "maxPage": 53,
    "numRows": 158,
    "rowsPerPage": 3,
    "rows": [
      {
        "countryName": "United Kingdom",
        "regionName": "England",
        "countryCode": "GB",
        "regionCode": "ENG",
        "pageViews": 189,
        "visitors": 90
      },
      {
        "countryName": "Australia",
        "regionName": "New South Wales",
        "countryCode": "AU",
        "regionCode": "NSW",
        "pageViews": 107,
        "visitors": 37
      },
      {
        "countryName": "Australia",
        "regionName": "Victoria",
        "countryCode": "AU",
        "regionCode": "VIC",
        "pageViews": 53,
        "visitors": 26
      }
    ]
  },
  "selector": "/v1/results/analytics/regions",
  "duration": 0.024
}
```

## Example: The regions of one country

```bash
curl "https://api.eu.silktide.com/v1/results/analytics/regions?view=all&period=custom&from=2026-09-01&to=2026-10-31&filters=%7B%22countryCode%22%3A%22is%3AGB%22%7D&rowsPerPage=2" \
  -H "Authorization: silktide token=$SILKTIDE_API_KEY"
```

Response:

```json
{
  "result": {
    "page": 1,
    "minPage": 1,
    "maxPage": 2,
    "numRows": 4,
    "rowsPerPage": 2,
    "rows": [
      {
        "countryName": "United Kingdom",
        "regionName": "England",
        "countryCode": "GB",
        "regionCode": "ENG",
        "pageViews": 189,
        "visitors": 90
      },
      {
        "countryName": "United Kingdom",
        "regionName": "Scotland",
        "countryCode": "GB",
        "regionCode": "SCT",
        "pageViews": 54,
        "visitors": 22
      }
    ]
  },
  "selector": "/v1/results/analytics/regions",
  "duration": 0.02
}
```
