{"openapi":"3.0.3","info":{"title":"Upcheck API","version":"1.0.0","description":"External API for Upcheck monitors. Authenticate with a personal access token (`upk_...`, create via POST /v1/tokens) sent as `Authorization: Bearer <token>`."},"servers":[{"url":"https://upcheck-api-a.rekwiem.com","description":"Production"},{"url":"https://upcheck-api-staging.rekwiem.com","description":"Staging"}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"A personal access token (`upk_...`) or an app session token."}},"schemas":{"ContentRule":{"type":"object","properties":{"type":{"type":"string","enum":["text_contains","text_absent","json_field"],"description":"Rule kind."},"value":{"type":"string","maxLength":256,"description":"text_contains/text_absent: literal to match."},"path":{"type":"string","maxLength":128,"description":"json_field: dot path, e.g. data.status."},"equals":{"type":"string","maxLength":256,"description":"json_field: expected value (omit = field must exist)."}},"required":["type"]},"HeaderOut":{"type":"object","properties":{"name":{"type":"string"},"type":{"type":"string","enum":["bearer","apikey","custom"]}},"required":["name"],"description":"Header name (+ type hint) only — values are write-only and never returned."},"Monitor":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"type":{"type":"string","enum":["http","keyword","api","heartbeat","scheduler","dns","port","ping","udp"],"description":"Check type — `http`, `heartbeat`, or `scheduler`."},"url":{"type":"string"},"method":{"type":"string"},"interval_sec":{"type":"integer"},"slow_ms":{"type":"integer"},"timeout_ms":{"type":"integer"},"expect_status":{"type":"integer","nullable":true},"follow_redirects":{"type":"boolean"},"check_ssl":{"type":"boolean"},"check_domain":{"type":"boolean"},"domain_expires_at":{"type":"number","nullable":true,"description":"Domain registration expiry (epoch ms) from RDAP; null until looked up. Read-only."},"cert_expires_at":{"type":"number","nullable":true,"description":"TLS certificate expiry (epoch ms); null until probed. Read-only."},"content_rules":{"type":"array","items":{"$ref":"#/components/schemas/ContentRule"}},"request_headers":{"type":"array","items":{"$ref":"#/components/schemas/HeaderOut"}},"request_body":{"type":"string","nullable":true},"fail_threshold":{"type":"integer"},"recover_threshold":{"type":"integer"},"grace_sec":{"type":"integer","description":"Heartbeat grace seconds (after interval_sec)."},"last_ping_at":{"type":"number","nullable":true,"description":"Heartbeat: last ping (epoch ms), null until the first."},"muted_until":{"type":"number","nullable":true,"description":"Down-detection + alerts suppressed until this epoch ms; null = not muted."},"enabled":{"type":"boolean"},"project_id":{"type":"string","nullable":true,"description":"Owning project id, or null if ungrouped."},"status":{"type":"string","nullable":true,"enum":["up","slow","down"],"description":"null until the first check completes."},"status_since":{"type":"number","nullable":true,"description":"When the current status began (epoch ms); null if never set."},"last_latency_ms":{"type":"number","nullable":true},"last_connect_ms":{"type":"number","nullable":true},"last_ttfb_ms":{"type":"number","nullable":true},"uptime_24h":{"type":"number","nullable":true,"description":"Percent (non-down) over 24h."},"avg_latency_24h":{"type":"number","nullable":true},"last_checked_at":{"type":"number","nullable":true,"description":"Epoch ms."}},"required":["id","name","type","url","method","interval_sec","slow_ms","timeout_ms","expect_status","follow_redirects","check_ssl","check_domain","domain_expires_at","cert_expires_at","content_rules","request_headers","request_body","fail_threshold","recover_threshold","grace_sec","last_ping_at","muted_until","enabled","project_id","status","status_since","last_latency_ms","last_connect_ms","last_ttfb_ms","uptime_24h","avg_latency_24h","last_checked_at"]},"Error":{"type":"object","properties":{"error":{"type":"string"},"reason":{"type":"string"},"limit":{"type":"number"}},"required":["error"]},"HeaderInput":{"type":"object","properties":{"name":{"type":"string","example":"Authorization"},"value":{"type":"string","description":"Plaintext value. On PATCH, omit to keep the stored value."},"type":{"type":"string","enum":["bearer","apikey","custom"],"description":"UI hint only."}},"required":["name"]},"MonitorInput":{"type":"object","properties":{"url":{"type":"string","format":"uri","description":"Required for `http` and `scheduler` monitors; omit for `heartbeat`.","example":"https://example.com/health"},"name":{"type":"string","default":"Untitled"},"type":{"type":"string","enum":["http","heartbeat","scheduler"],"default":"http","description":"Check type. `http` (we poll a URL to check it's up), `heartbeat` (your job pings us), or `scheduler` (we call your URL on a schedule as a trigger — 2xx = success). Other types (dns, port, ...) are planned."},"method":{"type":"string","enum":["HEAD","GET","POST","PUT","PATCH","DELETE","OPTIONS"],"default":"HEAD","description":"HEAD is forced to GET when content rules are set. Schedulers reject HEAD/OPTIONS (a trigger must act) and default to POST."},"interval_sec":{"type":"integer","description":"Floored to the plan minimum (free 300, pro 60). For heartbeat, the expected max gap between pings."},"grace_sec":{"type":"integer","description":"Heartbeat only: extra seconds after interval_sec before 'down' (default 60)."},"slow_ms":{"type":"integer","default":1500,"description":"Latency ≥ this ⇒ 'slow'."},"timeout_ms":{"type":"integer","default":10000,"description":"Clamped to 1000–60000."},"expect_status":{"type":"integer","nullable":true,"description":"Exact code required; null/0 ⇒ any 2xx/3xx."},"follow_redirects":{"type":"boolean","description":"Follow 3xx redirects and judge the final response. Off (default) treats a 3xx as reachable. Turning it on forces the fetch path (no connect/ttfb split)."},"check_ssl":{"type":"boolean","description":"https only: report a certificate/TLS failure as a distinct SSL problem instead of a generic connection error. Off by default."},"check_domain":{"type":"boolean","description":"Look up the domain's registration expiry via RDAP and warn before it lapses. Off by default."},"content_rules":{"type":"array","items":{"$ref":"#/components/schemas/ContentRule"},"maxItems":4},"request_headers":{"type":"array","items":{"$ref":"#/components/schemas/HeaderInput"},"maxItems":4},"request_body":{"type":"string","maxLength":8192,"description":"Request body for write methods (POST/PUT/PATCH/DELETE) — rejected with GET/HEAD. Sent with EVERY scheduled check, so point writes at test data or a dedicated test route. application/json unless a Content-Type header is set."},"fail_threshold":{"type":"integer","default":3,"description":"Consecutive fails before 'down'."},"recover_threshold":{"type":"integer","default":1},"project_id":{"type":"string","description":"Group under a project (id from /v1/projects)."}}},"CheckResult":{"type":"object","properties":{"status":{"type":"string","enum":["up","slow","down"]},"latency_ms":{"type":"number","nullable":true},"connect_ms":{"type":"number","nullable":true},"ttfb_ms":{"type":"number","nullable":true},"detail":{"type":"string","nullable":true,"description":"null when up; reason otherwise."},"http_status":{"type":"number","nullable":true}},"required":["status","latency_ms","connect_ms","ttfb_ms","detail","http_status"]},"MonitorPatch":{"type":"object","properties":{"url":{"type":"string","format":"uri","description":"Required for `http` and `scheduler` monitors; omit for `heartbeat`.","example":"https://example.com/health"},"name":{"type":"string","default":"Untitled"},"type":{"type":"string","enum":["http","heartbeat","scheduler"],"default":"http","description":"Check type. `http` (we poll a URL to check it's up), `heartbeat` (your job pings us), or `scheduler` (we call your URL on a schedule as a trigger — 2xx = success). Other types (dns, port, ...) are planned."},"method":{"type":"string","enum":["HEAD","GET","POST","PUT","PATCH","DELETE","OPTIONS"],"default":"HEAD","description":"HEAD is forced to GET when content rules are set. Schedulers reject HEAD/OPTIONS (a trigger must act) and default to POST."},"interval_sec":{"type":"integer","description":"Floored to the plan minimum (free 300, pro 60). For heartbeat, the expected max gap between pings."},"grace_sec":{"type":"integer","description":"Heartbeat only: extra seconds after interval_sec before 'down' (default 60)."},"slow_ms":{"type":"integer","default":1500,"description":"Latency ≥ this ⇒ 'slow'."},"timeout_ms":{"type":"integer","default":10000,"description":"Clamped to 1000–60000."},"expect_status":{"type":"integer","nullable":true,"description":"Exact code required; null/0 ⇒ any 2xx/3xx."},"follow_redirects":{"type":"boolean","description":"Follow 3xx redirects and judge the final response. Off (default) treats a 3xx as reachable. Turning it on forces the fetch path (no connect/ttfb split)."},"check_ssl":{"type":"boolean","description":"https only: report a certificate/TLS failure as a distinct SSL problem instead of a generic connection error. Off by default."},"check_domain":{"type":"boolean","description":"Look up the domain's registration expiry via RDAP and warn before it lapses. Off by default."},"content_rules":{"type":"array","items":{"$ref":"#/components/schemas/ContentRule"},"maxItems":4},"request_headers":{"type":"array","items":{"$ref":"#/components/schemas/HeaderInput"},"maxItems":4},"request_body":{"type":"string","maxLength":8192,"description":"Request body for write methods (POST/PUT/PATCH/DELETE) — rejected with GET/HEAD. Sent with EVERY scheduled check, so point writes at test data or a dedicated test route. application/json unless a Content-Type header is set."},"fail_threshold":{"type":"integer","default":3,"description":"Consecutive fails before 'down'."},"recover_threshold":{"type":"integer","default":1},"project_id":{"type":"string","description":"Group under a project (id from /v1/projects)."},"enabled":{"type":"boolean","description":"false = pause the monitor."}}},"Token":{"type":"object","properties":{"id":{"type":"string"},"project_id":{"type":"string","description":"The single project this token is scoped to. A PAT can only reach this project's resources."},"name":{"type":"string","nullable":true},"created_at":{"type":"number","description":"Epoch ms."},"last_used_at":{"type":"number","nullable":true},"expires_at":{"type":"number","nullable":true,"description":"Epoch ms; null = never expires."}},"required":["id","project_id","name","created_at","last_used_at","expires_at"]},"TokenCreated":{"allOf":[{"$ref":"#/components/schemas/Token"},{"type":"object","properties":{"token":{"type":"string","description":"Plaintext `upk_...` — returned ONCE, never again.","example":"upk_ab12…"}},"required":["token"]}]},"Project":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"created_at":{"type":"number","description":"Epoch ms."},"monitors":{"type":"number","description":"Monitor count (list only)."},"up":{"type":"number"},"slow":{"type":"number"},"down":{"type":"number"},"unknown":{"type":"number"}},"required":["id","name","created_at"]},"Connector":{"type":"object","properties":{"provider":{"type":"string"},"created_at":{"type":"number"},"meta":{"type":"string","nullable":true}},"required":["provider","created_at","meta"]},"ImportableProject":{"type":"object","properties":{"external_ref":{"type":"string"},"name":{"type":"string"},"url":{"type":"string"},"already_imported":{"type":"boolean"}},"required":["external_ref","name","url","already_imported"]},"ImportResult":{"type":"object","properties":{"created":{"type":"array","items":{"$ref":"#/components/schemas/Monitor"}},"skipped":{"type":"array","items":{"type":"string"},"description":"external_refs already imported."},"failed":{"type":"array","items":{"type":"object","properties":{"external_ref":{"type":"string"},"error":{"type":"string"}},"required":["external_ref","error"]}}},"required":["created","skipped","failed"]}},"parameters":{}},"paths":{"/v1/monitors":{"get":{"summary":"List the caller's monitors","tags":["Monitors"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Monitor"}}}}},"401":{"description":"Missing/invalid token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"summary":"Create a monitor","tags":["Monitors"],"security":[{"bearerAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MonitorInput"}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Monitor"}}}},"401":{"description":"Missing/invalid token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Monitor limit reached","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/monitors/test":{"post":{"summary":"Run one check against a draft config (nothing saved)","tags":["Monitors"],"security":[{"bearerAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MonitorInput"}}}},"responses":{"200":{"description":"Check result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckResult"}}}},"401":{"description":"Missing/invalid token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/monitors/{id}":{"patch":{"summary":"Update a monitor (partial)","tags":["Monitors"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MonitorPatch"}}}},"responses":{"200":{"description":"Updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Monitor"}}}},"401":{"description":"Missing/invalid token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"summary":"Delete a monitor","tags":["Monitors"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Deleted","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}},"required":["ok"]}}}},"401":{"description":"Missing/invalid token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/monitors/{id}/mute":{"post":{"summary":"Mute a monitor for N minutes (maintenance window; 0 clears)","tags":["Monitors"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"minutes":{"type":"integer","description":"Minutes to suppress down-detection + alerts; 0 clears, capped at 7 days."}},"required":["minutes"]}}}},"responses":{"200":{"description":"Updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Monitor"}}}},"401":{"description":"Missing/invalid token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/heartbeats/{id}/ping":{"post":{"summary":"Heartbeat check-in — call from your job (public; GET also works)","tags":["Monitors"],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Ping recorded","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}},"required":["ok"]}}}},"404":{"description":"Not a heartbeat / not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tokens":{"get":{"summary":"List personal access tokens","tags":["Tokens"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Token"}}}}},"401":{"description":"Missing/invalid token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"summary":"Create a project-scoped token (session auth only)","tags":["Tokens"],"security":[{"bearerAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"project_id":{"type":"string","description":"Project to scope the token to (id from /v1/projects). Required — every PAT is confined to one project. You must be its owner, admin, or member."},"name":{"type":"string","description":"Label for the token."},"ttl_seconds":{"type":"number","description":"Optional expiry (60–7776000s). Omit for a non-expiring token."}},"required":["project_id","name"]}}}},"responses":{"201":{"description":"Created — plaintext returned once","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenCreated"}}}},"400":{"description":"Missing project_id / not permitted on it","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Requires a session token, not a PAT","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tokens/{id}":{"delete":{"summary":"Revoke a token","tags":["Tokens"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Revoked","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}},"required":["ok"]}}}},"401":{"description":"Missing/invalid token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/projects":{"post":{"summary":"Create a project","tags":["Projects"],"security":[{"bearerAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"}},"required":["name"]}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Project"}}}},"401":{"description":"Missing/invalid token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"get":{"summary":"List projects with per-project status","tags":["Projects"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Project"}}}}},"401":{"description":"Missing/invalid token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/projects/{id}":{"patch":{"summary":"Rename a project","tags":["Projects"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"}},"required":["name"]}}}},"responses":{"200":{"description":"Renamed","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}},"required":["ok"]}}}},"401":{"description":"Missing/invalid token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"summary":"Delete a project (its monitors are detached, not deleted)","tags":["Projects"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Deleted","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}},"required":["ok"]}}}},"401":{"description":"Missing/invalid token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/connectors/{provider}/oauth/start":{"post":{"summary":"Begin the OAuth connect flow","tags":["Connectors"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","enum":["vercel","supabase"]},"required":true,"name":"provider","in":"path"}],"responses":{"200":{"description":"Open this URL to authorize","content":{"application/json":{"schema":{"type":"object","properties":{"authorize_url":{"type":"string"}},"required":["authorize_url"]}}}},"401":{"description":"Missing/invalid token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Provider not configured","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/connectors":{"get":{"summary":"List connected providers","tags":["Connectors"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Connector"}}}}},"401":{"description":"Missing/invalid token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/connectors/{provider}/projects":{"get":{"summary":"List a provider's projects (with import status)","tags":["Connectors"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","enum":["vercel","supabase"]},"required":true,"name":"provider","in":"path"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"projects":{"type":"array","items":{"$ref":"#/components/schemas/ImportableProject"}}},"required":["projects"]}}}},"401":{"description":"Missing/invalid token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not connected","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/connectors/{provider}/import":{"post":{"summary":"Import selected projects as monitors","tags":["Connectors"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","enum":["vercel","supabase"]},"required":true,"name":"provider","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"external_refs":{"type":"array","items":{"type":"string"}},"project_id":{"type":"string","description":"Import the monitors into this project."}},"required":["external_refs"]}}}},"responses":{"200":{"description":"Import result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportResult"}}}},"401":{"description":"Missing/invalid token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/connectors/{provider}":{"delete":{"summary":"Disconnect a provider","tags":["Connectors"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","enum":["vercel","supabase"]},"required":true,"name":"provider","in":"path"}],"responses":{"200":{"description":"Disconnected","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}},"required":["ok"]}}}},"401":{"description":"Missing/invalid token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not connected","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}