okokumo Sentinel API (1)

Download OpenAPI specification:

Infrastructure monitoring API — HTTP(S) checks, heartbeat/cron monitoring, TLS/domain expiry checks, and alert channels.

Account

Current user and organization

Authorizations:
ApiKeyAuth

Responses

Response samples

Content type
application/json
{
  • "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5",
  • "email": "string",
  • "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
  • "organization_name": "string",
  • "role": "owner"
}

API keys

List API keys

Owners/admins only. Only the display prefix is returned, never the raw key.

Authorizations:
ApiKeyAuth

Responses

Response samples

Content type
application/json
[
  • {
    }
]

Create an API key

Owners/admins only. The raw key is returned once, at creation — store it somewhere safe; only key_prefix is retrievable afterwards.

Authorizations:
ApiKeyAuth
Request Body schema: application/json
required
name
required
string

Responses

Request samples

Content type
application/json
{
  • "name": "string"
}

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "name": "string",
  • "key_prefix": "sk_ab12cd34",
  • "created_at": "2019-08-24T14:15:22Z",
  • "key": "string"
}

Revoke an API key

Authorizations:
ApiKeyAuth
path Parameters
id
required
string <uuid>

Responses

Checks

List checks

Authorizations:
ApiKeyAuth

Responses

Response samples

Content type
application/json
[
  • {
    }
]

Create a check

interval_seconds is floored by your plan (free 300s, starter 60s, pro 30s). For type: heartbeat or cron, omit url/method/assertions and send grace_seconds instead — the response includes a ping_token. A cron check may carry cron_expression (+ cron_timezone) to be judged against a crontab schedule rather than a flat period.

Authorizations:
ApiKeyAuth
Request Body schema: application/json
required
type
string
Default: "http"
Enum: "http" "heartbeat" "cron" "tls" "domain"
name
required
string
url
string

Required for http/tls/domain

method
string
Default: "GET"
interval_seconds
integer [ 30 .. 86400 ]
Default: 300
timeout_seconds
integer
Default: 10
grace_seconds
integer

heartbeat/cron only

cron_expression
string

Optional crontab schedule, cron type only. Five standard fields plus @daily/@hourly/@weekly/@monthly/@yearly/@every. Set, it replaces interval_seconds as the deadline: the check goes down when a scheduled run hasn't pinged within grace_seconds of its due time. The plan's interval floor applies to the tightest gap the expression produces. A CRON_TZ= prefix is rejected — use cron_timezone. Because PUT replaces rather than patches, omitting this clears the schedule.

cron_timezone
string

IANA zone the expression is read in, default UTC. Per check because a crontab fires in its host's local zone, and a fixed offset would drift an hour at each DST change.

failure_threshold
integer [ 1 .. 10 ]
Default: 2
Array of objects (Assertion)
enabled
boolean
Default: true

Responses

Request samples

Content type
application/json
{
  • "type": "http",
  • "name": "string",
  • "url": "string",
  • "method": "GET",
  • "interval_seconds": 300,
  • "timeout_seconds": 10,
  • "grace_seconds": 0,
  • "cron_expression": "0 3 * * 1-5",
  • "cron_timezone": "Europe/Paris",
  • "failure_threshold": 2,
  • "assertions": [
    ],
  • "enabled": true
}

Response samples

Content type
application/json
{
  • "type": "http",
  • "name": "string",
  • "url": "string",
  • "method": "GET",
  • "interval_seconds": 300,
  • "timeout_seconds": 10,
  • "grace_seconds": 0,
  • "cron_expression": "0 3 * * 1-5",
  • "cron_timezone": "Europe/Paris",
  • "failure_threshold": 2,
  • "assertions": [
    ],
  • "enabled": true,
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
  • "state": "up",
  • "consecutive_failures": 0,
  • "ping_token": "string",
  • "next_expected_ping_at": "2019-08-24T14:15:22Z",
  • "next_run_at": "2019-08-24T14:15:22Z",
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z"
}

Get a check

Authorizations:
ApiKeyAuth
path Parameters
id
required
string <uuid>

Responses

Response samples

