API Keys
API Keys (sk_live_*) authenticate tool clients (PicGo / Moraya / your own scripts) to Picora’s API. An API Key is also the credential for stdio MCP; Remote MCP uses OAuth instead and does not accept API Keys.
Creating an API Key
- Open Settings → API Keys
- Click Create new key
- Give it a name (e.g., “PicGo on MacBook”, “Production blog server”)
- Pick scopes (default: all)
- Click Create
- Copy the displayed key now — it’s shown once and never again
The full key looks like sk_live_abcdef0123456789... (40 characters total: sk_live_ prefix + 32 nanoid chars).
Scopes
Each key carries scope flags that determine what it can do:
Scopes are written in dot notation and are shared with OAuth grants, so an API Key and an OAuth token with the same scopes can do exactly the same things:
| Scope | Includes |
|---|---|
media.read | List images / videos / audio, read their metadata |
media.write | Upload media, update title and visibility |
media.delete | Permanently delete media (irreversible) |
kb.read | List knowledge bases, fetch manifests, read documents |
kb.write | Create, update and delete documents and knowledge bases |
account.read | Read profile (email, nickname, plan) |
usage.read | Read your own quota / usage counters |
By default, keys get the *.read and *.write scopes but not media.delete — to reduce blast radius if a key leaks.
You can refine scopes per key:
PicGo Blog Key → media.write only (cannot list / delete)CI Pipeline Key → media.write + kb.writeRead-only Audit Key → media.read + kb.read + usage.readKeys created before v0.31 carry one of three coarse tiers (read / read_write / read_write_delete); the server expands them into the same dot-notation scopes. See Authentication for the exact mapping.
Using an API Key
In every API request:
curl -H "Authorization: Bearer sk_live_..." https://api.picora.me/v1/imagesTool clients embed the key in their config:
- PicGo: see PicGo integration
- Moraya: see Moraya integration
- Custom scripts: just include
Authorization: Bearer sk_live_...header
Listing keys
Settings → API Keys shows all your active keys with:
- Name
- Last 4 characters (e.g.,
...4f3a) - Scopes granted
- Last used timestamp
- Created date
You cannot view the full key value after creation — only the suffix for identification.
Rotation
Best practice: rotate API Keys every 90 days, or immediately if you suspect compromise.
- Create a new key with the same name + same scopes
- Update your tool config to use the new key (test that it works)
- Once verified, click Revoke on the old key in the keys list
Revoked keys are immediately invalid — any in-flight requests using them get 401.
Revocation
Click Revoke on any active key. The token cache is purged within 5 seconds globally. The key cannot be recovered after revocation.
If you revoked the wrong key: create a new one with the same scopes. There’s no undo.
Security best practices
DO
- ✅ Use separate keys per tool / environment — easier to rotate / revoke
- ✅ Minimize scopes — only grant what the tool needs
- ✅ Store keys in environment variables or a secret manager (not in source code)
- ✅ Rotate every 90 days
- ✅ Revoke immediately on suspected leak
DON’T
- ❌ Commit keys to git (even private repos — they leak through forks, mirrors, CI logs)
- ❌ Embed keys in client-side code (browsers, mobile apps) — they’re visible in network tab
- ❌ Share keys via email / Slack / Discord — use a secret manager
- ❌ Use a single “master key” for everything — separate concerns
If you accidentally committed a key to git
- Revoke the key immediately in Settings → API Keys
- Remove from git history (use
git filter-branchor BFG Repo-Cleaner) - Force-push the cleaned history (warn collaborators first)
- Create a new key for your tool
GitHub’s secret scanning will detect leaked Picora keys and alert us — we’ll auto-revoke and email you within 1 hour.
Programmatic key management
You can manage keys via API:
# Create a key (requires JWT, not a key — keys can't create keys for security)POST /v1/api-keys{ "name": "Backup script", "scopes": ["media.write"]}
# ListGET /v1/api-keys
# RevokeDELETE /v1/api-keys/{keyId}See API Reference — API Keys for full details.
Common issues
“401 Unauthorized” with valid-looking key — check the Authorization header format: must be Bearer prefix + key. Common mistake: missing Bearer or extra whitespace.
“403 Forbidden — missing scope” — your key doesn’t have the required scope. Create a new key with the right scopes; the old key cannot be edited (only revoked).
“Key works locally but not from production server” — likely IP-based rate limit (production server gets shared IP via load balancer). Inspect the 429 response’s RateLimit-Limit / RateLimit-Remaining / Retry-After headers to confirm.
Related
- Integration tools — PicGo / Moraya / Typora / Obsidian setups
- API Reference
- Security overview
- AI Workflows — for Claude / Cursor (uses OAuth, not API Keys)