Authentication
Learn how to authenticate your API requests using API keys.
API Key Authentication
The SnipLink API uses API keys for authentication. Include your API key in theX-API-Key header of every request:
X-API-Key: snip_your_api_key_hereWarning about example values: All API keys shown in documentation (like snip_your_api_key_here or snip_a1b2c3d4...) are placeholders. You must use your actual API key from the dashboard. Example keys will result in authentication errors.
API Key Format
All API keys follow a consistent format for easy identification:
| Format | Description |
|---|---|
snip_ | All API keys start with the snip_ prefix, followed by 32+ alphanumeric characters. Example: snip_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6 |
Authentication Methods
The API supports two authentication methods:
| Method | Header | Use Case |
|---|---|---|
API Key | X-API-Key: snip_xxx | Server-to-server integrations and automated workflows (recommended) |
JWT Token | Authorization: Bearer <token> | Dashboard sessions and user-authenticated requests |
API Key Scopes
API keys can be created with specific scopes to limit their permissions. Following the principle of least privilege, you should only grant the scopes your application actually needs.
Scope Reference
| Scope | Permissions | Includes |
|---|---|---|
| Links | ||
links:read | View links and their metadata | — |
links:write | Create and update links | links:read |
links:delete | Delete links | links:write, links:read |
| Analytics | ||
analytics:read | View click analytics and statistics | — |
| Custom Domains | ||
domains:read | View custom domains | — |
domains:write | Add and configure custom domains | domains:read |
domains:delete | Remove custom domains | domains:write, domains:read |
| Webhooks | ||
webhooks:read | View webhook endpoints and delivery logs | — |
webhooks:write | Create and update webhook endpoints | webhooks:read |
webhooks:delete | Delete webhook endpoints | webhooks:write, webhooks:read |
| QR Codes | ||
qr:read | View QR codes | — |
qr:write | Generate and customize QR codes | qr:read |
qr:delete | Delete QR codes | qr:write, qr:read |
| Workspace | ||
workspace:read | View workspace settings | — |
workspace:admin | Full workspace administration | workspace:read, api-keys:* |
| API Keys | ||
api-keys:read | View API keys (without secrets) | — |
api-keys:write | Create and manage API keys | api-keys:read |
| Special | ||
* | Full Access — Complete access to all API operations | All scopes |
Scope Hierarchy
Scopes follow a hierarchy where higher privilege scopes automatically include lower ones:
:deletescopes include:writeand:read:writescopes include:readworkspace:adminincludesworkspace:readand allapi-keys:*scopes*(full access) includes all scopes
Security Note: Avoid using the * (full access) scope in production. Instead, grant only the specific scopes your application needs.
Common Scope Patterns
Here are recommended scope combinations for common use cases:
| Use Case | Recommended Scopes |
|---|---|
| Read-only analytics dashboard | links:read, analytics:read |
| Link management automation | links:write |
| Full link lifecycle (create, update, delete) | links:delete |
| Webhook integration setup | webhooks:write |
| QR code generation service | links:read, qr:write |
| Domain management | domains:delete |
Scope Errors
When an API key attempts to access a resource without the required scope, you'll receive a 403 Forbidden response:
{
"success": false,
"error": {
"code": "INSUFFICIENT_SCOPE",
"message": "API key lacks required scope: links:write",
"details": {
"requiredScope": "links:write",
"grantedScopes": ["links:read", "analytics:read"]
}
}
}Security Best Practices
- Never expose API keys in client-side code - API keys should only be used in server-side code.
- Use environment variables - Store API keys in environment variables, not in your codebase.
- Use minimal scopes - Only request the scopes your application needs.
- Rotate keys regularly - Generate new API keys periodically and revoke old ones. The API supports a grace period during rotation.
- Set expiration dates - Create API keys with expiration dates for temporary integrations.
API Key Rotation
The SnipLink API supports secure key rotation with a configurable grace period, allowing you to rotate keys without downtime.
How Key Rotation Works
- Generate new key - Call the rotate endpoint to generate a new API key.
- Grace period - Both old and new keys work during the grace period (default: 24 hours, max: 7 days).
- Update your systems - Deploy the new key to your applications.
- Old key expires - After the grace period, only the new key works.
| Parameter | Default | Description |
|---|---|---|
gracePeriodMs | 24 hours | Time window where both keys are valid (max: 7 days) |
Rotation Example
// Request
POST /v1/workspaces/{workspaceId}/api-keys/{apiKeyId}/rotate
{
"gracePeriodMs": 86400000 // 24 hours (optional)
}
// Response
{
"apiKey": {
"id": "key_abc123",
"name": "Production API Key",
"keyPrefix": "snip_xyz",
"version": 2
},
"newPlaintextKey": "snip_newkey123...", // Only returned once!
"previousKeyExpiresAt": "2025-01-16T12:00:00.000Z"
}Important: The new key is returned only once during rotation. Store it immediately in your secrets manager - you won't be able to retrieve it again.
Zero-Downtime Rotation Process
// 1. Rotate the key (both keys now work)
const response = await fetch(
`https://api.sniplink.co/v1/workspaces/${workspaceId}/api-keys/${keyId}/rotate`,
{
method: 'POST',
headers: { 'X-API-Key': currentApiKey },
body: JSON.stringify({ gracePeriodMs: 3600000 }) // 1 hour
}
);
const { newPlaintextKey, previousKeyExpiresAt } = await response.json();
// 2. Store the new key in your secrets manager
await secretsManager.update('SNIPLINK_API_KEY', newPlaintextKey);
// 3. Deploy new key to all instances
// Both keys work until previousKeyExpiresAt
// 4. After grace period, old key stops working automaticallyExample: Environment Variables
# .env (do not commit this file!)
SNIPLINK_API_KEY=snip_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6
SNIPLINK_WORKSPACE_ID=ws_xxxxxxxxxxxxx// Usage in Node.js
const apiKey = process.env.SNIPLINK_API_KEY;
const workspaceId = process.env.SNIPLINK_WORKSPACE_ID;
const response = await fetch(
`https://api.sniplink.co/v1/workspaces/${workspaceId}/links`,
{
headers: {
'X-API-Key': apiKey,
'Content-Type': 'application/json',
},
}
);Troubleshooting
401 Unauthorized
If you receive a 401 error, check the following:
- Verify your API key is correct and starts with
snip_ - Ensure the
X-API-Keyheader is set correctly - Check that your API key has the required scopes for the endpoint
- Confirm the API key hasn't been revoked or expired
403 Forbidden
A 403 error typically means your API key doesn't have the required scope for the operation. Check the endpoint documentation to see which scopes are required.