Topic Access Tokens
Topic access tokens provide scoped authentication for publishing to specific private topics.
For a detailed comparison of API keys vs topic access tokens, see Authentication.
Overview
Why use topic access tokens?
- Topic-scoped - Works only for a specific topic
- Secure - Limited access levels (read-only, write-only, or read-write)
- 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, alert systems)
- 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 access level:
read(subscribe),write(publish), orread_write(both) - Click Create
- Copy the token (shown only once!)
Via API
# Create a write-only token (for publishing)
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",
"access_level": "write"
}'
Response:
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"topic_id": "123e4567-e89b-12d3-a456-426614174000",
"user_id": "987fcdeb-51a2-3c4d-e5f6-789012345678",
"token": "tk_FjZTOcx14k4_Kg6RtUCikAPYc2KNjXIMkWQUvDSREFc",
"token_prefix": "tk_FjZTO",
"name": "CI Pipeline Token",
"access_level": "write",
"is_active": true,
"created_at": "2025-11-10T10:00:00Z",
"last_used": null,
"expires_at": null,
"is_valid": true,
"can_read": false,
"can_write": true
}
FREE tier users can create 1 token per private topic. Upgrade to ESSENTIALS for unlimited tokens.
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
Use the X-Topic-Token header or pass the token as a query parameter:
# Via header (recommended)
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
# Via query parameter (for tools that don't support custom headers)
curl -d "Build completed" \
"https://app.notifer.io/my-topic?token=tk_FjZTOcx14k4_Kg6RtUCikAPYc2KNjXIMkWQUvDSREFc"
For Python, JavaScript, and other usage examples, see Authentication Code Examples.
Token Access Levels
Control what each token can do:
| Access Level | Description | Use Case |
|---|---|---|
read | Subscribe to topic messages (read-only) | Log aggregation, monitoring dashboards |
write | Publish messages to the topic (write-only) | CI/CD notifications, monitoring alerts |
read_write | Both publish and subscribe | Full integration access |
Access Level Examples
Write Only (Most Common) - CI/CD pipeline that only needs to send notifications:
curl -X POST https://app.notifer.io/api/topics/deployments/access-tokens \
-H "Authorization: Bearer YOUR_JWT" \
-H "Content-Type: application/json" \
-d '{
"name": "GitHub Actions",
"access_level": "write"
}'
Read Only - External service consuming messages:
curl -X POST https://app.notifer.io/api/topics/events/access-tokens \
-H "Authorization: Bearer YOUR_JWT" \
-H "Content-Type: application/json" \
-d '{
"name": "Log Aggregator",
"access_level": "read"
}'
Read and Write - Full integration access:
curl -X POST https://app.notifer.io/api/topics/monitoring/access-tokens \
-H "Authorization: Bearer YOUR_JWT" \
-H "Content-Type: application/json" \
-d '{
"name": "Monitoring Service",
"access_level": "read_write"
}'
Token Management
List Tokens for a Topic
curl https://app.notifer.io/api/topics/my-topic/access-tokens \
-H "Authorization: Bearer YOUR_JWT"
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
For a detailed comparison of topic access tokens vs API keys (including when to use each), see Authentication.
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: 1" \
-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=1
MESSAGE="🚨 CRITICAL: Disk usage at ${USAGE}%"
elif [ "$USAGE" -gt 80 ]; then
PRIORITY=2
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: 1" \
-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 access level
Solution:
- Check token has
writeorread_writeaccess level for POST/PUT requests - Check token has
readorread_writeaccess level 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