Pushi is a comprehensive multi-tenant SaaS platform designed for companies that need reliable, scalable notification delivery across multiple channels. Send notifications to Pushover, Discord, Slack, and Mattermost with a single API call.
Get up and running with Pushi in just a few minutes.
Sign up for a free account to get started with basic Pushover and Slack notifications.
Sign Up NowWorkspaces provide complete data isolation. Each workspace has its own:
Set up your preferred notification channels:
Use your workspace API hash to send notifications:
curl -X POST https://your-domain.com/api/notify \
-H "Content-Type: application/json" \
-H "X-Workspace-Hash: your-workspace-hash" \
-d '{
"message": "Hello from Pushi!",
"title": "Test Notification"
}'
Pushi uses workspace-based authentication for API access. Each workspace has a unique hash that serves as the authentication token.
X-Workspace-Hash: your-64-character-workspace-hash
Workspaces are the foundation of Pushi's multi-tenant architecture. They provide complete isolation between different organizations, projects, or teams.
Each workspace maintains separate user lists, notification settings, and usage analytics.
Each workspace has its own subscription plan and billing cycle.
Users can have different roles (Owner, Admin, Member, Viewer) in each workspace.
Configure notification channels, webhook settings, and group permissions per workspace.
Plan | Workspaces per User | Members per Workspace | Groups per Workspace |
---|---|---|---|
Free | 1 | 5 | 3 |
Pro | 5 | 25 | 10 |
Enterprise | Unlimited | Unlimited | Unlimited |
Groups allow you to organize users within a workspace for targeted notifications. Each group can have its own notification settings or inherit from the workspace.
Groups can be configured in two ways:
Use the workspace's notification channels and settings. This is the default and recommended approach.
RecommendedDefine group-specific webhook URLs and notification preferences for specialized use cases.
AdvancedPushi supports multiple notification channels, allowing you to reach your team wherever they are.
Real-time push notifications to mobile devices and desktop.
Send messages to Slack channels and direct messages.
Rich embeds and messages for Discord servers.
Self-hosted team communication platform integration.
The Pushi API is built on REST principles with predictable URLs, standard HTTP response codes, and JSON payloads.
https://pushi.app/api
Code | Description | Meaning |
---|---|---|
200 | OK | Request successful |
400 | Bad Request | Invalid request parameters |
401 | Unauthorized | Invalid or missing workspace hash |
429 | Too Many Requests | Rate limit exceeded |
500 | Internal Server Error | Server error occurred |
Send notifications to all users in a workspace across all configured channels.
/api/notify
Content-Type: application/json
X-Workspace-Hash: your-workspace-hash
{
"message": "Your notification message",
"title": "Optional title",
"priority": 0,
"channels": ["pushover", "slack"]
}
Parameter | Type | Required | Description |
---|---|---|---|
message |
string | Yes | The notification message (max 1024 characters) |
title |
string | No | Optional title (max 250 characters) |
priority |
integer | No | Priority level: -2 (lowest) to 2 (emergency) |
channels |
array | No | Specific channels to target. Omit for all channels. |
{
"success": true,
"message": "Notification sent successfully",
"statistics": {
"pushover_success_count": 5,
"pushover_error_count": 0,
"webhook_success_count": 2,
"webhook_error_count": 0,
"total_channels": 3
}
}
Use your workspace hash to authenticate API requests. You can include it in the header, URL, or as a query parameter.
New: Use the optional channels
parameter to target specific notification channels (pushover, discord, slack, mattermost). If omitted, all configured channels receive the notification.
#!/bin/bash
# Using header authentication
curl -X POST "https://pushi.app/api/notify" \
-H "Content-Type: application/json" \
-H "X-Workspace-Hash: YOUR_WORKSPACE_HASH" \
-d '{
"message": "Hello from Pushi App API!",
"title": "Important Notification",
"priority": 0,
"sound": "pushover",
"url": "https://example.com/details",
"url_title": "View Details",
"channels": [
"pushover",
"slack"
]
}'
# Alternative: Using query parameter
curl -X POST "https://pushi.app/api/notify?workspace_hash=YOUR_WORKSPACE_HASH" \
-H "Content-Type: application/json" \
-d '{
"message": "Hello from Pushi App API!",
"title": "Important Notification",
"priority": 0,
"sound": "pushover",
"url": "https://example.com/details",
"url_title": "View Details",
"channels": [
"pushover",
"slack"
]
}'
<?php
// Using cURL
$ch = curl_init('https://pushi.app/api/notify');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'X-Workspace-Hash: YOUR_WORKSPACE_HASH'
]);
$payload = {
"message": "Hello from Pushi App API!",
"title": "Important Notification",
"priority": 0,
"sound": "pushover",
"url": "https://example.com/details",
"url_title": "View Details",
"channels": [
"pushover",
"slack"
]
};
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
$result = json_decode($response, true);
if ($httpCode === 200) {
echo "Success: " . $result['message'] . "\n";
echo "Notified: " . $result['data']['statistics']['successful_deliveries'] . " users\n";
} else {
echo "Error: " . $result['error'] . "\n";
}
// Alternative: Using file_get_contents
$options = [
'http' => [
'method' => 'POST',
'header' => [
'Content-Type: application/json',
'X-Workspace-Hash: YOUR_WORKSPACE_HASH'
],
'content' => json_encode({
"message": "Hello from Pushi App API!",
"title": "Important Notification",
"priority": 0,
"sound": "pushover",
"url": "https://example.com/details",
"url_title": "View Details",
"channels": [
"pushover",
"slack"
]
}) ]
];
$context = stream_context_create($options);
$response = file_get_contents('https://pushi.app/api/notify', false, $context);
$result = json_decode($response, true);
// Using Fetch API (Modern Browsers & Node.js 18+)
const sendNotification = async () => {
try {
const response = await fetch('https://pushi.app/api/notify', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Workspace-Hash': 'YOUR_WORKSPACE_HASH'
},
body: JSON.stringify({
"message": "Hello from Pushi App API!",
"title": "Important Notification",
"priority": 0,
"sound": "pushover",
"url": "https://example.com/details",
"url_title": "View Details",
"channels": [
"pushover",
"slack"
]
}) });
const result = await response.json();
if (response.ok) {
console.log('Success:', result.message);
console.log(`Notified ${result.data.statistics.successful_deliveries} users`);
} else {
console.error('Error:', result.error);
}
} catch (error) {
console.error('Network error:', error);
}
};
sendNotification();
// Using Axios (requires: npm install axios)
const axios = require('axios');
axios.post('https://pushi.app/api/notify', {
"message": "Hello from Pushi App API!",
"title": "Important Notification",
"priority": 0,
"sound": "pushover",
"url": "https://example.com/details",
"url_title": "View Details",
"channels": [
"pushover",
"slack"
]
}, {
headers: {
'Content-Type': 'application/json',
'X-Workspace-Hash': 'YOUR_WORKSPACE_HASH'
}
})
.then(response => {
console.log('Success:', response.data.message);
console.log(`Notified ${response.data.data.statistics.successful_deliveries} users`);
})
.catch(error => {
console.error('Error:', error.response?.data?.error || error.message);
});
#!/usr/bin/env python3
import requests
import json
# API endpoint and authentication
url = 'https://pushi.app/api/notify'
headers = {
'Content-Type': 'application/json',
'X-Workspace-Hash': 'YOUR_WORKSPACE_HASH'
}
# Notification payload
payload = {
"message": "Hello from Pushi App API!",
"title": "Important Notification",
"priority": 0,
"sound": "pushover",
"url": "https://example.com/details",
"url_title": "View Details",
"channels": [
"pushover",
"slack"
]
}
# Send the request
response = requests.post(url, json=payload, headers=headers)
# Handle the response
if response.status_code == 200:
result = response.json()
print(f"Success: {result['message']}")
stats = result['data']['statistics']
print(f"Notified {stats['successful_deliveries']} users")
else:
error = response.json()
print(f"Error {response.status_code}: {error.get('error', 'Unknown error')}")
# Alternative: Using urllib (built-in)
import urllib.request
import urllib.error
data = json.dumps(payload).encode('utf-8')
req = urllib.request.Request(
url,
data=data,
headers=headers,
method='POST'
)
try:
with urllib.request.urlopen(req) as response:
result = json.loads(response.read().decode())
print(f"Success: {result['message']}")
except urllib.error.HTTPError as e:
error = json.loads(e.read().decode())
print(f"Error {e.code}: {error.get('error', 'Unknown error')}")
#!/usr/bin/perl
use strict;
use warnings;
use LWP::UserAgent;
use JSON;
use HTTP::Request;
# Create user agent
my $ua = LWP::UserAgent->new;
$ua->timeout(10);
# API endpoint
my $url = 'https://pushi.app/api/notify';
# Create request
my $req = HTTP::Request->new('POST' => $url);
$req->header('Content-Type' => 'application/json');
$req->header('X-Workspace-Hash' => 'YOUR_WORKSPACE_HASH');
# Set request body
my $payload = {
"message": "Hello from Pushi App API!",
"title": "Important Notification",
"priority": 0,
"sound": "pushover",
"url": "https://example.com/details",
"url_title": "View Details",
"channels": [
"pushover",
"slack"
]
};
$req->content(encode_json($payload));
# Send request
my $response = $ua->request($req);
# Handle response
if ($response->is_success) {
my $result = decode_json($response->content);
print "Success: $result->{message}\n";
my $stats = $result->{data}->{statistics};
print "Notified $stats->{successful_deliveries} users\n";
} else {
my $error = decode_json($response->content);
print "Error: $error->{error}\n";
}
# Alternative: Using curl command
my $workspace_hash = 'YOUR_WORKSPACE_HASH';
my $json_payload = encode_json({
"message": "Hello from Pushi App API!",
"title": "Important Notification",
"priority": 0,
"sound": "pushover",
"url": "https://example.com/details",
"url_title": "View Details",
"channels": [
"pushover",
"slack"
]
});
my $cmd = qq{curl -X POST "$url" -H "Content-Type: application/json" -H "X-Workspace-Hash: $workspace_hash" -d '$json_payload'};
my $output = `$cmd 2>/dev/null`;
my $result = decode_json($output);
if ($result->{success}) {
print "Success: $result->{message}\n";
} else {
print "Error: $result->{error}\n";
}
Send targeted notifications to specific groups within your workspace.
/api/groups/{group_id}/notify
Parameter | Description |
---|---|
group_id |
The group's hashid (found in dashboard) |
Send to multiple groups by providing group IDs in the request body:
{
"message": "Server maintenance in 30 minutes",
"title": "Maintenance Alert",
"groups": ["abc123", "def456", "ghi789"],
"channels": ["pushover", "discord"]
}
API rate limits are enforced per workspace with both daily and hourly (burst) limits to prevent abuse while ensuring fair usage.
Plan | Daily Requests | Hourly Burst Limit |
---|---|---|
Free | 100 | 10 per hour |
Pro | 1,000 | 100 per hour |
Enterprise | 10,000 | 1,000 per hour |
All API responses include rate limit information:
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 99
X-RateLimit-Reset: 1640995200
X-RateLimit-Burst-Limit: 10
X-RateLimit-Burst-Remaining: 9
Pushover provides real-time notifications to iOS, Android, and desktop devices.
Send rich embeds and messages to Discord servers and channels.
Integrate with Slack channels and direct messages using incoming webhooks.
Connect to self-hosted or cloud Mattermost instances.
Pushi implements enterprise-grade security measures to protect your data and communications.
Common issues and their solutions.
X-Workspace-Hash
header name