Using the API

NotifyHero provides a simple REST API for subscribing to topics and receiving messages programmatically.

Endpoints

All endpoints are relative to https://app.notifyhero.com.

Subscribe to Messages

| Endpoint | Format | Description | |----------|--------|-------------| | GET /<topic>/json | JSON stream | Newline-delimited JSON | | GET /<topic>/sse | SSE | Server-sent events | | GET /<topic>/raw | Raw text | Plain text, one message per line | | GET /<topic>/ws | WebSocket | WebSocket connection |

Publish Messages

| Endpoint | Method | Description | |----------|--------|-------------| | POST /<topic> | POST | Publish with body as message | | PUT /<topic> | PUT | Publish with body as message | | POST / | POST | Publish with JSON body |

Message Format

Messages are returned as JSON objects:

{
  "id": "sPs9p1xXPU",
  "time": 1639182025,
  "event": "message",
  "topic": "mytopic",
  "title": "Alert",
  "message": "Something happened!",
  "priority": 4,
  "tags": ["warning", "skull"],
  "click": "https://example.com",
  "attachment": {
    "name": "image.jpg",
    "type": "image/jpeg",
    "size": 12345,
    "url": "https://app.notifyhero.com/file/abc123.jpg"
  }
}

Fields

| Field | Type | Description | |-------|------|-------------| | id | string | Unique message ID | | time | integer | Unix timestamp | | event | string | Event type (message, open, keepalive) | | topic | string | Topic name | | title | string | Message title (optional) | | message | string | Message body | | priority | integer | Priority 1-5 (optional) | | tags | array | List of tags (optional) | | click | string | Click URL (optional) | | attachment | object | Attachment details (optional) | | actions | array | Action buttons (optional) |

Subscribing

JSON Stream

const eventSource = new EventSource('https://app.notifyhero.com/mytopic/json');

eventSource.onmessage = (event) => {
  const message = JSON.parse(event.data);
  console.log(message.message);
};

Server-Sent Events

const eventSource = new EventSource('https://app.notifyhero.com/mytopic/sse');

eventSource.addEventListener('message', (event) => {
  const data = JSON.parse(event.data);
  console.log(data.message);
});

WebSocket

const ws = new WebSocket('wss://app.notifyhero.com/mytopic/ws');

ws.onmessage = (event) => {
  const message = JSON.parse(event.data);
  console.log(message.message);
};

Polling

Get cached messages without keeping connection open:

curl "https://app.notifyhero.com/mytopic/json?poll=1"

Publishing

Simple Message

curl -d "Hello World" https://app.notifyhero.com/mytopic

With Headers

curl \
  -H "Title: Alert" \
  -H "Priority: high" \
  -H "Tags: warning" \
  -d "Something happened" \
  https://app.notifyhero.com/mytopic

JSON Body

curl -d '{
  "topic": "mytopic",
  "title": "Alert",
  "message": "Something happened",
  "priority": 4,
  "tags": ["warning"]
}' https://app.notifyhero.com/

Query Parameters

Subscribe Parameters

| Parameter | Description | Example | |-----------|-------------|---------| | since | Messages since time | ?since=1h, ?since=1639182025 | | poll | Poll mode (return and close) | ?poll=1 | | scheduled | Include scheduled messages | ?scheduled=1 | | id | Filter by message ID | ?id=abc123 |

Publish Parameters

| Parameter | Header | Description | |-----------|--------|-------------| | title | Title | Message title | | priority | Priority | Priority (1-5 or name) | | tags | Tags | Comma-separated tags | | delay | Delay | Scheduled delivery | | click | Click | Click URL | | attach | Attach | Attachment URL | | filename | Filename | Attachment filename | | icon | Icon | Notification icon URL | | actions | Actions | Action buttons | | email | Email | Email for forwarding |

Authentication

Bearer Token

curl -H "Authorization: Bearer tk_xxx" https://app.notifyhero.com/mytopic/json

Basic Auth

curl -u username:password https://app.notifyhero.com/mytopic/json

Query Parameter

curl "https://app.notifyhero.com/mytopic/json?auth=tk_xxx"

Rate Limiting

The API implements rate limiting:

  • Messages: 60 per hour per visitor
  • Attachments: 100MB per hour per visitor

When rate limited, you'll receive a 429 Too Many Requests response.

Error Responses

{
  "code": 40301,
  "http": 403,
  "error": "forbidden",
  "link": "https://docs.example.com/errors"
}

| Code | HTTP | Description | |------|------|-------------| | 40001 | 400 | Invalid request | | 40101 | 401 | Unauthorized | | 40301 | 403 | Forbidden | | 40401 | 404 | Topic not found | | 42901 | 429 | Rate limited |

Examples

Python

import requests
import json

# Subscribe
response = requests.get(
    'https://app.notifyhero.com/mytopic/json',
    stream=True
)
for line in response.iter_lines():
    if line:
        message = json.loads(line)
        print(message['message'])

Node.js

const EventSource = require('eventsource');

const es = new EventSource('https://app.notifyhero.com/mytopic/sse');
es.onmessage = (e) => {
    const data = JSON.parse(e.data);
    console.log(data.message);
};

Go

resp, _ := http.Get("https://app.notifyhero.com/mytopic/json")
scanner := bufio.NewScanner(resp.Body)
for scanner.Scan() {
    var msg Message
    json.Unmarshal(scanner.Bytes(), &msg)
    fmt.Println(msg.Message)
}