---
title: "How do I authenticate RevenueDot API requests?"
description: "RevenueDot uses public app keys for the SDK endpoints, secret keys for REST API v1 and v2, and a session cookie for the dashboard. Secret keys carry permissions."
url: https://revenuedot.app/docs/api/authentication
---

# How do I authenticate RevenueDot API requests?

Send every key as a bearer token: `Authorization: Bearer <key>`. Which key depends on the API:

| Credential | Looks like | Use it for | Keep it |
|---|---|---|---|
| Public app key | `appl_...`, `goog_...`, `test_...` | [SDK endpoints](https://revenuedot.app/docs/api/sdk-endpoints.md) for that app | In your app. It is public by design |
| Secret key | `sk_...` | [REST API v1](https://revenuedot.app/docs/api/rest-v1.md), [REST API v2](https://revenuedot.app/docs/api/rest-v2.md), [extensions](https://revenuedot.app/docs/api/extensions.md), and SDK endpoints from your backend | On your servers only |
| Dashboard session | cookie `rd_session` | REST API v2 from the dashboard, for every project you belong to | In the browser |
| Pub/Sub push token | Google-signed JWT | Google Play notifications, when `pubsub_audience` is set | Sent by Google |

## Security schemes in the OpenAPI document

- **`publicApiKey`**: A public app key (`appl_`, `mac_`, `goog_`, `test_`, `amzn_`, `strp_`, `rcb_`, `pdl_`, `roku_`). Safe to ship in an app. The SDK sends it on every request.
- **`secretApiKey`**: A project secret key (`sk_...`). Server side only. Its `permissions` limit what it can do.
- **`dashboardSession`**: The dashboard session cookie from `POST /auth/login`. It authorizes `/v2` for every project the user belongs to.
- **`googlePubSubOidc`**: Google-signed OIDC token of a Pub/Sub push subscription. Checked only when the app's `pubsub_audience` credential is set.

## Where keys come from

- **Public app key:** created with the app. Read it with `GET /v2/projects/{project_id}/apps/{app_id}/public_api_keys` or on the app's dashboard page. During a migration you can keep your RevenueCat key with `POST /v2/projects/{project_id}/import/apps/{app_id}/public_key`.
- **Secret key:** `POST /v2/projects/{project_id}/api_keys` or the dashboard's **API keys** page. The key is shown once. RevenueDot stores only its SHA-256 hash.
- **OAuth for MCP clients:** an MCP client can get a secret key through [OAuth 2.1 with PKCE](https://revenuedot.app/docs/api/extensions.md#oauth-for-mcp-clients). The user picks one project and read or read-write access.

## Permissions (secret keys)

A secret key belongs to one project and holds a list of permissions. `*` allows everything. A `read_write` permission also allows `read`. A prefix wildcard such as `customer_information:*` allows every permission under it. Dashboard users with the viewer role get only `read` permissions. A key can only create keys with permissions it holds itself.

Permissions the operations use:

- `charts_metrics:overview:read`
- `customer_information:customers:read`
- `customer_information:customers:read_write`
- `customer_information:purchases:read`
- `customer_information:purchases:read_write`
- `customer_information:subscriptions:read`
- `customer_information:subscriptions:read_write`
- `project_configuration:api_keys:read`
- `project_configuration:api_keys:read_write`
- `project_configuration:apps:read`
- `project_configuration:apps:read_write`
- `project_configuration:collaborators:read`
- `project_configuration:entitlements:read`
- `project_configuration:entitlements:read_write`
- `project_configuration:integrations:read`
- `project_configuration:integrations:read_write`
- `project_configuration:offerings:read`
- `project_configuration:offerings:read_write`
- `project_configuration:packages:read`
- `project_configuration:packages:read_write`
- `project_configuration:products:read`
- `project_configuration:products:read_write`
- `project_configuration:projects:read`
- `project_configuration:projects:read_write`

Each operation's section on the reference pages lists the permissions it needs. A missing permission answers 403 `authorization_error` and names it.

## Common mistakes

- **A public key on REST API v2** answers 403: "API v2 requires a secret API key (sk_...)".
- **A secret key in an app** gives anyone who unpacks the app full access to your project. Delete it (`DELETE /v2/projects/{project_id}/api_keys/{key_id}`) and create a new one.
- **Another project's id** with a valid key answers 404, not 403, so ids cannot be probed.

## Related

- [Projects, apps and API keys](https://revenuedot.app/docs/concepts/projects-and-apps.md)
- [Errors](https://revenuedot.app/docs/api/errors.md)
