Authentication
All Rinda API requests require authentication via an API key passed as a Bearer token.
API Keys
API keys are prefixed with rk_ followed by the environment identifier:
| Prefix | Environment |
|---|---|
rk_prod_... | Production |
rk_stg_... | Staging |
rk_dev_... | Development |
Creating an API Key
- Log in to the Rinda Dashboard
- Navigate to Settings > API Keys
- Click Create API Key
- Give it a descriptive name (e.g., "backend-service")
- Copy the key — it is only shown once
Using Your API Key
- Node.js SDK
- REST API
import { Rinda } from '@rindahq/sdk';
const rinda = new Rinda({
apiKey: process.env.RINDA_API_KEY, // rk_prod_...
});
curl https://api.rinda.dev/v1/queues \
-H "Authorization: Bearer $RINDA_API_KEY"
Works with any HTTP client in any language — just set the Authorization: Bearer <key> header.
Environment scoping
Each API key belongs to one project and one environment. A production key cannot reach staging queues, or the other way round.
Permissions
By default a key can do anything its plan allows. On a paid plan you can narrow that when creating the key:
| Preset | What it can do |
|---|---|
| Full access | Everything |
| Read only | Receive messages, list and inspect queues |
| Write only | Send messages, create and configure queues |
| Custom | Any combination of the individual permissions |
The individual permissions are queues:read, queues:write, messages:read,
and messages:write. A request outside a key's permissions is refused with
403 and a body naming the permission that was missing:
{
"error": {
"code": "insufficient_scope",
"message": "This API key cannot perform this action.",
"required": "messages:write",
"granted": ["messages:read", "queues:read"]
}
}
A key issued before permissions existed has none recorded and keeps full access, so nothing breaks on upgrade.
Expiry
On a paid plan a key can be given an expiry — 30, 90, or 365 days. After that it stops authenticating. A key with no expiry never lapses.
Rotating a key without downtime
Rotation issues a replacement and keeps the old key working for an overlap window, so there is no moment when neither key is valid:
curl -X POST https://api.rinda.dev/v1/api-keys/{keyId}/rotate \
-H "Authorization: Bearer $RINDA_SESSION" \
-H "Content-Type: application/json" \
-d '{"overlapHours": 24}'
{
"key": "rk_prod_the_new_key_shown_once",
"name": "Production Key",
"replaced": { "prefix": "rk_prod_a1b2c3", "expiresAt": "2026-08-26T12:00:00Z" }
}
The replacement carries the same permissions, environment, and expiry policy. The sequence is:
- Rotate. Both keys work.
- Deploy the new key.
- The old key expires at the end of the overlap — no action needed.
Both keys count against your plan's per-environment key limit during the overlap, so rotation needs a free slot. The Free tier allows one key per environment and therefore cannot rotate without a gap; paid plans allow three or more.
Rotation is not the same as revoking. Revoking cuts a key off immediately — right for a leaked key, wrong for a planned replacement.
Security practices
- Never commit keys. Use environment variables.
- Give each service its own key, so one can be revoked without affecting the others.
- Narrow the permissions. A service that only consumes needs
messages:read. - Rotate on a schedule using the overlap above, rather than revoking and scrambling to redeploy.
- Use environment-specific keys. Never a production key in development.
Error Responses
If authentication fails, the API returns a 401 Unauthorized response:
{
"statusCode": 401,
"message": "Unauthorized",
"error": "Invalid or missing API key"
}