API Reference
Base URL: https://apisentinel.io — All endpoints return JSON. All write endpoints require authentication.
Getting Started
Up and running in three steps.
Get your API key
Sign up at /signup to generate a free API key instantly. No credit card required. The Free plan includes 500 validations/month and 1 active monitor.
Make your first validation call
Send a POST request with your x-api-key header and a JSON body. If using curl or an SDK, also set Content-Type: application/json — in Postman, selecting Body → Raw → JSON sets it automatically:
POST https://apisentinel.io/api/v1/validate
x-api-key: as_live_xxxxxxxxxxxxxxxxxxxx
Content-Type: application/json
{
"url": "https://api.example.com/health",
"checks": {
"statusCode": { "expected": 200 },
"responseTiming": { "maxMs": 1000 }
}
}Set up a monitor
Register your endpoint for continuous monitoring. You'll receive an email alert the first time it fails:
POST https://apisentinel.io/api/v1/monitors
x-api-key: as_live_xxxxxxxxxxxxxxxxxxxx
Content-Type: application/json
{
"name": "Production API",
"url": "https://api.example.com/health",
"alert_email": "you@example.com"
}Authentication
All API requests must include your API key in the x-api-key header. API keys are scoped to your account — all monitors and usage logs are isolated per key.
// Include this header on every request
x-api-key: as_live_xxxxxxxxxxxxxxxxxxxxContent-Type: application/json. Postman users: selecting Body → Raw → JSON sets this header automatically — you only need to add x-api-key manually. curl and SDK users must include Content-Type: application/json explicitly, or the server will reject the request body.Error responses
Missing or invalid keys return a 401 with one of:
{ "error": "Missing x-api-key header" }
{ "error": "Invalid or inactive API key" }Validate an endpoint
Sends a one-off request to any URL and returns a structured health report. Checks are optional — omit any you don't need. Results are logged to your account's usage history.
Request body
| Parameter | Type | Required | Description |
|---|---|---|---|
| url | string | Yes | The endpoint URL to validate |
| method | string | No | HTTP method. Defaults to "GET" |
| headers | object | No | Key-value pairs sent with the request |
| body | string | No | Raw request body (for POST/PUT requests) |
| checks.statusCode.expected | number | number[] | No | Expected HTTP status code(s) |
| checks.responseTiming.maxMs | number | No | Maximum acceptable response time in milliseconds |
| checks.ssl.enabled | boolean | No | Whether to validate the SSL certificate |
| checks.ssl.minDaysRemaining | number | No | Minimum days before cert expiry. Defaults to 14 |
Request example — GET with checks
{
"url": "https://api.example.com/health",
"method": "GET",
"headers": {
"Authorization": "Bearer token123"
},
"checks": {
"statusCode": {
"expected": 200
},
"responseTiming": {
"maxMs": 1000
},
"ssl": {
"enabled": true,
"minDaysRemaining": 30
}
}
}Request example — POST with body
Use the body field to send a request body. Pass it as a stringified JSON string.
{
"url": "https://api.example.com/users",
"method": "POST",
"headers": {
"Authorization": "Bearer token123",
"Content-Type": "application/json"
},
"body": "{"name": "Alice", "email": "alice@example.com"}",
"checks": {
"statusCode": {
"expected": 201
},
"responseTiming": {
"maxMs": 2000
}
}
}Response — 200 OK
{
"url": "https://api.example.com/health",
"timestamp": "2026-05-09T12:00:00.000Z",
"passed": true,
"durationMs": 243,
"statusCode": 200,
"checks": [
{
"name": "status_code",
"passed": true,
"message": "Status code 200 is as expected",
"details": {
"statusCode": 200,
"expected": [200]
}
},
{
"name": "response_timing",
"passed": true,
"message": "Response time 243ms is within the 1000ms limit",
"details": {
"durationMs": 243,
"maxMs": 1000
}
},
{
"name": "ssl",
"passed": true,
"message": "SSL certificate valid, 187 days until expiry",
"details": {
"valid": true,
"expiryDate": "2026-11-12T00:00:00.000Z",
"daysRemaining": 187,
"issuer": { "O": "Let's Encrypt" },
"subject": { "CN": "api.example.com" }
}
}
]
}Response — check failure
When one or more checks fail, passed is false and the failing check carries a descriptive message. The HTTP status is still 200 — the status code reflects the API call, not the target.
{
"url": "https://api.example.com/health",
"timestamp": "2026-05-09T12:00:00.000Z",
"passed": false,
"durationMs": 1847,
"statusCode": 200,
"checks": [
{
"name": "status_code",
"passed": true,
"message": "Status code 200 is as expected",
"details": { "statusCode": 200, "expected": [200] }
},
{
"name": "response_timing",
"passed": false,
"message": "Response time 1847ms exceeded the 1000ms limit",
"details": { "durationMs": 1847, "maxMs": 1000 }
}
]
}Create a monitor
Registers an endpoint for continuous monitoring. The cron runner checks all active monitors on schedule and sends an email alert to alert_email whenever a monitor transitions from passing to failing.
429 response. Upgrade your plan for more.Request body
| Parameter | Type | Required | Description |
|---|---|---|---|
| name | string | Yes | Human-readable label for this monitor |
| url | string | Yes | The endpoint URL to monitor |
| method | string | No | HTTP method. Defaults to "GET" |
| headers | object | No | Key-value pairs sent with each check request |
| interval | string | No | Check frequency: "1m", "5m", "1h". Defaults to "5m" |
| checks | object | No | Same check options as POST /api/v1/validate |
| alert_email | string | No | Email for failure alerts. Defaults to your account email |
interval value set. Pro plan supports 10-minute check intervals. Scale plan supports 5-minute check intervals.Request example
{
"name": "Production API",
"url": "https://api.example.com/health",
"method": "GET",
"interval": "5m",
"checks": {
"statusCode": {
"expected": 200
},
"responseTiming": {
"maxMs": 2000
},
"ssl": {
"enabled": true,
"minDaysRemaining": 14
}
},
"alert_email": "you@example.com"
}Response — 201 Created
{
"monitor_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "active"
}List monitors
Returns active monitors associated with your API key, ordered by creation date descending. Deactivated monitors are excluded by default.
Query parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| include_inactive | boolean | No | Set to "true" to include deactivated monitors in the response |
is_active: true are returned. Append ?include_inactive=true to retrieve all monitors regardless of status.Response — 200 OK
{
"monitors": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Production API",
"url": "https://api.example.com/health",
"method": "GET",
"interval": "5m",
"is_active": true,
"alert_email": "you@example.com",
"checks": {
"statusCode": { "expected": 200 },
"responseTiming": { "maxMs": 2000 }
},
"created_at": "2026-05-09T12:00:00.000Z"
}
]
}Get a monitor
Returns a single monitor along with its 20 most recent check results. Use this to inspect historical pass/fail status and response times.
Path parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | string (UUID) | Yes | The monitor ID returned when it was created |
Response — 200 OK
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Production API",
"url": "https://api.example.com/health",
"method": "GET",
"interval": "5m",
"is_active": true,
"alert_email": "you@example.com",
"created_at": "2026-05-09T12:00:00.000Z",
"recent_checks": [
{
"id": "abc12300-0000-0000-0000-000000000001",
"status_code": 200,
"response_time": 243,
"passed": true,
"created_at": "2026-05-09T12:05:00.000Z"
},
{
"id": "abc12300-0000-0000-0000-000000000002",
"status_code": 503,
"response_time": 4821,
"passed": false,
"created_at": "2026-05-09T12:00:00.000Z"
}
]
}recent_checks will be an empty array ([]) until the first scheduled check runs. Checks execute on the interval configured when the monitor was created.Response — 404 Not Found
{ "error": "Monitor not found" }Deactivate a monitor
Sets the monitor's is_active flag to false — the monitor will no longer run scheduled checks or send alerts. The record and its full check history are preserved in the database; nothing is permanently deleted. To reactivate a deactivated monitor, contact support.
Path parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | string (UUID) | Yes | The monitor ID to deactivate |
Response — 200 OK
{ "status": "deactivated" }