Source: https://datafa.st/docs/api/website/breakdowns/cities
Markdown source: https://datafa.st/docs/api/website/breakdowns/cities.md
Description: Return analytics broken down by city.

# Get city analytics

`GET https://datafa.st/api/v1/analytics/cities`

Return analytics broken down by city.

## Request

### Authentication

- `df_` website API key for one website.
- `dft_` account token with `analytics:read`. Pass `websiteId` as a query parameter.


### Query parameters

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `fields` | string | No | Controls which columns are returned for each breakdown row. Use it to include the dimension plus only the metrics you need. Valid fields: `city`, `visitors`, `revenue`, `payments`. Example: `fields=visitors,revenue,payments`. |
| `startAt` | string | No | Sets the beginning of the reporting window. Use it when you want a specific date range instead of the endpoint default. Must be provided with `endAt`. Example: `startAt=2026-05-01`. |
| `endAt` | string | No | Sets the end of the reporting window. Must be provided with `startAt`. Example: `endAt=2026-05-21`. |
| `timezone` | string | No | Controls how dates are interpreted and how time buckets are grouped. Defaults to the website timezone. Example: `timezone=America/New_York`. |
| `limit` | number | No | Controls how many rows are returned. Use it with `offset` to paginate through long lists. Defaults to `100`. Example: `limit=50`. |
| `offset` | number | No | Skips rows before returning results. Use it to fetch the next page after a previous request. Defaults to `0`. Example: `offset=50`. |
| `filter_country` | string | No | Limits results to visitors from one or more countries. Operators: `is`, `is_not`. Use country names or codes. Example: `filter_country=US,Canada`. |
| `filter_region` | string | No | Limits results to visitors from a region or state. Example: `filter_region=California`. |
| `filter_city` | string | No | Limits results to visitors from a city. Example: `filter_city=San Francisco`. |
| `filter_device` | string | No | Limits results by device type. Useful for mobile vs desktop analysis. Example: `filter_device=mobile`. |
| `filter_browser` | string | No | Limits results by browser. Use this to compare browser-specific traffic or revenue. Example: `filter_browser=Chrome,Safari`. |
| `filter_os` | string | No | Limits results by operating system. Example: `filter_os=iOS,Android`. |
| `filter_referrer` | string | No | Limits results by referrer domain or normalized source. Example: `filter_referrer=Google`. |
| `filter_page` | string | No | Limits results to visitors who viewed a page. Operators: `is`, `is_not`, `contains`, `does_not_contain`. Example: `filter_page=contains:/docs`. |
| `filter_entry_page` | string | No | Limits results by first page in the session. Operators: `is`, `is_not`, `contains`, `does_not_contain`. Example: `filter_entry_page=/pricing`. |
| `filter_hostname` | string | No | Limits results by tracked hostname. Useful when one website tracks multiple hostnames. Example: `filter_hostname=app.example.com`. |
| `filter_goal` | string | No | Limits results to visitors who completed a specific goal. Example: `filter_goal=signup`. |
| `filter_utm_source` | string | No | Limits results by UTM source. Example: `filter_utm_source=google`. |
| `filter_utm_medium` | string | No | Limits results by UTM medium. Example: `filter_utm_medium=cpc`. |
| `filter_utm_campaign` | string | No | Limits results by UTM campaign. Example: `filter_utm_campaign=launch`. |
| `filter_utm_term` | string | No | Limits results by UTM term. Example: `filter_utm_term=brand-keyword`. |
| `filter_utm_content` | string | No | Limits results by UTM content. Example: `filter_utm_content=hero-cta`. |
| `filter_ref` | string | No | Limits results by the `ref` URL parameter. Example: `filter_ref=twitter`. |
| `filter_source` | string | No | Limits results by the `source` URL parameter. Example: `filter_source=newsletter`. |
| `filter_via` | string | No | Limits results by the `via` URL parameter. Example: `filter_via=partner`. |

## Response

Returns a JSON object with `status` and endpoint-specific fields.

### Response fields

| Field | Type | Description |
| --- | --- | --- |
| `data[].city` | string | City name. |
| `data[].visitors` | number | Number of unique visitors represented by this row or time bucket. Use it to compare traffic volume across dates, pages, sources, countries, devices, or campaigns. |
| `data[].revenue` | number | Revenue attributed to this row or time bucket, in the website currency. Use it to see which time periods or dimensions influenced paid conversions. |
| `data[].payments` | number | Number of payment events attributed to this row or time bucket. Use it when you need transaction count instead of revenue amount. |
| `pagination.limit` | number | Maximum number of rows returned in one response. Use with `offset` to paginate through long result sets. |
| `pagination.offset` | number | Number of rows to skip before returning results. Use it with `limit` for pagination. |
| `pagination.total` | number | Total rows. |

### Errors

Common errors include `400` for invalid input, `401` for missing or invalid tokens, `403` for missing permission or suspended tracking, `404` for missing resources, and `500` for server errors.

## Code examples

### Example request

```bash
curl -X GET "https://datafa.st/api/v1/analytics/cities?limit=20&startAt=2026-05-01&endAt=2026-05-19" \
  -H "Authorization: Bearer df_xxx"
```

### Success response

```json
{
  "status": "success",
  "data": [
    {
      "city": "San Francisco",
      "visitors": 320,
      "revenue": 980,
      "payments": 12
    }
  ],
  "pagination": {
    "limit": 20,
    "offset": 0,
    "total": 1
  }
}
```
