Signals API
Send heartbeat pings, query signal history, and subscribe to real-time updates via SSE.
Signals are the heartbeat of Ionhour's monitoring. Every ping your service sends creates a signal record. Ionhour uses signals to determine check status, detect outages, and track uptime.
Send a Heartbeat
GET /signals/ping/:tokenThe simplest way to send a heartbeat.
curl https://signal.ionhour.com/api/signals/ping/YOUR_TOKENResponse:
{"message": "OK"}Ionhour captures the source IP address and user agent with each ping.
POST /signals/ping/:tokenSend a heartbeat with a JSON payload for additional context.
curl -X POST https://signal.ionhour.com/api/signals/ping/YOUR_TOKEN \
-H "Content-Type: application/json" \
-d '{
"status": "completed",
"rows_processed": 1500,
"duration_ms": 4200
}'Payload Limits:
- Maximum payload size: 10 KB
- Payload is stored with the signal and visible in the signal history.
POST /signals/ping/:tokenInclude a dependencies array in the payload to report the health of external services your application depends on:
curl -X POST https://signal.ionhour.com/api/signals/ping/YOUR_TOKEN \
-H "Content-Type: application/json" \
-d '{
"dependencies": [
{"name": "PostgreSQL", "status": "ok"},
{"name": "Redis", "status": "down"}
]
}'When a dependency is reported as down, Ionhour creates a DEPENDENCY_DOWN incident for the check. See Dependencies for details.
What Happens When a Ping is Received
Each ping triggers the full monitoring pipeline:
- Signal created — stored in MongoDB with type
SUCCESS. - Check status updated —
lastPingAtandnextDueAtare recalculated. - Incident resolution — if the check was DOWN, active incidents are resolved.
- Dependency evaluation — if the check has dependencies, their impact is assessed.
- SSE broadcast — connected clients receive the signal in real time.
Signal History
GET /signals/token/:tokenReturns paginated signal history for a check. Requires authentication.
Query Parameters
| Parameter | Type | Description |
|---|---|---|
page | number | Page number (default: 1) |
limit | number | Items per page (default: 20) |
startDate | ISO string | Filter signals after this date |
endDate | ISO string | Filter signals before this date |
Example
curl -H "Authorization: Bearer ionh_your_key" \
"https://api.ionhour.com/api/signals/token/YOUR_TOKEN?limit=10"Signal Types
Each signal has a type indicating how it was created:
| Type | Description |
|---|---|
SUCCESS | A heartbeat was received (from a ping) |
SUSPECT | The check is overdue — system-generated when the check transitions to LATE |
FAIL | The check has failed — system-generated when the check transitions to DOWN |
DEPLOYMENT | A deployment window started or ended — includes deployment metadata |
Real-Time Updates (SSE)
GET /signals/sseSubscribe to a Server-Sent Events stream for real-time signal and check updates. Requires authentication.
Query Parameters
| Parameter | Type | Description |
|---|---|---|
token | string | Optional check token to filter events to a single check |
Example
curl -N -H "Authorization: Bearer ionh_your_key" \
"https://signal.ionhour.com/api/signals/sse?token=YOUR_TOKEN"Event Types
The SSE stream emits these event types:
| Event | Description |
|---|---|
| Signal events | New signals for the subscribed check (or all user's checks if no token) |
| Check updates | Status changes on checks |
| Heartbeat | Keep-alive pings every 15 seconds |
Connection details
- The SSE connection stays open until the client disconnects.
- Heartbeat events are sent every 15 seconds to keep the connection alive.
- If no
tokenis provided, the stream includes events for all checks accessible to the authenticated user. - Rate limit: 30 connections per 60 seconds.
Client Example
const eventSource = new EventSource(
'https://signal.ionhour.com/api/signals/sse?token=YOUR_TOKEN',
{
headers: {
'Authorization': 'Bearer ionh_your_key'
}
}
);
eventSource.onmessage = (event) => {
const data = JSON.parse(event.data);
console.log('Signal received:', data);
};
eventSource.onerror = (error) => {
console.error('SSE connection error:', error);
};