tickingora. API docs OpenAPI llms.txt tickingora.com Get an API key

API reference

Base URL https://dev.tickingora.com/api/v1 · Tickingora Management API 1.0.0 · openapi.yaml · openapi.json

Tickingora is API-first: everything you can configure in the dashboard wizard you can do with this API — with exactly the same validation, plan limits and scheduling engine.

  • Authenticate with an API key: Authorization: Bearer <api-key> (create keys in Settings → API keys). Keys carry scopes: monitors:read, monitors:write, incidents:read.
  • All times are UTC in ISO 8601 (2026-10-26T05:00:00Z). Schedules are interpreted in the monitor's timezone.
  • Errors always look like {"error": {"code": "...", "message": "...", "details": {...}}}.
  • The secret Heartbeat ping_url is shown only once — when a monitor is created or its token rotated. Tokens are stored hashed; a lost URL can only be replaced (rotate-token).
  • Give monitors a stable external_id (e.g. production:nightly-backup) to find them later and to make repeated set-up runs safe; Idempotency-Key protects single requests (24 h).

Account

GET /account

Current account, plan limits and usage · any scope

Works with any scope. Useful before creating monitors (check remaining capacity).

StatusDescriptionBody
200 Account details. Account
401 Missing, invalid or expired API key (UNAUTHENTICATED). Error
429 Too many requests (RATE_LIMITED); see Retry-After. Error

Monitors

GET /monitors

List monitors · scope monitors:read

ParameterInTypeDescription
external_id query string Find a monitor by its external_id.
type query string
status query MonitorStatus
limit query integer Page size (default 50).
cursor query string The next_cursor value from the previous page.
StatusDescriptionBody
200 A page of monitors, ordered by id. Monitor
401 Missing, invalid or expired API key (UNAUTHENTICATED). Error
403 The key lacks the required scope (FORBIDDEN_SCOPE). Error
422 VALIDATION_ERROR — details lists the invalid fields or query parameters. Error
429 Too many requests (RATE_LIMITED); see Retry-After. Error

POST /monitors

Create a Heartbeat or HTTP Check monitor · scope monitors:write

Send Idempotency-Key to make retries safe: repeating the request with the same key and body returns the original response (header Idempotent-Replayed: true) instead of creating a second monitor. Keys are kept for 24 hours.

If external_id is already used by another monitor of the account, nothing is created and the response is 409 MONITOR_ALREADY_EXISTS with details.monitor_id — read or update that monitor instead. Unlike Idempotency-Key (kept 24 hours), this protection is permanent.

For Heartbeat monitors the response contains heartbeat.ping_url — store it now, it is shown only once (tokens are stored hashed; use rotate-token to get a new one). A replay of the same request with the same Idempotency-Key within 24 hours returns the same response, ping URL included; replays are stored encrypted and deleted when the 24 hours pass.

ParameterInTypeDescription
Idempotency-Key header string

Request body — MonitorCreate

Heartbeat, weekdays 06:00–07:00, skip Polish holidays
{
    "type": "heartbeat",
    "external_id": "production:bank-import",
    "name": "Bank import",
    "timezone": "Europe/Warsaw",
    "schedule": {
        "preset": "daily",
        "days": [
            1,
            2,
            3,
            4,
            5
        ],
        "start": "06:00",
        "end": "07:00"
    },
    "calendar": {
        "skip_holidays": true
    }
}
HTTP Check at 07:00 and 19:00 with an API key header
{
    "type": "http",
    "name": "Production API",
    "timezone": "Europe/Warsaw",
    "schedule": {
        "preset": "custom",
        "days": [
            1,
            2,
            3,
            4,
            5,
            6,
            7
        ],
        "windows": [
            {
                "start": "07:00"
            },
            {
                "start": "19:00"
            }
        ]
    },
    "http": {
        "url": "https://api.example.com/health",
        "expected_status": "2xx",
        "headers": [
            {
                "name": "X-API-Key",
                "value": "secret-key"
            }
        ]
    },
    "recovery": {
        "enabled": true,
        "interval_minutes": 15
    }
}
StatusDescriptionBody
201 Monitor created (or the stored response of an earlier request with the same Idempotency-Key). Monitor
401 Missing, invalid or expired API key (UNAUTHENTICATED). Error
403 Missing scope (FORBIDDEN_SCOPE) or the plan's active monitor limit is reached (PLAN_LIMIT_REACHED). Error
409 MONITOR_ALREADY_EXISTS (the external_id is taken; details.monitor_id) or IDEMPOTENCY_IN_PROGRESS (the same Idempotency-Key is still being processed). Error
415 The body is not JSON (UNSUPPORTED_MEDIA_TYPE). Error
422 VALIDATION_ERROR (details per field) or IDEMPOTENCY_KEY_REUSED (the key was used with a different body). Error
429 Too many requests (RATE_LIMITED); see Retry-After. Error

