> ## Documentation Index
> Fetch the complete documentation index at: https://docs.taap.it/llms.txt
> Use this file to discover all available pages before exploring further.

# Radar API

> Read your Radar (Visitors) analytics programmatically with a project-scoped API key

The **Radar API** lets external applications read the analytics collected by Taapit Radar
(the Visitors product): aggregate metrics, time series, realtime visitors and top
breakdowns (pages, sources, locations, devices).

## Base URL

```
https://taap.it/api/v1/radar
```

## Authentication

Radar endpoints are authenticated with a **project-scoped API key**. Every key belongs to a
single Radar project (one website), so you never pass a `projectId` — the project is resolved
from the key itself.

Send the key as a Bearer token:

```http theme={null}
Authorization: Bearer taapit_your_api_key_here
```

You can also use the `x-api-key` header instead:

```http theme={null}
x-api-key: taapit_your_api_key_here
```

<Info>
  API keys are created from the Radar dashboard under **Project settings → API**. The full key
  is shown only once at creation — store it securely and never expose it client-side.
</Info>

### Permissions

Each key carries a permission level (**All**, **Read only** or **Restricted**). All current
Radar endpoints are read-only, so any permission level can call them. Write scopes are reserved
for future write endpoints.

## Endpoints

<CardGroup cols={2}>
  <Card title="Metrics" icon="chart-simple" href="/api-reference/radar/metrics">
    Aggregate metrics over a date range (people, visits, pageviews, revenue…).
  </Card>

  <Card title="Time series" icon="chart-line" href="/api-reference/radar/timeseries">
    Time-bucketed series of the core metrics.
  </Card>

  <Card title="Realtime" icon="signal-stream" href="/api-reference/radar/realtime">
    Active visitors in a rolling window.
  </Card>

  <Card title="Breakdowns" icon="layer-group" href="/api-reference/radar/breakdowns">
    Top pages, sources, locations and devices.
  </Card>

  <Card title="People" icon="users" href="/api-reference/radar/people">
    List people (visitors) with their key attributes and filters.
  </Card>

  <Card title="Person details" icon="user" href="/api-reference/radar/people-details">
    A single person with their sessions and activity heatmap.
  </Card>

  <Card title="Last visitors" icon="bolt" href="/api-reference/radar/last-visitors">
    Visitors active in the last few minutes (live feed).
  </Card>

  <Card title="Custom events" icon="bullseye" href="/api-reference/radar/custom-events">
    Most frequent custom events tracked for the project.
  </Card>
</CardGroup>

## Date parameters

Endpoints that accept a date range use the `start` and `end` query parameters in ISO 8601
format (UTC), for example `2026-01-01T00:00:00Z`.

## Rate limits & quotas

Radar endpoints are backed by an analytics engine that bills per query, so each API key has
**per-key rate limits** to keep usage (and your costs) under control:

| Window | Default limit           |
| ------ | ----------------------- |
| Second | 3 requests / second     |
| Minute | 60 requests / minute    |
| Day    | 5,000 requests / day    |
| Month  | 50,000 requests / month |

The per-second cap is a **burst guard**: a single key can never spike above a few requests per
second, keeping usage comfortably under the analytics engine's per-second billing threshold.

Every response includes rate-limit headers so you can track your remaining budget:

```http theme={null}
X-RateLimit-Limit: 5000        # daily limit
X-RateLimit-Remaining: 4987    # requests left today
X-RateLimit-Reset: 1769990400  # UTC epoch seconds when the daily window resets
```

When a limit is exceeded the API returns **`429 Too Many Requests`** with a `Retry-After`
header (seconds to wait) and a `scope` field indicating which window was hit
(`second`, `minute`, `day` or `month`).

<Warning>
  Usage is logged **per key and per endpoint**. Polling endpoints like `realtime` and
  `last-visitors` consume quota on every call — cache responses and avoid sub-minute polling
  unless you really need it. Each call to `breakdowns` runs several aggregations, so it counts
  as one request but is heavier than a single metric read.
</Warning>

## Errors

<ResponseExample>
  ```json 401 Unauthorized theme={null}
  {
    "error": "Invalid API key"
  }
  ```

  ```json 400 Bad Request theme={null}
  {
    "error": "Both 'start' and 'end' query parameters are required"
  }
  ```

  ```json 429 Too Many Requests theme={null}
  {
    "error": "Rate limit exceeded",
    "scope": "minute",
    "retryAfterSeconds": 42
  }
  ```

  ```json 500 Internal Server Error theme={null}
  {
    "error": "Internal server error"
  }
  ```
</ResponseExample>
