@belvador/api 0.1.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -44,6 +44,10 @@ try {
44
44
  Create one in Settings → API tokens. The client never puts the token in an error message.
45
45
  - **Errors** are RFC 9457 problem+json, surfaced as `BelvadorApiError` with a stable `code`,
46
46
  `status`, `scope` (for `API_SCOPE_INSUFFICIENT`), `retryAfter` and `requestId`.
47
+ - **Approvals**: sensitive operations (keys, members, tokens, alert destinations, node changes) throw
48
+ `APPROVAL_REQUIRED` with `e.approval` = `{ id, url, expiresAt, state }`. A person opens `url` on
49
+ belvador.dev and approves with their authenticator code; call again with the same `idempotencyKey`
50
+ (or `call("approvals.get", { approval_id })`) to read the outcome. Only https `/approve/<id>` links are kept.
47
51
  - **Retries**: reads, and writes sent with an `idempotencyKey`, are retried on 429 / 502–504 and network
48
52
  errors (`retries`, default 2), honouring `Retry-After` up to 10 s. `NODE_OFFLINE` is not retried.
49
53
  - **Scopes**: `await belvador.scopes()` returns the token's effective scopes (the `Belvador-Scopes` header).
package/dist/client.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { OPERATIONS, type OperationId, type OperationMeta, type OperationParams } from "./operations.gen.js";
2
- export declare const CLIENT_VERSION = "0.1.0";
2
+ export declare const CLIENT_VERSION = "0.3.0";
3
3
  export declare const DEFAULT_BASE_URL = "https://api.belvador.dev";
4
4
  /** Personal (`blv_pat_`), service (`blv_svc_`) or OAuth access (`blv_oat_`) token. */
5
5
  export declare const TOKEN_PATTERN: RegExp;
package/dist/client.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { BelvadorApiError, errorFrom } from "./errors.js";
2
2
  import { nodeErrorWord, nodeReadRequest, nodeRefusal, nodeWindowMissing, NODE_REFUSAL_STATUS, reshapeNodeAnswer, } from "./node-wire.gen.js";
3
3
  import { OPERATIONS } from "./operations.gen.js";
4
- export const CLIENT_VERSION = "0.1.0";
4
+ export const CLIENT_VERSION = "0.3.0";
5
5
  export const DEFAULT_BASE_URL = "https://api.belvador.dev";
6
6
  /** Personal (`blv_pat_`), service (`blv_svc_`) or OAuth access (`blv_oat_`) token. */
7
7
  export const TOKEN_PATTERN = /^blv_(pat|svc|oat)_[A-Za-z0-9_-]{20,200}$/;
@@ -170,7 +170,9 @@ class Client {
170
170
  method: meta.method,
171
171
  headers,
172
172
  ...(parts.body !== undefined ? { body: JSON.stringify(parts.body) } : {}),
173
- }, meta.method === "GET" || !!opts.idempotencyKey, opts.signal);
173
+ },
174
+ // Reads are safe to retry, including a read that posts a JSON body (a backtest).
175
+ meta.method === "GET" || meta.scope.endsWith(":read") || !!opts.idempotencyKey, opts.signal);
174
176
  this.#noteScopes(res);
175
177
  if (res.status === 401)
176
178
  this.#ticket = null;
package/dist/errors.d.ts CHANGED
@@ -20,6 +20,11 @@ export declare class BelvadorApiError extends Error {
20
20
  pointer: string;
21
21
  code: string;
22
22
  }> | undefined;
23
+ /**
24
+ * `APPROVAL_REQUIRED` (403): the approval a person gives on belvador.dev. Retry the same call
25
+ * with the same Idempotency-Key after they approved to get the stored result.
26
+ */
27
+ readonly approval: Approval | undefined;
23
28
  constructor(code: string, status: number, extra?: {
24
29
  title?: string;
25
30
  detail?: string;
@@ -30,7 +35,17 @@ export declare class BelvadorApiError extends Error {
30
35
  pointer: string;
31
36
  code: string;
32
37
  }>;
38
+ approval?: Approval;
33
39
  });
34
40
  }
41
+ export type ApprovalState = "pending" | "approved" | "executed" | "rejected" | "expired" | "failed";
42
+ export type Approval = {
43
+ id: string;
44
+ url: string;
45
+ expiresAt: string;
46
+ state: ApprovalState;
47
+ };
48
+ /** Approval members of a problem body; only an https `/approve/<id>` link is accepted. */
49
+ export declare function approvalFrom(body: Record<string, unknown>): Approval | undefined;
35
50
  /** An error answer → BelvadorApiError (problem+json fields, scope challenge, Retry-After). */
36
51
  export declare function errorFrom(res: Response): Promise<BelvadorApiError>;