GET /monitors/{id}

Get a monitor · scope monitors:read

ParameterInTypeDescription
id required path integer
StatusDescriptionBody
200 The monitor. Monitor
401 Missing, invalid or expired API key (UNAUTHENTICATED). Error
403 The key lacks the required scope (FORBIDDEN_SCOPE). Error
404 The monitor does not exist or belongs to another account (MONITOR_NOT_FOUND). Error
429 Too many requests (RATE_LIMITED); see Retry-After. Error

PATCH /monitors/{id}

Update a monitor · scope monitors:write

Partial update. Top-level fields and fields inside calendar, http, notifications and recovery replace the current values; schedule and arrays (e.g. http.headers) are replaced as a whole. A header sent without value keeps its stored secret. Schedule changes apply from the next window; history is never rewritten. The monitor type cannot be changed.

ParameterInTypeDescription
id required path integer

Request body — MonitorPatch

Example
{
    "schedule": {
        "preset": "hourly",
        "days": [
            1,
            2,
            3,
            4,
            5
        ],
        "hour_from": 8,
        "hour_to": 18,
        "minute_start": 0,
        "minute_end": 15
    },
    "notifications": {
        "extra_email": "ops@example.com"
    }
}
StatusDescriptionBody
200 The updated monitor. Monitor
401 Missing, invalid or expired API key (UNAUTHENTICATED). Error
403 The key lacks the required scope (FORBIDDEN_SCOPE). Error
404 The monitor does not exist or belongs to another account (MONITOR_NOT_FOUND). Error
409 MONITOR_ALREADY_EXISTS — another monitor of the account uses this external_id (details.monitor_id). Error
415 The body is not JSON (UNSUPPORTED_MEDIA_TYPE). Error
422 VALIDATION_ERROR — details lists the invalid fields or query parameters. Error
429 Too many requests (RATE_LIMITED); see Retry-After. Error

DELETE /monitors/{id}

Delete a monitor · scope monitors:write

Stops monitoring immediately and revokes the ping URL. History is removed together with the plan retention.

ParameterInTypeDescription
id required path integer
StatusDescriptionBody
204 Deleted. —
401 Missing, invalid or expired API key (UNAUTHENTICATED). Error
403 The key lacks the required scope (FORBIDDEN_SCOPE). Error
404 The monitor does not exist or belongs to another account (MONITOR_NOT_FOUND). Error
429 Too many requests (RATE_LIMITED); see Retry-After. Error

POST /monitors/{id}/pause

Pause a monitor · scope monitors:write

No windows are expected while paused. An open incident is closed without a recovery e-mail. Idempotent.

ParameterInTypeDescription
id required path integer
StatusDescriptionBody
200 The paused monitor. Monitor
401 Missing, invalid or expired API key (UNAUTHENTICATED). Error
403 The key lacks the required scope (FORBIDDEN_SCOPE). Error
404 The monitor does not exist or belongs to another account (MONITOR_NOT_FOUND). Error
429 Too many requests (RATE_LIMITED); see Retry-After. Error

