Secret API keys authenticate your servers to the Tried API. Send the key as a bearer token:
curl https://api.tried.com.au/list-agents \
-H "Authorization: Bearer key_4f1c..."Keys belong to a workspace. Anyone with a key can act on that workspace within the key's scopes, so keep keys on your server. For browsers and websites, use a public key instead.
Key format and storage#
- A key is
key_followed by 48 hex characters (192 random bits). - Tried stores a SHA-256 hash for lookups and an encrypted copy (AES-256-GCM, derived from the server's
SESSION_SECRET). The dashboard shows a masked value: the first 8 characters, eight asterisks and the last 4 (for examplekey_4f1c********9a2e). - The full key is shown once, when you create it.
- Each use updates Last used, so you can tell when an old key is safe to delete.
Create a key#
Open API Keys#
Go to Settings, API Keys and click Add Key. Admins and developers can manage keys. Members cannot see this page's keys.
Name it and set access#
Give the key a Name (for example Production backend). Optionally tick Use for webhook signing and set Scopes, IP allowlist and Rate limit (requests per minute).
Save the key#
The Save your API key dialog shows the full key once: This is the only time the full key is shown. Store it somewhere safe. Click Copy, then I've saved it.
The table lists Name (with a Webhook badge on the webhook key), Key Value (masked), Access, Last used and Created at.
Scopes#
A key with no scopes has Full access: it can call every endpoint. Adding scopes limits the key to the endpoints in those scopes. A request outside them returns 403 with This API key lacks the "<scope>" scope.
| Scope | Label | Covers |
|---|---|---|
agents |
Agents | Agents, LLMs, flows, voices, tests, copilot, share links, workflows |
calls |
Calls | Calls, batch calls, chats, SMS, contacts, recordings, analysis backfill |
numbers |
Numbers | Phone numbers, SIP trunks, branded caller ID, verified numbers, concurrency settings |
kb |
Knowledge bases | Knowledge bases and their sources |
analytics |
Analytics | Analytics, QA, alerting, get-concurrency, dashboards |
admin |
Admin | Everything, including keys and billing |
Endpoints that match no other scope (for example /api-keys, /billing, /workspace) need admin. A key with admin passes every scope check.
IP allowlist#
Add IPv4 or IPv6 addresses (up to 50) under IP allowlist. Requests from any other address get 403 with This API key is not allowed from <ip>. Leave it empty to allow any IP. Entries are exact addresses, not CIDR ranges.
Behind a load balancer, the API must see the client's real address. Check the address in a 403 message if a key you expect to work is rejected.
Rate limit per key#
Each key has a sliding one-minute window. The default is 600 requests per minute (RATE_LIMIT_PER_KEY on the server). Set Rate limit (requests per minute) to give a key its own limit (1 to 100,000). Responses carry:
| Header | Meaning |
|---|---|
x-ratelimit-limit |
Requests allowed per minute for this key |
x-ratelimit-remaining |
Requests left in the current window |
x-ratelimit-reset |
Seconds until the window resets |
Over the limit, the API returns 429 with retry-after. A per-IP limit (default 3,000 per minute, RATE_LIMIT_PER_IP) also applies to every request before authentication. The windows live in Redis when REDIS_URL is set, so they hold across API instances.
The webhook key#
Exactly one key per workspace is the webhook key. Its secret signs every outgoing webhook in the x-tried-signature header (and x-retell-signature, for receivers built for Retell). The workspace's first key, Default key, starts as the webhook key.
To change it, open a key's menu and choose Set as webhook key, or tick Use for webhook signing when creating a key. The previous webhook key loses the flag. Your receivers must then verify with the new key's secret. See Secure webhooks for verification code.
Deleting the webhook key leaves the workspace without one. The delete dialog warns This is your webhook signing key. Set another key as the webhook key first.
Rotate a key#
There is no limit on the number of active keys, so you can rotate without downtime:
- Create a new key with the same scopes and allowlist.
- Deploy it to your servers.
- Watch Last used on the old key until it stops changing.
- Delete the old key. Requests using it fail immediately.
Key creation, access changes and deletion are recorded in the audit log as api_key.create, api_key.update and api_key.delete.
API#
| Method and path | Purpose |
|---|---|
GET /api-keys |
List keys (masked) |
POST /api-keys |
Create: name, is_webhook_key, scopes, allowed_ips, rate_limit_per_minute. Returns api_key once |
PATCH /api-keys/:id |
Change name, webhook flag or access |
DELETE /api-keys/:id |
Delete (204) |
{
"api_key_id": "key_8d2f4a6b1c3e5d7f9a0b2c4d",
"name": "Production backend",
"masked_key": "key_4f1c********9a2e",
"is_webhook_key": false,
"created_timestamp": 1760668800000,
"last_used_timestamp": null,
"scopes": ["calls", "agents"],
"allowed_ips": ["203.0.113.10"],
"rate_limit_per_minute": 300,
"api_key": "key_4f1c...9a2e"
}api_key_id identifies the key record. api_key is the secret and only appears in this response.