Reference

REST API

Complete reference for the Yorker REST API — all endpoints, methods, request/response schemas.

REST API

The Yorker REST API provides programmatic access to monitors, alerts, SLOs, notification channels, and locations. All endpoints return JSON and validate request bodies through shared Zod schemas.


Authentication

To authenticate API requests, include your API key in the Authorization header as a Bearer token.

Authorization: Bearer sk_...

All endpoints require authentication. Unauthenticated requests return 401 Unauthorized.


Base URL

https://app.yorkermonitoring.com

Common Response Patterns

Success

Successful responses return a 2xx status code with a JSON body.

Validation Error (400)

{
  "error": "Validation failed",
  "details": {
    "fieldErrors": { "name": ["String must contain at least 1 character(s)"] },
    "formErrors": []
  }
}

Not Found (404)

{ "error": "Check not found" }

Conflict (409)

{ "error": "Channel is in use by alert rule \"my-alert\". Remove it from those first." }

Checks

List Checks

To list all checks for your team:

GET /api/checks

Response 200

{
  "checks": [
    {
      "id": "chk_abc123",
      "teamId": "team_xyz",
      "name": "Homepage",
      "type": "http",
      "configJson": { "url": "https://example.com", "method": "GET", "timeoutMs": 30000, "followRedirects": true, "maxRedirects": 5, "assertions": [] },
      "frequencySeconds": 300,
      "locations": ["loc_us_east", "loc_eu_central"],
      "enabled": true,
      "createdAt": "2025-01-15T10:00:00.000Z",
      "updatedAt": null
    }
  ]
}

Create Check

To create a new check:

POST /api/checks

Request body -- validated through CreateCheckSchema

For HTTP checks:

FieldTypeRequiredDefaultDescription
namestringYes--Check name (1-255 characters).
type"http"Yes--Check type.
enabledbooleanNotrueWhether the check is active.
frequencySecondsnumberNo300Check interval (10-86400).
locationsstring[]Yes--Location IDs (at least one).
httpConfigobjectYes--HTTP configuration (see below).

httpConfig fields:

FieldTypeRequiredDefaultDescription
urlstringYes--Target URL (must be a valid URL).
methodstringNo"GET"GET | POST | PUT | DELETE | PATCH | HEAD
headersobjectNo--Request headers (string key-value pairs).
bodystringNo--Request body.
authobjectNo--Auth config (basic, bearer, or api-key).
followRedirectsbooleanNotrueFollow HTTP redirects.
maxRedirectsnumberNo5Maximum number of redirects.
timeoutMsnumberNo30000Request timeout in milliseconds.
assertionsarrayNo[]Assertion rules. See Assertions.

For browser checks:

FieldTypeRequiredDefaultDescription
namestringYes--Check name (1-255 characters).
type"browser"Yes--Check type.
enabledbooleanNotrueWhether the check is active.
frequencySecondsnumberNo300Check interval (10-86400).
locationsstring[]Yes--Location IDs (at least one).
browserConfigobjectYes--Browser configuration (see below).

browserConfig fields:

FieldTypeRequiredDefaultConstraintsDescription
browserModestringYes"scripted" | "url"Execution mode.
scriptstringYes (scripted)Playwright script content (for "scripted" mode).
urlstringYes (url)Valid URLTarget URL (for "url" mode).
timeoutMsnumberNo300005000-120000Script timeout in milliseconds.
viewportobjectNo{ width: 1280, height: 720 }Viewport dimensions.
devicestringNoPlaywright device name for emulation.
screenshotModestringNo"every_step"every_step | failure_only | disabledScreenshot capture mode.
videoEnabledbooleanNofalseRecord video.

For MCP checks:

FieldTypeRequiredDefaultDescription
namestringYesCheck name (1-255 characters).
type"mcp"YesCheck type.
enabledbooleanNotrueWhether the check is active.
frequencySecondsnumberNo300Check interval (10-86400).
locationsstring[]YesLocation IDs (at least one).
mcpConfigobjectYesMCP configuration (see below).

