List incidents
const url = 'https://app.tunnelhq.com/api/v1/incidents?status=active&limit=200';const options = {method: 'GET', headers: {'X-Project-Id': 'prj_12', 'X-API-Key': '<X-API-Key>'}};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request GET \ --url 'https://app.tunnelhq.com/api/v1/incidents?status=active&limit=200' \ --header 'X-API-Key: <X-API-Key>' \ --header 'X-Project-Id: prj_12'Returns the project’s incidents. Any role in the project can call it.
Open incidents come first (down before degraded, then the ones nobody has acknowledged),
then the rest, newest first. Incidents of paused monitors aren’t listed.
error_message is the latest check message during the incident.
Need an API key? See Getting an API key.
Authorizations
Section titled “Authorizations”Parameters
Section titled “ Parameters ”Header Parameters
Section titled “Header Parameters”The project, as prj_12 or 12. A workspace key can only reach its own workspace’s projects.
Example
prj_12Query Parameters
Section titled “Query Parameters”active for open incidents, recovered for closed ones. Left out (or any other value), both.
How many incidents to consider, before the status filter.
Responses
Section titled “ Responses ”The incidents.
object
object
active while the incident is open.
critical for a down incident, warning for a degraded one.
ISO 8601, UTC.
ISO 8601, UTC. null while open.
ISO 8601, UTC.
The incident’s level: down or degraded.
A check message from the incident.
Incidents returned.
Open incidents among the ones considered, whatever status you sent.
Example
{ "incidents": [ { "id": "inc_318", "server_id": "srv_57", "server_name": "sg-vless-01", "status": "active", "severity": "critical", "started_at": "2026-09-25T13:12:40.000Z", "ended_at": null, "acknowledged": false, "acknowledged_at": null, "error_type": "down", "error_message": "Tunnel unreachable" } ], "total": 1, "active": 1}Headers
Section titled “Headers”Requests the workspace’s plan allows per minute.
Requests left in the current minute.
Unix time, in seconds, when the current minute ends.
The X-Project-Id header is missing or malformed.
object
The HTTP status, repeated.
What went wrong.
More detail, on some errors.
Seconds to wait, on the 429 for wrong keys.
Examples
{ "error": true, "code": 400, "message": "X-Project-Id header is required (e.g. prj_1 or numeric id)"}{ "error": true, "code": 400, "message": "Invalid project ID format (use prj_1 or numeric id)"}The API key is missing, wrong, expired, switched off, or no longer valid.
object
The HTTP status, repeated.
What went wrong.
More detail, on some errors.
Seconds to wait, on the 429 for wrong keys.
Examples
{ "error": true, "code": 401, "message": "API key is required. Provide X-API-Key header or Authorization: Bearer <key>"}{ "error": true, "code": 401, "message": "Invalid or expired API key"}{ "error": true, "code": 401, "message": "API key has expired"}{ "error": true, "code": 401, "message": "API key owner account is inactive"}{ "error": true, "code": 401, "message": "This API key's workspace access has been removed"}The key can’t reach this project.
object
The HTTP status, repeated.
What went wrong.
More detail, on some errors.
Seconds to wait, on the 429 for wrong keys.
Examples
{ "error": true, "code": 403, "message": "This API key is scoped to a different organization"}{ "error": true, "code": 403, "message": "You do not have access to this project"}No active project has this ID.
object
The HTTP status, repeated.
What went wrong.
More detail, on some errors.
Seconds to wait, on the 429 for wrong keys.
Example
{ "error": true, "code": 404, "message": "Project not found or inactive"}A usage limit was reached, or this IP address made too many requests with a wrong key.
Usage limits are per workspace and plan: per minute (Retry-After: 60), per day
(Retry-After: 3600), and per month (no Retry-After). They use their own body shape.
An IP address may send 10 wrong keys a minute; one more is allowed every 6 seconds. While
that allowance is used up, every request from the address is refused, even one with a
valid key.
object
Seconds to wait. Absent for the monthly limit.
object
The HTTP status, repeated.
What went wrong.
More detail, on some errors.
Seconds to wait, on the 429 for wrong keys.
Examples
{ "error": "Rate limit exceeded", "message": "Per-minute limit of 60 requests exceeded", "retry_after": 60}{ "error": "Daily limit exceeded", "message": "Daily limit of 25000 requests exceeded", "retry_after": 3600}{ "error": "Monthly limit exceeded", "message": "Monthly limit of 250000 requests exceeded"}{ "error": true, "code": 429, "message": "Too many failed API key attempts from this address. Wait a few seconds and try again.", "retry_after": 6}Headers
Section titled “Headers”Seconds to wait. 60 for the per-minute limit, 3600 for the daily limit, 6 after wrong keys. Absent for the monthly limit.
Something failed on TunnelHQ’s side.
object
The HTTP status, repeated.
What went wrong.
More detail, on some errors.
Seconds to wait, on the 429 for wrong keys.
Example
{ "error": true, "code": 500, "message": "Internal server error"}