POST /monitors/{id}/resume

Resume a paused monitor · scope monitors:write

Counts towards the plan's active monitor limit. Idempotent.

ParameterInTypeDescription
id required path integer
StatusDescriptionBody
200 The active monitor. Monitor
401 Missing, invalid or expired API key (UNAUTHENTICATED). Error
403 Missing scope (FORBIDDEN_SCOPE) or the plan's active monitor limit is reached (PLAN_LIMIT_REACHED). Error
404 The monitor does not exist or belongs to another account (MONITOR_NOT_FOUND). Error
429 Too many requests (RATE_LIMITED); see Retry-After. Error

POST /monitors/{id}/rotate-token

Generate a new Heartbeat ping URL · scope monitors:write

The previous URL stops working immediately. The new URL is returned only in this response — it is not stored in plain text. This is also the way to recover a lost URL.

ParameterInTypeDescription
id required path integer
StatusDescriptionBody
200 The new ping URL. —
401 Missing, invalid or expired API key (UNAUTHENTICATED). Error
403 The key lacks the required scope (FORBIDDEN_SCOPE). Error
404 The monitor does not exist or belongs to another account (MONITOR_NOT_FOUND). Error
409 UNSUPPORTED_FOR_MONITOR_TYPE — e.g. rotate-token on an HTTP Check. Error
429 Too many requests (RATE_LIMITED); see Retry-After. Error

History

GET /monitors/{id}/runs

Run history · scope monitors:read

Windows (Heartbeat) or checks (HTTP) that already started, newest first, within the plan's history retention (Free: 30 days).

ParameterInTypeDescription
id required path integer
status query RunStatus
from query string Only runs scheduled at or after this time.
to query string Only runs scheduled before this time.
limit query integer Page size (default 50).
cursor query string The next_cursor value from the previous page.
StatusDescriptionBody
200 A page of runs. Run
401 Missing, invalid or expired API key (UNAUTHENTICATED). Error
403 The key lacks the required scope (FORBIDDEN_SCOPE). Error
404 The monitor does not exist or belongs to another account (MONITOR_NOT_FOUND). Error
422 VALIDATION_ERROR — details lists the invalid fields or query parameters. Error
429 Too many requests (RATE_LIMITED); see Retry-After. Error

GET /monitors/{id}/incidents

Incident history · scope incidents:read

ParameterInTypeDescription
id required path integer
status query string
limit query integer Page size (default 50).
cursor query string The next_cursor value from the previous page.
StatusDescriptionBody
200 A page of incidents, newest first. Incident
401 Missing, invalid or expired API key (UNAUTHENTICATED). Error
403 The key lacks the required scope (FORBIDDEN_SCOPE). Error
404 The monitor does not exist or belongs to another account (MONITOR_NOT_FOUND). Error
422 VALIDATION_ERROR — details lists the invalid fields or query parameters. Error
429 Too many requests (RATE_LIMITED); see Retry-After. Error

Schemas

Error

FieldTypeDescription
error required object
error.code required string — VALIDATION_ERROR, PLAN_LIMIT_REACHED, MONITOR_NOT_FOUND, MONITOR_ALREADY_EXISTS, RATE_LIMITED, UNAUTHENTICATED, FORBIDDEN_SCOPE, IDEMPOTENCY_KEY_REUSED, IDEMPOTENCY_IN_PROGRESS, UNSUPPORTED_FOR_MONITOR_TYPE, UNSUPPORTED_MEDIA_TYPE, NOT_FOUND, METHOD_NOT_ALLOWED, HTTP_ERROR, INTERNAL_ERROR
error.message required string
error.details object For validation errors — field path → list of messages.

Page

FieldTypeDescription
data required array
next_cursor required string | null
has_more required boolean

MonitorStatus

Type: string — waiting, healthy, alerting, paused, unknown

RunStatus