mcpConfig fields:

FieldTypeRequiredDefaultConstraintsDescription
endpointstringYesValid URLStreamable HTTP endpoint of the MCP server.
timeoutMsnumberNo300005000-120000Request timeout in milliseconds.
authobjectNobasic, bearer, api-keySame auth shape as HTTP checks.
expectedToolsstring[]NoTool names that must be present. Missing tools fail the check.
testCallsarrayNoTool invocations to exercise. Each entry has toolName, optional arguments (object), and optional expectedOutputContains.
detectSchemaDriftbooleanNotrueEmit events when tool list or signatures change between runs.

Response 201

{
  "check": {
    "id": "chk_abc123",
    "teamId": "team_xyz",
    "name": "Homepage",
    "type": "http",
    "configJson": { "url": "https://example.com", "method": "GET", "timeoutMs": 30000, "followRedirects": true, "maxRedirects": 5, "assertions": [] },
    "frequencySeconds": 300,
    "locations": ["loc_us_east"],
    "enabled": true,
    "createdAt": "2025-01-15T10:00:00.000Z",
    "updatedAt": null
  }
}

Error 403 -- Plan limit exceeded.

Get Check

To get a single check with its 50 most recent results:

GET /api/checks/:id

Response 200

{
  "check": { "id": "chk_abc123", "name": "Homepage", "..." : "..." },
  "results": [
    {
      "id": "res_xyz789",
      "checkId": "chk_abc123",
      "runId": "run_abc",
      "locationId": "loc_us_east",
      "status": "success",
      "responseTimeMs": 142,
      "httpStatusCode": 200,
      "startedAt": "2025-01-15T10:05:00.000Z",
      "completedAt": "2025-01-15T10:05:00.142Z"
    }
  ]
}

Update Check

To update an existing check:

PUT /api/checks/:id

Request body -- all fields are optional (partial update):

FieldTypeDescription
namestringCheck name.
configJsonobjectFull HTTP or browser config object (replaces existing).
frequencySecondsnumberCheck interval.
locationsstring[]Location IDs.
enabledbooleanWhether the check is active.

Response 200

{ "check": { "id": "chk_abc123", "..." : "..." } }

Delete Check

To delete a check and its results:

DELETE /api/checks/:id

Response 200

{ "success": true }

List Check Results

To get paginated results for a check:

GET /api/checks/:id/results

Query parameters:

ParameterTypeDefaultMaxDescription
limitnumber50200Number of results to return.
offsetnumber0--Pagination offset.
detail"true"----Include Tier B debug data (network requests, console logs, screenshots).

Response 200

{
  "results": [
    {
      "id": "res_xyz789",
      "checkId": "chk_abc123",
      "runId": "run_abc",
      "locationId": "loc_us_east",
      "status": "success",
      "responseTimeMs": 142,
      "httpStatusCode": 200,
      "timing": {
        "dnsLookupMs": 12,
        "tcpConnectMs": 18,
        "tlsHandshakeMs": 25,
        "ttfbMs": 80,
        "contentTransferMs": 7,
        "totalMs": 142
      },
      "startedAt": "2025-01-15T10:05:00.000Z",
      "completedAt": "2025-01-15T10:05:00.142Z"
    }
  ],
  "limit": 50,
  "offset": 0
}

When detail=true, browser check results also include networkRequestsJson, screenshotsJson, and consoleLogsJson fields.

Trigger Ad-Hoc Run

To trigger an immediate check run across all assigned locations:

POST /api/checks/:id/trigger

Request body: none

Response 200

{
  "triggered": true,
  "locations": 3
}

Alerts

List Alert Rules

To list all alert rules for a check:

GET /api/checks/:id/alerts

Response 200

{
  "alerts": [
    {
      "id": "alert_abc123",
      "checkId": "chk_xyz",
      "name": "downtime-alert",
      "enabled": true,
      "conditions": [
        { "type": "consecutive_failures", "count": 3 }
      ],
      "channelIds": ["nch_abc"],
      "channels": [
        { "type": "slack", "webhookUrl": "https://hooks.slack.com/..." }
      ],
      "createdAt": "2025-01-15T10:00:00.000Z",
      "updatedAt": null
    }
  ]
}

