Authentication
Authenticate Loop API requests with bearer API keys, learn how to store keys securely, rotate them safely, and pass them through every SDK client.
Overview
Every request to the Loop API is authenticated with an API key passed as a bearer token. The same key works across the REST API and all SDK clients. Keys are scoped to a single project, so feedback created with one key only ever appears in that project.
The REST base URL is:
https://api.loop.dev/v2
Bearer authentication
Pass your key in the Authorization header using the Bearer scheme:
curl https://api.loop.dev/v2/feedback \
-H "Authorization: Bearer $LOOP_API_KEY"
If the key is missing, malformed, or revoked, the API responds with 401 Unauthorized:
{
"error": {
"type": "authentication_error",
"message": "Invalid or missing API key."
}
}
Using keys in the SDKs
Each SDK reads the key once at construction time. Load it from the environment rather than hardcoding it.
import { Loop } from '@loop/sdk';
const loop = new Loop(process.env.LOOP_API_KEY);
import os
from loop import Loop
loop = Loop(api_key=os.environ['LOOP_API_KEY'])
client := loop.New(os.Getenv("LOOP_API_KEY"))
Set the variable in your shell or deployment environment:
export LOOP_API_KEY="sk_live_xxx"
Key types
Loop issues two kinds of keys per project:
| Prefix | Environment | Use |
|---|---|---|
sk_live_ |
Production | Real feedback from your live application |
sk_test_ |
Test | Local development and CI; isolated from live data |
Test keys never trigger production webhooks and never count against your monthly item quota, so they are safe to use in automated tests.
Storing keys securely
API keys grant full access to a project's feedback. Treat them like passwords:
- Keep keys server-side. Never embed a
sk_live_key in client-side JavaScript, a mobile binary, or a public repository. The drop-in widget uses a separate, restricted embed token — not your API key. - Load from the environment. Use environment variables or a secrets manager (such as your platform's secret store) rather than committing keys.
- Scope by project. Use separate projects — and therefore separate keys — for staging and production.
- Use test keys in CI. Wire
sk_test_keys into continuous integration so test runs never touch live data.
Rotating keys
Rotate a key immediately if it may have been exposed. Loop supports overlapping keys so you can rotate without downtime:
- Generate a new key in the dashboard. Both the old and new key are valid during the overlap.
- Roll the new key out to your servers and deployments.
- Confirm traffic is flowing on the new key, then revoke the old one.
Revoking a key takes effect immediately; any request using a revoked key returns 401.
Handling auth errors
Build a small amount of defensive handling around authentication so failures surface clearly rather than silently dropping feedback.
try {
await loop.feedback.create({
user: { id: 'u_8f2c' },
message: 'Quick note from the settings page.',
sentiment: 'neutral',
source: 'in-app-widget',
});
} catch (err) {
if (err.status === 401) {
console.error('Loop API key is invalid or revoked — check LOOP_API_KEY.');
}
throw err;
}
Next steps
With authentication in place, you are ready to use the full API. Continue to the Feedback API reference to create and list feedback, or set up Webhooks to receive events in real time.