Heartbeat: waiting, success, missed, unknown (Tickingora itself was down). HTTP Check: scheduled, running, success, failed, not_executed (not run on time by Tickingora).

Type: string — waiting, scheduled, running, success, missed, failed, not_executed, unknown

Weekdays

ISO weekdays, 1 = Monday … 7 = Sunday.

Type: array

Time

Type: string

HeartbeatSchedule

Heartbeat windows are half-open [start, end) and may cross midnight. Windows must not overlap; the Free plan allows at most one window per 60 minutes.

FieldTypeDescription
(one of) HeartbeatDailySchedule
(one of) HeartbeatHourlySchedule
(one of) HeartbeatCustomSchedule

HttpSchedule

HTTP Checks run at points in time (no end). The Free plan allows at most one check per 60 minutes.

FieldTypeDescription
(one of) HttpDailySchedule
(one of) HttpHourlySchedule
(one of) HttpCustomSchedule

HeartbeatDailySchedule

One window per selected day.

FieldTypeDescription
preset required "daily"
days required Weekdays
start required Time
end required Time

HttpDailySchedule

One check per selected day.

FieldTypeDescription
preset required "daily"
days required Weekdays
start required Time

HeartbeatHourlySchedule

A window every hour from hour_from to hour_to (the last hour with a window).

FieldTypeDescription
preset required "hourly"
days required Weekdays
hour_from required integer
hour_to required integer
minute_start required integer
minute_end required integer Equal to minute_start = a full-hour window.

HttpHourlySchedule

A check every hour from hour_from to hour_to at minute_start.

FieldTypeDescription
preset required "hourly"
days required Weekdays
hour_from required integer
hour_to required integer
minute_start required integer

HeartbeatCustomSchedule

Explicit windows on the selected days.

FieldTypeDescription
preset required "custom"
days required Weekdays
windows required array of object
windows[].start required Time
windows[].end required Time

HttpCustomSchedule

Explicit check times on the selected days.

FieldTypeDescription
preset required "custom"
days required Weekdays
windows required array of object
windows[].start required Time

Calendar

FieldTypeDescription
skip_holidays boolean Skip Polish public holidays.
excluded_dates array of string

HeaderInput

FieldTypeDescription
name required string
value string Required for a new header. Omit on PATCH to keep the stored value.

HttpInput

FieldTypeDescription
url required string (uri) Public HTTPS URL, port 443 or 8443. Redirects are not followed.
expected_status string "200" (exactly 200), "2xx" (any 2xx) or a single code such as "204".
headers array of HeaderInput Extra request headers (Free plan, up to 5). Values are encrypted and never returned. Host, Content-Length, Transfer-Encoding, Connection, X-Forwarded-* and Proxy-* are not allowed.

HttpPatch

Like HttpInput, but every field is optional; omitted fields keep their values.

FieldTypeDescription
url string (uri)
expected_status string
headers array of HeaderInput Replaces the whole list. A header without value keeps its stored secret.

Notifications

FieldTypeDescription
extra_email string | null (email) One extra recipient besides the account e-mail. It receives alerts only after confirming the address (we send a confirmation e-mail).
on_failure boolean E-mail when an incident opens (first failure).
on_recovery boolean E-mail when the monitor recovers.

Recovery

Extra checks after a failure until the service responds correctly.

FieldTypeDescription
enabled boolean
interval_minutes integer | null — 15, 30, 60, null Free plan: 15, 30 or 60. Required when enabled.

ExternalId

Your stable technical identifier, unique in the account (e.g. production:nightly-backup). Use it to find the monitor later and to make set-up scripts safe to re-run.

Type: string|null

MonitorCreate

Pick the variant by type: Heartbeat monitors have no http/recovery; HTTP Checks require http.

FieldTypeDescription
(one of) HeartbeatMonitorCreate
(one of) HttpMonitorCreate

HeartbeatMonitorCreate