The channels array contains resolved channel configurations for display. The channelIds array contains the raw channel IDs.

Create Alert Rule

To create an alert rule for a check:

POST /api/checks/:id/alerts

Request body -- validated through CreateAlertRuleSchema:

FieldTypeRequiredDefaultDescription
namestring | nullNonullAlert rule name.
enabledbooleanNotrueWhether the rule is active.
conditionsarrayYes--At least one condition. See Alert Conditions.
channelIdsstring[]Yes--At least one notification channel ID.

Response 201

{ "id": "alert_abc123" }

Update Alert Rule

To update an existing alert rule:

PUT /api/alerts/:alertId

Request body -- validated through UpdateAlertRuleSchema (all fields optional):

FieldTypeDescription
namestring | nullAlert rule name.
enabledbooleanWhether the rule is active.
conditionsarrayAt least one condition (replaces existing).
channelIdsstring[]At least one channel ID (replaces existing).

Response 200

{ "success": true }

Delete Alert Rule

To delete an alert rule:

DELETE /api/alerts/:alertId

Response 200

{ "success": true }

Alert Conditions

Each condition in the conditions array must have a type field. Available types:

TypeFieldsDescription
consecutive_failurescount (default: 2, min: 1)Alert after N consecutive failures.
response_time_thresholdmaxMs (required)Alert when response time exceeds threshold.
multi_location_failureminLocations (default: 2, min: 2), windowSeconds (default: 300)Alert when failures occur from multiple locations within a time window.
ssl_expirydaysBeforeExpiry (default: 14, min: 1), severity (optional)Alert when SSL certificate nears expiration.
ssl_certificate_changedseverity (optional)Alert when the leaf certificate fingerprint changes between runs.
ssl_self_signedseverity (optional)Alert when a self-signed or untrusted-root certificate is detected.
ssl_protocol_deprecatedminProtocol (default: TLSv1.2, allowed: TLSv1.2, TLSv1.3), severity (optional)Alert when the TLS handshake negotiates a protocol older than minProtocol.
burn_ratesloId (required), burnRateThreshold (positive number), longWindowMinutes (min 60), shortWindowMinutes (min 5, must be less than long)SLO burn-rate alert. Typically generated automatically from SLOs with burnRateAlertsEnabled: true.

All SSL conditions (including ssl_expiry) accept an optional severity field with value critical, warning, or info.


Alert Instances

Alert instances represent individual occurrences of a triggered alert rule. They track state transitions through a lifecycle: active -> acknowledged -> resolved (or recovered automatically).

List Alert Instances

To list alert instances for your team:

GET /api/alerts/instances

Query parameters:

ParameterTypeDefaultDescription
statestring--Filter by state. Comma-separated: active, acknowledged, recovered, resolved.
checkIdstring--Filter by check ID.
limitnumber50Results per page (1-200).
offsetnumber0Pagination offset.

Response 200

{
  "instances": [
    {
      "id": "ainst_abc123",
      "ruleId": "alert_xyz",
      "checkId": "chk_xyz",
      "state": "active",
      "severity": "critical",
      "startedAt": "2025-01-15T10:00:00.000Z",
      "acknowledgedAt": null,
      "recoveredAt": null,
      "resolvedAt": null,
      "durationMs": null,
      "notificationCount": 2,
      "contextJson": {},
      "muted": false,
      "ruleName": "downtime-alert",
      "checkName": "Homepage"
    }
  ],
  "limit": 50,
  "offset": 0
}

Get Alert Instance

To get a single alert instance with its full event timeline:

GET /api/alerts/instances/:id

Response 200