Content type
application/json
{
  • "type": "http",
  • "name": "string",
  • "url": "string",
  • "method": "GET",
  • "interval_seconds": 300,
  • "timeout_seconds": 10,
  • "grace_seconds": 0,
  • "cron_expression": "0 3 * * 1-5",
  • "cron_timezone": "Europe/Paris",
  • "failure_threshold": 2,
  • "assertions": [
    ],
  • "enabled": true,
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
  • "state": "up",
  • "consecutive_failures": 0,
  • "ping_token": "string",
  • "next_expected_ping_at": "2019-08-24T14:15:22Z",
  • "next_run_at": "2019-08-24T14:15:22Z",
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z"
}

Replace a check

Replaces the whole check — it does not patch. Omitted fields are not kept from the existing row. type is immutable after creation.

Authorizations:
ApiKeyAuth
path Parameters
id
required
string <uuid>
Request Body schema: application/json
required
type
string
Default: "http"
Enum: "http" "heartbeat" "cron" "tls" "domain"
name
required
string
url
string

Required for http/tls/domain

method
string
Default: "GET"
interval_seconds
integer [ 30 .. 86400 ]
Default: 300
timeout_seconds
integer
Default: 10
grace_seconds
integer

heartbeat/cron only

cron_expression
string

Optional crontab schedule, cron type only. Five standard fields plus @daily/@hourly/@weekly/@monthly/@yearly/@every. Set, it replaces interval_seconds as the deadline: the check goes down when a scheduled run hasn't pinged within grace_seconds of its due time. The plan's interval floor applies to the tightest gap the expression produces. A CRON_TZ= prefix is rejected — use cron_timezone. Because PUT replaces rather than patches, omitting this clears the schedule.

cron_timezone
string

IANA zone the expression is read in, default UTC. Per check because a crontab fires in its host's local zone, and a fixed offset would drift an hour at each DST change.

failure_threshold
integer [ 1 .. 10 ]
Default: 2
Array of objects (Assertion)
enabled
boolean
Default: true

Responses

Request samples

Content type
application/json
{
  • "type": "http",
  • "name": "string",
  • "url": "string",
  • "method": "GET",
  • "interval_seconds": 300,
  • "timeout_seconds": 10,
  • "grace_seconds": 0,
  • "cron_expression": "0 3 * * 1-5",
  • "cron_timezone": "Europe/Paris",
  • "failure_threshold": 2,
  • "assertions": [
    ],
  • "enabled": true
}

Response samples

Content type
application/json
{
  • "type": "http",
  • "name": "string",
  • "url": "string",
  • "method": "GET",
  • "interval_seconds": 300,
  • "timeout_seconds": 10,
  • "grace_seconds": 0,
  • "cron_expression": "0 3 * * 1-5",
  • "cron_timezone": "Europe/Paris",
  • "failure_threshold": 2,
  • "assertions": [
    ],
  • "enabled": true,
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
  • "state": "up",
  • "consecutive_failures": 0,
  • "ping_token": "string",
  • "next_expected_ping_at": "2019-08-24T14:15:22Z",
  • "next_run_at": "2019-08-24T14:15:22Z",
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z"
}

Delete a check

Authorizations:
ApiKeyAuth
path Parameters
id
required
string <uuid>

Responses

Preview a crontab schedule

Resolves a crontab expression to its next runs without writing anything, so a schedule can be checked before it is relied on. Uses the same parser as the silence detector, so the preview and the deadline that actually pages you cannot disagree.

Authorizations:
ApiKeyAuth
query Parameters
cron_expression
required
string
Example: cron_expression=0 3 * * 1-5
cron_timezone
string
Default: "UTC"
Example: cron_timezone=Europe/Paris

Responses

Response samples

Content type
application/json
{
  • "cron_expression": "string",
  • "cron_timezone": "string",
  • "next": [
    ],
  • "min_gap_seconds": 0,
  • "plan_min_interval_seconds": 0,
  • "below_plan_minimum": true
}

Latency/uptime stats

Authorizations:
ApiKeyAuth
path Parameters
id
required
string <uuid>
query Parameters
period
string
Default: "day"
Enum: "day" "week" "month"

day = 15-min buckets, week = 2h buckets, month = 12h buckets

Responses

Response samples

Content type
application/json
[
  • {
    }
]

Recent state transitions

Last 50 state changes, newest first.

