API Keys
User API keys provide secure authentication for scripts, integrations, and automated workflows across all your topics.
For a detailed comparison of API keys vs topic access tokens, see Authentication.
Overview
Why use API keys?
- Authenticate scripts and automation
- Avoid exposing user credentials
- Track API usage per key
- Scope permissions (publish, subscribe, manage)
- Set expiration dates
Creating API Keys
Via Web Dashboard
- Go to Settings → API Keys
- Click "Create API Key"
- Enter name and description
- Select scopes (permissions)
- Optionally set expiration date
- Copy the generated key (shown only once!)
Via API
curl -X POST https://app.notifer.io/api/keys \
-H "Authorization: Bearer your_jwt_token" \
-H "Content-Type: application/json" \
-d '{
"name": "my-script-key",
"description": "Automation script",
"scopes": ["publish", "subscribe"]
}'
Response:
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"user_id": "123e4567-e89b-12d3-a456-426614174000",
"name": "my-script-key",
"key": "noti_1234567890abcdefghijklmnopqrstuv",
"key_prefix": "noti_123",
"description": "Automation script",
"scopes": ["publish", "subscribe"],
"request_count": 0,
"is_active": true,
"created_at": "2025-11-02T10:00:00Z",
"last_used": null,
"expires_at": null,
"is_valid": true
}
The API key is shown only once during creation. Save it securely! If you lose it, you'll need to create a new key.
Using API Keys
Use the X-API-Key header to authenticate requests:
curl -d "Automated message" \
-H "X-API-Key: noti_your_key_here" \
https://app.notifer.io/my-topic
For Python, JavaScript, CLI, and other usage examples, see Authentication Code Examples.
Key Scopes
Control what each API key can do:
| Scope | Description | Example Use Case |
|---|---|---|
* (all) | Full access | Development and testing |
publish | Publish messages to topics | CI/CD notifications |
subscribe | Subscribe to topics | Log aggregation |
topics:read | List and view topics | Monitoring dashboard |
topics:write | Create and manage topics | Automation scripts |
account:read | Read account information | Profile viewers |
account:write | Update account settings | Settings automation |
keys:read | View API keys | Audit scripts |
keys:write | Manage API keys | Admin automation |
Scope Best Practices
CI/CD Pipeline - Only needs publish permission:
curl -X POST https://app.notifer.io/api/keys \
-H "Authorization: Bearer your_jwt_token" \
-H "Content-Type: application/json" \
-d '{"name": "ci-pipeline", "scopes": ["publish"]}'
Monitoring Script - Needs both read and publish:
curl -X POST https://app.notifer.io/api/keys \
-H "Authorization: Bearer your_jwt_token" \
-H "Content-Type: application/json" \
-d '{"name": "monitoring", "scopes": ["publish", "topics:read"]}'
Admin Automation - Full access (default when scopes omitted):
curl -X POST https://app.notifer.io/api/keys \
-H "Authorization: Bearer your_jwt_token" \
-H "Content-Type: application/json" \
-d '{"name": "admin-script"}'
Key Management
List All Keys
curl https://app.notifer.io/api/keys \
-H "Authorization: Bearer your_jwt_token"
Revoke a Key
Temporarily disable a key (can be re-enabled):
curl -X POST https://app.notifer.io/api/keys/{key_id}/revoke \
-H "Authorization: Bearer your_jwt_token"
Delete a Key
Permanently delete a key (cannot be undone):
curl -X DELETE https://app.notifer.io/api/keys/{key_id} \
-H "Authorization: Bearer your_jwt_token"
Key Expiration
Set expiration dates for temporary access when creating keys via API:
curl -X POST https://app.notifer.io/api/keys \
-H "Authorization: Bearer your_jwt_token" \
-H "Content-Type: application/json" \
-d '{
"name": "temp-key",
"expires_at": "2025-12-02T00:00:00Z"
}'
Expired keys:
- Automatically stop working at expiration time
- Can be viewed in the dashboard (marked as "expired")
- Cannot be re-enabled (create a new key instead)
Usage Tracking
Monitor API key usage in the dashboard:
- Request count - Total requests made with this key
- Last used - Timestamp of most recent use
- Usage by endpoint - Breakdown of API calls
- Rate limit status - Current rate limit usage
Security Best Practices
Storage
Do:
- Store keys in environment variables
- Use secret managers (AWS Secrets Manager, HashiCorp Vault)
- Use CI/CD secret storage (GitHub Secrets, GitLab CI Variables)
- Rotate keys periodically
Don't:
- Commit keys to version control
- Share keys in plain text (email, chat)
- Use the same key across multiple services
- Grant more permissions than needed
Environment Variables
# Store in .env file (don't commit!)
NOTIFER_API_KEY=noti_your_key_here
# Load in script
source .env
curl -H "X-API-Key: $NOTIFER_API_KEY" \
https://app.notifer.io/my-topic
GitHub Actions Secrets
- name: Publish notification
run: |
curl -d "Deploy completed" \
-H "X-API-Key: ${{ secrets.NOTIFER_API_KEY }}" \
https://app.notifer.io/deployments
Docker Secrets
# Create secret
echo "noti_your_key_here" | docker secret create notifer_key -
# Use in service
docker service create \
--name app \
--secret notifer_key \
myapp
Rate Limits
API keys inherit rate limits from your account tier:
| Tier | Per Minute | Per Hour |
|---|---|---|
| FREE | 10 | 100 |
| ESSENTIALS | 30 | 300 |
| TEAM | 100 | 1,000 |
Rate limit headers in response:
curl -i -H "X-API-Key: noti_your_key" \
https://app.notifer.io/my-topic
Response:
HTTP/1.1 200 OK
X-RateLimit-Limit: 10
X-RateLimit-Remaining: 9
X-RateLimit-Reset: 1699000000
Troubleshooting
401 Unauthorized
Cause: Invalid or missing API key
Solution:
- Check key is correct (no extra spaces)
- Verify key hasn't been revoked or deleted
- Ensure using correct header:
X-API-Key
403 Forbidden
Cause: Insufficient permissions
Solution:
- Check key scopes include required permission
- Verify topic access (private topics require ownership)
- Check rate limits
429 Too Many Requests
Cause: Rate limit exceeded
Solution:
- Implement exponential backoff
- Upgrade to higher tier
- Spread requests over time
- Check
X-RateLimit-Resetheader for reset time
Examples
Shell Script with Error Handling
#!/bin/bash
API_KEY="${NOTIFER_API_KEY}"
TOPIC="server-alerts"
send_notification() {
local message="$1"
local priority="${2:-3}"
response=$(curl -s -w "\n%{http_code}" \
-d "$message" \
-H "X-API-Key: $API_KEY" \
-H "X-Priority: $priority" \
"https://app.notifer.io/$TOPIC")
http_code=$(echo "$response" | tail -n1)
if [ "$http_code" -eq 200 ] || [ "$http_code" -eq 201 ]; then
echo "✓ Notification sent"
return 0
else
echo "✗ Failed with code $http_code"
return 1
fi
}
# Usage
send_notification "Server backup completed" 3
Python with Retry Logic
import os
import time
import requests
from typing import Optional
API_KEY = os.getenv("NOTIFER_API_KEY")
BASE_URL = "https://app.notifer.io"
def publish_with_retry(
topic: str,
message: str,
max_retries: int = 3
) -> Optional[dict]:
"""Publish message with exponential backoff retry."""
headers = {"X-API-Key": API_KEY}
url = f"{BASE_URL}/{topic}"
for attempt in range(max_retries):
try:
response = requests.post(
url,
data=message,
headers=headers,
timeout=10
)
if response.status_code in [200, 201]:
return response.json()
if response.status_code == 429:
# Rate limited - wait and retry
retry_after = int(response.headers.get('Retry-After', 60))
time.sleep(retry_after)
continue
# Other error - don't retry
response.raise_for_status()
except requests.RequestException as e:
if attempt == max_retries - 1:
raise
time.sleep(2 ** attempt) # Exponential backoff
return None
# Usage
publish_with_retry("alerts", "Test message")
For a detailed comparison of API keys vs topic access tokens (including when to use each), see Authentication.
Next Steps
- Topic Access Tokens - Topic-scoped authentication
- Private Topics - Secure your notifications
- HTTP Publishing - Publishing examples
- Authentication - Authentication overview