{
  "instance": {
    "id": "ainst_abc123",
    "ruleId": "alert_xyz",
    "checkId": "chk_xyz",
    "teamId": "team_xyz",
    "state": "acknowledged",
    "severity": "critical",
    "triggeringResultId": "res_abc",
    "triggeringTraceId": "abc123def456",
    "recoveryResultId": null,
    "startedAt": "2025-01-15T10:00:00.000Z",
    "acknowledgedAt": "2025-01-15T10:05:00.000Z",
    "acknowledgedBy": "user_abc",
    "recoveredAt": null,
    "resolvedAt": null,
    "durationMs": null,
    "notificationCount": 2,
    "contextJson": {},
    "muted": false,
    "ruleName": "downtime-alert",
    "checkName": "Homepage"
  },
  "events": [
    {
      "id": "aevt_abc",
      "instanceId": "ainst_abc123",
      "type": "triggered",
      "actorId": null,
      "createdAt": "2025-01-15T10:00:00.000Z"
    },
    {
      "id": "aevt_def",
      "instanceId": "ainst_abc123",
      "type": "acknowledged",
      "actorId": "user_abc",
      "createdAt": "2025-01-15T10:05:00.000Z"
    }
  ]
}

Acknowledge Alert Instance

To acknowledge an active alert instance (transitions from active to acknowledged):

POST /api/alerts/instances/:id/acknowledge

Request body: none

Response 200

{ "success": true, "state": "acknowledged" }

Error 409 -- Instance is not in active state.

Resolve Alert Instance

To manually resolve an alert instance (transitions from active or acknowledged to resolved):

POST /api/alerts/instances/:id/resolve

Request body: none

Response 200

{ "success": true, "state": "resolved", "durationMs": 300000 }

Error 409 -- Instance is already recovered or resolved.


Notification Channels

List Channels

To list all notification channels for your team:

GET /api/notification-channels

Response 200

{
  "channels": [
    {
      "id": "nch_abc123",
      "name": "ops-slack",
      "type": "slack",
      "config": { "type": "slack", "webhookUrl": "https://hooks.slack.com/..." },
      "createdAt": "2025-01-15T10:00:00.000Z",
      "updatedAt": null
    }
  ]
}

Create Channel

To create a notification channel:

POST /api/notification-channels

Request body -- validated through CreateNotificationChannelSchema:

FieldTypeRequiredDescription
namestringYesChannel name (1-100 characters). Must be unique within the team.
channelobjectYesChannel configuration.

channel object (discriminated by type):

Slack:

FieldTypeRequiredDescription
type"slack"YesChannel type.
webhookUrlstring (URL)YesSlack incoming webhook URL.

Email:

FieldTypeRequiredDescription
type"email"YesChannel type.
addressesstring[]YesAt least one valid email address.

Webhook:

FieldTypeRequiredDefaultDescription
type"webhook"Yes--Channel type.
urlstring (URL)Yes--Webhook endpoint URL.
method"POST" | "PUT"No"POST"HTTP method.
headersobjectNo--Custom headers.

Response 201

{
  "channel": {
    "id": "nch_abc123",
    "name": "ops-slack",
    "type": "slack",
    "config": { "type": "slack", "webhookUrl": "https://hooks.slack.com/..." }
  }
}

Error 409 -- A channel with that name already exists.

Get Channel

To get a single notification channel:

GET /api/notification-channels/:id

Response 200

{
  "channel": {
    "id": "nch_abc123",
    "name": "ops-slack",
    "type": "slack",
    "config": { "type": "slack", "webhookUrl": "https://hooks.slack.com/..." },
    "createdAt": "2025-01-15T10:00:00.000Z",
    "updatedAt": null
  }
}

Update Channel

To update a notification channel:

PUT /api/notification-channels/:id

Request body -- validated through UpdateNotificationChannelSchema (all fields optional):

FieldTypeDescription
namestringChannel name (1-100 characters).
channelobjectChannel configuration. The type field cannot change -- delete and recreate to change type.

Response 200

{ "success": true }

Error 400 -- Channel type cannot be changed. Error 409 -- A channel with that name already exists.

Delete Channel

To delete a notification channel:

