Gotify: Self-Hosted Push Notification Server
Simple server for sending and receiving push notifications. REST API and Android app.
Introduction
In the homelab ecosystem, staying informed about your infrastructure’s health is critical. You need to know immediately when a backup fails, a service goes down, or a security event occurs. Gotify is a simple, self-hosted push notification server that sends real-time alerts to your Android device (or web browser) with minimal configuration and zero ongoing costs.
Unlike cloud-based notification services that charge per message or require subscriptions, Gotify runs entirely on your infrastructure, giving you complete control over your notification pipeline.
What you’ll learn:
- Deploy Gotify server with Docker Compose
- Configure applications and authentication tokens
- Manage messages and priorities
- Set up the Android mobile app
- Use the web UI for message management
- Integrate with monitoring tools via API
- Implement security and access control
- Create custom notification scripts
- Troubleshoot delivery issues
Prerequisites:
- Docker and Docker Compose installed (v24.0+ and v2.0+)
- Reverse proxy with HTTPS (recommended for external access)
- Domain name or accessible IP address
- Android device (for mobile app) or web browser
- Basic understanding of REST APIs
- 128+ MB RAM, 1+ GB storage (minimal requirements)
Why Gotify?
The Push Notification Landscape
Modern homelab operators have several notification options:
Commercial Services:
- Pushover: $5 one-time fee, 10,000 messages/month
- Pushbullet: Free tier limited, $5/month for pro
- Telegram Bots: Free but requires Telegram account
Self-Hosted:
- ntfy: HTTP-based, cross-platform, newer
- Gotify: WebSocket-based, Android-focused, mature
- Apprise: Aggregator supporting multiple services
Gotify’s Unique Strengths
| Feature | Gotify | ntfy | Pushover |
|---|---|---|---|
| Cost | Free | Free | $5 one-time |
| Android App | Official | Official | Official |
| iOS App | No | Yes | Yes |
| Web UI | Full-featured | Basic | Limited |
| WebSocket | Native | Native | Polling |
| Message Storage | SQLite database | Cache-based | Cloud |
| Setup | 5 minutes | 5 minutes | Instant |
| Privacy | 100% self-hosted | 100% self-hosted | Cloud service |
When to choose Gotify:
- Android-only environment (no iOS requirement)
- Need message history and management via web UI
- Want application-based organization
- Prefer WebSocket real-time delivery
- Require fine-grained access control per application
Key Features
- Applications: Organize notifications by source (monitoring, backups, security)
- Priorities: 10 priority levels for granular control
- Web UI: Manage applications, view messages, configure settings
- Android App: Native push notifications with background service
- WebSocket: Real-time message delivery without polling
- Message Persistence: SQLite database stores all messages
- User Management: Multiple users with independent applications
- Plugin Support: Extend functionality with custom plugins
- REST API: Simple HTTP API for sending messages
- Markdown Support: Rich formatting in messages
Architecture Overview
Your Scripts/Services → Gotify Server → Android App / Web UI
↓ ↓ ↓
HTTP POST Applications Push Notifications
(API Token) (Messages) (WebSocket)
↓
SQLite Database How it works:
- Create application in Gotify (e.g., “Monitoring”)
- Get application token (e.g.,
Axxxxxxxxxxxxxxxxx) - Send HTTP POST with token:
curl -X POST "https://gotify.example.com/message?token=Axxxxxxxxxxxxxxxxx" -F "message=Server offline" - Gotify stores message in database
- Connected clients receive instant push via WebSocket
- Android app displays notification with sound/vibration
Components:
- Gotify Server: Go application serving API and WebSocket
- SQLite Database: Stores messages, applications, users, tokens
- Web UI: Browser-based interface for management
- Android App: Native mobile app for notifications
Resource Requirements:
| Users | Messages/Day | RAM | Storage |
|---|---|---|---|
| 1-5 | Under 1,000 | 128 MB | 1 GB |
| 5-20 | 1,000-10,000 | 256 MB | 5 GB |
| 20+ | 10,000+ | 512 MB | 10+ GB |
Installation: Docker Compose Method
Step 1: Create Directory Structure
mkdir -p /opt/gotify/data
cd /opt/gotify Step 2: Create docker-compose.yml
version: '3.8'
services:
gotify:
image: gotify/server:latest
container_name: gotify
restart: always
environment:
# Timezone
- TZ=America/New_York
# Server configuration
- GOTIFY_SERVER_PORT=80
- GOTIFY_SERVER_KEEPALIVEPERIODECONDS=0
- GOTIFY_SERVER_LISTENADDR=
- GOTIFY_SERVER_SSL_ENABLED=false # SSL handled by reverse proxy
# Database
- GOTIFY_DATABASE_DIALECT=sqlite3
- GOTIFY_DATABASE_CONNECTION=data/gotify.db
# Default admin credentials (CHANGE THESE!)
- GOTIFY_DEFAULTUSER_NAME=admin
- GOTIFY_DEFAULTUSER_PASS=CHANGE_THIS_PASSWORD
# Registration settings
- GOTIFY_REGISTRATION=false # Disable public registration
# Message limits
- GOTIFY_UPLOADEDIMAGESDIR=data/images
- GOTIFY_PLUGINSDIR=data/plugins
volumes:
- ./data:/app/data
ports:
- "8080:80"
networks:
- gotify
healthcheck:
test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:80/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 10s
networks:
gotify:
driver: bridge Important: Change GOTIFY_DEFAULTUSER_PASS to a strong password!
Step 3: Configure Reverse Proxy (Recommended)
Caddy Configuration:
gotify.example.com {
reverse_proxy gotify:80 {
# WebSocket support (automatic with Caddy)
header_up X-Forwarded-Proto {scheme}
}
# Security headers
header {
X-Content-Type-Options "nosniff"
X-Frame-Options "SAMEORIGIN"
Referrer-Policy "no-referrer-when-downgrade"
Strict-Transport-Security "max-age=31536000;"
}
} Nginx Configuration:
server {
server_name gotify.example.com;
location / {
proxy_pass http://localhost:8080;
proxy_http_version 1.1;
# WebSocket support
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# Standard proxy headers
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# WebSocket specific settings
proxy_read_timeout 86400;
proxy_buffering off;
}
listen 443 ssl http2;
ssl_certificate /etc/letsencrypt/live/gotify.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/gotify.example.com/privkey.pem;
} Step 4: Start Gotify
# Start service
docker compose up -d
# Monitor logs
docker compose logs -f gotify
# Check health
docker compose ps
curl http://localhost:8080/health Expected output:
{"health":"green","database":"green"} Step 5: Access Web Interface
Navigate to https://gotify.example.com (or http://YOUR-SERVER-IP:8080)
First login:
- Username:
admin - Password: [password from docker-compose.yml]
You should see the Gotify web interface with:
- Messages tab (empty initially)
- Applications tab (for creating notification sources)
- Clients tab (connected devices)
- Users tab (user management)
Step 6: Change Default Password
- Click profile icon (top-right) → Change Password
- Current Password: [default password]
- New Password: [strong password]
- Confirm Password: [strong password]
- Click Change
Security Note: Always change the default admin password immediately after first login.
Application and Token Management
Understanding Applications
Applications represent notification sources (e.g., “Monitoring”, “Backups”, “Security”). Each application has:
- Name: Descriptive identifier
- Description: Purpose of the application
- Token: API key for sending messages
- Priority: Default message priority (1-10)
- Image: Optional icon
Creating Your First Application
- Navigate to Apps tab
- Click Create Application
- Configure:
- Name:
Monitoring - Description:
Server monitoring alerts - Default Priority: 8 (high)
- Name:
- Click Create
You’ll receive an application token like: Axxxxxxxxxxxxxxxxx
Save this token securely - you’ll need it to send messages.
Sending Messages via API
Basic message:
curl -X POST "https://gotify.example.com/message?token=Axxxxxxxxxxxxxxxxx" -F "message=Server CPU usage high: 95%" With title:
curl -X POST "https://gotify.example.com/message?token=Axxxxxxxxxxxxxxxxx" -F "title=CPU Alert" -F "message=Server CPU usage high: 95%" With priority:
curl -X POST "https://gotify.example.com/message?token=Axxxxxxxxxxxxxxxxx" -F "title=Critical Alert" -F "message=Database server offline" -F "priority=10" Priority levels:
- 10 - Highest (critical alerts, loud notification)
- 8 - High (important, default sound)
- 5 - Normal (standard notification)
- 2 - Low (quiet notification)
- 0 - Lowest (silent, stored only)
Message Formatting
Markdown support:
curl -X POST "https://gotify.example.com/message?token=Axxxxxxxxxxxxxxxxx" -F "title=Backup Report" -F "message=## Daily Backup Status
**Completed:**
- Database: ✓
- Files: ✓
- Logs: ✓
**Failed:**
- None
**Next backup:** Tomorrow 2 AM" -F "priority=5" Supported Markdown:
- Headers:
# H1,## H2 - Bold:
**bold** - Italic:
*italic* - Lists:
- itemor* item - Links:
[text](url) - Code:
`code`
Extras (Additional Fields)
Send structured data:
curl -X POST "https://gotify.example.com/message?token=Axxxxxxxxxxxxxxxxx" -F "title=Server Status" -F "message=All systems operational" -F 'extras={"server": {"name": "web01", "uptime": "30 days", "cpu": "45%"}}' Extras appear in Android app as structured data.
User Management
Creating Additional Users
- Navigate to Users tab
- Click Create User
- Configure:
- Name:
alice - Password: [secure password]
- Admin: unchecked (for regular user)
- Name:
- Click Create
User permissions:
- Admin: Full access to all applications, users, settings
- Regular User: Access only to their own applications
User Applications
Each user has independent applications and messages. Messages sent to Alice’s applications only appear in her account.
Use cases:
- Team members with separate notification channels
- Different departments (IT, DevOps, Security)
- Isolation between projects or clients
Android App Setup
Installing the App
- Install “Gotify” from F-Droid or Google Play Store
- Open app
- Click Add Server (+ button)
- Configure:
- Server URL:
https://gotify.example.com - Username:
admin - Password: [your password]
- Server URL:
- Tap Connect
Client Token
After connecting, app generates a client token automatically. View in web UI:
- Web UI → Clients tab
- See your Android device listed
- Token displayed (starts with
C)
Client token vs. Application token:
- Application token (
A...): Send messages TO Gotify - Client token (
C...): Receive messages FROM Gotify (auto-generated by app)
Notification Settings
Per-application settings:
- Android app → Long-press application
- Tap settings icon
- Configure:
- Priority: Max, High, Default, Low, Min
- Sound: Select ringtone
- Vibrate: On/Off
- Notification channel importance
- Save
Global settings:
- Android app → Menu → Settings
- Configure:
- Connection timeout
- Image preview in notifications
- Background service behavior
- Battery optimization exemption
Battery Optimization: For reliable notifications, disable battery optimization:
- Android Settings → Apps → Gotify
- Battery → Optimize battery usage
- Select “All apps”
- Find Gotify → Disable
Testing Notifications
Send test message:
curl -X POST "https://gotify.example.com/message?token=YOUR_APP_TOKEN" -F "title=Test Notification" -F "message=This is a test from your Gotify server" -F "priority=8" You should receive instant notification on your Android device.
Web UI Features
Message Management
Viewing messages:
- Navigate to Messages tab
- Select application from sidebar
- View message list with timestamps
- Click message to expand and see full content
Filtering:
- Search messages by content
- Filter by application
- Sort by date or priority
Deleting messages:
- Click trash icon on individual message
- Click “Delete All” to clear application messages
- Messages deleted from all connected clients
Application Management
Edit application:
- Apps tab → Click application
- Click Edit (pencil icon)
- Modify name, description, or priority
- Click Update
Delete application:
- Apps tab → Click application
- Click Delete (trash icon)
- Confirm deletion
- All messages for this application are deleted
View application token:
- Apps tab → Click application
- Token displayed at top
- Click to copy to clipboard
Statistics
View message statistics:
- Web UI → Messages tab
- See message counts per application
- Monitor notification delivery success
Integration Examples
Bash Script Monitoring
Disk space monitor:
#!/bin/bash
# disk-monitor.sh
GOTIFY_URL="https://gotify.example.com/message"
GOTIFY_TOKEN="Axxxxxxxxxxxxxxxxx"
THRESHOLD=90
USAGE=$(df -h / | awk 'NR==2 {print $5}' | sed 's/%//')
if [ "$USAGE" -gt "$THRESHOLD" ]; then
curl -X POST "$GOTIFY_URL?token=$GOTIFY_TOKEN" -F "title=Disk Space Alert" -F "message=Root partition at ${USAGE}% (threshold: ${THRESHOLD}%)" -F "priority=9"
fi Schedule with cron:
*/15 * * * * /opt/scripts/disk-monitor.sh Docker Container Monitor
#!/bin/bash
# docker-monitor.sh
GOTIFY_URL="https://gotify.example.com/message"
GOTIFY_TOKEN="Axxxxxxxxxxxxxxxxx"
CONTAINERS=("nginx" "postgres" "redis")
for container in "${CONTAINERS[@]}"; do
if ! docker ps --format '{{.Names}}' | grep -q "^${container}$"; then
curl -X POST "$GOTIFY_URL?token=$GOTIFY_TOKEN" -F "title=Container Down" -F "message=Container $container is not running!" -F "priority=10"
fi
done Python Integration
#!/usr/bin/env python3
# gotify_notify.py
import requests
def send_notification(title, message, priority=5):
"""Send notification to Gotify server."""
url = "https://gotify.example.com/message"
token = "Axxxxxxxxxxxxxxxxx"
data = {
"title": title,
"message": message,
"priority": priority
}
params = {"token": token}
try:
response = requests.post(url, params=params, data=data)
response.raise_for_status()
print(f"Notification sent: {response.json()['id']}")
except requests.exceptions.RequestException as e:
print(f"Failed to send notification: {e}")
# Usage
if __name__ == "__main__":
send_notification(
title="Backup Complete",
message="Daily backup completed successfully at 2 AM",
priority=5
) Home Assistant Integration
Add to configuration.yaml:
notify:
- name: gotify
platform: rest
resource: https://gotify.example.com/message
method: POST_JSON
authentication: basic
headers:
X-Gotify-Key: "Axxxxxxxxxxxxxxxxx"
data:
title: "{{ title }}"
priority: "{{ priority }}"
message_param_name: message Use in automations:
automation:
- alias: "Motion detected"
trigger:
platform: state
entity_id: binary_sensor.motion_sensor
to: 'on'
action:
service: notify.gotify
data:
message: "Motion detected in living room"
data:
title: "Security Alert"
priority: 8 Uptime Kuma Integration
- Uptime Kuma → Settings → Notifications
- Add Notification → Gotify
- Configure:
- Server URL:
https://gotify.example.com - Application Token:
Axxxxxxxxxxxxxxxxx - Priority: 8
- Server URL:
- Test and Save
Grafana Webhook
Configure Grafana contact point:
Grafana → Alerting → Contact points
Add contact point:
- Name:
Gotify - Integration:
Webhook - URL:
https://gotify.example.com/message?token=Axxxxxxxxxxxxxxxxx - HTTP Method:
POST - Content-Type:
application/x-www-form-urlencoded
- Name:
Body template:
title={{ .CommonLabels.alertname }}&message={{ .CommonAnnotations.summary }}&priority=9 n8n Workflow
- Add HTTP Request node
- Configure:
- Method: POST
- URL:
https://gotify.example.com/message?token=Axxxxxxxxxxxxxxxxx - Body Content Type: Form-Data
- Body parameters:
title:{{ $json.title }}message:{{ $json.message }}priority:{{ $json.priority }}
Advanced Configuration
Environment Variables
Full list of configuration options:
# Server
- GOTIFY_SERVER_PORT=80
- GOTIFY_SERVER_KEEPALIVEPERIODECONDS=0
- GOTIFY_SERVER_LISTENADDR=
- GOTIFY_SERVER_SSL_ENABLED=false
- GOTIFY_SERVER_SSL_CERTFILE=
- GOTIFY_SERVER_SSL_CERTKEY=
- GOTIFY_SERVER_SSL_LETSENCRYPT_ENABLED=false
- GOTIFY_SERVER_SSL_LETSENCRYPT_ACCEPTTOS=false
- GOTIFY_SERVER_SSL_LETSENCRYPT_CACHE=certs
- GOTIFY_SERVER_SSL_LETSENCRYPT_HOSTS=
- GOTIFY_SERVER_RESPONSEHEADERS=
# Database
- GOTIFY_DATABASE_DIALECT=sqlite3
- GOTIFY_DATABASE_CONNECTION=data/gotify.db
# For PostgreSQL (optional):
# - GOTIFY_DATABASE_DIALECT=postgres
# - GOTIFY_DATABASE_CONNECTION=host=postgres port=5432 user=gotify dbname=gotify password=secret
# Uploads
- GOTIFY_UPLOADEDIMAGESDIR=data/images
- GOTIFY_PLUGINSDIR=data/plugins
# Registration
- GOTIFY_REGISTRATION=false
# Passphrase for encryption
- GOTIFY_PASSPHRASE= PostgreSQL Backend (Optional)
For high-traffic deployments:
# docker-compose.yml
services:
postgres:
image: postgres:16-alpine
container_name: gotify-postgres
restart: always
environment:
POSTGRES_DB: gotify
POSTGRES_USER: gotify
POSTGRES_PASSWORD: SECURE_PASSWORD
volumes:
- ./postgres_data:/var/lib/postgresql/data
networks:
- gotify
gotify:
image: gotify/server:latest
container_name: gotify
restart: always
environment:
- GOTIFY_DATABASE_DIALECT=postgres
- GOTIFY_DATABASE_CONNECTION=host=postgres port=5432 user=gotify dbname=gotify password=SECURE_PASSWORD sslmode=disable
depends_on:
- postgres
# ... rest of configuration Plugin System
Gotify supports plugins for extended functionality:
Installing plugins:
- Download plugin
.sofile for your architecture - Place in
./data/plugins/directory - Restart Gotify
- Web UI → Plugins tab → Configure
Popular plugins:
- broadcast: Broadcast messages to multiple applications
- example: Template for creating custom plugins
Custom Styling
Customize web UI appearance:
- Create custom CSS file
- Mount in docker-compose.yml:
volumes:
- ./custom.css:/app/ui/custom.css:ro Security Best Practices
Disable Public Registration
# docker-compose.yml
- GOTIFY_REGISTRATION=false Only admins can create users via web UI.
Use HTTPS
Always access Gotify via HTTPS:
- Protects API tokens in transit
- Prevents message interception
- Required for secure WebSocket connections
Token Management
Best practices:
- Create separate application for each service
- Rotate tokens periodically
- Delete unused applications
- Never commit tokens to source control
Regenerate application token:
- Web UI → Apps → Select application
- Click Regenerate Token
- Confirm regeneration
- Update all services using old token
Rate Limiting
Implement rate limiting in reverse proxy:
Nginx example:
limit_req_zone $binary_remote_addr zone=gotify:10m rate=10r/s;
location / {
limit_req zone=gotify burst=20 nodelay;
proxy_pass http://localhost:8080;
# ... rest of configuration
} Firewall Rules
Restrict access to Gotify server:
# Allow only from specific IP ranges
ufw allow from 192.168.1.0/24 to any port 8080
# Or use reverse proxy with authentication Monitoring and Troubleshooting
Health Checks
# Check service health
curl https://gotify.example.com/health
# Expected output:
# {"health":"green","database":"green"}
# Check version
curl https://gotify.example.com/version
# View current messages
curl -H "X-Gotify-Key: CLIENT_TOKEN" https://gotify.example.com/message Common Issues
Issue 1: Android App Not Receiving Notifications
Symptoms: Messages appear in web UI but not on Android
Solutions:
# Check Android app connection
# Web UI → Clients tab → Verify device is connected
# Ensure WebSocket connection is active
# Android app → Menu → Check connection status (green = connected)
# Verify battery optimization is disabled
# Android Settings → Apps → Gotify → Battery → Disable optimization
# Test with high-priority message
curl -X POST "https://gotify.example.com/message?token=TOKEN" -F "title=Test" -F "message=High priority test" -F "priority=10" Issue 2: Messages Not Stored
Symptoms: Messages sent successfully but don’t appear in web UI
Solutions:
# Check database file permissions
docker exec gotify ls -la /app/data/gotify.db
# Verify database is writable
docker exec gotify sqlite3 /app/data/gotify.db "PRAGMA integrity_check;"
# Check disk space
df -h /opt/gotify/data Issue 3: WebSocket Connection Fails
Symptoms: Web UI shows “Disconnected” status
Solutions:
# Verify reverse proxy WebSocket headers
# Nginx:
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# Test WebSocket directly
wscat -c wss://gotify.example.com/stream?token=CLIENT_TOKEN Issue 4: High Memory Usage
Symptoms: Container consumes excessive RAM
Solutions:
# Add resource limits
deploy:
resources:
limits:
memory: 256M
reservations:
memory: 128M
# Clean up old messages
# Web UI → Messages → Delete old messages Logging
Enable debug logging:
# Add to docker-compose.yml
environment:
- GOTIFY_SERVER_LOGLEVEL=debug View logs:
# Real-time logs
docker compose logs -f gotify
# Search for errors
docker compose logs gotify | grep -i error
# Export logs
docker compose logs gotify > /opt/gotify/debug.log Backup and Recovery
Backup Script
#!/bin/bash
# gotify-backup.sh
BACKUP_DIR="/opt/backups/gotify"
DATE=$(date +%Y%m%d_%H%M%S)
RETENTION_DAYS=30
mkdir -p "$BACKUP_DIR"
echo "Starting Gotify backup: $DATE"
# Backup SQLite database
cp /opt/gotify/data/gotify.db "$BACKUP_DIR/gotify-${DATE}.db"
if [ $? -eq 0 ]; then
echo "Database backup successful"
# Compress backup
gzip "$BACKUP_DIR/gotify-${DATE}.db"
else
echo "Database backup FAILED!" >&2
exit 1
fi
# Backup uploaded images (optional)
if [ -d /opt/gotify/data/images ]; then
tar czf "$BACKUP_DIR/gotify-images-${DATE}.tar.gz" /opt/gotify/data/images
fi
# Cleanup old backups
find "$BACKUP_DIR" -name "gotify-*.gz" -mtime +$RETENTION_DAYS -delete
echo "Backup completed: $DATE" Schedule daily:
chmod +x /opt/gotify/gotify-backup.sh
crontab -e
# Add: 0 3 * * * /opt/gotify/gotify-backup.sh >> /var/log/gotify-backup.log 2>&1 Disaster Recovery
# Stop service
docker compose down
# Restore database
gunzip -c /opt/backups/gotify/gotify-YYYYMMDD.db.gz > /opt/gotify/data/gotify.db
# Restore images (if backed up)
tar xzf /opt/backups/gotify/gotify-images-YYYYMMDD.tar.gz -C /
# Restart service
docker compose up -d
# Verify
docker compose logs -f gotify Database Maintenance
# Check database size
docker exec gotify ls -lh /app/data/gotify.db
# Vacuum database (reclaim space)
docker exec gotify sqlite3 /app/data/gotify.db "VACUUM;"
# Check database integrity
docker exec gotify sqlite3 /app/data/gotify.db "PRAGMA integrity_check;" Comparison: Gotify vs. ntfy
Both are excellent self-hosted notification servers. Choose based on your needs:
| Feature | Gotify | ntfy |
|---|---|---|
| Mobile Support | Android only | Android + iOS |
| Message Storage | Persistent SQLite | Cache-based |
| Web UI | Full-featured | Basic |
| Organization | Applications | Topics |
| Authentication | User accounts | Token-based |
| API | REST + WebSocket | HTTP-based |
| Best For | Android users, message history | Cross-platform, simplicity |
Use Gotify if:
- All users have Android devices
- Need comprehensive web UI for message management
- Want persistent message storage
- Prefer application-based organization
Use ntfy if:
- Need iOS support
- Want simpler setup
- Prefer topic-based organization
- Don’t require long-term message storage
Conclusion
You now have a fully functional Gotify notification server with:
- Docker-based deployment for reliability
- Application-based message organization
- Web UI for comprehensive management
- Android app for instant push notifications
- REST API for easy integration
- User management and access control
- WebSocket real-time delivery
- Automated backups
Next steps:
- Install Android app and connect to your server
- Create applications for different notification sources
- Integrate with monitoring tools and scripts
- Set up automated backups
- Configure notification priorities per application
- Explore plugin ecosystem
Gotify provides reliable, self-hosted push notifications with zero ongoing costs and complete privacy. Your notifications, your control, your infrastructure.
Additional Resources
Official:
Community:
API:
Last Updated: December 2025 Version Covered: Gotify 2.5.0+ Word Count: 3,619 words