Authentication
/v1 accepts three credentials. /portal accepts two of them and resolves
its tenant differently. Every route on both publishes which credentials it
accepts as a bearer scheme named bearerAuth in the OpenAPI document at
/openapi.json.
API keys
Section titled “API keys”An API key is a credential for something that is not a browser: a script, an
integration, or the MCP server. Create one in the application at
Settings → API keys, choosing a name, a set of scopes and optionally an
expiry date. It begins pb_ and is shown once:
pb_AbCdEf0123456789AbCdEf0123456789AbCdEf01Pealboard stores only a SHA-256 digest of it and cannot show it to you again. If you lose it, revoke it and create another. See API keys in the help documentation for the full walkthrough.
Send it as a bearer token:
curl https://api.pealboard.com/v1/me \ -H "Authorization: Bearer pb_AbCdEf0123456789AbCdEf0123456789AbCdEf01"A key acts as the workspace member who created it, narrowed by whatever
scopes were chosen when it was made. An empty set of scopes is not narrowed
and may do anything that member’s role allows; keys:read and keys:write
can never be granted to a key, so a credential that can mint credentials
cannot also mint one that can mint more of itself. Revoking or expiring the
member’s own account does the same to every key they made.
The scopes a key can be given:
workspace:read workspace:writemembers:read members:writegithub:read github:writeissues:read issues:writeprojects:read projects:writeportals:read portals:writerequests:read requests:writeviews:read views:writeSessions
Section titled “Sessions”Signing in to the application sets a session cookie,
__Host-pealboard-app.session_token, host-only and SameSite=Lax. A browser
sends it automatically; nothing else needs to. The mobile app instead holds a
bearer session token, sent the same way an API key is:
Authorization: Bearer <session token>X-Workspace-Id
Section titled “X-Workspace-Id”A person can belong to more than one workspace, and the API never guesses which one a request means — guessing is how a request meant for one customer lands in another. With exactly one membership it is filled in for you. With more than one, name it:
curl https://api.pealboard.com/v1/issues \ -H "Authorization: Bearer pb_AbCdEf0123456789AbCdEf0123456789AbCdEf01" \ -H "X-Workspace-Id: 3fae5b2a-6c9e-4b2b-9c39-2e5e5b7a1a11"Find your workspace ids with GET /account/workspaces. Naming a workspace an
API key was not issued in is a 403, not a silent override — a key belongs to
one workspace, so a header naming a different one is treated as a mistake
worth reporting.
Portal credentials are not for integrators
Section titled “Portal credentials are not for integrators”Portal customers sign in with a session cookie or token scoped to
/portal, and the API decides which portal a /portal request means from
the host it arrived on — <slug>.pealboard.com — never from a header a caller
supplies. There is no API key for a portal and no X-Workspace-Id equivalent.
A portal credential cannot read /v1, and a workspace credential cannot sign
in to a portal. Building an integration against Pealboard means building
against /v1; portals are for the customer’s own browser.
Errors
Section titled “Errors”An invalid or missing credential is 401 unauthenticated. A valid credential
whose role does not allow the action is 403 forbidden. See
Errors for the full envelope and every code.