API key endpoints
Programmatic key management. For the conceptual lifecycle (mint → use → rotate → revoke) and best practices, see Authentication — API keys.
GET /api/key/whoami
Identify the caller. Works for any auth method (JWT or API key).
curl -H "Authorization: Bearer $KEY" \
"https://portal.scrapewise.ai/api/scraper-api/api/key/whoami"Response:
{
"customerRef": "...",
"scope": "USER",
"prefix": "abc1234",
"name": "my-laptop",
"id": "...",
"createdAt": "2026-05-10T...",
"lastUsedAt": "2026-05-19T..."
}For Firebase JWT callers, prefix is empty.
PUT /api/key/generate
Mint a new API key.
curl -X PUT \
-H "Authorization: Bearer $EXISTING_KEY" \
"https://portal.scrapewise.ai/api/scraper-api/api/key/generate?name=my-new-key&scope=USER"Query params:
| Param | Required | Description |
|---|---|---|
name | yes | Human label. Any non-empty string up to 64 chars. |
scope | yes | One of USER, LLM_READ, LLM_FULL. See Scopes. |
Response:
{
"id": "key_xyz789",
"prefix": "abc1234",
"name": "my-new-key",
"scope": "USER",
"key": "sw_live_abc1234.<long-secret>",
"createdAt": "2026-05-19T12:30:00Z"
}The key field is the only place the full secret appears. Save it immediately — after the response, only the hash is retained.
Permissions
The calling key must itself have scope USER to mint new keys. LLM_READ / LLM_FULL cannot mint child keys (since AI agents shouldn’t be able to provision new credentials).
GET /api/key/list
List all keys for the calling customer.
curl -H "Authorization: Bearer $KEY" \
"https://portal.scrapewise.ai/api/scraper-api/api/key/list"Response:
{
"keys": [
{
"id": "key_xyz789",
"prefix": "abc1234",
"name": "my-new-key",
"scope": "USER",
"createdAt": "2026-05-19T...",
"lastUsedAt": "2026-05-19T..."
},
...
]
}Secrets are never returned. Use prefix + lastUsedAt to identify keys.
DELETE /api/key/{id}
Revoke a key by id (from /api/key/list).
curl -X DELETE -H "Authorization: Bearer $KEY" \
"https://portal.scrapewise.ai/api/scraper-api/api/key/key_xyz789"Revocation is immediate — the next request with that key returns 401.
A key can revoke other keys in the same customer (including keys with higher scope). A key can also revoke itself, though usually you’d use a different key to do so.
Note — prefix vs id
When you list keys you see both:
prefix(7 chars, e.g.abc1234) — embedded in the key string, visible in audit logsid(the internal identifier, e.g.key_xyz789) — used in delete URLs
The DELETE endpoint expects id, not prefix.
Node.js wrapper
class ScrapewiseKeys {
constructor(private bearer: string) {}
private async req(path: string, init?: RequestInit): Promise<unknown> {
const res = await fetch(`https://portal.scrapewise.ai/api/scraper-api${path}`, {
...init,
headers: { ...init?.headers, Authorization: `Bearer ${this.bearer}` },
});
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
return res.json();
}
whoami() {
return this.req('/api/key/whoami');
}
mint(name: string, scope: 'USER' | 'LLM_READ' | 'LLM_FULL') {
return this.req(`/api/key/generate?name=${encodeURIComponent(name)}&scope=${scope}`, { method: 'PUT' });
}
list() {
return this.req('/api/key/list');
}
revoke(id: string) {
return this.req(`/api/key/${id}`, { method: 'DELETE' });
}
}Common errors
| Status / code | Meaning |
|---|---|
401 unauthorized | Bad Authorization header |
403 scope_rejected | Calling key isn’t allowed to do this (e.g. LLM_READ trying to mint) |
404 key_not_found | DELETE: id doesn’t exist for your customer |
422 invalid_scope | scope query param isn’t one of the three customer-mintable scopes |