Skip to main content

Overview

Plausible uses API key-based authentication. All API requests must include a valid API key as a Bearer token in the Authorization header.

Creating an API Key

1

Navigate to API Keys settings

Go to your API Keys settings page in your Plausible account.
2

Create a new key

Click ”+ New API Key” and provide:
  • Name: A descriptive name for the key (e.g., “Production Analytics Dashboard”)
  • Team: Select which team this key should be scoped to
3

Choose scopes

The scope is automatically determined based on the key type:
  • Stats API keys get stats:read:* scope
  • Sites API keys get sites:provision:* scope (Enterprise only)
4

Save and copy the key

After creating the key, copy it immediately. For security reasons, you won’t be able to see the full key again.
Store your API key securely! It provides access to your analytics data and should be treated like a password.

Authentication Method

Include your API key in the Authorization header as a Bearer token:
Authorization: Bearer YOUR_API_KEY

Example Request

curl https://plausible.io/api/v1/stats/aggregate \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -G \
  -d 'site_id=example.com' \
  -d 'period=30d'

API Key Types

Team-Scoped Keys

Modern API keys are scoped to a specific team:

Characteristics:
  • Bound to a single team
  • Only works with sites owned by that team
  • User must be a team member (guests cannot use team keys)
  • Subject to team-based rate limits
  • Generated with a 6-character prefix for identification
Key Format: 64-character URL-safe string Storage: Keys are hashed using SHA-256 before storage. Only the first 6 characters (prefix) are stored in plain text for identification.

Legacy Keys (Deprecated)

Older API keys created before team-scoping:

Characteristics:
  • Work across all teams the user belongs to
  • Can access sites where user is a guest
  • Subject to user-based rate limits
  • Cannot be created through the UI anymore
Legacy keys are maintained for backwards compatibility only. New integrations should use team-scoped keys.

API Scopes and Permissions

stats:read:*

Default scope - Allows reading analytics data
  • Query aggregate statistics
  • Access breakdown reports
  • Retrieve timeseries data
  • View realtime visitor counts
  • Read site metadata
Available to: All API keys (implicit scope)

sites:read:*

Read-only access to site configurations
  • List all sites
  • Get site details
  • List goals
  • List custom properties
  • View site guests
  • List teams
Available to: All API keys (implicit scope)

sites:provision:*

Full provisioning access - Requires Enterprise plan
  • All sites:read:* permissions
  • Create new sites
  • Update site settings
  • Delete sites
  • Create and delete goals
  • Manage custom properties
  • Create shared links
  • Invite and remove guests
Available to: Sites API keys on Enterprise plans only
The scopes use wildcard matching. For example, if an API key has sites:* scope, it matches both sites:read:* and sites:provision:*.

Authentication Errors

The API returns specific error messages for authentication failures:

Missing API Key

{
  "error": "Missing API key. Please use a valid Plausible API key as a Bearer Token."
}
HTTP Status: 401 Unauthorized Cause: No Authorization header provided or header format is incorrect Solution: Include the header as Authorization: Bearer YOUR_API_KEY

Invalid API Key

{
  "error": "Invalid API key. Please make sure you're using a valid API key with access to the resource you've requested."
}
HTTP Status: 401 Unauthorized Causes:
  • API key doesn’t exist
  • API key has been deleted
  • Key is valid but doesn’t have access to the requested site
  • Team-scoped key used for a site in a different team

Invalid API Key with Site Access

For Stats API requests:
{
  "error": "Invalid API key or site ID. Please make sure you're using a valid API key with access to the site you've requested."
}
HTTP Status: 401 Unauthorized Causes:
  • Site ID doesn’t exist
  • API key doesn’t have permission to access the site
  • User is not a member of the site’s team

Insufficient Scope

{
  "error": "Invalid API key. Please make sure you're using a valid API key with access to the resource you've requested."
}
HTTP Status: 401 Unauthorized Cause: API key doesn’t have the required scope for the endpoint Solution: Create a new API key with the appropriate scope or use a different key

Rate Limiting

API keys are subject to rate limits to ensure fair usage:

Hourly Limit

Default: 600 requests/hour per team
(Configurable per team in Enterprise plans)

Burst Limit

All keys are subject to a burst limit to prevent abuse:
Requests: Configurable (default varies)
Period: Configurable in seconds
Rate Limit Headers: Currently not included in responses

Rate Limit Errors

Hourly Limit Exceeded

{
  "error": "Too many API requests. The limit is 600 per hour. Please contact us to request more capacity."
}
HTTP Status: 429 Too Many Requests

Burst Limit Exceeded

{
  "error": "Too many API requests in a short period of time. The limit is 100 per 60 seconds. Please throttle your requests."
}
HTTP Status: 429 Too Many Requests
Rate limits are enforced per team (for team-scoped keys) or per user (for legacy keys), not per API key. Multiple keys for the same team share the same rate limit.

Security Best Practices

  • Never commit API keys to version control
  • Use environment variables or secret management services
  • Rotate keys periodically
  • Delete unused keys immediately
  • Create separate keys for each team
  • Limit blast radius if a key is compromised
  • Easier to track usage and manage access
  • Only request the scopes you need
  • Use stats:read:* for read-only analytics access
  • Only use sites:provision:* when you need write access
  • Track which keys are being used
  • Watch for unusual patterns
  • Delete keys that haven’t been used in 90+ days

Troubleshooting

Problem: Key works locally but fails in productionCommon causes:
  • Whitespace or newlines in the environment variable
  • Key was copied incorrectly (missing characters)
  • Using a different key than intended
Solution: Verify the exact key value being used and ensure proper trimming of whitespace.
Problem: Authentication fails even with correct API keyCommon causes:
  • Team-scoped key used for site in different team
  • User is a guest on the site (team keys require membership)
  • Site was transferred to another team
Solution: Check that the key’s team matches the site’s team. Verify team membership in settings.
Problem: Getting 402 Payment Required errorsCommon causes:
  • Team subscription has lapsed
  • Required feature not available on current plan
  • Attempting to use Sites API without Enterprise plan
Solution: Check team billing status and plan features. Upgrade if necessary.

Implementation from Source

API key authentication is implemented in:
  • Key structure: lib/plausible/auth/api_key.ex:44-58
  • Authorization logic: lib/plausible_web/plugs/authorize_public_api.ex:50-65
  • Scope verification: lib/plausible_web/plugs/authorize_public_api.ex:156-173
  • Rate limiting: lib/plausible_web/plugs/authorize_public_api.ex:187-214
For self-hosted instances, rate limits and some authentication behaviors can be configured via environment variables.

Build docs developers (and LLMs) love