Authentication
Bearer API keys, what they can reach, and the scopes a key carries.
Every request carries an org API key as a bearer token:
Authorization: Bearer spk_live_0123456789abcdef0123456789abcdefThe key is the proof of which workspace you are, so no request names a workspace. Keys are created and revoked in Settings → API keys; ShowPilot stores only a hash and shows the full key once.
Scopes
A key carries a list of scopes in the form resource:verb. Each endpoint names the one it needs, next to its operation id in the reference. Reads and writes are separate scopes, so a key made for a warehouse job can never change anything.
| Scope | Grants |
|---|---|
insights:read | The Insights endpoints. Every key created before scopes existed has this one. |
tours:read | List tours and read a tour's document, including drafts. |
hubs:read | List hubs and read one with its tour ids. |
agents:read | List agents and read one. |
visitors:read | List visitors and read one with their journey. |
conversations:read | List conversations and read one with its messages. |
leads:read | List and read leads. |
leads:write | Update a lead's owner, status or CRM link. |
follow_ups:read | List and read follow-ups. |
follow_ups:write | Answer or dismiss a follow-up. |
sittings:read | A tour's sittings, one row per play. |
A new key starts with every read scope and no write scopes; turn on the writes a tool needs and turn off the reads it does not. Other write scopes (tours:write, agents:write, knowledge:write and the rest) are reserved and arrive with the endpoints that use them. A key without an endpoint's scope gets 403 insufficient-scope.
Test keys and the sandbox
Every workspace has a sandbox: a separate copy that starts with sample tours, visitors, conversations, leads, follow-ups, a meeting and a few events, and that nothing live ever writes to. A test key (spk_test_…, picked when you create the key) runs every call there. Same endpoints, same scopes, same shapes; the only differences are what you get back and what you can break.
- Responses carry
X-ShowPilot-Mode: test(orlive), so a client can refuse to point a live key at a test config. - Events from the sandbox carry
livemode: false. Webhooks you add with a test key fire from the sandbox only. GET /v1/sandboxsays what a test key is looking at;POST /v1/sandbox/resetthrows away everything you wrote and seeds it again.- A live key on either sandbox endpoint gets
403 sandbox-only, never a silent no-op.
curl https://api.showpilot.com/v1/tours \
-H "Authorization: Bearer spk_test_0123456789abcdef0123456789abcdef"The sample data is plainly named (Acme Example, Northwind Example, .example addresses), so a first call reads as what it is.
Good to know
- One key per tool. Revoking one tool's key then breaks nothing else.
- Rotation is create the new key, switch the tool, revoke the old one. Keys do not expire on their own.
- Last used on the keys page updates on every successful call, which is the quickest way to confirm a tool is wired up.