Appendix API
Create an API key
Issue a new API key for your account. The full key is shown once.
https://api.screamingdata.dev/v1/appendix/keys- Authentication
- API key (HTTP Basic)
- Cost
- Free
- Body
- Array of up to 100 tasks
Overview
Creates a new API key. The response is the only time the full key is shown — store it in your secret manager right away. Afterwards only prefix and last4 are visible in user_data.
Each element of the array creates one key. An account can have up to 20 active keys; beyond that the task fails with 40000 — revoke a key first. Use separate keys per environment or integration so you can rotate or revoke one without touching the others.
Cost
Request
POST /v1/appendix/keys with Content-Type: application/json.
Body fields
The request body is a JSON array of 1–100 task objects. Each object has these fields:
labelA name that helps you recognise the key, for example the environment or service using it.
- Max length100 characters
- Example
ci-pipeline
Request example
The examples read your credentials from the API_LOGIN and API_KEY environment variables.
curl --request POST \
--url "https://api.screamingdata.dev/ v1/ appendix/ keys" \
--user "$API_LOGIN:$API_KEY" \
--header "Content-Type: application/json" \
--data '[
{
"label": "ci-pipeline"
}
]'import os
import requests
response = requests.post(
"https://api.screamingdata.dev/ v1/ appendix/ keys",
auth=(os.environ["API_LOGIN"], os.environ["API_KEY"]),
json=[
{"label": "ci-pipeline"},
],
timeout=30,
)
data = response.json()
print(data["status_code"], data["status_message"], "cost:", data["cost"])
for task in data["tasks"]:
print(task["id"], task["status_code"], task["status_message"])const auth = Buffer.from(`${process.env.API_LOGIN}:${process.env.API_KEY}`).toString("base64");
const response = await fetch("https://api.screamingdata.dev/ v1/ appendix/ keys", {
method: "POST",
headers: {
Authorization: `Basic ${auth}`,
"Content-Type": "application/json",
},
body: JSON.stringify([
{ label: "ci-pipeline" },
]),
});
const data = await response.json();
console.log(data.status_code, data.status_message, "cost:", data.cost);
for (const task of data.tasks) {
console.log(task.id, task.status_code, task.status_message);
}Response
HTTP 200. The body is the standard response envelope; check status_code at the top level and in every task.
{
"version": "1.0.0",
"status_code": 20000,
"status_message": "Ok.",
"time": "0.0233 sec.",
"cost": 0,
"tasks_count": 1,
"tasks_error": 0,
"tasks": [
{
"id": "09241258-3e7a-4b1c-8d9f-5a2c0e6b4d13",
"status_code": 20000,
"status_message": "Ok.",
"time": "0.0071 sec.",
"cost": 0,
"result_count": 1,
"path": [
"v1",
"appendix",
"keys"
],
"data": {
"api": "appendix",
"function": "keys",
"label": "ci-pipeline"
},
"result": [
{
"id": 22,
"key": "sd_live_R8vN2kQp-EXAMPLE-not-a-real-key-Ky0e",
"prefix": "sd_live_R8vN",
"last4": "Ky0e",
"label": "ci-pipeline",
"created_at": "2026-09-24T12:58:30Z",
"last_used_at": null,
"revoked_at": null
}
]
}
]
}Result fields
Each element of tasks[].result is a new api key. The only response that contains the full key. Store it securely right away.
idKey id. Use it to revoke the key.
keyFull API key: sd_live_ followed by 40 URL-safe characters. Shown once.
prefixFirst 12 characters, for display.
last4Last 4 characters, for display.
labelYour label.
created_atCreation time, ISO 8601 in UTC.
last_used_atAlways null for a new key.
revoked_atAlways null for a new key.
Status codes
Codes this endpoint can return, at the request or task level. See Status codes for handling advice.
| Code | Message | HTTP | Level | When |
|---|---|---|---|---|
| 20000 | Ok. | 200 | Request / task | The request, or the individual task, was processed successfully. |
| 40000 | Bad Request. | 400 / 200 | Request / task | The body is not valid JSON or does not have the expected shape (for example, not an array of task objects, or more than one task for live). Also returned with HTTP 413 for bodies larger than 1 MiB and with HTTP 405 for a wrong HTTP method. As a task-level code (HTTP 200) it means the task cannot be carried out as asked, for example because the account already has the maximum number of API keys or monitored products. |
| 40100 | Authentication failed. | 401 | Request | The Authorization header is missing or malformed, or the login and API key do not match. |
| 40101 | API key revoked. | 401 | Request | The API key was revoked. Use another active key or create a new one. |
| 40102 | Account disabled. | 401 | Request | The account is disabled. Contact support. |
| 40202 | Rate limit exceeded. | 429 | Request | Too many requests or tasks per minute for this account, or too many access requests from one IP address. The Retry-After header says how many seconds to wait. |
| 40501 | Invalid field: `<name>`. | 400 / 200 | Request / task | A field has a wrong type, format or value; the message names the field, for example "Invalid field: `priority`." |
| 50000 | Internal error. | 500 | Request | Unexpected server error. The request can be retried; contact support if it persists. |