DELETE /api/notification-channels/:id

The channel must not be referenced by any alert rules or SLOs. Remove references first.

Response 200

{ "success": true }

Error 409 -- Channel is still in use by an alert rule or SLO.


SLOs

List SLOs

To list all SLO definitions for your team:

GET /api/slos

Query parameters:

ParameterTypeDefaultDescription
checkIdstring--Filter by check ID.
sloTypestring--Filter by SLO type: check or third_party.
limitnumber50Results per page (1-200).
offsetnumber0Pagination offset.

Response 200

{
  "slos": [
    {
      "id": "slo_abc123",
      "checkId": "chk_xyz",
      "teamId": "team_xyz",
      "name": "Homepage SLO",
      "targetBasisPoints": 9990,
      "windowDays": 30,
      "burnRateAlertsEnabled": true,
      "channelIds": ["nch_abc"],
      "enabled": true,
      "sloType": "check",
      "patternId": null,
      "sliType": "availability",
      "perfThresholdMs": null,
      "scope": "check",
      "createdAt": "2025-01-15T10:00:00.000Z",
      "updatedAt": null,
      "checkName": "Homepage"
    }
  ],
  "limit": 50,
  "offset": 0
}

Create SLO

To create a new SLO definition:

POST /api/slos

Request body -- validated through CreateSloSchema (discriminated union on sloType):

For check-based SLOs:

FieldTypeRequiredDefaultConstraintsDescription
sloType"check"Yes----SLO type. Defaults to "check" if omitted.
checkIdstringYes----Check ID this SLO tracks.
namestringYes--1-255 charactersSLO name.
targetBasisPointsnumberYes--Integer, 1-9999Availability target (e.g., 9990 = 99.90%).
windowDaysnumberYes--7 | 14 | 30Rolling window in days.
burnRateAlertsEnabledbooleanNotrue--Enable burn rate alerting.
channelIdsstring[]No----Notification channel IDs for alerts.
enabledbooleanNotrue--Whether the SLO is active.

Response 201

{
  "slo": {
    "id": "slo_abc123",
    "checkId": "chk_xyz",
    "teamId": "team_xyz",
    "name": "Homepage SLO",
    "targetBasisPoints": 9990,
    "windowDays": 30,
    "burnRateAlertsEnabled": true,
    "channelIds": [],
    "enabled": true,
    "sloType": "check",
    "patternId": null,
    "sliType": "availability",
    "perfThresholdMs": null,
    "scope": "check",
    "createdAt": "2025-01-15T10:00:00.000Z",
    "updatedAt": null
  }
}

Get SLO

To get a single SLO definition:

GET /api/slos/:id

Response 200

{
  "slo": {
    "id": "slo_abc123",
    "checkId": "chk_xyz",
    "name": "Homepage SLO",
    "targetBasisPoints": 9990,
    "windowDays": 30,
    "burnRateAlertsEnabled": true,
    "channelIds": ["nch_abc"],
    "enabled": true,
    "sloType": "check",
    "checkName": "Homepage",
    "..." : "..."
  }
}

Update SLO

To update an existing SLO definition:

PUT /api/slos/:id

Request body -- validated through UpdateSloSchema (all fields optional):

FieldTypeConstraintsDescription
namestring1-255 charactersSLO name.
checkIdstring--Check ID (cannot be set on team-wide SLOs).
targetBasisPointsnumberInteger, 1-9999Availability target.
windowDaysnumber7 | 14 | 30Rolling window.
burnRateAlertsEnabledboolean--Enable burn rate alerting.
channelIdsstring[]--Notification channel IDs.
enabledboolean--Whether the SLO is active.
perfThresholdMsnumberInteger, min 1. Only valid for performance SLIs.Performance threshold.

Note: sloType, scope, and sliType are immutable after creation. Changing them would invalidate historical data.

Response 200

{
  "slo": { "id": "slo_abc123", "..." : "..." }
}

Delete SLO

To delete an SLO definition:

DELETE /api/slos/:id

