You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Machine/spec files piece of the 2026-06-26 docs reality audit (WIP tip
83fb982), applied on top of the merged family pieces and reconciled
against today's main + live API.
- public/openapi.json: provenance metadata refresh only (x-generated-at,
x-commit-sha). Semantic body (paths + schemas) verified byte-identical
to main via scripts/check-openapi-version.mjs — no unmerged-family
(opportunities) endpoint changes to revert.
- public/openapi-version.json: sync stale sidecar 2.1.0 -> 3.1.0 to match
openapi.json info.version (stamp-openapi.mjs regenerates at build; this
fixes the committed state).
- public/sitemap.xml: regenerated with scripts/generate-sitemap.mjs
against today's content tree (228 URLs). Supersedes the audit's 224-URL
snapshot, which was already missing concepts/market-lifecycle (4
locales) added to main after the audit.
- content/en/api-reference/account-keys.mdx: key-management envelope
fixes from the audit ({success, data, meta}; create returns 200 not
201; rotate new_key/old_key shape + gracePeriodHours 0-72; delete
envelope; real error messages), sk_live_ example keys (truncated —
GitHub push protection rejects full-length fakes) replacing main's
fictional "sharpapi_..." format, plus two today-reality corrections
against the live handler: id_masked = "..." + last 8 chars, and
max_keys = 1 for pro tier (was 5).
Live-verified: GET /account/keys with an internal (no user_id) key
returns exactly the documented 400 {"error":{"code":"validation_error",
"message":"No user_id associated with this API key"}}; all four
operation response shapes and error strings confirmed against
sharp-api-go keys.go on main (1940dc1).
Co-authored-by: sharp-resolver[bot] <3736210+sharp-resolver[bot]@users.noreply.github.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: content/en/api-reference/account-keys.mdx
+97-87Lines changed: 97 additions & 87 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,5 +1,5 @@
1
1
---
2
-
description: "SharpAPI API key management — create, list, rotate, and delete API keys programmatically. Manage multiple keys per account with granular permissions and usage tracking."
2
+
description: "SharpAPI API key management — create, list, rotate, and delete API keys programmatically. Responses use the key-management success envelope."
3
3
---
4
4
5
5
import { Callout, Tabs } from'nextra/components'
@@ -10,7 +10,7 @@ Create, list, rotate, and delete API keys for your account.
10
10
11
11
## Authentication
12
12
13
-
All key management endpoints require authentication via an existing APIkey. **Available to all tiers.**
13
+
Key management endpoints support dashboard session auth and API-key auth. When you authenticate with an API key, that key must be associated with a SharpAPI user account; internal or service keys without `user_id` return `400 validation_error`.
14
14
15
15
<Callouttype="warning">
16
16
**Security:** API key management operations are sensitive. Only perform these from server-side code, never from a client-side application.
| `tier` | string | Subscription tier associated with the key. |
102
+
| `is_active` | boolean | Whether the key is currently active. |
103
+
| `created_at` | string | ISO 8601 timestamp of key creation. |
104
+
| `updated_at` | string | ISO 8601 timestamp of last key update. |
116
105
117
106
---
118
107
@@ -128,7 +117,7 @@ POST /api/v1/account/keys
128
117
129
118
| Field | Type | Required | Description |
130
119
|-------|------|----------|-------------|
131
-
|`name`| string |Yes|A descriptive name for the key (e.g., "Production", "Mobile App")|
120
+
| `name` | string | No | Descriptive name for the key, max 100 characters. If omitted, the API assigns a default name. |
132
121
133
122
### Example Request
134
123
@@ -154,9 +143,9 @@ const response = await fetch(
154
143
body:JSON.stringify({ name:'Mobile App' })
155
144
}
156
145
);
157
-
const { data } =awaitresponse.json();
146
+
const { data, meta } =awaitresponse.json();
158
147
console.log(`New key: ${data.key}`);
159
-
// IMPORTANT: Store this key securely. It will not be shown again.
148
+
console.warn(meta.warning);
160
149
```
161
150
</Tabs.Tab>
162
151
<Tabs.Tab>
@@ -168,35 +157,39 @@ response = requests.post(
168
157
json={'name':'Mobile App'},
169
158
headers={'X-API-Key':'YOUR_API_KEY'}
170
159
)
171
-
new_key= response.json()['data']
172
-
print(f"New key: {new_key['key']}")
173
-
# IMPORTANT: Store this key securely. It will not be shown again.
160
+
body=response.json()
161
+
print(f"New key: {body['data']['key']}")
162
+
print(body['meta']['warning'])
174
163
```
175
164
</Tabs.Tab>
176
165
</Tabs>
177
166
178
-
### Response (201)
167
+
### Response (200)
179
168
180
169
```json
181
170
{
171
+
"success":true,
182
172
"data": {
183
173
"id":"key_new345mno678",
184
-
"key": "sharpapi_new345mno678pqr901stu234vwx567",
174
+
"key":"sk_live_new345mno678...",
185
175
"name":"Mobile App",
186
176
"tier":"pro"
177
+
},
178
+
"meta": {
179
+
"warning":"This is the only time the key value will be shown. Store it securely."
187
180
}
188
181
}
189
182
```
190
183
191
184
<Callout type="warning">
192
-
**Important:** The full `key` value is **only returned once** at creation time. Store it securely immediately. Subsequent requests will only show the `id_masked` preview.
185
+
**Important:** The full `key` value is only returned once at creation time. Store it securely immediately.
Generate a new key value for an existing API key. The old key is immediately revoked and replaced with a new one.
283
+
Generate a new key value and replace an existing API key. By default, the old key is revoked immediately. You may request a grace period up to 72 hours.
290
284
291
285
```
292
286
POST/api/v1/account/keys/{keyId}/rotate
@@ -296,15 +290,24 @@ POST /api/v1/account/keys/{keyId}/rotate
296
290
297
291
| Parameter | Type | Description |
298
292
|-----------|------|-------------|
299
-
|`keyId`| string | The `key_id` of the key to rotate |
293
+
| `keyId` | string | The key id to rotate. |
294
+
295
+
### Request Body
296
+
297
+
| Field | Type | Required | Description |
298
+
|-------|------|----------|-------------|
299
+
| `gracePeriodHours` | number | No | Keep the old key valid for this many hours, from `0` to `72`. Defaults to `0`. |
300
+
| `name` | string | No | Name for the replacement key. Defaults to the old key's name. |
"warning":"The new key value is only shown once. Store it securely.",
367
+
"message":"Key rotated. Old key has been revoked immediately."
354
368
}
355
369
}
356
370
```
357
371
358
372
<Callout type="warning">
359
-
**Immediate effect:** The previous key value is revoked the instant rotation completes. Update your application configuration before the next API request. The new `key` value is only shown once.
360
-
</Callout>
361
-
362
-
<Callouttype="info">
363
-
**Tip:** If you are rotating the key you are currently authenticating with, the rotation will succeed, but you must use the new key for all subsequent requests.
373
+
**Immediate effect:** Unless you request a grace period, the previous key value is revoked the instant rotation completes. Update your application configuration before the next API request. The new `key` value is only shown once.
364
374
</Callout>
365
375
366
376
---
367
377
368
378
## Response Headers
369
379
370
-
All key management endpoints return standard ratelimit headers:
380
+
Key management endpoints return standard rate-limit headers:
371
381
372
382
```
373
383
X-RateLimit-Limit:300
374
384
X-RateLimit-Remaining:294
375
-
X-RateLimit-Reset: 1707401400
385
+
X-RateLimit-Reset:1782851940
376
386
X-Data-Delay:0
377
-
X-Request-Id: req_keys123xyz
387
+
X-Request-Id:1782851943426721-511042
378
388
```
379
389
380
390
## Best Practices
381
391
382
-
1.**Use descriptive names** - Name keys by their purpose (e.g., "Production Server", "Staging", "Mobile App") to easily identify them later
383
-
2.**Rotate regularly** - Rotate keys periodically (e.g., every 90 days) as a security best practice
384
-
3.**Use separate keys per environment** - Create distinct keys for production, staging, and development
385
-
4.**Review inactive keys** - Identify and clean up unused keys
386
-
5.**Store keys in secrets management** - Use environment variables or a secrets manager, never hardcode keys
387
-
6.**Revoke compromised keys immediately** - If a key is exposed, delete or rotate it right away
392
+
1. **Use descriptive names** - Name keys by their purpose, such as "Production Server" or "Staging".
393
+
2. **Rotate regularly** - Rotate keys periodically, such as every 90 days.
394
+
3. **Use separate keys per environment** - Create distinct keys for production, staging, and development.
395
+
4. **Review inactive keys** - Identify and clean up unused keys.
396
+
5. **Store keys in secrets management** - Use environment variables or a secrets manager, never hardcode keys.
397
+
6. **Revoke compromised keys immediately** - If a key is exposed, delete or rotate it right away.
0 commit comments