Personal keys
A personal key lets a script, a server or an AI client that sends a header — Claude Code, Cursor, n8n, your own reporting job — read your shops without signing in through a browser. It reads exactly what a connected AI client reads, through the same tools, and nothing else — and, only if you allow it when you create the key, it can make the changes a connected client can make: managing your sites' notification destinations and uptime monitors.
It is not the site key. A site key belongs to a SITE and lets the plugin or the SDK send data in; a personal key belongs to a PERSON and lets them read out.
Creating one
Your profile → Personal keys → Create a key. Choose:
- a name, so you can tell your keys apart later;
- what it may read — specific sites or whole organizations, one or the other (an organization includes sites added to it later);
- how long it lives — 90 days unless you choose otherwise, never more than 365;
- whether it may make changes — it reads only unless you allow changes. This choice is final: it cannot be changed afterwards, in either direction. If you need the other kind, create another key.
You then enter your password again, and a code from your authenticator if two-factor authentication is on. A key reads your data while you are not signed in, so being signed in is not enough to create one.
The key is shown once. We keep only a fingerprint of it, so nobody — including us — can show it to you again. If you lose it, revoke it and create another. You can hold up to 10 at once.
Using it
Send it in the Authorization header, never in a web address:
# List what the key may call
curl -H "Authorization: Bearer sp_key_…" https://api.store-pilot.net/api/v1/key/tools
# Call one tool
curl -X POST -H "Authorization: Bearer sp_key_…" -H "Content-Type: application/json" \
-d '{"siteId": 42}' https://api.store-pilot.net/api/v1/key/tools/get_site_overview
A key opens only these addresses — /api/v1/key/… and /mcp. The dashboard's own
addresses, such as /api/v1/sites, use a different sign-in and answer 401 to a key; that does
not mean the key is broken. Every refusal a key meets carries a docs field pointing here, and
https://api.store-pilot.net/api/v1 lists the key addresses for anything that goes looking.
Using it from an AI client
When you create a key, the pop-up shows it with the two things below already filled in. Copy them then, while the key is still on screen.
Claude Code — the key is the sign-in, so no browser opens:
claude mcp add --transport http storepilot https://api.store-pilot.net/mcp \
--header "Authorization: Bearer sp_key_…"
Cursor — in .cursor/mcp.json:
{
"mcpServers": {
"storepilot": {
"url": "https://api.store-pilot.net/mcp",
"headers": { "Authorization": "Bearer sp_key_…" }
}
}
}
Claude Desktop — a client that cannot send a header itself can run it through
mcp-remote:
{
"mcpServers": {
"storepilot": {
"command": "npx",
"args": ["mcp-remote", "https://api.store-pilot.net/mcp", "--header", "Authorization:${STOREPILOT_AUTH}"],
"env": { "STOREPILOT_AUTH": "Bearer sp_key_…" }
}
}
}
In claude.ai on the web, add StorePilot as a connector and sign in instead — see Connect your AI assistant; no key is needed there.
Any other assistant that can make web requests: paste the note from the pop-up into the chat before you ask about your shop. It names the key, the header, the addresses above and the documentation, and tells the assistant not to try dashboard addresses. Left to guess, an assistant tries one address and header after another — which gets nowhere, and which some assistants' safety checks read as guessing at credentials.
Reference
Every tool, its arguments and its answers are described at
api.store-pilot.net/api/v1/key/docs, with the
machine-readable OpenAPI document at
/api/v1/key/openapi.json — import it
into Postman, Insomnia or a code generator. Both are generated from the same list the API answers
from, so a tool appears there the moment it exists. The page has no "Try it out" button on
purpose: a key refuses any request sent from a web page.
Two things are refused on purpose:
- A key in the query string (
?key=…) is refused before it is even looked up — addresses end up in logs, browser history and analytics. - A request from a web page is refused: a key is for servers. A request carrying a browser
Originheader answers 403, and no browser may read a key response.
Making changes
A key reads. A key created with changes allowed can also manage the sites' notification
destinations — list, add, change, test, copy and delete them, with
list_notification_destinations, save_notification_destination,
test_notification_destination, copy_notification_destination,
delete_notification_destination and set_notification_channel — and their uptime monitors,
with list_uptime_monitors, save_uptime_monitor and delete_uptime_monitor, under exactly the
conditions a connected AI client faces (see
Reading, and the changes you can allow):
- the organization's owner must have allowed changes from connected AI clients, and approved the host of any webhook or Slack address; a monitor may only check the site's own domain;
- you need the admin role on the site;
- it makes at most 30 changes an hour;
- every owner and admin of the organization gets an email and a notification for each change, naming the key, the action and where the destination sends.
A key created without changes allowed is refused those tools with a 403 (insufficient_scope).
Whether a key may make changes is decided when it is created and cannot be changed afterwards,
so a key that leaks can never be given more than it was created with.
What it can read
The same as a connected AI client, under the same rules — see What it can read. It never receives a postal address, a postcode, an IP address or session-recording footage. The sites are re-checked against your live team membership on every request: leave an organization and the key stops reading it at once.
Knowing when it is used
Each row on your profile shows when the key was last used and from which network (a /24, never a full address). We email you the first time a key is used, and again whenever it is used from a network it has not been used from before — the one signal that tells you a key you forgot about is in somebody else's hands.
Seeing what it read
Your profile → What keys and AI connections read counts every call your keys and connected AI clients made over the last 7, 30 or 90 days: per day, per tool, per site and per credential. Each call is one of three things:
- Answered — the tool replied (an id that names nothing still counts as answered: the reply
was
null). - Refused — we turned it down: a site the key may not read, a missing or malformed
siteId, a role the site does not give you, or the change tool asked by a key created without changes allowed. A key whose refusals climb is usually an integration sending the wrong site. - Failed — an error on our side.
Narrow it to one site, one key or connection, or one tool with the menus beside the window; each narrows your own calls only. This is the one screen for the report — the organization's copy is gone from the dashboard. A call to a tool name that does not exist is answered but not counted. Counts are kept for 90 days.
Revoking
Your profile → Personal keys → Revoke ends a key at once. Every key is also revoked, together with every AI connection, when you:
- change your password or reset it through the emailed link,
- turn two-factor authentication off, or an operator resets it,
- move your account to a new email address,
- press Sign out everywhere else.
A key also ends by itself on its expiry date. Deleting your account deletes its keys.