Response 200

{ "success": true }

Get SLO Status

To get the current computed state of an SLO (availability, error budget, burn rates):

GET /api/slos/:id/status

Response 200

{
  "state": {
    "sloId": "slo_abc123",
    "checkId": "chk_xyz",
    "patternId": null,
    "name": "Homepage SLO",
    "sloType": "check",
    "sliType": "availability",
    "targetBasisPoints": 9990,
    "windowDays": 30,
    "availability": 0.9995,
    "totalCount": 8640,
    "successCount": 8636,
    "avgDurationMs": null,
    "perfComplianceRatio": null,
    "errorBudgetTotal": 43.2,
    "errorBudgetConsumed": 21.6,
    "errorBudgetRemaining": 21.6,
    "budgetConsumedRatio": 0.5,
    "burnRate1h": 0.0,
    "burnRate6h": 0.2,
    "burnRate24h": 0.5
  }
}
FieldTypeDescription
availabilitynumberCurrent availability ratio (0-1).
totalCountnumberTotal check runs in the window.
successCountnumberSuccessful check runs.
errorBudgetTotalnumberTotal error budget in estimated minutes.
errorBudgetConsumednumberError budget consumed in estimated minutes.
errorBudgetRemainingnumberError budget remaining in estimated minutes.
budgetConsumedRationumberFraction of budget consumed (0-1).
burnRate1hnumber1-hour burn rate.
burnRate6hnumber6-hour burn rate.
burnRate24hnumber24-hour burn rate.

Locations

List Locations

To list all available monitoring locations (hosted and private):

GET /api/locations

Query parameters:

ParameterTypeDefaultDescription
include_deprecated"true"--Also include deprecated locations (for migration UI).

Response 200

{
  "locations": [
    {
      "id": "loc_us_east",
      "name": "us-east",
      "region": "iad",
      "displayName": "US East (Ashburn)",
      "type": "hosted",
      "status": "active",
      "health": "active",
      "latitude": 39.0438,
      "longitude": -77.4874
    },
    {
      "id": "loc_staging_eu",
      "name": "staging-eu",
      "region": "private",
      "displayName": "Staging EU",
      "type": "private",
      "status": "active",
      "health": "active",
      "teamId": "team_xyz",
      "lastHeartbeat": "2025-01-15T10:03:45.000Z"
    }
  ]
}
FieldTypeDescription
idstringLocation ID (use this in check locations arrays).
namestringShort name.
regionstringFly region code (hosted) or "private".
displayNamestringHuman-readable name.
typestring"hosted" or "private".
statusstringLifecycle status: "active", "deprecated", or "retired".
healthstringRuntime health: "active", "degraded", or "offline". Hosted locations are always "active"; private locations are derived from heartbeat recency.
replacedBystringSuccessor location ID (only for deprecated/retired locations).
teamIdstringOnly set for private locations.
lastHeartbeatstring (ISO-8601)Only set for private locations. Most recent runner check-in.
latitudenumberGeographic latitude (optional).
longitudenumberGeographic longitude (optional).

NL Generation

POST /api/checks/generate has two modes, distinguished by whether the request body includes a spec field:

  • Playwright mode — default. Generates a Playwright browser script from a natural language description via Claude. Used by the dashboard's NL monitor builder.
  • Spec mode — generates HTTP checks from an OpenAPI document by reusing the same pipeline as POST /api/specs/:id/generate-checks. The spec can be referenced by ID, fetched from a URL, or matched by name against an existing spec.

Generate Playwright Script

To generate a Playwright monitoring script from a natural language description:

POST /api/checks/generate

Request body:

FieldTypeRequiredDescription
descriptionstringYesNatural language description of what to monitor (min 10 characters).
targetUrlstring (URL)NoTarget URL for the script.
previousScriptstringNoExisting script to refine.
refinementstringNoRefinement instructions (used with previousScript).

Response 200

{
  "mode": "playwright",
  "script": "// @step: Navigate to homepage\nawait page.goto('https://example.com');\n...",
  "description": "Monitor the login flow",
  "model": "claude-sonnet-4-20250514"
}

