Notifications and webhooks
Configuring traffic balance alerts, the requirements for four delivery channels, and the actual webhook payload.
The platform's notification capability is narrower than a full event subscription system — what exists today is one trigger, traffic balance alerts, deliverable to four channels. Set expectations accordingly before integrating.
Supported channels
| Channel | Notes |
|---|---|
| Sent to the account email | |
| Webhook | POST to your HTTPS endpoint |
| Bark | iOS push service |
| Telegram | Managed by the binding flow, not the generic channel endpoint |
Webhook requirements
The actual webhook payload
This is the complete request; there are no other fields:
POST /your-endpoint HTTP/1.1
Content-Type: application/json
User-Agent: NextProxy-Notification/1.0
{
"type": "webhook",
"title": "Low traffic balance",
"body": "12.3 GB remaining, below your 20 GB alert threshold."
}
How to use it safely given those limits
With no signature available, use an unguessable URL path as the shared secret, plus origin checks:
import crypto from 'node:crypto';
import express from 'express';
const app = express();
app.use(express.json());
// The secret lives in the path, because the payload carries no signature to verify
const WEBHOOK_PATH = `/hooks/nextproxy/${process.env.WEBHOOK_SECRET}`;
app.post(WEBHOOK_PATH, (req, res) => {
// The platform always sends this UA, so it works as one weak check
if (req.get('user-agent') !== 'NextProxy-Notification/1.0') {
return res.status(404).end();
}
const { title, body } = req.body ?? {};
if (typeof title !== 'string' || typeof body !== 'string') {
return res.status(400).json({ error: 'bad payload' });
}
// Answer 2xx before doing slow work — there are no retries, so a timeout loses it
res.status(200).end();
queueAlert({ title, body }).catch((error) => {
console.error('failed to enqueue alert', error);
});
});
async function queueAlert(alert) {
// Forward into your own alerting system
console.log('[NextProxy]', alert.title, alert.body);
}
app.listen(3000);
Traffic balance alerts
This is the only alert trigger currently implemented, and it watches the dynamic residential traffic pool.
Configuration
/api/v1/traffic-alert-settings/api/v1/traffic-alert-settingscurl -X PUT 'https://api.example.com/api/v1/traffic-alert-settings' \
-H 'Authorization: Bearer at_YOUR_ACCESS_TOKEN' \
-H 'Origin: https://console.example.com' \
-H 'Content-Type: application/json' \
-d '{
"enabled": true,
"thresholdBytes": 21474836480,
"channelIds": ["channel-id-1", "channel-id-2"]
}'
Rules
Alert threshold, from 1 MB to 100 TB. Fires when the remaining balance drops below it.
Associated notification channels, up to 20.
While below the threshold, at most one message per calendar day (Beijing time).
That prevents being bombarded while you sit below the threshold, but it also means you will not get a second reminder that day.
Firing also writes an in-app notification, so the message is visible in the console even if external delivery fails.
Creating a notification channel
/api/v1/notification-channelscurl -X POST 'https://api.example.com/api/v1/notification-channels' \
-H 'Authorization: Bearer at_YOUR_ACCESS_TOKEN' \
-H 'Origin: https://console.example.com' \
-H 'Content-Type: application/json' \
-d '{
"type": "webhook",
"name": "Ops alerts",
"target": "https://hooks.example.com/nextproxy/SECRET"
}'
Other endpoints:
/api/v1/notification-channels/api/v1/notification-channels/:id/api/v1/notification-channels/:idIn-app notifications
Three categories: system, renewal and activity.
/api/v1/notifications/api/v1/notifications/:id/read/api/v1/notifications/read-allWhat does not exist today
Listing these explicitly so you don't design around features that aren't there:
| What you might want | Reality |
|---|---|
| Wallet balance alerts | Not available. Traffic balance only |
| Percentage-based usage alerts | Not available. Absolute byte thresholds only |
| Static IP expiry reminders | No scheduled job for it |
| General business event webhook subscriptions | Not available. Webhooks only carry traffic alerts |
| Webhook signature verification | No signature header or secret |
| Webhook retry on failure | No retry queue |
An example of self-built monitoring
import time
import requests
def check_traffic_balance(client, warn_gb: float = 20.0) -> None:
"""Poll the traffic balance and route alerts through your own channel.
The platform sends at most one alert per day; polling covers the
"second time the same day" gap.
"""
summary = client.get("/api/v1/proxy/usage/summary")
remaining_gb = summary["trafficRemainBytes"] / (1024 ** 3)
if remaining_gb < warn_gb:
notify_ops(
f"NextProxy traffic balance {remaining_gb:.1f} GB, below {warn_gb} GB"
)
def check_expiring_resources(client, warn_days: int = 7) -> None:
"""Static resource expiry has no platform-side reminder, so check it yourself."""
deadline = time.time() + warn_days * 86400
for path in ("/api/v1/static-residential", "/api/v1/static-datacenter"):
for resource in client.get(path).get("items", []):
expires_at = resource.get("expiresAt")
if expires_at and _to_epoch(expires_at) < deadline:
notify_ops(f"{resource['ip']} expires at {expires_at}")