Topic Access Tokens¶
Topic access tokens provide scoped authentication for publishing to specific private topics.
API Keys vs Topic Access Tokens
Confused about which to use?
- Topic Access Tokens (
tk_...) - Scoped to one topic, recommended for scripts and integrations - User API Keys (
noti_...) - Work across all your topics, for broader automation
Overview¶
Why use topic access tokens?
- Topic-scoped - Works only for a specific topic
- Secure - Limited permissions (publish-only or subscribe-only)
- Shareable - Safe to share with external services
- Revocable - Revoke without affecting other integrations
- Trackable - Monitor usage per token
Perfect for:
- CI/CD pipelines notifying a single topic
- Third-party integrations (monitoring tools, webhooks)
- Sharing topic access with teammates without sharing account credentials
- Automated scripts that publish to one topic
Creating Topic Access Tokens¶
Via Web Dashboard¶
- Go to your topic page (e.g.,
app.notifer.io/topic/my-topic) - Click Topic Settings (gear icon)
- Navigate to Access Tokens tab
- Click Create Token
- Enter token name (e.g., "CI Pipeline")
- Select permissions:
publish,subscribe, or both - Click Create
- Copy the token (shown only once!)
Via API¶
# Create a publish-only token
curl -X POST https://app.notifer.io/api/topics/my-topic/access-tokens \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "CI Pipeline Token",
"permissions": ["publish"]
}'
Response:
{
"id": "token_abc123",
"token": "tk_FjZTOcx14k4_Kg6RtUCikAPYc2KNjXIMkWQUvDSREFc",
"name": "CI Pipeline Token",
"topic": "my-topic",
"permissions": ["publish"],
"created_at": "2025-11-10T10:00:00Z",
"last_used_at": null
}
Save Your Token
The token is shown only once during creation. Save it securely! If you lose it, you'll need to create a new token.
Using Topic Access Tokens¶
In HTTP Requests (Recommended)¶
Use the X-Topic-Token header:
curl -d "Build completed successfully" \
-H "X-Topic-Token: tk_FjZTOcx14k4_Kg6RtUCikAPYc2KNjXIMkWQUvDSREFc" \
-H "X-Title: CI/CD" \
-H "X-Priority: 3" \
https://app.notifer.io/my-topic
As Query Parameter¶
For tools that don't support custom headers:
curl -d "Build completed" \
"https://app.notifer.io/my-topic?token=tk_FjZTOcx14k4_Kg6RtUCikAPYc2KNjXIMkWQUvDSREFc"
In Python¶
import requests
TOKEN = "tk_FjZTOcx14k4_Kg6RtUCikAPYc2KNjXIMkWQUvDSREFc"
response = requests.post(
"https://app.notifer.io/my-topic",
data="Build completed",
headers={
"X-Topic-Token": TOKEN,
"X-Title": "CI/CD",
"X-Priority": "3"
}
)
In JavaScript¶
const TOKEN = 'tk_FjZTOcx14k4_Kg6RtUCikAPYc2KNjXIMkWQUvDSREFc';
fetch('https://app.notifer.io/my-topic', {
method: 'POST',
headers: {
'X-Topic-Token': TOKEN,
'X-Title': 'CI/CD',
'Content-Type': 'text/plain'
},
body: 'Build completed'
});
Token Permissions¶
Control what each token can do:
| Permission | Description | Use Case |
|---|---|---|
publish |
Publish messages to the topic | CI/CD notifications, monitoring alerts |
subscribe |
Subscribe to topic messages | Log aggregation, webhooks |
publish,subscribe |
Both publish and subscribe | Full integration access |
Permission Examples¶
Token Management¶
List Tokens for a Topic¶
Revoke a Token¶
curl -X DELETE https://app.notifer.io/api/topics/my-topic/access-tokens/token_abc123 \
-H "Authorization: Bearer YOUR_JWT"
After revocation:
- Token immediately stops working
- All requests with this token return
401 Unauthorized - Token cannot be re-enabled (create a new one instead)
Monitor Token Usage¶
View in topic settings:
- Last used - When the token was last used
- Total requests - Number of requests made with this token
- Created by - User who created the token
Comparison with API Keys¶
Understanding when to use each authentication method:
| Feature | Topic Access Token (tk_...) |
User API Key (noti_...) |
|---|---|---|
| Scope | Single topic only | All your topics |
| Prefix | tk_... |
noti_... |
| Header | X-Topic-Token |
X-API-Key |
| Permissions | Per-token (publish/subscribe) | Global scopes |
| Best for | Topic-specific integrations | Multi-topic automation |
| Sharing | ✅ Safe (limited scope) | ❌ Risky (full access) |
| Revocation impact | Only affects one topic | Affects all integrations |
| Created via | Topic settings | Account settings |
| Example use | CI/CD for one topic | Admin scripts, dashboards |
When to Use Topic Access Tokens¶
✅ Use topic access tokens when:
- Integrating with external services (GitHub Actions, monitoring tools)
- Each integration should only access one topic
- You want to share access without sharing account credentials
- You need fine-grained permission control per topic
- You want to easily revoke access for one integration
When to Use API Keys¶
✅ Use API keys when:
- Building automation that works across multiple topics
- Creating admin scripts or dashboards
- You control the entire integration
- You need topic management permissions (create, delete topics)
Security Best Practices¶
Storage¶
Do:
- Store tokens in environment variables
- Use CI/CD secret storage (GitHub Secrets, GitLab CI Variables)
- Use secret managers (AWS Secrets Manager, HashiCorp Vault)
- Create separate tokens for each integration
- Revoke unused tokens
Don't:
- Commit tokens to version control
- Share tokens in plain text (email, Slack)
- Use the same token across multiple services
- Grant more permissions than needed (e.g., publish+subscribe when only publish is needed)
Environment Variables¶
# Store in .env file (add to .gitignore!)
NOTIFER_TOPIC_TOKEN=tk_FjZTOcx14k4_Kg6RtUCikAPYc2KNjXIMkWQUvDSREFc
# Load in script
source .env
curl -H "X-Topic-Token: $NOTIFER_TOPIC_TOKEN" \
-d "Message" \
https://app.notifer.io/my-topic
GitHub Actions¶
# Store token in repository secrets
- name: Notify deployment
run: |
curl -d "Deploy completed" \
-H "X-Topic-Token: ${{ secrets.NOTIFER_TOPIC_TOKEN }}" \
-H "X-Title: Deployment" \
https://app.notifer.io/deployments
Docker Secrets¶
# Create secret
echo "tk_..." | docker secret create notifer_token -
# Use in docker-compose.yml
services:
app:
secrets:
- notifer_token
environment:
NOTIFER_TOKEN_FILE: /run/secrets/notifer_token
secrets:
notifer_token:
external: true
Real-World Examples¶
GitHub Actions CI/CD¶
name: Deploy and Notify
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Deploy
run: ./deploy.sh
- name: Notify success
if: success()
run: |
curl -d "Deployment to production succeeded ✅" \
-H "X-Topic-Token: ${{ secrets.NOTIFER_TOPIC_TOKEN }}" \
-H "X-Title: Deploy Success" \
-H "X-Priority: 3" \
-H "X-Tags: ci,deploy,success" \
https://app.notifer.io/deployments
- name: Notify failure
if: failure()
run: |
curl -d "Deployment to production failed ❌" \
-H "X-Topic-Token: ${{ secrets.NOTIFER_TOPIC_TOKEN }}" \
-H "X-Title: Deploy Failed" \
-H "X-Priority: 5" \
-H "X-Tags: ci,deploy,error" \
https://app.notifer.io/deployments
Server Monitoring Script¶
#!/bin/bash
TOPIC_TOKEN="tk_FjZTOcx14k4_Kg6RtUCikAPYc2KNjXIMkWQUvDSREFc"
TOPIC="server-alerts"
# Check disk space
USAGE=$(df -h / | awk 'NR==2 {print $5}' | sed 's/%//')
if [ "$USAGE" -gt 90 ]; then
PRIORITY=5
MESSAGE="🚨 CRITICAL: Disk usage at ${USAGE}%"
elif [ "$USAGE" -gt 80 ]; then
PRIORITY=4
MESSAGE="⚠️ WARNING: Disk usage at ${USAGE}%"
else
exit 0
fi
curl -d "$MESSAGE" \
-H "X-Topic-Token: $TOPIC_TOKEN" \
-H "X-Priority: $PRIORITY" \
-H "X-Tags: server,disk,monitoring" \
"https://app.notifer.io/$TOPIC"
Database Backup Notification¶
#!/bin/bash
TOKEN="tk_your_token_here"
TOPIC="backups"
# Perform backup
if pg_dump production_db > /backups/db_$(date +%Y%m%d).sql; then
# Success notification
curl -d "Database backup completed: $(date)" \
-H "X-Topic-Token: $TOKEN" \
-H "X-Title: Backup Success" \
-H "X-Priority: 3" \
-H "X-Tags: database,backup,success" \
"https://app.notifer.io/$TOPIC"
else
# Failure notification
curl -d "Database backup FAILED: $(date)" \
-H "X-Topic-Token: $TOKEN" \
-H "X-Title: Backup Failed" \
-H "X-Priority: 5" \
-H "X-Tags: database,backup,error" \
"https://app.notifer.io/$TOPIC"
fi
Troubleshooting¶
401 Unauthorized¶
Cause: Invalid or missing token
Solution:
- Verify token is correct (no extra spaces or newlines)
- Check token hasn't been revoked
- Ensure using correct header:
X-Topic-Token(notX-API-Key) - Confirm token is for the correct topic
403 Forbidden¶
Cause: Token lacks required permission
Solution:
- Check token has
publishpermission for POST/PUT requests - Check token has
subscribepermission for SSE/WebSocket connections - Verify topic is still private (token only works for private topics)
Token Shows as Never Used¶
Cause: Token not being sent correctly
Solution:
- Check header name:
X-Topic-Token(case-sensitive) - Verify nginx is passing through the header (see nginx config)
- Test with curl verbosely:
curl -v ...
Nginx Configuration¶
If running your own nginx proxy, ensure it passes through the X-Topic-Token header:
location ~ ^/[a-zA-Z0-9_-]+$ {
proxy_pass http://backend:8000;
# Required: Pass through authentication headers
proxy_set_header X-Topic-Token $http_x_topic_token;
proxy_set_header Authorization $http_authorization;
# Also pass through message headers
proxy_set_header X-Title $http_x_title;
proxy_set_header X-Priority $http_x_priority;
proxy_set_header X-Tags $http_x_tags;
}
Next Steps¶
- API Keys - User-level authentication
- Private Topics - Topic privacy and access control
- HTTP Publishing - Publishing examples
- Authentication Overview - All authentication methods