Repository navigation
API Reference API Keys
github-actions[bot] edited this page Oct 7, 2026
·
1 revision
Keys for this API. Part of the API reference: setup, shared types and errors are there.
-
List API keys:
GET /keys -
Create an API key:
POST /keys -
Revoke an API key:
DELETE /keys/:id
GET /keys · scope keys:read
Never their secrets. With the scopes and presets there are.
| Parameter | In | Required | Description |
|---|---|---|---|
site |
query | no | The site (a key always uses its own). |
Request
curl "$HELPPUFF_URL/api/v1/keys" \
-H "Authorization: Bearer $HELPPUFF_API_KEY"const response = await fetch(`${process.env.HELPPUFF_URL}/api/v1/keys`, {
headers: {
Authorization: `Bearer ${process.env.HELPPUFF_API_KEY}`,
},
});
if (!response.ok) throw new Error(((await response.json()) as ApiError).error.message);
const data = (await response.json()) as ListAPIKeysResponse;Response 200
{
"keys": [
{
"id": "k7m3p9q2r4s8",
"name": "Website backend",
"prefix": "hp_live_k7m3p9q2r4s8",
"site": "acme",
"scopes": [
"chat",
"leads:read"
],
"allowIps": [],
"ratePerMinute": 120,
"createdBy": "owner@acme.example",
"createdAt": 1760000000000,
"expiresAt": null,
"lastUsedAt": null,
"revokedAt": null
}
],
"scopes": [
{
"scope": "chat",
"description": "Talk to the assistant as a visitor…"
}
],
"presets": [
{
"id": "chat",
"label": "Chat only",
"scopes": [
"chat"
]
}
]
}type ListAPIKeysResponse = {
keys: Array<{
id: string;
name: string;
prefix: string;
site: string;
scopes: string[];
allowIps: string[];
ratePerMinute: number;
createdBy: string;
createdAt: number;
expiresAt: number | null;
lastUsedAt: number | null;
revokedAt: number | null;
}>;
scopes: Array<{
scope: string;
description: string;
}>;
presets: Array<{
id: string;
label: string;
scopes: string[];
}>;
};POST /keys · scope keys:write
The full key is in this answer only: store it in your secrets manager. A key cannot create a key with scopes it does not have.
| Body field | Required | Description |
|---|---|---|
name |
yes | What the key is for. |
preset |
no |
chat, crm, read or full. Or, instead: |
scopes |
no | A list of scopes (see the API page). |
expiresInDays |
no | 1–3650; absent or null: never. |
allowIps |
no | IP addresses or CIDR ranges it may be used from. |
ratePerMinute |
no | Requests a minute (default 120). |
Request
curl -X POST "$HELPPUFF_URL/api/v1/keys" \
-H "Authorization: Bearer $HELPPUFF_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Website backend",
"preset": "chat",
"expiresInDays": 365
}'type CreateAPIKeyRequest = {
/** What the key is for. */
name: string;
/** `chat`, `crm`, `read` or `full`. Or, instead: */
preset?: string;
/** A list of scopes (see the API page). */
scopes?: string;
/** 1–3650; absent or null: never. */
expiresInDays?: number;
/** IP addresses or CIDR ranges it may be used from. */
allowIps?: string;
/** Requests a minute (default 120). */
ratePerMinute?: string;
};
const response = await fetch(`${process.env.HELPPUFF_URL}/api/v1/keys`, {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.HELPPUFF_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
name: 'Website backend',
preset: 'chat',
expiresInDays: 365
} satisfies CreateAPIKeyRequest),
});
if (!response.ok) throw new Error(((await response.json()) as ApiError).error.message);
const data = (await response.json()) as CreateAPIKeyResponse;Response 201
{
"key": "hp_live_k7m3p9q2r4s8_Zx1…",
"id": "k7m3p9q2r4s8",
"name": "Website backend",
"prefix": "hp_live_k7m3p9q2r4s8",
"site": "acme",
"scopes": [
"chat"
],
"allowIps": [],
"ratePerMinute": 120,
"createdBy": "owner@acme.example",
"createdAt": 1760000000000,
"expiresAt": 1791536000000,
"lastUsedAt": null,
"revokedAt": null
}type CreateAPIKeyResponse = {
key: string;
id: string;
name: string;
prefix: string;
site: string;
scopes: string[];
allowIps: string[];
ratePerMinute: number;
createdBy: string;
createdAt: number;
expiresAt: number;
lastUsedAt: number | null;
revokedAt: number | null;
};Errors
| Status | Code | When |
|---|---|---|
| 403 | forbidden |
The calling key would hand out scopes it does not have. |
DELETE /keys/:id · scope keys:write
Refused everywhere within 30 seconds. :id is the key's id or prefix.
| Parameter | In | Required | Description |
|---|---|---|---|
id |
path | yes | The record's id. |
site |
query | no | The site (a key always uses its own). |
Request
curl -X DELETE "$HELPPUFF_URL/api/v1/keys/ID" \
-H "Authorization: Bearer $HELPPUFF_API_KEY"const id = '…';
const response = await fetch(`${process.env.HELPPUFF_URL}/api/v1/keys/${id}`, {
method: 'DELETE',
headers: {
Authorization: `Bearer ${process.env.HELPPUFF_API_KEY}`,
},
});
if (!response.ok) throw new Error(((await response.json()) as ApiError).error.message);
const data = (await response.json()) as RevokeAPIKeyResponse;Response 200
{
"id": "k7m3p9q2r4s8",
"name": "Website backend",
"prefix": "hp_live_k7m3p9q2r4s8",
"site": "acme",
"scopes": [
"chat",
"leads:read"
],
"allowIps": [],
"ratePerMinute": 120,
"createdBy": "owner@acme.example",
"createdAt": 1760000000000,
"expiresAt": null,
"lastUsedAt": null,
"revokedAt": 1760000060000,
"revoked": true
}type RevokeAPIKeyResponse = {
id: string;
name: string;
prefix: string;
site: string;
scopes: string[];
allowIps: string[];
ratePerMinute: number;
createdBy: string;
createdAt: number;
expiresAt: number | null;
lastUsedAt: number | null;
revokedAt: number;
revoked: boolean;
};Start
Tutorials
- All tutorials
- Order tracking
- Send chats to your CRM
- Nearest store
- Verified account changes
- Logged-in customer support
- Product and stock
- Hot leads to Slack
- Knowledge base or tool?
- Testing and monitoring
- Why the AI never books
Configure
- Configuration
- Configuration reference
- CLI reference
- Knowledge base
- Prompt and instructions
- Tools: your APIs in the chat
- Agent files: import and export
- Signed-in visitors
- The widget
- The playground
- Leads and callbacks
- Jobs
- Photos and files
- Bookings and the calendar
- Integrations
- Live chat
- Telegram
- Webhooks
- Email notifications
API
API reference
- Overview
- Account
- Chat
- Conversations
- Live chat
- Labels and notes
- Leads
- Callbacks
- Jobs
- Appointments
- Integrations
- Knowledge
- Prompt
- Tools
- Settings
- Webhooks
- Analytics
- Team
- API keys
- Audit
Providers
- Overview
- Models and providers
- Custom model
- Custom knowledge base
- Workers AI (default)
- AI models: speed, quality, cost
- Cloudflare AI Search
- OpenAI
- Gemini
- Anthropic Claude
- Retell
- Your own API
Operate
- Deployment
- Turn on Turnstile
- Upgrading
- Costs and limits
- Cloudflare Free plan limits
- Security
- Troubleshooting
Build