Authentication
Every API request is authenticated with an API key sent as a Bearer token:
http
Authorization: Bearer dk_live_your_api_keyRequests without a valid key are rejected with 401 Unauthorized — see the
error catalog.
API keys#
- Keys have the format
dk_live_followed by 32 URL-safe base64 characters, e.g.dk_live_a1B2c3D4.... - One key per venue. Generating a new key replaces the previous one — the old key stops working immediately.
- Only the first 16 characters (the prefix) are stored in readable form and shown in the app for identification. The full key is stored as a hash and cannot be recovered after generation.
The full key is shown only once
Copy the key right after generating it and store it in a secrets manager. Never commit API keys to source control or embed them in client-side code. If a key leaks, revoke it or generate a new one — the old key is invalidated instantly.
Generating and revoking keys#
In the DuckHub app, open Integrations (available on every plan, including the free Egg plan):
- Generate API key — creates the key and shows it once.
- Regenerate — replaces the existing key (old one stops working).
- Revoke — deletes the key; all API access stops until a new key is generated.
About dk_test_ keys
The API accepts the dk_test_ prefix as a valid key format, but
DuckHub currently issues only dk_live_ keys — there is no separate test
mode. Use a non-production venue for testing.
Request headers#
| Header | Value | Required |
|---|---|---|
Authorization | Bearer dk_live_... | Yes |
Content-Type | application/json | For requests with a body |
User-Agent | e.g. my-pos/1.2 (+https://example.com) | Recommended — helps diagnose integration issues |
Example authenticated request#
bash
curl -X POST https://api.duck-hub.com/v1/sync \
-H "Authorization: Bearer dk_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{"categories":[{"externalId":"cat-mains","name":"Mains"}]}'javascript
const response = await fetch('https://api.duck-hub.com/v1/sync', {
method: 'POST',
headers: {
Authorization: 'Bearer dk_live_your_api_key',
'Content-Type': 'application/json',
},
body: JSON.stringify({
categories: [{ externalId: 'cat-mains', name: 'Mains' }],
}),
})
const result = await response.json()Authentication errors#
| Response | Cause |
|---|---|
401 Missing API key | No Authorization header, or it does not start with Bearer |
401 Invalid API key format | The token does not start with dk_live_ or dk_test_ |
401 Invalid API key | Unknown, revoked or regenerated key |