Authentication
Every authenticated request carries one header:
Authorization: Bearer <token>The API looks at the shape of the token and sends it to exactly one validator:
| Token | Shape | Where it comes from | Use it for |
|---|---|---|---|
| Session JWT | Three dot-separated segments | POST /api/v1/auth/login; short-lived, renewed with POST /api/v1/auth/refresh |
The Pitch2Sale web app |
| Personal access token | pat_ followed by 64 hex characters |
Settings → API keys, or the API keys endpoints | Integrations and scripts (recommended) |
| OAuth access token | 64 hex characters, no prefix | Issued to installed OAuth apps | Installed apps only |
A token that looks like a JWT but fails verification is rejected. It never falls back to the other validators, so a malformed token always fails the same way.
curl -H "Authorization: Bearer pat_…" "https://api.pitch2sale.com/api/v1/leads?limit=5"Never put a token in a URL, a browser bundle or a repository. Keep it in an environment variable or a secret manager on your server.
Who the request runs as
Section titled “Who the request runs as”A personal access token belongs to the user who created it and to that user’s organization. Requests made with it:
- see only that organization’s data;
- inherit the user’s role permissions — the key can do what the user can do, and no more;
- stop working when the key is revoked, the user is deactivated, or the organization is inactive or suspended.
Scopes on the key narrow this further on some endpoints; see API keys → Scopes.
Authentication failures (401)
Section titled “Authentication failures (401)”| Body | Meaning |
|---|---|
{"error":"Authentication required"} |
No Authorization header, or it does not start with Bearer . |
{"error":"Invalid or expired token"} |
A personal access token or OAuth token that is unknown, revoked or belongs to an inactive user. |
{"error":"Token expired"} |
A session JWT past its expiry. Refresh it. |
{"error":"Invalid token"} |
A JWT-shaped token that fails signature verification. |
A personal access token for an organization that is inactive or suspended gets 403 {"error":"Organization is inactive"}.
Permission and plan failures
Section titled “Permission and plan failures”Authentication only proves who you are. Each endpoint then checks up to three more things:
-
Role permission (403). The endpoint requires a permission such as
leads.create. If the user’s role lacks it:{ "error": "Forbidden", "required_permission": "leads.create" } -
Plan feature (402). Some endpoints belong to a feature that the organization’s plan must include:
{ "error": "plan_upgrade_required", "feature": "settings.webhooks", "current_plan": "starter" }errorisfeature_disabledinstead when the feature has been switched off for the organization. -
Token scope (403). On endpoints that check scopes, a key without the required scope gets
{"error":"Token does not have required scope: write:leads"}.
See Errors for the full envelope.