Authorizations:
ApiKeyAuth
path Parameters
id
required
string <uuid>

Responses

Response samples

Content type
application/json
[
  • {
    }
]

What became of this check's alerts

The last 20 delivery attempts, newest first. A state change and a delivered notification are different things; this reports the second. A skipped row with no channel means nobody was told, and detail says why — no channels, none confirmed, routing that excludes them, or a maintenance window. Records begin when the endpoint shipped.

Authorizations:
ApiKeyAuth
path Parameters
id
required
string <uuid>

Responses

Response samples

Content type
application/json
[
  • {
    }
]

Alert-channel routing for a check

No rows = every org channel fires (default). Assigned rows = only those channels fire.

Authorizations:
ApiKeyAuth
path Parameters
id
required
string <uuid>

Responses

Response samples

Content type
application/json
{
  • "channel_ids": [
    ]
}

Set alert-channel routing for a check

Authorizations:
ApiKeyAuth
path Parameters
id
required
string <uuid>
Request Body schema: application/json
required
channel_ids
required
Array of strings <uuid> [ items <uuid > ]

Responses

Request samples

Content type
application/json
{
  • "channel_ids": [
    ]
}

Response samples

Content type
application/json
{
  • "channel_ids": [
    ]
}

Alert channels

List alert channels

Authorizations:
ApiKeyAuth

Responses

Response samples

Content type
application/json
[
  • {
    }
]

Create an alert channel

For type: webhook, a signing secret is auto-generated if config.secret is omitted — always send the existing secret back unchanged on update, or a new one is minted and downstream signature verification silently breaks.

Authorizations:
ApiKeyAuth
Request Body schema: application/json
required
type
required
string
Enum: "email" "webhook" "slack" "discord" "telegram"
name
required
string
required
object

email: {to}. webhook: {url, secret?}. slack: {webhook_url}. discord: {webhook_url} — the incoming-webhook URL from the Discord channel's own settings (Edit Channel → Integrations → Webhooks), including the token after the webhook id. telegram: {} — our bot is the destination, so there is nothing to supply; the response carries a one-time connect_url to open and press Start.

Responses

Request samples

Content type
application/json
{
  • "type": "email",
  • "name": "string",
  • "config": {
    }
}

Response samples

Content type
application/json
{
  • "type": "email",
  • "name": "string",
  • "config": {
    },
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
  • "connect_url": "string"
}

Replace an alert channel

Authorizations:
ApiKeyAuth
path Parameters
id
required
string <uuid>
Request Body schema: application/json
required
type
required
string
Enum: "email" "webhook" "slack" "discord" "telegram"
name
required
string
required
object

email: {to}. webhook: {url, secret?}. slack: {webhook_url}. discord: {webhook_url} — the incoming-webhook URL from the Discord channel's own settings (Edit Channel → Integrations → Webhooks), including the token after the webhook id. telegram: {} — our bot is the destination, so there is nothing to supply; the response carries a one-time connect_url to open and press Start.

Responses

Request samples

Content type
application/json
{
  • "type": "email",
  • "name": "string",
  • "config": {
    }
}

Response samples

Content type
application/json
{
  • "type": "email",
  • "name": "string",
  • "config": {
    },
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
  • "connect_url": "string"
}

Delete an alert channel

Authorizations:
ApiKeyAuth
path Parameters
id
required
string <uuid>

Responses

Send a test alert

Authorizations:
ApiKeyAuth
path Parameters
id
required
string <uuid>

Responses

Status page

Read the status page and its component ids

Read-only with an API key; changing the page's configuration (slug, components, custom domain, publishing the page) is session-only, so a leaked key can't repoint your public address. components[].id is what component_ids on an incident refers to. 404 until the page exists.

Authorizations:
ApiKeyAuth

Responses

Response samples

Content type
application/json
{
  • "slug": "string",
  • "title": "string",
  • "published": true,
  • "theme": "dark",
  • "public_url": "string",
  • "domain": {
    },
  • "components": [
    ]
}

Incidents

List incidents

Every incident on the page, drafts included — this is the authoring view, not the public one. Newest first.

Authorizations:
ApiKeyAuth

Responses

Response samples

Content type
application/json
[
  • {
    }
]

Declare an incident

