Skip to main content

Topic Access Tokens

Topic access tokens provide scoped authentication for publishing to specific private topics.

Comparing authentication methods

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

  1. Go to your topic page (e.g., app.notifer.io/topic/my-topic)
  2. Click Topic Settings (gear icon)
  3. Navigate to Access Tokens tab
  4. Click Create Token
  5. Enter token name (e.g., "CI Pipeline")
  6. Select access level: read (subscribe), write (publish), or read_write (both)
  7. Click Create
  8. 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
}
Token Limits

FREE tier users can create 1 token per private topic. Upgrade to ESSENTIALS for unlimited tokens.

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

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"
More code examples

For Python, JavaScript, and other usage examples, see Authentication Code Examples.

Token Access Levels

Control what each token can do:

Access LevelDescriptionUse Case
readSubscribe to topic messages (read-only)Log aggregation, monitoring dashboards
writePublish messages to the topic (write-only)CI/CD notifications, monitoring alerts
read_writeBoth publish and subscribeFull 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
Comparing authentication methods

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 (not X-API-Key)
  • Confirm token is for the correct topic

403 Forbidden

Cause: Token lacks required access level

Solution:

  • Check token has write or read_write access level for POST/PUT requests
  • Check token has read or read_write access 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