Error 503 — NL creation not configured (server missing ANTHROPIC_API_KEY).

Generate Checks From OpenAPI Spec

To generate HTTP checks from an OpenAPI spec in a single round trip — useful when an integration knows the spec source but does not want to manage the spec entity separately:

POST /api/checks/generate

Request body:

FieldTypeRequiredDefaultDescription
specobjectYesDiscriminated by spec.source. See variants below.
locationsstring[]YesLocations to assign to generated checks. Must contain at least one.
frequencySecondsintegerNo300Check frequency in seconds, between 10 and 86400.
validateHeadersbooleanNofalseAlso validate response headers against the spec (toggles validateHeaders on the generated openapi_conformance assertion).
confirmbooleanNofalseRequired when the spec yields more than 50 new operations.

Spec reference variantsspec.source selects how the spec is resolved:

sourceRequired fieldsOptional fieldsBehavior
"id"specIdUses the spec already stored on the team. Returns 404 if not found.
"url"specUrl (HTTP or HTTPS URL)name (1–255 chars)Fetches the spec via the SSRF-guarded loader (blocks private/reserved IPs and credential-bearing URLs; plain HTTP is permitted for internal networks, redirects are rejected to prevent SSRF). If a spec with the same content hash already exists for the team, it is reused; otherwise a new spec entity is inserted. When name is omitted it is derived from info.title, falling back to api-{hostname}, with a numeric suffix appended on collision.
"name"specNameLooks up an existing spec by exact name (per-team unique). Returns 404 if not found.

Response 200 (or 201 if at least one check was created) — same envelope as POST /api/specs/:id/generate-checks. The mode field marks this as the spec branch and spec.newlyCreated indicates whether the URL variant inserted a brand-new spec row.

{
  "mode": "spec",
  "spec": { "id": "spec_abc", "name": "Petstore API", "newlyCreated": true },
  "created": [
    { "id": "chk_xyz", "name": "GET /pets", "operationKey": "GET /pets" }
  ],
  "skipped": [
    { "operationKey": "GET /pets/{id}", "reason": "already_exists" }
  ],
  "summary": {
    "operationsInSpec": 12,
    "eligible": 11,
    "created": 10,
    "skipped": 1,
    "labelAttachmentFailures": 0
  }
}

Errors:

  • 400 — invalid request body ({ error: "Validation failed", details: {...} }).
  • 403 — plan limit reached. Body contains { error: "<plan limit message>" }.
  • 404 — spec not found (id and name variants only).
  • 409 — confirmation required: { error: "This spec would create N new monitors. Confirm to create all of them.", requiresConfirmation: true, operationCount: N, threshold: 50 }. Re-submit with confirm: true.
  • 409 — (url variant only) a spec with the resolved name already exists with different content. Pass an explicit name or use the id variant.
  • 422 — the loaded spec content failed to parse, OR the upstream URL fetch returned an error / non-OpenAPI body / exceeded the 10 MB cap. Body contains { error: "<details>" }.

API Specs

API specs store OpenAPI documents that HTTP checks can validate against via the openapi_conformance assertion. See Assertions → openapi_conformance.

List Specs

GET /api/specs

Returns a summary list (no full contents — use the detail endpoint to fetch the parsed spec).

Create Spec

POST /api/specs

Request body — discriminated by sourceType:

Upload mode:

FieldTypeRequiredDescription
namestringYesSpec name (1-255 characters).
sourceType"upload"Yes
contentstringYesRaw OpenAPI JSON or YAML (up to 4 MB).

URL mode:

FieldTypeRequiredDescription
namestringYesSpec name (1-255 characters).
sourceType"url"Yes
sourceUrlstring (URL)YesURL Yorker fetches the spec from.

Get Spec

GET /api/specs/:id

Returns the full parsed spec including contentJson.

Update Spec

PUT /api/specs/:id

