API keys
Private keys: list, create (secret shown once), revoke.
This is not the live API. This page documents an earlier, in-browser mock API (routes like /accounts, /messaging and /brand), kept for reference. The real, read-only API that runs today is described in The API.
API keys — workspace secrets
Private keys authenticate your programs as your workspace. Each key is scoped (account + groups + send/receive bits) and only its prefix is stored — the full secret appears once at creation. The dashboard's API tab creates and revokes these; this section documents the exact mock these routes are exercised against.
Use GET /api-keys to list, POST /api-keys to create (validates unique name case-insensitively and well-formed scopes), and DELETE /api-keys/{id} to revoke immediately (unknown ids are a no-op 200). All three live in apps/web/src/lib/api/server.ts and are the only routes currently tested by api-coverage.test.ts.
GET /api-keys — List API keys
Records carry the prefix only — there is no secret field to leak.
POST /api-keys — Create an API key
The full secret appears exactly once, in this response.
DELETE /api-keys/{id} — Revoke an API key
Revoking is immediate; unknown ids are a no-op returning the list.
List API keys
Records carry the prefix only — there is no secret field to leak.
/api-keysResponse Body
Key list.
TypeScript Definitions
Use the response body type in TypeScript.
apiKeysRequiredarray<object>curl -X GET "http://localhost:5174/api-keys"fetch("http://localhost:5174/api-keys")package mainimport ( "fmt" "net/http" "io/ioutil")func main() { url := "http://localhost:5174/api-keys" req, _ := http.NewRequest("GET", url, nil) res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := ioutil.ReadAll(res.Body) fmt.Println(res) fmt.Println(string(body))}import requestsurl = "http://localhost:5174/api-keys"response = requests.request("GET", url)print(response.text){
"apiKeys": [
{
"id": "string",
"name": "string",
"prefix": "string",
"secretHash": "string",
"scopes": {
"accountId": "string",
"groupIds": [
"string"
],
"canSendMessages": true,
"canReceiveMessages": true
},
"createdAt": "string",
"lastUsedAt": "string"
}
]
}Create an API key
The full secret appears exactly once, in this response.
/api-keysRequest Body
application/jsonRequirednameRequiredstringKey name; unique case-insensitively.
scopesRequiredobjectResponse Body
Created; key is the full secret (once-only).
TypeScript Definitions
Use the response body type in TypeScript.
apiKeyRequiredobjectapiKeysRequiredarray<object>keyRequiredstringFull secret — returned exactly once, never again.
Failure envelope returned with 4xx statuses.
TypeScript Definitions
Use the response body type in TypeScript.
errorRequiredstringHuman-readable failure reason, e.g. "A key needs a name".
Failure envelope returned with 4xx statuses.
TypeScript Definitions
Use the response body type in TypeScript.
errorRequiredstringHuman-readable failure reason, e.g. "A key needs a name".
curl -X POST "http://localhost:5174/api-keys" \ -H "Content-Type: application/json" \ -d '{ "name": "string", "scopes": { "accountId": "string", "groupIds": [ "string" ], "canSendMessages": true, "canReceiveMessages": true } }'const body = JSON.stringify({ "name": "string", "scopes": { "accountId": "string", "groupIds": [ "string" ], "canSendMessages": true, "canReceiveMessages": true }})fetch("http://localhost:5174/api-keys", { body})package mainimport ( "fmt" "net/http" "io/ioutil" "strings")func main() { url := "http://localhost:5174/api-keys" body := strings.NewReader(`{ "name": "string", "scopes": { "accountId": "string", "groupIds": [ "string" ], "canSendMessages": true, "canReceiveMessages": true } }`) req, _ := http.NewRequest("POST", url, body) req.Header.Add("Content-Type", "application/json") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := ioutil.ReadAll(res.Body) fmt.Println(res) fmt.Println(string(body))}import requestsurl = "http://localhost:5174/api-keys"body = { "name": "string", "scopes": { "accountId": "string", "groupIds": [ "string" ], "canSendMessages": true, "canReceiveMessages": true }}response = requests.request("POST", url, json = body, headers = { "Content-Type": "application/json"})print(response.text){
"apiKey": {
"id": "string",
"name": "string",
"prefix": "string",
"secretHash": "string",
"scopes": {
"accountId": "string",
"groupIds": [
"string"
],
"canSendMessages": true,
"canReceiveMessages": true
},
"createdAt": "string",
"lastUsedAt": "string"
},
"apiKeys": [
{
"id": "string",
"name": "string",
"prefix": "string",
"secretHash": "string",
"scopes": {
"accountId": "string",
"groupIds": [
"string"
],
"canSendMessages": true,
"canReceiveMessages": true
},
"createdAt": "string",
"lastUsedAt": "string"
}
],
"key": "string"
}{
"error": "string"
}{
"error": "string"
}Revoke an API key
Revoking is immediate; unknown ids are a no-op returning the list.
/api-keys/{id}Path Parameters
idRequiredstringKey id.
Response Body
Remaining key list.
TypeScript Definitions
Use the response body type in TypeScript.
apiKeysRequiredarray<object>curl -X DELETE "http://localhost:5174/api-keys/string"fetch("http://localhost:5174/api-keys/string")package mainimport ( "fmt" "net/http" "io/ioutil")func main() { url := "http://localhost:5174/api-keys/string" req, _ := http.NewRequest("DELETE", url, nil) res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := ioutil.ReadAll(res.Body) fmt.Println(res) fmt.Println(string(body))}import requestsurl = "http://localhost:5174/api-keys/string"response = requests.request("DELETE", url)print(response.text){
"apiKeys": [
{
"id": "string",
"name": "string",
"prefix": "string",
"secretHash": "string",
"scopes": {
"accountId": "string",
"groupIds": [
"string"
],
"canSendMessages": true,
"canReceiveMessages": true
},
"createdAt": "string",
"lastUsedAt": "string"
}
]
}