FieldTypeDescription
type required "heartbeat"
external_id ExternalId
name required string
description string | null
timezone string IANA time zone; defaults to the account time zone.
schedule required HeartbeatSchedule
calendar Calendar
notifications Notifications

HttpMonitorCreate

FieldTypeDescription
type required "http"
external_id ExternalId
name required string
description string | null
timezone string IANA time zone; defaults to the account time zone.
schedule required HttpSchedule
calendar Calendar
http required HttpInput
notifications Notifications
recovery Recovery

MonitorPatch

Any subset of the monitor's fields. Use the schedule variant of the monitor's type; http and recovery are accepted only for HTTP Checks. type cannot be changed.

FieldTypeDescription
external_id ExternalId
name string
description string | null
timezone string
schedule any
calendar Calendar
http HttpPatch
notifications Notifications
recovery Recovery

Monitor

FieldTypeDescription
id required integer
external_id required string | null Unique per account (database constraint).
type required string — heartbeat, http
status required MonitorStatus
name required string
description required string | null
timezone required string
schedule required any
calendar required object
calendar.skip_holidays required boolean
calendar.excluded_dates required array of string
http required object | null
http.url required string
http.expected_status required string
http.headers required array of object
http.headers[].name required string
http.headers[].has_value required boolean The value is stored but never returned.
notifications required object
notifications.account_email required string
notifications.extra_email required string | null
notifications.extra_email_status required string | null — pending, verified, unsubscribed, null pending — confirmation e-mail sent, no alerts yet; verified — receives alerts; unsubscribed — the recipient opted out.
notifications.on_failure required boolean
notifications.on_recovery required boolean
recovery required object | null
recovery.enabled required boolean
recovery.interval_minutes required integer | null
heartbeat required object | null
heartbeat.ping_url required string | null Only in the create response (shown once, stored hashed); otherwise null.
heartbeat.ping_url_note required string
last_run required object | null
last_run.status required RunStatus
last_run.at required string | null (date-time)
open_incident required null | Incident
next_runs required array of object The next five expected windows/checks (holidays, exclusions and DST applied).
next_runs[].start required string (date-time)
next_runs[].end required string | null (date-time)
paused_at required string | null (date-time)
created_at required string (date-time)
updated_at required string (date-time)

Run

FieldTypeDescription
id required integer
kind required string — regular, recovery
status required RunStatus
scheduled_start required string (date-time)
scheduled_end required string | null (date-time) Heartbeat window end (exclusive).
signal_count required integer Heartbeat signals received in the window.
attempt_count required integer HTTP attempts made (max 3; recovery checks 1).
attempts required array | null HTTP Check only (null for Heartbeat) — every attempt as recorded.
attempts[].number required integer
attempts[].at required string (date-time)
attempts[].http_status required integer | null
attempts[].duration_ms required integer | null
attempts[].error_type required string | null — http_status, timeout, dns, tls, connection, blocked, error, null
attempts[].error required string | null Transport error message (secrets redacted); null for HTTP status mismatches.
last_http_status required integer | null
last_duration_ms required integer | null
last_error required string | null
note required string | null
finished_at required string | null (date-time) Heartbeat: time of the first signal (or the window end when missed).

Incident

FieldTypeDescription
id required integer
status required string — open, recovered, closed
opened_at required string (date-time)
closed_at required string | null (date-time)
close_reason required string | null recovered, paused …
failed_runs_count required integer
opened_by_run_id required integer | null
closed_by_run_id required integer | null

Account

FieldTypeDescription
email required string
timezone required string
plan required object
plan.name required string
plan.limits required object
plan.limits.active_heartbeat required integer
plan.limits.active_http required integer
plan.limits.min_interval_minutes required integer
plan.limits.history_days required integer
plan.limits.max_headers required integer
plan.limits.recovery_intervals required array of integer
plan.usage required object
plan.usage.active_heartbeat required integer
plan.usage.active_http required integer
api_key required object
api_key.name required string
api_key.scopes required array of string
api_key.expires_at required string | null (date-time)