package/dist/errors.js CHANGED
@@ -17,6 +17,11 @@ export class BelvadorApiError extends Error {
17
17
  requestId;
18
18
  /** Field errors: JSON pointers into the request with a code. */
19
19
  errors;
20
+ /**
21
+ * `APPROVAL_REQUIRED` (403): the approval a person gives on belvador.dev. Retry the same call
22
+ * with the same Idempotency-Key after they approved to get the stored result.
23
+ */
24
+ approval;
20
25
  constructor(code, status, extra = {}) {
21
26
  super(extra.title ? `${code}: ${extra.title}` : extra.detail ? `${code}: ${extra.detail}` : code);
22
27
  this.code = code;
@@ -27,8 +32,35 @@ export class BelvadorApiError extends Error {
27
32
  this.retryAfter = extra.retryAfter;
28
33
  this.requestId = extra.requestId;
29
34
  this.errors = extra.errors;
35
+ this.approval = extra.approval;
30
36
  }
31
37
  }
38
+ const APPROVAL_STATES = ["pending", "approved", "executed", "rejected", "expired", "failed"];
39
+ const UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
40
+ /** Approval members of a problem body; only an https `/approve/<id>` link is accepted. */
41
+ export function approvalFrom(body) {
42
+ const id = body["approval_id"];
43
+ const url = body["approval_url"];
44
+ const exp = body["expires_at"];
45
+ const state = body["state"];
46
+ if (typeof id !== "string" || !UUID.test(id) || typeof url !== "string" || url.length > 300)
47
+ return undefined;
48
+ let u;
49
+ try {
50
+ u = new URL(url);
51
+ }
52
+ catch {
53
+ return undefined;
54
+ }
55
+ const local = u.protocol === "http:" && (u.hostname === "localhost" || u.hostname === "127.0.0.1");
56
+ if ((u.protocol !== "https:" && !local) || !u.pathname.endsWith(`/approve/${id}`))
57
+ return undefined;
58
+ if (typeof exp !== "string" || Number.isNaN(Date.parse(exp)))
59
+ return undefined;
60
+ if (typeof state !== "string" || !APPROVAL_STATES.includes(state))
61
+ return undefined;
62
+ return { id, url: u.toString(), expiresAt: exp, state: state };
63
+ }
32
64
  const str = (v, max = 500) => typeof v === "string" && v ? v.slice(0, max) : undefined;
33
65
  /** An error answer → BelvadorApiError (problem+json fields, scope challenge, Retry-After). */
34
66
  export async function errorFrom(res) {
@@ -69,5 +101,8 @@ export async function errorFrom(res) {
69
101
  extra.requestId = requestId;
70
102
  if (errors?.length)
71
103
  extra.errors = errors;
104
+ const approval = approvalFrom(body);
105
+ if (approval)
106
+ extra.approval = approval;
72
107
  return new BelvadorApiError(code, res.status, extra);
73
108
  }
package/dist/index.d.ts CHANGED
@@ -1,3 +1,3 @@
1
1
  export { CLIENT_VERSION, createClient, DEFAULT_BASE_URL, requestParts, SCOPES_HEADER, TOKEN_PATTERN, type ApiResult, type BelvadorClient, type CallOptions, type ClientOptions, type Page, type PagedOperationId, } from "./client.js";
2
- export { BelvadorApiError } from "./errors.js";
2
+ export { BelvadorApiError, type Approval, type ApprovalState } from "./errors.js";
3
3
  export { API_VERSION, OPERATIONS, type HttpMethod, type OperationId, type OperationMeta, type OperationParams, } from "./operations.gen.js";
@@ -26,6 +26,9 @@ export declare const NODE_REFUSAL_STATUS: {
26
26
  readonly QUERY_WINDOW_REQUIRED: 400;
27
27
  readonly QUERY_WINDOW_TOO_LARGE: 400;
28
28
  readonly INVALID_INPUT: 400;
29
+ readonly OCCURRENCE_LIMIT: 409;
30
+ readonly OCCURRENCE_DUE_INVALID: 400;
31
+ readonly MONITOR_SELECTOR_INVALID: 400;
29
32
  readonly UNAVAILABLE: 503;
30
33
  };
31
34
  export type NodeRefusalCode = keyof typeof NODE_REFUSAL_STATUS;
@@ -66,6 +66,9 @@ export const NODE_REFUSAL_STATUS = {
66
66
  QUERY_WINDOW_REQUIRED: 400,
67
67
  QUERY_WINDOW_TOO_LARGE: 400,
68
68
  INVALID_INPUT: 400,
69
+ OCCURRENCE_LIMIT: 409,
70
+ OCCURRENCE_DUE_INVALID: 400,
71
+ MONITOR_SELECTOR_INVALID: 400,
69
72
  UNAVAILABLE: 503,
70
73
  };
71
74
  const refuse = (code, extra = {}) => ({
@@ -85,6 +88,14 @@ export function nodeRefusal(status, error) {
85
88
  return refuse("NODE_BUSY", { retryAfter: 2 });
86
89
  if (error === "query_timeout")
87
90
  return refuse("QUERY_TIMEOUT");
91
+ if (error === "occurrence_limit")
92
+ return refuse("OCCURRENCE_LIMIT");
93
+ if (error === "due_out_of_range")
94
+ return refuse("OCCURRENCE_DUE_INVALID");
95
+ if (error === "selector_invalid")
96
+ return refuse("MONITOR_SELECTOR_INVALID");
97
+ if (error === "unknown_monitor")
98
+ return refuse("NOT_FOUND");
88
99
  if (status === 503 || status === 504 || status === 502)
89
100
  return refuse("NODE_OFFLINE");
90
101
  if (status === 400 || status === 422) {
@@ -110,6 +110,20 @@ export declare const OPERATIONS: {
110
110
  readonly node: null;
111
111
  readonly defaults: {};
112
112
  };
113
+ readonly "approvals.get": {
114
+ readonly method: "GET";
115
+ readonly path: "/v1/approvals/{approval_id}";
116
+ readonly pathParams: readonly ["approval_id"];
117
+ readonly scope: "org:read";
118
+ readonly kind: "read";
119
+ readonly sensitivity: "normal";
120
+ readonly idempotency: "none";
121
+ readonly ifMatch: false;
122
+ readonly paged: false;
123
+ readonly status: 200;
124
+ readonly node: null;
125
+ readonly defaults: {};
126
+ };
113
127
  readonly "audit.list": {
114
128
  readonly method: "GET";
115
129
  readonly path: "/v1/audit-log";
@@ -269,6 +283,132 @@ export declare const OPERATIONS: {
269
283
  };
270
284
  readonly defaults: {};
271
285
  };
286
+ readonly "incident_rules.delete": {
287
+ readonly method: "DELETE";
288
+ readonly path: "/v1/incident-rules/{rule_id}";
289
+ readonly pathParams: readonly ["rule_id"];
290
+ readonly scope: "alerts:write";
291
+ readonly kind: "write";
292
+ readonly sensitivity: "normal";
293
+ readonly idempotency: "none";
294
+ readonly ifMatch: false;
295
+ readonly paged: false;
296
+ readonly status: 200;
297
+ readonly node: null;
298
+ readonly defaults: {};
299
+ };
300
+ readonly "incident_rules.list": {
301
+ readonly method: "GET";
302
+ readonly path: "/v1/incident-rules";
303
+ readonly pathParams: readonly [];
304
+ readonly scope: "alerts:read";
305
+ readonly kind: "read";
306
+ readonly sensitivity: "normal";
307
+ readonly idempotency: "none";
308
+ readonly ifMatch: false;
309
+ readonly paged: false;
310
+ readonly status: 200;
311
+ readonly node: null;
312
+ readonly defaults: {};
313
+ };
314
+ readonly "incident_rules.save": {
315
+ readonly method: "POST";
316
+ readonly path: "/v1/incident-rules";
317
+ readonly pathParams: readonly [];
318
+ readonly scope: "alerts:write";
319
+ readonly kind: "write";
320
+ readonly sensitivity: "normal";
321
+ readonly idempotency: "optional";
322
+ readonly ifMatch: false;
323
+ readonly paged: false;
324
+ readonly status: 200;
325
+ readonly node: null;
326
+ readonly defaults: {};
327
+ };
328
+ readonly "incidents.acknowledge": {
329
+ readonly method: "POST";
330
+ readonly path: "/v1/incidents/{incident_id}/ack";
331
+ readonly pathParams: readonly ["incident_id"];
332
+ readonly scope: "incidents:write";
333
+ readonly kind: "write";
334
+ readonly sensitivity: "normal";
335
+ readonly idempotency: "optional";
336
+ readonly ifMatch: false;
337
+ readonly paged: false;
338
+ readonly status: 200;
339
+ readonly node: null;
340
+ readonly defaults: {};
341
+ };
342
+ readonly "incidents.get": {
343
+ readonly method: "GET";
344
+ readonly path: "/v1/incidents/{incident_id}";
345
+ readonly pathParams: readonly ["incident_id"];
346
+ readonly scope: "incidents:read";
347
+ readonly kind: "read";
348
+ readonly sensitivity: "normal";
349
+ readonly idempotency: "none";
350
+ readonly ifMatch: false;
351
+ readonly paged: false;
352
+ readonly status: 200;
353
+ readonly node: null;
354
+ readonly defaults: {};
355
+ };
356
+ readonly "incidents.list": {
357
+ readonly method: "GET";
358
+ readonly path: "/v1/incidents";
359
+ readonly pathParams: readonly [];
360
+ readonly scope: "incidents:read";
361
+ readonly kind: "read";
362
+ readonly sensitivity: "normal";
363
+ readonly idempotency: "none";
364
+ readonly ifMatch: false;
365
+ readonly paged: true;
366
+ readonly status: 200;
367
+ readonly node: null;
368
+ readonly defaults: {};
369
+ };
370
+ readonly "incidents.note": {
371
+ readonly method: "POST";
372
+ readonly path: "/v1/incidents/{incident_id}/notes";
373
+ readonly pathParams: readonly ["incident_id"];
374
+ readonly scope: "incidents:write";
375
+ readonly kind: "write";
376
+ readonly sensitivity: "normal";
377
+ readonly idempotency: "optional";
378
+ readonly ifMatch: false;
379
+ readonly paged: false;
380
+ readonly status: 200;
381
+ readonly node: null;
382
+ readonly defaults: {};
383
+ };
384
+ readonly "incidents.resolve": {
385
+ readonly method: "POST";
386
+ readonly path: "/v1/incidents/{incident_id}/resolve";
387
+ readonly pathParams: readonly ["incident_id"];
388
+ readonly scope: "incidents:write";
389
+ readonly kind: "write";
390
+ readonly sensitivity: "normal";
391
+ readonly idempotency: "optional";
392
+ readonly ifMatch: false;
393
+ readonly paged: false;
394
+ readonly status: 200;
395
+ readonly node: null;
396
+ readonly defaults: {};
397
+ };
398
+ readonly "incidents.update": {
399
+ readonly method: "PATCH";
400
+ readonly path: "/v1/incidents/{incident_id}";
401
+ readonly pathParams: readonly ["incident_id"];
402
+ readonly scope: "incidents:write";
403
+ readonly kind: "write";
404
+ readonly sensitivity: "normal";
405
+ readonly idempotency: "none";
406
+ readonly ifMatch: false;
407
+ readonly paged: false;
408
+ readonly status: 200;
409
+ readonly node: null;
410
+ readonly defaults: {};
411
+ };
272
412
  readonly "ingest_keys.create": {
273
413
  readonly method: "POST";
274
414
  readonly path: "/v1/projects/{project_id}/ingest-keys";
@@ -506,6 +646,62 @@ export declare const OPERATIONS: {
506
646
  };
507
647
  readonly defaults: {};
508
648
  };
649
+ readonly "maintenance.create": {
650
+ readonly method: "POST";
651
+ readonly path: "/v1/maintenance-windows";
652
+ readonly pathParams: readonly [];
653
+ readonly scope: "monitors:write";
654
+ readonly kind: "write";
655
+ readonly sensitivity: "normal";
656
+ readonly idempotency: "required";
657
+ readonly ifMatch: false;
658
+ readonly paged: false;
659
+ readonly status: 201;
660
+ readonly node: null;
661
+ readonly defaults: {};
662
+ };
663
+ readonly "maintenance.delete": {
664
+ readonly method: "DELETE";
665
+ readonly path: "/v1/maintenance-windows/{window_id}";
666
+ readonly pathParams: readonly ["window_id"];
667
+ readonly scope: "monitors:write";
668
+ readonly kind: "write";
669
+ readonly sensitivity: "normal";
670
+ readonly idempotency: "none";
671
+ readonly ifMatch: false;
672
+ readonly paged: false;
673
+ readonly status: 200;
674
+ readonly node: null;
675
+ readonly defaults: {};
676
+ };
677
+ readonly "maintenance.list": {
678
+ readonly method: "GET";
679
+ readonly path: "/v1/maintenance-windows";
680
+ readonly pathParams: readonly [];
681
+ readonly scope: "monitors:read";
682
+ readonly kind: "read";
683
+ readonly sensitivity: "normal";
684
+ readonly idempotency: "none";
685
+ readonly ifMatch: false;
686
+ readonly paged: true;
687
+ readonly status: 200;
688
+ readonly node: null;
689
+ readonly defaults: {};
690
+ };
691
+ readonly "maintenance.update": {
692
+ readonly method: "PATCH";
693
+ readonly path: "/v1/maintenance-windows/{window_id}";
694
+ readonly pathParams: readonly ["window_id"];
695
+ readonly scope: "monitors:write";
696
+ readonly kind: "write";
697
+ readonly sensitivity: "normal";
698
+ readonly idempotency: "none";
699
+ readonly ifMatch: false;
700
+ readonly paged: false;
701
+ readonly status: 200;
702
+ readonly node: null;
703
+ readonly defaults: {};
704
+ };
509
705
  readonly "members.change_role": {
510
706
  readonly method: "PATCH";
511
707
  readonly path: "/v1/members/{user_id}";
@@ -548,6 +744,22 @@ export declare const OPERATIONS: {
548
744
  readonly node: null;
549
745
  readonly defaults: {};
550
746
  };
747
+ readonly "monitors.backtest": {
748
+ readonly method: "POST";
749
+ readonly path: "/v1/monitors/backtest";
750
+ readonly pathParams: readonly [];
751
+ readonly scope: "monitors:read";
752
+ readonly kind: "node";
753
+ readonly sensitivity: "normal";
754
+ readonly idempotency: "none";
755
+ readonly ifMatch: false;
756
+ readonly paged: false;
757
+ readonly status: 200;
758
+ readonly node: {
759
+ readonly path: "q/monitors/backtest";
760
+ };
761
+ readonly defaults: {};
762
+ };
551
763
  readonly "monitors.create": {
552
764
  readonly method: "POST";
553
765
  readonly path: "/v1/monitors";
@@ -618,6 +830,23 @@ export declare const OPERATIONS: {
618
830
  readonly node: null;
619
831
  readonly defaults: {};
620
832
  };
833
+ readonly "monitors.occurrences": {
834
+ readonly method: "GET";
835
+ readonly path: "/v1/monitors/{monitor_id}/occurrences";
836
+ readonly pathParams: readonly ["monitor_id"];
837
+ readonly scope: "monitors:read";
838
+ readonly kind: "node";
839
+ readonly sensitivity: "normal";
840
+ readonly idempotency: "none";
841
+ readonly ifMatch: false;
842
+ readonly paged: true;
843
+ readonly status: 200;
844
+ readonly node: {
845
+ readonly path: "q/monitors/{monitor_id}/occurrences";
846
+ readonly list: "occurrences";
847
+ };
848
+ readonly defaults: {};
849
+ };
621
850
  readonly "monitors.set_muted": {
622
851
  readonly method: "PUT";
623
852
  readonly path: "/v1/monitors/{monitor_id}/mute";
@@ -646,6 +875,22 @@ export declare const OPERATIONS: {
646
875
  readonly node: null;
647
876
  readonly defaults: {};
648
877
  };
878
+ readonly "monitors.signal": {
879
+ readonly method: "GET";
880
+ readonly path: "/v1/monitors/{monitor_id}/signal";
881
+ readonly pathParams: readonly ["monitor_id"];
882
+ readonly scope: "monitors:read";
883
+ readonly kind: "node";
884
+ readonly sensitivity: "normal";
885
+ readonly idempotency: "none";
886
+ readonly ifMatch: false;
887
+ readonly paged: false;
888
+ readonly status: 200;
889
+ readonly node: {
890
+ readonly path: "q/monitors/{monitor_id}/signal";
891
+ };
892
+ readonly defaults: {};
893
+ };
649
894
  readonly "monitors.update": {
650
895
  readonly method: "PATCH";
651
896
  readonly path: "/v1/monitors/{monitor_id}";
@@ -814,6 +1059,80 @@ export declare const OPERATIONS: {
814
1059
  readonly node: null;
815
1060
  readonly defaults: {};
816
1061
  };
1062
+ readonly "notification_policies.delete": {
1063
+ readonly method: "DELETE";
1064
+ readonly path: "/v1/notification-policies/{policy_id}";
1065
+ readonly pathParams: readonly ["policy_id"];
1066
+ readonly scope: "alerts:write";
1067
+ readonly kind: "write";
1068
+ readonly sensitivity: "normal";
1069
+ readonly idempotency: "none";
1070
+ readonly ifMatch: false;
1071
+ readonly paged: false;
1072
+ readonly status: 200;
1073
+ readonly node: null;
1074
+ readonly defaults: {};
1075
+ };
1076
+ readonly "notification_policies.list": {
1077
+ readonly method: "GET";
1078
+ readonly path: "/v1/notification-policies";
1079
+ readonly pathParams: readonly [];
1080
+ readonly scope: "alerts:read";
1081
+ readonly kind: "read";
1082
+ readonly sensitivity: "normal";
1083
+ readonly idempotency: "none";
1084
+ readonly ifMatch: false;
1085
+ readonly paged: false;
1086
+ readonly status: 200;
1087
+ readonly node: null;
1088
+ readonly defaults: {};
1089
+ };
1090
+ readonly "notification_policies.save": {
1091
+ readonly method: "POST";
1092
+ readonly path: "/v1/notification-policies";
1093
+ readonly pathParams: readonly [];
1094
+ readonly scope: "alerts:write";
1095
+ readonly kind: "write";
1096
+ readonly sensitivity: "normal";
1097
+ readonly idempotency: "optional";
1098
+ readonly ifMatch: false;
1099
+ readonly paged: false;
1100
+ readonly status: 200;
1101
+ readonly node: null;
1102
+ readonly defaults: {};
1103
+ };
1104
+ readonly "occurrences.cancel": {
1105
+ readonly method: "DELETE";
1106
+ readonly path: "/v1/occurrences/{monitor_slug}/{occurrence_id}";
1107
+ readonly pathParams: readonly ["monitor_slug", "occurrence_id"];
1108
+ readonly scope: "monitors:write";
1109
+ readonly kind: "node";
1110
+ readonly sensitivity: "normal";
1111
+ readonly idempotency: "none";
1112
+ readonly ifMatch: false;
1113
+ readonly paged: false;
1114
+ readonly status: 200;
1115
+ readonly node: {
1116
+ readonly path: "w/monitors/occurrences/cancel";
1117
+ };
1118
+ readonly defaults: {};
1119
+ };
1120
+ readonly "occurrences.create": {
1121
+ readonly method: "POST";
1122
+ readonly path: "/v1/occurrences";
1123
+ readonly pathParams: readonly [];
1124
+ readonly scope: "monitors:write";
1125
+ readonly kind: "node";
1126
+ readonly sensitivity: "normal";
1127
+ readonly idempotency: "none";
1128
+ readonly ifMatch: false;
1129
+ readonly paged: false;
1130
+ readonly status: 200;
1131
+ readonly node: {
1132
+ readonly path: "w/monitors/occurrences";
1133
+ };
1134
+ readonly defaults: {};
1135
+ };
817
1136
  readonly "ping_tokens.reset": {
818
1137
  readonly method: "POST";
819
1138
  readonly path: "/v1/monitors/{monitor_id}/ping-tokens/reset";
@@ -1545,8 +1864,9 @@ export interface OperationParams {
1545
1864
  is_enabled: boolean;
1546
1865
  notify_all: boolean;
1547
1866
  destination_ids: Array<string>;
1548
- monitor_kinds?: Array<"missed" | "failed" | "timeout" | "unknown">;
1867
+ monitor_kinds?: Array<"missed" | "failed" | "timeout" | "unknown" | "count" | "assertion" | "deadline" | "stalled">;
1549
1868
  slo_severities?: Array<"page" | "ticket">;
1869
+ policy_id?: string | null;
1550
1870
  };
1551
1871
  /** Turn a rule on or off. */
1552
1872
  "alert_rules.set_enabled": {
@@ -1560,14 +1880,18 @@ export interface OperationParams {
1560
1880
  state?: "open" | "resolved" | "all";
1561
1881
  monitor_id?: string;
1562
1882
  };
1883
+ /** State of an approval this token asked for (admins: any in the workspace): pending, approved, executed, rejected, expired or failed, with its result ids. */
1884
+ "approvals.get": {
1885
+ approval_id: string;
1886
+ };
1563
1887
  /** Audit log, newest first (admins). */
1564
1888
  "audit.list": {
1565
1889
  limit?: number;
1566
1890
  cursor?: string;
1567
1891
  };
1568
- /** Start adding a Telegram, Slack, email or webhook destination; a person enters its secrets. */
1892
+ /** Start adding a Telegram, Slack, email, webhook, PagerDuty or incident.io destination; a person enters its secrets. */
1569
1893
  "destinations.create": {
1570
- provider: "telegram" | "slack" | "email" | "webhook";
1894
+ provider: "telegram" | "slack" | "email" | "webhook" | "pagerduty" | "incident_io";
1571
1895
  name: string;
1572
1896
  project_ids: Array<number>;
1573
1897
  locale: "vi" | "en";
@@ -1614,6 +1938,58 @@ export interface OperationParams {
1614
1938
  issue_id: number;
1615
1939
  cursor?: string;
1616
1940
  };
1941
+ /** Delete an incident rule; open incidents stay as they are. */
1942
+ "incident_rules.delete": {
1943
+ rule_id: string;
1944
+ };
1945
+ /** Rules that turn alerts into incidents: match, grouping, window and recovery wait. */
1946
+ "incident_rules.list": Record<string, never>;
1947
+ /** Create (`rule_id` null) or replace an incident rule. Admins. */
1948
+ "incident_rules.save": {
1949
+ rule_id: string | null;
1950
+ input: {
1951
+ name: string;
1952
+ is_enabled: boolean;
1953
+ position?: number;
1954
+ project_ids: Array<number>;
1955
+ environments: Array<string>;
1956
+ kinds: Array<"monitor" | "uptime" | "slo" | "issue">;
1957
+ min_severity: "critical" | "high" | "medium" | "low";
1958
+ group_by: "monitor" | "project_env";
1959
+ window_minutes: number;
1960
+ recovery_hold_minutes: number;
1961
+ };
1962
+ };
1963
+ /** Take ownership of an open incident; stops its escalation. Members and up. */
1964
+ "incidents.acknowledge": {
1965
+ incident_id: string;
1966
+ };
1967
+ /** One incident with its linked alerts, timeline (notes included) and message deliveries (`accepted` = the provider took it; only a person acknowledges). */
1968
+ "incidents.get": {
1969
+ incident_id: string;
1970
+ };
1971
+ /** Incidents (INC-n): state, severity and peak, owner, linked alert count; newest first. */
1972
+ "incidents.list": {
1973
+ limit?: number;
1974
+ cursor?: string;
1975
+ state?: "active" | "resolved" | "all";
1976
+ };
1977
+ /** Add a note to the incident timeline (plain text, ≤ 2,000 characters). */
1978
+ "incidents.note": {
1979
+ incident_id: string;
1980
+ note: string;
1981
+ };
1982
+ /** Close an incident by hand with a reason (1–500 characters); it is labelled "not verified". */
1983
+ "incidents.resolve": {
1984
+ incident_id: string;
1985
+ note: string;
1986
+ };
1987
+ /** Rename an incident or assign it to a member (`owner_user_id: null` clears it). */
1988
+ "incidents.update": {
1989
+ incident_id: string;
1990
+ title?: string;
1991
+ owner_user_id?: string | null;
1992
+ };
1617
1993
  /** Create an OTLP ingest key (`bvi_`). */
1618
1994
  "ingest_keys.create": {
1619
1995
  project_id: number;
@@ -1762,6 +2138,59 @@ export interface OperationParams {
1762
2138
  order?: "asc" | "desc";
1763
2139
  cursor?: string;
1764
2140
  };
2141
+ /** Hold back monitor notifications during a one-off or weekly window (workspace, projects or monitors); monitors keep evaluating and recording. */
2142
+ "maintenance.create": Record<string, never> & ((Record<string, unknown>) & ({
2143
+ kind: "once";
2144
+ starts_at: string;
2145
+ scope: "workspace" | "project" | "monitor";
2146
+ project_ids: Array<number>;
2147
+ monitor_ids: Array<string>;
2148
+ timezone: string;
2149
+ duration_minutes: number;
2150
+ reason: string;
2151
+ } | {
2152
+ kind: "weekly";
2153
+ weekdays: Array<number>;
2154
+ start_time: string;
2155
+ scope: "workspace" | "project" | "monitor";
2156
+ project_ids: Array<number>;
2157
+ monitor_ids: Array<string>;
2158
+ timezone: string;
2159
+ duration_minutes: number;
2160
+ reason: string;
2161
+ }));
2162
+ /** Delete a maintenance window; notifications resume at once. */
2163
+ "maintenance.delete": {
2164
+ window_id: string;
2165
+ };
2166
+ /** Maintenance windows and whether each is active now. */
2167
+ "maintenance.list": {
2168
+ limit?: number;
2169
+ cursor?: string;
2170
+ };
2171
+ /** Replace a maintenance window's scope, times and reason. */
2172
+ "maintenance.update": {
2173
+ window_id: string;
2174
+ } & ((Record<string, unknown>) & ({
2175
+ kind: "once";
2176
+ starts_at: string;
2177
+ scope: "workspace" | "project" | "monitor";
2178
+ project_ids: Array<number>;
2179
+ monitor_ids: Array<string>;
2180
+ timezone: string;
2181
+ duration_minutes: number;
2182
+ reason: string;
2183
+ } | {
2184
+ kind: "weekly";
2185
+ weekdays: Array<number>;
2186
+ start_time: string;
2187
+ scope: "workspace" | "project" | "monitor";
2188
+ project_ids: Array<number>;
2189
+ monitor_ids: Array<string>;
2190
+ timezone: string;
2191
+ duration_minutes: number;
2192
+ reason: string;
2193
+ }));
1765
2194
  /** Change a member's role. */
1766
2195
  "members.change_role": {
1767
2196
  user_id: string;
@@ -1776,10 +2205,55 @@ export interface OperationParams {
1776
2205
  "members.remove": {
1777
2206
  user_id: string;
1778
2207
  };
1779
- /** Create a cron or heartbeat monitor. A heartbeat monitor returns its ping token once. */
1780
- "monitors.create": {
2208
+ /** How often count/assertion settings would have alerted over the last 30 days of stored data (same rule as the live evaluator). */
2209
+ "monitors.backtest": {
2210
+ project: number;
2211
+ settings: {
2212
+ type: "count";
2213
+ selector: {
2214
+ signal: "event" | "check_in" | "span" | "log";
2215
+ match: Array<{
2216
+ key: string;
2217
+ op: "eq" | "ne" | "lt" | "le" | "gt" | "ge" | "in" | "exists" | "not_exists" | "prefix";
2218
+ value?: string | number | boolean | Array<string>;
2219
+ }>;
2220
+ };
2221
+ window_minutes: number;
2222
+ comparator: "lt" | "gt" | "outside";
2223
+ threshold: number;
2224
+ threshold_high: number | null;
2225
+ missing_data: "alert" | "keep" | "resolve" | "treat_as_zero";
2226
+ environments: Array<string>;
2227
+ severity: "critical" | "high" | "medium" | "low";
2228
+ recovery_threshold: number;
2229
+ } | {
2230
+ type: "assertion";
2231
+ selector: {
2232
+ signal: "event" | "check_in" | "span" | "log";
2233
+ match: Array<{
2234
+ key: string;
2235
+ op: "eq" | "ne" | "lt" | "le" | "gt" | "ge" | "in" | "exists" | "not_exists" | "prefix";
2236
+ value?: string | number | boolean | Array<string>;
2237
+ }>;
2238
+ };
2239
+ assert: Array<{
2240
+ key: string;
2241
+ op: "eq" | "ne" | "lt" | "le" | "gt" | "ge" | "in" | "exists" | "not_exists" | "prefix";
2242
+ value?: string | number | boolean | Array<string>;
2243
+ }>;
2244
+ window_minutes: number;
2245
+ threshold: number;
2246
+ missing_data: "alert" | "keep" | "resolve" | "treat_as_zero";
2247
+ environments: Array<string>;
2248
+ severity: "critical" | "high" | "medium" | "low";
2249
+ recovery_threshold: number;
2250
+ };
2251
+ };
2252
+ /** Create a cron or heartbeat monitor, or a signal monitor (`settings.type`: count, assertion, deadline, progress). A heartbeat monitor returns its ping token once. */
2253
+ "monitors.create": Record<string, never> & (({
1781
2254
  project_id: number;
1782
2255
  slug: string;
2256
+ }) & ({
1783
2257
  name: string;
1784
2258
  mode?: "check_in" | "heartbeat";
1785
2259
  kind: "crontab" | "interval" | "on_demand";
@@ -1797,7 +2271,62 @@ export interface OperationParams {
1797
2271
  failure_threshold: number;
1798
2272
  recovery_threshold: number;
1799
2273
  expected_environments: Array<string>;
1800
- };
2274
+ } | {
2275
+ name: string;
2276
+ settings: {
2277
+ type: "count";
2278
+ selector: {
2279
+ signal: "event" | "check_in" | "span" | "log";
2280
+ match: Array<{
2281
+ key: string;
2282
+ op: "eq" | "ne" | "lt" | "le" | "gt" | "ge" | "in" | "exists" | "not_exists" | "prefix";
2283
+ value?: string | number | boolean | Array<string>;
2284
+ }>;
2285
+ };
2286
+ window_minutes: number;
2287
+ comparator: "lt" | "gt" | "outside";
2288
+ threshold: number;
2289
+ threshold_high: number | null;
2290
+ missing_data: "alert" | "keep" | "resolve" | "treat_as_zero";
2291
+ environments: Array<string>;
2292
+ severity: "critical" | "high" | "medium" | "low";
2293
+ recovery_threshold: number;
2294
+ } | {
2295
+ type: "assertion";
2296
+ selector: {
2297
+ signal: "event" | "check_in" | "span" | "log";
2298
+ match: Array<{
2299
+ key: string;
2300
+ op: "eq" | "ne" | "lt" | "le" | "gt" | "ge" | "in" | "exists" | "not_exists" | "prefix";
2301
+ value?: string | number | boolean | Array<string>;
2302
+ }>;
2303
+ };
2304
+ assert: Array<{
2305
+ key: string;
2306
+ op: "eq" | "ne" | "lt" | "le" | "gt" | "ge" | "in" | "exists" | "not_exists" | "prefix";
2307
+ value?: string | number | boolean | Array<string>;
2308
+ }>;
2309
+ window_minutes: number;
2310
+ threshold: number;
2311
+ missing_data: "alert" | "keep" | "resolve" | "treat_as_zero";
2312
+ environments: Array<string>;
2313
+ severity: "critical" | "high" | "medium" | "low";
2314
+ recovery_threshold: number;
2315
+ } | {
2316
+ type: "deadline";
2317
+ occurrence_grace_minutes: number;
2318
+ progress_timeout_minutes: number | null;
2319
+ environments: Array<string>;
2320
+ severity: "critical" | "high" | "medium" | "low";
2321
+ recovery_threshold: number;
2322
+ } | {
2323
+ type: "progress";
2324
+ progress_timeout_minutes: number;
2325
+ environments: Array<string>;
2326
+ severity: "critical" | "high" | "medium" | "low";
2327
+ recovery_threshold: number;
2328
+ };
2329
+ }));
1801
2330
  /** Delete a monitor; `confirm_slug` must repeat its slug. */
1802
2331
  "monitors.delete": {
1803
2332
  monitor_id: string;
@@ -1811,11 +2340,19 @@ export interface OperationParams {
1811
2340
  "monitors.get": {
1812
2341
  monitor_id: string;
1813
2342
  };
1814
- /** Cron and heartbeat monitors. */
2343
+ /** Monitors of every type (cron, heartbeat, count, assertion, deadline, progress); `type` narrows the list. */
1815
2344
  "monitors.list": {
1816
2345
  limit?: number;
1817
2346
  cursor?: string;
1818
2347
  project_id?: number;
2348
+ type?: "job" | "count" | "assertion" | "deadline" | "progress";
2349
+ };
2350
+ /** Occurrences of a deadline monitor (pending, on time, late, missed, failed, cancelled), newest due first. */
2351
+ "monitors.occurrences": {
2352
+ monitor_id: string;
2353
+ state?: "open" | "finished" | "all";
2354
+ environment?: string;
2355
+ cursor?: string;
1819
2356
  };
1820
2357
  /** Mute or unmute a monitor's alerts. */
1821
2358
  "monitors.set_muted": {
@@ -1827,9 +2364,15 @@ export interface OperationParams {
1827
2364
  monitor_id: string;
1828
2365
  until: string | "forever" | null;
1829
2366
  };
1830
- /** Replace a monitor's schedule, margins and thresholds. */
2367
+ /** A signal monitor's minute counts (count/assertion) for up to 24 h per environment, and its open runs (progress, deadline). */
2368
+ "monitors.signal": {
2369
+ monitor_id: string;
2370
+ hours?: number;
2371
+ };
2372
+ /** Replace a monitor's schedule, margins and thresholds, or a signal monitor's settings (the type stays). */
1831
2373
  "monitors.update": {
1832
2374
  monitor_id: string;
2375
+ } & ((Record<string, unknown>) & ({
1833
2376
  name: string;
1834
2377
  mode?: "check_in" | "heartbeat";
1835
2378
  kind: "crontab" | "interval" | "on_demand";
@@ -1847,7 +2390,62 @@ export interface OperationParams {
1847
2390
  failure_threshold: number;
1848
2391
  recovery_threshold: number;
1849
2392
  expected_environments: Array<string>;
1850
- };
2393
+ } | {
2394
+ name: string;
2395
+ settings: {
2396
+ type: "count";
2397
+ selector: {
2398
+ signal: "event" | "check_in" | "span" | "log";
2399
+ match: Array<{
2400
+ key: string;
2401
+ op: "eq" | "ne" | "lt" | "le" | "gt" | "ge" | "in" | "exists" | "not_exists" | "prefix";
2402
+ value?: string | number | boolean | Array<string>;
2403
+ }>;
2404
+ };
2405
+ window_minutes: number;
2406
+ comparator: "lt" | "gt" | "outside";
2407
+ threshold: number;
2408
+ threshold_high: number | null;
2409
+ missing_data: "alert" | "keep" | "resolve" | "treat_as_zero";
2410
+ environments: Array<string>;
2411
+ severity: "critical" | "high" | "medium" | "low";
2412
+ recovery_threshold: number;
2413
+ } | {
2414
+ type: "assertion";
2415
+ selector: {
2416
+ signal: "event" | "check_in" | "span" | "log";
2417
+ match: Array<{
2418
+ key: string;
2419
+ op: "eq" | "ne" | "lt" | "le" | "gt" | "ge" | "in" | "exists" | "not_exists" | "prefix";
2420
+ value?: string | number | boolean | Array<string>;
2421
+ }>;
2422
+ };
2423
+ assert: Array<{
2424
+ key: string;
2425
+ op: "eq" | "ne" | "lt" | "le" | "gt" | "ge" | "in" | "exists" | "not_exists" | "prefix";
2426
+ value?: string | number | boolean | Array<string>;
2427
+ }>;
2428
+ window_minutes: number;
2429
+ threshold: number;
2430
+ missing_data: "alert" | "keep" | "resolve" | "treat_as_zero";
2431
+ environments: Array<string>;
2432
+ severity: "critical" | "high" | "medium" | "low";
2433
+ recovery_threshold: number;
2434
+ } | {
2435
+ type: "deadline";
2436
+ occurrence_grace_minutes: number;
2437
+ progress_timeout_minutes: number | null;
2438
+ environments: Array<string>;
2439
+ severity: "critical" | "high" | "medium" | "low";
2440
+ recovery_threshold: number;
2441
+ } | {
2442
+ type: "progress";
2443
+ progress_timeout_minutes: number;
2444
+ environments: Array<string>;
2445
+ severity: "critical" | "high" | "medium" | "low";
2446
+ recovery_threshold: number;
2447
+ };
2448
+ }));
1851
2449
  /** Start a backup now (at most once per 10 minutes). */
1852
2450
  "node.backup_now": Record<string, never>;
1853
2451
  /** Cancel a scheduled node deletion. */
@@ -1891,6 +2489,48 @@ export interface OperationParams {
1891
2489
  "node.upgrade": {
1892
2490
  node_id: string;
1893
2491
  };
2492
+ /** Delete a policy (not the default); its rules fall back to the default policy. */
2493
+ "notification_policies.delete": {
2494
+ policy_id: string;
2495
+ };
2496
+ /** Notification policies: quiet hours, digest, fallback chain and escalation. */
2497
+ "notification_policies.list": Record<string, never>;
2498
+ /** Create (`policy_id` null) or replace a policy. Critical and high are never held; chains use existing destinations only. Admins. */
2499
+ "notification_policies.save": {
2500
+ policy_id: string | null;
2501
+ is_default: boolean;
2502
+ input: {
2503
+ name: string;
2504
+ timezone: string;
2505
+ quiet_hours: {
2506
+ days: Array<number>;
2507
+ start: string;
2508
+ end: string;
2509
+ } | null;
2510
+ quiet_severities: Array<"medium" | "low">;
2511
+ digest: "off" | "hourly" | "daily";
2512
+ digest_at: string | null;
2513
+ digest_severities: Array<"medium" | "low">;
2514
+ fallback: Array<string>;
2515
+ escalate_after_minutes: number | null;
2516
+ escalation: Array<string>;
2517
+ };
2518
+ };
2519
+ /** Cancel a pending occurrence (the app moved or dropped the job); a cancelled occurrence never alerts. */
2520
+ "occurrences.cancel": {
2521
+ monitor_slug: string;
2522
+ occurrence_id: string;
2523
+ project: number;
2524
+ environment?: string;
2525
+ };
2526
+ /** Register one run a deadline monitor expects (`due_at` within 35 days); the same id again moves its due time while it is pending. */
2527
+ "occurrences.create": {
2528
+ project: number;
2529
+ monitor_slug: string;
2530
+ occurrence_id: string;
2531
+ due_at: string;
2532
+ environment?: string;
2533
+ };
1894
2534
  /** Suspected leak: stop every live ping token and issue a new one. */
1895
2535
  "ping_tokens.reset": {
1896
2536
  monitor_id: string;
@@ -86,6 +86,20 @@ export const OPERATIONS = {
86
86
  node: null,
87
87
  defaults: {},
88
88
  },
89
+ "approvals.get": {
90
+ method: "GET",
91
+ path: "/v1/approvals/{approval_id}",
92
+ pathParams: ["approval_id"],
93
+ scope: "org:read",
94
+ kind: "read",
95
+ sensitivity: "normal",
96
+ idempotency: "none",
97
+ ifMatch: false,
98
+ paged: false,
99
+ status: 200,
100
+ node: null,
101
+ defaults: {},
102
+ },
89
103
  "audit.list": {
90
104
  method: "GET",
91
105
  path: "/v1/audit-log",
@@ -240,6 +254,132 @@ export const OPERATIONS = {
240
254
  node: { path: "q/issues/{issue_id}/events", list: "events" },
241
255
  defaults: {},
242
256
  },
257
+ "incident_rules.delete": {
258
+ method: "DELETE",
259
+ path: "/v1/incident-rules/{rule_id}",
260
+ pathParams: ["rule_id"],
261
+ scope: "alerts:write",
262
+ kind: "write",
263
+ sensitivity: "normal",
264
+ idempotency: "none",
265
+ ifMatch: false,
266
+ paged: false,
267
+ status: 200,
268
+ node: null,
269
+ defaults: {},
270
+ },
271
+ "incident_rules.list": {
272
+ method: "GET",
273
+ path: "/v1/incident-rules",
274
+ pathParams: [],
275
+ scope: "alerts:read",
276
+ kind: "read",
277
+ sensitivity: "normal",
278
+ idempotency: "none",
279
+ ifMatch: false,
280
+ paged: false,
281
+ status: 200,
282
+ node: null,
283
+ defaults: {},
284
+ },
285
+ "incident_rules.save": {
286
+ method: "POST",
287
+ path: "/v1/incident-rules",
288
+ pathParams: [],
289
+ scope: "alerts:write",
290
+ kind: "write",
291
+ sensitivity: "normal",
292
+ idempotency: "optional",
293
+ ifMatch: false,
294
+ paged: false,
295
+ status: 200,
296
+ node: null,
297
+ defaults: {},
298
+ },
299
+ "incidents.acknowledge": {
300
+ method: "POST",
301
+ path: "/v1/incidents/{incident_id}/ack",
302
+ pathParams: ["incident_id"],
303
+ scope: "incidents:write",
304
+ kind: "write",
305
+ sensitivity: "normal",
306
+ idempotency: "optional",
307
+ ifMatch: false,
308
+ paged: false,
309
+ status: 200,
310
+ node: null,
311
+ defaults: {},
312
+ },
313
+ "incidents.get": {
314
+ method: "GET",
315
+ path: "/v1/incidents/{incident_id}",
316
+ pathParams: ["incident_id"],
317
+ scope: "incidents:read",
318
+ kind: "read",
319
+ sensitivity: "normal",
320
+ idempotency: "none",
321
+ ifMatch: false,
322
+ paged: false,
323
+ status: 200,
324
+ node: null,
325
+ defaults: {},
326
+ },
327
+ "incidents.list": {
328
+ method: "GET",
329
+ path: "/v1/incidents",
330
+ pathParams: [],
331
+ scope: "incidents:read",
332
+ kind: "read",
333
+ sensitivity: "normal",
334
+ idempotency: "none",
335
+ ifMatch: false,
336
+ paged: true,
337
+ status: 200,
338
+ node: null,
339
+ defaults: {},
340
+ },
341
+ "incidents.note": {
342
+ method: "POST",
343
+ path: "/v1/incidents/{incident_id}/notes",
344
+ pathParams: ["incident_id"],
345
+ scope: "incidents:write",
346
+ kind: "write",
347
+ sensitivity: "normal",
348
+ idempotency: "optional",
349
+ ifMatch: false,
350
+ paged: false,
351
+ status: 200,
352
+ node: null,
353
+ defaults: {},
354
+ },
355
+ "incidents.resolve": {
356
+ method: "POST",
357
+ path: "/v1/incidents/{incident_id}/resolve",
358
+ pathParams: ["incident_id"],
359
+ scope: "incidents:write",
360
+ kind: "write",
361
+ sensitivity: "normal",
362
+ idempotency: "optional",
363
+ ifMatch: false,
364
+ paged: false,
365
+ status: 200,
366
+ node: null,
367
+ defaults: {},
368
+ },
369
+ "incidents.update": {
370
+ method: "PATCH",
371
+ path: "/v1/incidents/{incident_id}",
372
+ pathParams: ["incident_id"],
373
+ scope: "incidents:write",
374
+ kind: "write",
375
+ sensitivity: "normal",
376
+ idempotency: "none",
377
+ ifMatch: false,
378
+ paged: false,
379
+ status: 200,
380
+ node: null,
381
+ defaults: {},
382
+ },
243
383
  "ingest_keys.create": {
244
384
  method: "POST",
245
385
  path: "/v1/projects/{project_id}/ingest-keys",
@@ -450,6 +590,62 @@ export const OPERATIONS = {
450
590
  node: { path: "q/logs", list: "logs", window: true },
451
591
  defaults: {},
452
592
  },
593
+ "maintenance.create": {
594
+ method: "POST",
595
+ path: "/v1/maintenance-windows",
596
+ pathParams: [],
597
+ scope: "monitors:write",
598
+ kind: "write",
599
+ sensitivity: "normal",
600
+ idempotency: "required",
601
+ ifMatch: false,
602
+ paged: false,
603
+ status: 201,
604
+ node: null,
605
+ defaults: {},
606
+ },
607
+ "maintenance.delete": {
608
+ method: "DELETE",
609
+ path: "/v1/maintenance-windows/{window_id}",
610
+ pathParams: ["window_id"],
611
+ scope: "monitors:write",
612
+ kind: "write",
613
+ sensitivity: "normal",
614
+ idempotency: "none",
615
+ ifMatch: false,
616
+ paged: false,
617
+ status: 200,
618
+ node: null,
619
+ defaults: {},
620
+ },
621
+ "maintenance.list": {
622
+ method: "GET",
623
+ path: "/v1/maintenance-windows",
624
+ pathParams: [],
625
+ scope: "monitors:read",
626
+ kind: "read",
627
+ sensitivity: "normal",
628
+ idempotency: "none",
629
+ ifMatch: false,
630
+ paged: true,
631
+ status: 200,
632
+ node: null,
633
+ defaults: {},
634
+ },
635
+ "maintenance.update": {
636
+ method: "PATCH",
637
+ path: "/v1/maintenance-windows/{window_id}",
638
+ pathParams: ["window_id"],
639
+ scope: "monitors:write",
640
+ kind: "write",
641
+ sensitivity: "normal",
642
+ idempotency: "none",
643
+ ifMatch: false,
644
+ paged: false,
645
+ status: 200,
646
+ node: null,
647
+ defaults: {},
648
+ },
453
649
  "members.change_role": {
454
650
  method: "PATCH",
455
651
  path: "/v1/members/{user_id}",
@@ -492,6 +688,20 @@ export const OPERATIONS = {
492
688
  node: null,
493
689
  defaults: {},
494
690
  },
691
+ "monitors.backtest": {
692
+ method: "POST",
693
+ path: "/v1/monitors/backtest",
694
+ pathParams: [],
695
+ scope: "monitors:read",
696
+ kind: "node",
697
+ sensitivity: "normal",
698
+ idempotency: "none",
699
+ ifMatch: false,
700
+ paged: false,
701
+ status: 200,
702
+ node: { path: "q/monitors/backtest" },
703
+ defaults: {},
704
+ },
495
705
  "monitors.create": {
496
706
  method: "POST",
497
707
  path: "/v1/monitors",
@@ -562,6 +772,20 @@ export const OPERATIONS = {
562
772
  node: null,
563
773
  defaults: {},
564
774
  },
775
+ "monitors.occurrences": {
776
+ method: "GET",
777
+ path: "/v1/monitors/{monitor_id}/occurrences",
778
+ pathParams: ["monitor_id"],
779
+ scope: "monitors:read",
780
+ kind: "node",
781
+ sensitivity: "normal",
782
+ idempotency: "none",
783
+ ifMatch: false,
784
+ paged: true,
785
+ status: 200,
786
+ node: { path: "q/monitors/{monitor_id}/occurrences", list: "occurrences" },
787
+ defaults: {},
788
+ },
565
789
  "monitors.set_muted": {
566
790
  method: "PUT",
567
791
  path: "/v1/monitors/{monitor_id}/mute",
@@ -590,6 +814,20 @@ export const OPERATIONS = {
590
814
  node: null,
591
815
  defaults: {},
592
816
  },
817
+ "monitors.signal": {
818
+ method: "GET",
819
+ path: "/v1/monitors/{monitor_id}/signal",
820
+ pathParams: ["monitor_id"],
821
+ scope: "monitors:read",
822
+ kind: "node",
823
+ sensitivity: "normal",
824
+ idempotency: "none",
825
+ ifMatch: false,
826
+ paged: false,
827
+ status: 200,
828
+ node: { path: "q/monitors/{monitor_id}/signal" },
829
+ defaults: {},
830
+ },
593
831
  "monitors.update": {
594
832
  method: "PATCH",
595
833
  path: "/v1/monitors/{monitor_id}",
@@ -758,6 +996,76 @@ export const OPERATIONS = {
758
996
  node: null,
759
997
  defaults: {},
760
998
  },
999
+ "notification_policies.delete": {
1000
+ method: "DELETE",
1001
+ path: "/v1/notification-policies/{policy_id}",
1002
+ pathParams: ["policy_id"],
1003
+ scope: "alerts:write",
1004
+ kind: "write",
1005
+ sensitivity: "normal",
1006
+ idempotency: "none",
1007
+ ifMatch: false,
1008
+ paged: false,
1009
+ status: 200,
1010
+ node: null,
1011
+ defaults: {},
1012
+ },
1013
+ "notification_policies.list": {
1014
+ method: "GET",
1015
+ path: "/v1/notification-policies",
1016
+ pathParams: [],
1017
+ scope: "alerts:read",
1018
+ kind: "read",
1019
+ sensitivity: "normal",
1020
+ idempotency: "none",
1021
+ ifMatch: false,
1022
+ paged: false,
1023
+ status: 200,
1024
+ node: null,
1025
+ defaults: {},
1026
+ },
1027
+ "notification_policies.save": {
1028
+ method: "POST",
1029
+ path: "/v1/notification-policies",
1030
+ pathParams: [],
1031
+ scope: "alerts:write",
1032
+ kind: "write",
1033
+ sensitivity: "normal",
1034
+ idempotency: "optional",
1035
+ ifMatch: false,
1036
+ paged: false,
1037
+ status: 200,
1038
+ node: null,
1039
+ defaults: {},
1040
+ },
1041
+ "occurrences.cancel": {
1042
+ method: "DELETE",
1043
+ path: "/v1/occurrences/{monitor_slug}/{occurrence_id}",
1044
+ pathParams: ["monitor_slug", "occurrence_id"],
1045
+ scope: "monitors:write",
1046
+ kind: "node",
1047
+ sensitivity: "normal",
1048
+ idempotency: "none",
1049
+ ifMatch: false,
1050
+ paged: false,
1051
+ status: 200,
1052
+ node: { path: "w/monitors/occurrences/cancel" },
1053
+ defaults: {},
1054
+ },
1055
+ "occurrences.create": {
1056
+ method: "POST",
1057
+ path: "/v1/occurrences",
1058
+ pathParams: [],
1059
+ scope: "monitors:write",
1060
+ kind: "node",
1061
+ sensitivity: "normal",
1062
+ idempotency: "none",
1063
+ ifMatch: false,
1064
+ paged: false,
1065
+ status: 200,
1066
+ node: { path: "w/monitors/occurrences" },
1067
+ defaults: {},
1068
+ },
761
1069
  "ping_tokens.reset": {
762
1070
  method: "POST",
763
1071
  path: "/v1/monitors/{monitor_id}/ping-tokens/reset",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@belvador/api",
3
- "version": "0.1.0",
3
+ "version": "0.3.0",
4
4
  "description": "Typed client for the Belvador API (api.belvador.dev, OpenAPI 3.1): every operation by operationId, problem+json errors, retries, and node reads straight from the edge with short-lived tickets.",
5
5
  "license": "MIT",
6
6
  "author": "Belvador (https://belvador.dev)",