# Authentication

URL: https://pieowl.com/docs/api/authentication



Authentication [#authentication]

Every request to the Pieowl API is tied to a client. A client has a client ID and a client secret. Each API needs a certain client type:

* **Track API**: any client. The default `write` client works.
* **Export API**: `read` or `root`
* **Insights API**: `read` or `root`
* **Import API**: `read` or `root`
* **Manage API**: `root` only

When you add a site, Pieowl creates a `write` client for it. That client can send events, but it can't use the Export, Insights, Import or Manage APIs. Create another client with the right type for those.

Headers [#headers]

Send these headers with every request:

* `pieowl-client-id`: your client ID
* `pieowl-client-secret`: your client secret

Example [#example]

```bash
curl 'https://api.pieowl.com/insights/YOUR_PROJECT_ID/metrics?range=30d' \
  -H 'pieowl-client-id: YOUR_CLIENT_ID' \
  -H 'pieowl-client-secret: YOUR_CLIENT_SECRET'
```

Replace `YOUR_PROJECT_ID` with your site ID (`projectId`), and `YOUR_CLIENT_ID` and `YOUR_CLIENT_SECRET` with your own values.

Create a client [#create-a-client]

In the dashboard, go to **Settings → Developers → Keys**. Create a client and pick its type. Copy the secret right away, because it is only shown once.

Client types [#client-types]

| Type    | What it can do                                              |
| ------- | ----------------------------------------------------------- |
| `write` | Send events and profile updates (Track API)                 |
| `read`  | Read data for its own site (Export, Insights, Import)       |
| `root`  | Read data for any site in your team, and use the Manage API |

A `root` client has access to every site in your team. Use it only on a server, and keep its secret safe.

Keep your credentials safe [#keep-your-credentials-safe]

1. **Keep secrets on the server.** Never put a client secret in browser or app code.
2. **Use HTTPS** for every request.
3. **Rotate secrets** from time to time. Create a new client, switch over, then delete the old one.
4. **Use the smallest access you need.** Pick `read` over `root` when you only read data.

Error responses [#error-responses]

If authentication fails on the Export, Insights, Import or Manage APIs, you get `401 Unauthorized`. The message tells you what went wrong:

```json
{
  "error": "Unauthorized",
  "message": "Export: Invalid client secret"
}
```

Common causes:

* The client ID or secret is wrong.
* The client ID is not a valid UUID.
* The client type is too low, for example a `write` client calling the Export API, or a `read` client calling the Manage API.
* The client has no secret.

The Track API also returns `401`, with a plain-text message such as `Ingestion: Invalid cors or secret`.

Rate limits [#rate-limits]

Some APIs limit how many requests one client can make:

* **Export and Insights APIs**: 100 requests per 10 seconds
* **Manage API**: 20 requests per 10 seconds
* **Track, Profile and Import APIs**: no rate limit

If you go over the limit, you get `429 Too Many Requests`. Wait a little, then retry with exponential backoff. See [Rate limits](/docs/api-reference/rate-limits) for details.