Owner/admin, Pro plan or above. Starts as a private draft — send published: true (here or on a later PUT) to show it to visitors. body, when present, becomes the first timeline entry.

Authorizations:
ApiKeyAuth
Request Body schema: application/json
required
title
required
string <= 120 characters
status
string (IncidentStatus)
Default: "investigating"
Enum: "investigating" "identified" "monitoring" "resolved"
impact
string
Default: "minor"
Enum: "minor" "major" "critical"
published
boolean

Absent leaves it unchanged. New incidents are unpublished — invisible to visitors — until this is true.

archived
boolean

Absent leaves it unchanged. True closes the incident and files it into the page's history, which visitors reach by clicking the status panel.

component_ids
Array of strings <uuid> [ items <uuid > ]

Replaces the affected set wholesale. Ids from GET /status-page.

body
string <= 4000 characters

Create only — becomes the first timeline entry

Responses

Request samples

Content type
application/json
{
  • "title": "string",
  • "status": "investigating",
  • "impact": "minor",
  • "published": true,
  • "archived": true,
  • "component_ids": [
    ],
  • "body": "string"
}

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "title": "string",
  • "status": "investigating",
  • "impact": "minor",
  • "published": true,
  • "auto_drafted": true,
  • "started_at": "2019-08-24T14:15:22Z",
  • "resolved_at": "2019-08-24T14:15:22Z",
  • "archived_at": "2019-08-24T14:15:22Z",
  • "component_ids": [
    ],
  • "updates": [
    ]
}

Replace an incident

Replaces the incident itself — title, severity, affected components, whether it's published. Timeline entries are posted separately and are never rewritten from here. published and archived are applied only when present, so an edit that omits them can't silently unpublish a live incident. archived: true also resolves it.

Authorizations:
ApiKeyAuth
path Parameters
id
required
string <uuid>
Request Body schema: application/json
required
title
required
string <= 120 characters
status
string (IncidentStatus)
Default: "investigating"
Enum: "investigating" "identified" "monitoring" "resolved"
impact
string
Default: "minor"
Enum: "minor" "major" "critical"
published
boolean

Absent leaves it unchanged. New incidents are unpublished — invisible to visitors — until this is true.

archived
boolean

Absent leaves it unchanged. True closes the incident and files it into the page's history, which visitors reach by clicking the status panel.

component_ids
Array of strings <uuid> [ items <uuid > ]

Replaces the affected set wholesale. Ids from GET /status-page.

body
string <= 4000 characters

Create only — becomes the first timeline entry

Responses

Request samples

Content type
application/json
{
  • "title": "string",
  • "status": "investigating",
  • "impact": "minor",
  • "published": true,
  • "archived": true,
  • "component_ids": [
    ],
  • "body": "string"
}

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "title": "string",
  • "status": "investigating",
  • "impact": "minor",
  • "published": true,
  • "auto_drafted": true,
  • "started_at": "2019-08-24T14:15:22Z",
  • "resolved_at": "2019-08-24T14:15:22Z",
  • "archived_at": "2019-08-24T14:15:22Z",
  • "component_ids": [
    ],
  • "updates": [
    ]
}

Delete an incident

Removes the incident and its timeline. To close one while keeping the story on the page, archive it instead.

Authorizations:
ApiKeyAuth
path Parameters
id
required
string <uuid>

Responses

Post a timeline update

Append-only. status is optional — an update that doesn't move the incident along is still worth posting; when present it moves the incident, and resolved stamps resolved_at. Posting to an archived incident un-archives it.

Authorizations:
ApiKeyAuth
path Parameters
id
required
string <uuid>
Request Body schema: application/json
required
body
required
string <= 4000 characters
status
string (IncidentStatus)
Default: "investigating"
Enum: "investigating" "identified" "monitoring" "resolved"

Responses

Request samples

Content type
application/json
{
  • "body": "string",
  • "status": "investigating"
}

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "title": "string",
  • "status": "investigating",
  • "impact": "minor",
  • "published": true,
  • "auto_drafted": true,
  • "started_at": "2019-08-24T14:15:22Z",
  • "resolved_at": "2019-08-24T14:15:22Z",
  • "archived_at": "2019-08-24T14:15:22Z",
  • "component_ids": [
    ],
  • "updates": [
    ]
}