API Authentication
Authenticate requests to the Logspot API with a public key, an API token, or an OAuth client.
Every request to the Logspot API carries a credential: a public key in a header for client-side code, or, for server-side code, an API token sent as a Bearer token. Machine services can also use an OAuth client to mint short-lived tokens. API tokens and OAuth clients carry scopes that decide what they may do.
Find Your Keys
Public key. In the Logspot dashboard, go to Project Settings → Integrations. The Project Key
section shows your Public Key, prefixed pk_. It is safe to include in client-side code.
Secret key. Server-side keys are API tokens you create on demand. In Settings → Integrations → API Keys, or the API Keys section of a project's Integrations tab, click Create API Key, choose its scopes, and copy the secret once. Secret keys are shown only at creation; afterward the dashboard shows just the last four characters. If you lose one, create a new key and revoke the old.
A secret key is prefixed sk_ and is server-side only. Never expose it in a browser, a mobile app, or a
public repository. Store it in an environment variable or a secret manager, for example
LOGSPOT_SECRET_KEY, rather than hardcoding it.
A key can be scoped to one project or to the whole organization. A key created from a project's Integrations tab is scoped to that project, which is what server-side ingestion needs. Keys created under Settings → Integrations can be organization-wide, for reading across every project.
Authenticate a Request
The pk_ / sk_ prefix is part of the key and the API will reject the request without it.
Server-side, send an API token as a Bearer token:
curl https://api.logspot.io/v1/track \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk_a1b2c3d4e5f6" \
-d '{"name": "Signup Completed", "user_id": "user_123"}'Client-side, send the public key in the x-logspot-pk header:
curl https://api.logspot.io/v1/track \
-H "Content-Type: application/json" \
-H "x-logspot-pk: pk_a1b2c3d4e5f6" \
-d '{"name": "Page Viewed"}'A legacy project secret can still be sent as x-logspot-sk: sk_... and behaves like a project-scoped API
token. The older unversioned paths (/track) keep working as aliases of /v1/....
In Postman or Insomnia, set Authorization to Bearer Token and paste the full sk_... value.
Which Key to Use
Ingestion is addressed by the credential: the key names the project, so ingest calls never take a project
id. Reads of one project's data address it in the path, /v1/projects/{project_id}/...; an organization
key can read any project in the organization, a project key only its own, and the project in the path must
match. Organization-level operations (privacy requests, companies, identities, members) are flat and
need an organization key.
| Endpoint | Public key | Project key | Organization key |
|---|---|---|---|
/v1/track, /v1/identify, /v1/group, /v1/consent | Yes | Yes | No |
/v1/projects/{project_id}/search-events | No | Yes | Yes |
/v1/projects/{project_id}/analytics/* | No | Yes | Yes |
/v1/projects/{project_id}/embed/ott | No | Yes | Yes |
/v1/projects/{project_id}/revenue/* | No | Yes | Yes |
/v1/privacy-requests (deletion and export requests) | No | No | Yes |
/v1/companies/*, /v1/identities/*, /v1/projects, /v1/members | No | No | Yes |
Each key also carries scopes (for example events:write or analytics:read); a request needs the matching
scope as well as the right key type.
Requests made with the public key are rate limited per IP address. Requests made with an API token are rate limited per key.
If a request returns a 401, check that the header value still carries its pk_ or sk_ prefix, that
the endpoint accepts the key type you used, and that the key belongs to the project you are writing to.
Scopes
When you create an API token or an OAuth client you grant it scopes. A request needs the scope its
endpoint requires (a 403 means the credential is valid but missing that scope). Ingest scopes work with
a project token; read scopes work with a project or organization token, except the organization-wide
reads (companies, identities, members) which need an organization token. Privacy request scopes always
need an organization token.
API Access is a Pro plan feature. Reading data with an API token or OAuth client, and minting embed
tokens, requires the Pro or Enterprise plan; on Free and Essentials those requests return 403 with a
message naming the plan. Ingest scopes work on every plan, and so does the AI assistant connection
(MCP), because it acts as a signed-in person rather than a machine credential.
| Scope | Grants | Plan |
|---|---|---|
events:write | Send events via /track | All |
identities:write | Identify users via /identify | All |
groups:write | Associate users with groups via /group | All |
consent:write | Record consent via /consent | All |
events:read | Search raw events via /search-events | Pro |
analytics:read | Read analytics counts, aggregates, and metrics | Pro |
revenue:read | Read revenue metrics, attribution, and cohorts | Pro |
identities:read | Read identity profiles, sessions, and activity (personal data) | Pro |
privacy_requests:read | Read the status of privacy requests (DSR/DSAR) | All |
privacy_requests:write | File deletion and export privacy requests | All |
embeds:write | Mint embed one-time tokens via /embed/ott | Pro |
projects:read | List the organization's projects | Pro |
organization:read | Read organization members and settings metadata | Pro |
Machine-to-Machine Access (OAuth Clients)
For a backend service that should not hold a long-lived secret key, create an OAuth client in
Settings → Integrations → OAuth Clients. You choose a name and the scopes the client may ever use;
Logspot returns a client id and a client secret once. The client then exchanges them for short-lived
access tokens using the standard client_credentials grant, naming the REST API as the resource:
curl https://api.logspot.io/api/auth/oauth2/token \
-u "$LOGSPOT_CLIENT_ID:$LOGSPOT_CLIENT_SECRET" \
-d grant_type=client_credentials \
-d scope="analytics:read events:read" \
-d resource=https://api.logspot.io/v1Use the returned access_token as a Bearer token exactly like an API token:
curl https://api.logspot.io/v1/companies/top \
-H "Authorization: Bearer $ACCESS_TOKEN"A few rules follow from how these tokens are issued:
- A token can only carry scopes inside the client's ceiling; asking for more returns
invalid_scope. - Tokens are bound to the REST API resource. A token minted for the MCP resource is rejected here, and
a REST token is rejected at
/mcp. - An OAuth client is organization-scoped, so it can read across projects but cannot ingest events (ingestion needs a project key). Because an owner or admin creates it, it satisfies owner-or-admin requirements by construction, so the companies, revenue, and identity endpoints are reachable.
- Rotate the secret from the same page; the previous secret stops working immediately.
Migrating from a Project Secret Key
Older integrations used a per-project secret sent as x-logspot-sk. That still works and is treated as a
project-scoped API token, so nothing breaks. When you next touch an integration, prefer an API token:
- Create a token in Settings → Integrations (organization-wide) or a project's Integrations tab
(project-scoped), and send it as
Authorization: Bearer sk_.... - A token is scoped and revocable, and you can hold several at once, so you can rotate without downtime and give each integration only the scopes it needs.
- Two behaviors moved to the organization level and no longer accept a project secret: privacy requests
(
/v1/privacy-requests, formerly the project/privacy/*routes) need an organization token, and the cross-project reads (companies, identities, members) always did. - New projects no longer generate a secret key at all. Create an API token instead.