Accepts name, content (switches to upload mode), or sourceUrl (switches to url mode). You cannot provide both content and sourceUrl in the same request.

Delete Spec

DELETE /api/specs/:id

Fails if any checks still reference the spec via an openapi_conformance assertion.

Sync URL-mode Spec

POST /api/specs/:id/sync

Forces Yorker to re-fetch a url-mode spec immediately. Runners invalidate their cached copy on the next poll.

Generate Checks From Spec

POST /api/specs/:id/generate-checks

Generates one HTTP check per operation in the spec. Operations that already have a corresponding check are skipped — re-running this endpoint is idempotent. Returns 201 when at least one check is created, 200 otherwise.

Request body:

FieldTypeRequiredDefaultDescription
locationsstring[]YesLocations to assign to generated checks. Must contain at least one.
frequencySecondsintegerNo300Check frequency in seconds, between 10 and 86400.
validateHeadersbooleanNofalseAlso validate response headers against the spec (toggles validateHeaders on the generated openapi_conformance assertion).
confirmbooleanNofalseRequired when the spec yields more than 50 new operations. Re-submit with true to proceed.

Response 201 / 200

{
  "spec": { "id": "spec_abc", "name": "Petstore API" },
  "created": [
    { "id": "chk_xyz", "name": "GET /pets", "operationKey": "GET /pets" }
  ],
  "skipped": [
    { "operationKey": "GET /pets/{id}", "reason": "already_exists" }
  ],
  "summary": {
    "operationsInSpec": 12,
    "eligible": 11,
    "created": 10,
    "skipped": 1,
    "labelAttachmentFailures": 0
  }
}
FieldTypeDescription
specobjectThe spec the checks were generated from (id, name).
createdarrayChecks created in this call (id, name, operationKey).
skippedarrayOperations the generator skipped (operationKey, reason). Reasons include already_exists, no_responses, no_server_url, invalid_url, deprecated, and others — see GenerateChecksSkipReason.
summary.operationsInSpecnumberTotal operations the spec exposes.
summary.eligiblenumberOperations that passed the per-operation filters.
summary.creatednumberNew checks created in this call.
summary.skippednumberOperations skipped (existing + filtered).
summary.labelAttachmentFailuresnumberLabel attachments that failed mid-loop (extremely rare).

Errors:

  • 400 — invalid request body ({ error: "Validation failed", details: {...} }).
  • 403 — plan limit reached. Body contains { error: "<plan limit message>" }.
  • 404 — spec not found (or belongs to another team).
  • 409 — confirmation required: { error: "This spec would create N new monitors. Confirm to create all of them.", requiresConfirmation: true, operationCount: N, threshold: 50 }. Re-submit with confirm: true.
  • 422 — the stored spec content failed to parse ({ error: "<parser message>" }).

Maintenance Windows

Maintenance windows silence or pause checks during scheduled work. See Configuration → maintenanceWindows for the YAML schema.

List Maintenance Windows

GET /api/maintenance-windows

Create Maintenance Window

POST /api/maintenance-windows

Request body:

FieldTypeRequiredDefaultDescription
namestringYesWindow name (1-200 characters).
mode"pause" | "continue"No"pause"pause stops running checks; continue runs them but silences notifications.
checkIdsstring[] | nullYesArray of check IDs to cover. Pass null to apply to all checks for the team. If provided as an array, it must contain at least one ID.
startsAtstring (ISO-8601)YesStart timestamp.
endsAtstring (ISO-8601)YesEnd timestamp. Must be after startsAt.
recurringbooleanNofalseEnable recurrence.
recurrenceRulestring (RRULE)Required if recurringRFC 5545 recurrence rule. Supported: FREQ=DAILY, FREQ=WEEKLY (optionally with BYDAY), FREQ=MONTHLY (optionally with BYMONTHDAY). Recurring window duration cannot exceed 31 days.

Get / Update / Delete Maintenance Window

GET    /api/maintenance-windows/:id
PUT    /api/maintenance-windows/:id
DELETE /api/maintenance-windows/:id