@nasebanal/cli 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 +123 -4
- package/dist/apis.js +1 -0
- package/dist/index.js +9 -1
- package/dist/loginPage.js +112 -0
- package/dist/logo.js +7 -0
- package/dist/oauth.js +13 -5
- package/dist/reports/ci.js +59 -0
- package/dist/reports/csv.js +56 -0
- package/dist/reports/junit.js +119 -0
- package/dist/reports/locust.js +68 -0
- package/dist/reports/specmatic.js +69 -0
- package/dist/reports/upload.js +335 -0
- package/package.json +1 -1
- package/specs/account.yaml +484 -298
- package/specs/app-template.yaml +64 -62
- package/specs/assurance.yaml +1730 -0
- package/specs/recorder.yaml +375 -422
- package/specs/target.yaml +355 -363
|
@@ -0,0 +1,1730 @@
|
|
|
1
|
+
openapi: 3.0.3
|
|
2
|
+
info:
|
|
3
|
+
title: NASEBANAL - Assurance API
|
|
4
|
+
description: "Backend of NASEBANAL Assurance (quality assurance for APIs and web apps, under NASEBANAL Evolution). Authenticates users via Auth0 JWT and Personal Access Tokens (PAT) and integrates with the Account API. External monitoring: register URLs to be probed on an interval, then read availability reports. Test results: report the normalised result of each CI/CD job into a named project (typically one per repository), then read its runs and suites. Every response is wrapped as `{ success, data }` (or `{ success: false, error }`)."
|
|
5
|
+
version: 1.0.0
|
|
6
|
+
contact:
|
|
7
|
+
name: NASEBANAL
|
|
8
|
+
url: https://www.nasebanal.com
|
|
9
|
+
servers:
|
|
10
|
+
- url: http://localhost:8791
|
|
11
|
+
description: Local dev (wrangler dev)
|
|
12
|
+
- url: https://api.assurance.nasebanal.com
|
|
13
|
+
description: Production
|
|
14
|
+
security:
|
|
15
|
+
- BearerAuth: []
|
|
16
|
+
tags:
|
|
17
|
+
- name: Health
|
|
18
|
+
description: Health check endpoints
|
|
19
|
+
- name: User
|
|
20
|
+
description: User profile endpoints
|
|
21
|
+
- name: Monitors
|
|
22
|
+
description: "External monitoring: URLs probed on an interval"
|
|
23
|
+
- name: Reports
|
|
24
|
+
description: Availability reports built from daily rollups and incidents
|
|
25
|
+
- name: Projects
|
|
26
|
+
description: "Test results reported from CI/CD: named projects (typically one per repository), one run per pipeline run, one suite result per job"
|
|
27
|
+
- name: Contracts
|
|
28
|
+
description: "Outsourcing contracts: deliverables tied to projects, documents and the SLA clause"
|
|
29
|
+
paths:
|
|
30
|
+
/api/v1/health:
|
|
31
|
+
get:
|
|
32
|
+
tags:
|
|
33
|
+
- Health
|
|
34
|
+
operationId: getHealth
|
|
35
|
+
summary: Health check
|
|
36
|
+
description: Returns the health status of the API.
|
|
37
|
+
security: []
|
|
38
|
+
responses:
|
|
39
|
+
"200":
|
|
40
|
+
description: API is healthy
|
|
41
|
+
content:
|
|
42
|
+
application/json:
|
|
43
|
+
schema:
|
|
44
|
+
type: object
|
|
45
|
+
properties:
|
|
46
|
+
status:
|
|
47
|
+
type: string
|
|
48
|
+
example: ok
|
|
49
|
+
timestamp:
|
|
50
|
+
type: string
|
|
51
|
+
format: date-time
|
|
52
|
+
/api/v1/me:
|
|
53
|
+
get:
|
|
54
|
+
tags:
|
|
55
|
+
- User
|
|
56
|
+
operationId: getCurrentUser
|
|
57
|
+
summary: Get current user profile
|
|
58
|
+
description: Returns the authenticated user's profile information from the Account API.
|
|
59
|
+
responses:
|
|
60
|
+
"200":
|
|
61
|
+
description: User profile
|
|
62
|
+
content:
|
|
63
|
+
application/json:
|
|
64
|
+
schema:
|
|
65
|
+
$ref: "#/components/schemas/UserResponse"
|
|
66
|
+
"401":
|
|
67
|
+
$ref: "#/components/responses/Unauthorized"
|
|
68
|
+
/api/v1/monitors:
|
|
69
|
+
get:
|
|
70
|
+
tags:
|
|
71
|
+
- Monitors
|
|
72
|
+
operationId: listMonitors
|
|
73
|
+
summary: List monitors
|
|
74
|
+
description: Monitors owned by the caller, newest first, each with its 7-day uptime.
|
|
75
|
+
responses:
|
|
76
|
+
"200":
|
|
77
|
+
description: Monitors
|
|
78
|
+
content:
|
|
79
|
+
application/json:
|
|
80
|
+
schema:
|
|
81
|
+
type: object
|
|
82
|
+
required:
|
|
83
|
+
- success
|
|
84
|
+
- data
|
|
85
|
+
properties:
|
|
86
|
+
success:
|
|
87
|
+
type: boolean
|
|
88
|
+
example: true
|
|
89
|
+
data:
|
|
90
|
+
type: object
|
|
91
|
+
required:
|
|
92
|
+
- data
|
|
93
|
+
- total
|
|
94
|
+
- limit
|
|
95
|
+
properties:
|
|
96
|
+
data:
|
|
97
|
+
type: array
|
|
98
|
+
items:
|
|
99
|
+
$ref: "#/components/schemas/MonitorWithUptime"
|
|
100
|
+
total:
|
|
101
|
+
type: integer
|
|
102
|
+
limit:
|
|
103
|
+
type: integer
|
|
104
|
+
description: Maximum monitors per user
|
|
105
|
+
"401":
|
|
106
|
+
$ref: "#/components/responses/Unauthorized"
|
|
107
|
+
"403":
|
|
108
|
+
$ref: "#/components/responses/Forbidden"
|
|
109
|
+
parameters:
|
|
110
|
+
- $ref: "#/components/parameters/ActiveOrganization"
|
|
111
|
+
post:
|
|
112
|
+
tags:
|
|
113
|
+
- Monitors
|
|
114
|
+
operationId: createMonitor
|
|
115
|
+
summary: Create a monitor
|
|
116
|
+
description: The URL must be a public http(s) host on port 80, 443, 8080 or 8443; private, loopback, link-local and single-label hosts are refused.
|
|
117
|
+
requestBody:
|
|
118
|
+
required: true
|
|
119
|
+
content:
|
|
120
|
+
application/json:
|
|
121
|
+
schema:
|
|
122
|
+
$ref: "#/components/schemas/MonitorCreate"
|
|
123
|
+
responses:
|
|
124
|
+
"201":
|
|
125
|
+
description: Monitor created
|
|
126
|
+
content:
|
|
127
|
+
application/json:
|
|
128
|
+
schema:
|
|
129
|
+
type: object
|
|
130
|
+
required:
|
|
131
|
+
- success
|
|
132
|
+
- data
|
|
133
|
+
properties:
|
|
134
|
+
success:
|
|
135
|
+
type: boolean
|
|
136
|
+
example: true
|
|
137
|
+
data:
|
|
138
|
+
$ref: "#/components/schemas/Monitor"
|
|
139
|
+
"400":
|
|
140
|
+
$ref: "#/components/responses/ValidationError"
|
|
141
|
+
"401":
|
|
142
|
+
$ref: "#/components/responses/Unauthorized"
|
|
143
|
+
"403":
|
|
144
|
+
$ref: "#/components/responses/Forbidden"
|
|
145
|
+
"409":
|
|
146
|
+
description: The per-user monitor limit is reached (`LIMIT_REACHED`)
|
|
147
|
+
content:
|
|
148
|
+
application/json:
|
|
149
|
+
schema:
|
|
150
|
+
$ref: "#/components/schemas/Error"
|
|
151
|
+
parameters:
|
|
152
|
+
- $ref: "#/components/parameters/ActiveOrganization"
|
|
153
|
+
/api/v1/monitors/{id}:
|
|
154
|
+
parameters:
|
|
155
|
+
- name: id
|
|
156
|
+
in: path
|
|
157
|
+
required: true
|
|
158
|
+
schema:
|
|
159
|
+
type: string
|
|
160
|
+
description: Monitor id
|
|
161
|
+
get:
|
|
162
|
+
tags:
|
|
163
|
+
- Monitors
|
|
164
|
+
operationId: getMonitor
|
|
165
|
+
summary: Get a monitor
|
|
166
|
+
description: One monitor with its settings and latest state.
|
|
167
|
+
responses:
|
|
168
|
+
"200":
|
|
169
|
+
description: Monitor
|
|
170
|
+
content:
|
|
171
|
+
application/json:
|
|
172
|
+
schema:
|
|
173
|
+
type: object
|
|
174
|
+
required:
|
|
175
|
+
- success
|
|
176
|
+
- data
|
|
177
|
+
properties:
|
|
178
|
+
success:
|
|
179
|
+
type: boolean
|
|
180
|
+
example: true
|
|
181
|
+
data:
|
|
182
|
+
$ref: "#/components/schemas/Monitor"
|
|
183
|
+
"401":
|
|
184
|
+
$ref: "#/components/responses/Unauthorized"
|
|
185
|
+
"403":
|
|
186
|
+
$ref: "#/components/responses/Forbidden"
|
|
187
|
+
"404":
|
|
188
|
+
$ref: "#/components/responses/NotFound"
|
|
189
|
+
parameters:
|
|
190
|
+
- $ref: "#/components/parameters/ActiveOrganization"
|
|
191
|
+
patch:
|
|
192
|
+
tags:
|
|
193
|
+
- Monitors
|
|
194
|
+
operationId: updateMonitor
|
|
195
|
+
summary: Update a monitor
|
|
196
|
+
description: Send only the fields to change. Changing `url` resets the monitor to `pending` and closes any open incident.
|
|
197
|
+
requestBody:
|
|
198
|
+
required: true
|
|
199
|
+
content:
|
|
200
|
+
application/json:
|
|
201
|
+
schema:
|
|
202
|
+
$ref: "#/components/schemas/MonitorUpdate"
|
|
203
|
+
responses:
|
|
204
|
+
"200":
|
|
205
|
+
description: Updated monitor
|
|
206
|
+
content:
|
|
207
|
+
application/json:
|
|
208
|
+
schema:
|
|
209
|
+
type: object
|
|
210
|
+
required:
|
|
211
|
+
- success
|
|
212
|
+
- data
|
|
213
|
+
properties:
|
|
214
|
+
success:
|
|
215
|
+
type: boolean
|
|
216
|
+
example: true
|
|
217
|
+
data:
|
|
218
|
+
$ref: "#/components/schemas/Monitor"
|
|
219
|
+
"400":
|
|
220
|
+
$ref: "#/components/responses/ValidationError"
|
|
221
|
+
"401":
|
|
222
|
+
$ref: "#/components/responses/Unauthorized"
|
|
223
|
+
"403":
|
|
224
|
+
$ref: "#/components/responses/Forbidden"
|
|
225
|
+
"404":
|
|
226
|
+
$ref: "#/components/responses/NotFound"
|
|
227
|
+
parameters:
|
|
228
|
+
- $ref: "#/components/parameters/ActiveOrganization"
|
|
229
|
+
delete:
|
|
230
|
+
tags:
|
|
231
|
+
- Monitors
|
|
232
|
+
operationId: deleteMonitor
|
|
233
|
+
summary: Delete a monitor
|
|
234
|
+
description: Also deletes its results, daily rollups and incidents.
|
|
235
|
+
responses:
|
|
236
|
+
"200":
|
|
237
|
+
description: Deleted
|
|
238
|
+
content:
|
|
239
|
+
application/json:
|
|
240
|
+
schema:
|
|
241
|
+
type: object
|
|
242
|
+
required:
|
|
243
|
+
- success
|
|
244
|
+
- data
|
|
245
|
+
properties:
|
|
246
|
+
success:
|
|
247
|
+
type: boolean
|
|
248
|
+
example: true
|
|
249
|
+
data:
|
|
250
|
+
type: object
|
|
251
|
+
properties:
|
|
252
|
+
id:
|
|
253
|
+
type: string
|
|
254
|
+
deleted:
|
|
255
|
+
type: boolean
|
|
256
|
+
"401":
|
|
257
|
+
$ref: "#/components/responses/Unauthorized"
|
|
258
|
+
"403":
|
|
259
|
+
$ref: "#/components/responses/Forbidden"
|
|
260
|
+
"404":
|
|
261
|
+
$ref: "#/components/responses/NotFound"
|
|
262
|
+
parameters:
|
|
263
|
+
- $ref: "#/components/parameters/ActiveOrganization"
|
|
264
|
+
/api/v1/monitors/{id}/check:
|
|
265
|
+
parameters:
|
|
266
|
+
- name: id
|
|
267
|
+
in: path
|
|
268
|
+
required: true
|
|
269
|
+
schema:
|
|
270
|
+
type: string
|
|
271
|
+
description: Monitor id
|
|
272
|
+
post:
|
|
273
|
+
tags:
|
|
274
|
+
- Monitors
|
|
275
|
+
operationId: checkMonitor
|
|
276
|
+
summary: Run a check now
|
|
277
|
+
description: "Probes the URL immediately and records the outcome. A target that is down still returns 200 with `ok: false` (the check ran). Refused with 429 within 10 seconds of the previous check."
|
|
278
|
+
responses:
|
|
279
|
+
"200":
|
|
280
|
+
description: Check outcome
|
|
281
|
+
content:
|
|
282
|
+
application/json:
|
|
283
|
+
schema:
|
|
284
|
+
type: object
|
|
285
|
+
required:
|
|
286
|
+
- success
|
|
287
|
+
- data
|
|
288
|
+
properties:
|
|
289
|
+
success:
|
|
290
|
+
type: boolean
|
|
291
|
+
example: true
|
|
292
|
+
data:
|
|
293
|
+
type: object
|
|
294
|
+
properties:
|
|
295
|
+
ok:
|
|
296
|
+
type: boolean
|
|
297
|
+
status_code:
|
|
298
|
+
type: integer
|
|
299
|
+
nullable: true
|
|
300
|
+
response_ms:
|
|
301
|
+
type: integer
|
|
302
|
+
error:
|
|
303
|
+
$ref: "#/components/schemas/CheckError"
|
|
304
|
+
monitor:
|
|
305
|
+
$ref: "#/components/schemas/Monitor"
|
|
306
|
+
"401":
|
|
307
|
+
$ref: "#/components/responses/Unauthorized"
|
|
308
|
+
"403":
|
|
309
|
+
$ref: "#/components/responses/Forbidden"
|
|
310
|
+
"404":
|
|
311
|
+
$ref: "#/components/responses/NotFound"
|
|
312
|
+
"429":
|
|
313
|
+
description: Checked moments ago (`RATE_LIMITED`)
|
|
314
|
+
content:
|
|
315
|
+
application/json:
|
|
316
|
+
schema:
|
|
317
|
+
$ref: "#/components/schemas/Error"
|
|
318
|
+
parameters:
|
|
319
|
+
- $ref: "#/components/parameters/ActiveOrganization"
|
|
320
|
+
/api/v1/monitors/{id}/results:
|
|
321
|
+
parameters:
|
|
322
|
+
- name: id
|
|
323
|
+
in: path
|
|
324
|
+
required: true
|
|
325
|
+
schema:
|
|
326
|
+
type: string
|
|
327
|
+
description: Monitor id
|
|
328
|
+
get:
|
|
329
|
+
tags:
|
|
330
|
+
- Monitors
|
|
331
|
+
operationId: listMonitorResults
|
|
332
|
+
summary: List recent check results
|
|
333
|
+
description: Newest first. Raw results are kept for 7 days; use the report for longer windows.
|
|
334
|
+
parameters:
|
|
335
|
+
- name: limit
|
|
336
|
+
in: query
|
|
337
|
+
required: false
|
|
338
|
+
schema:
|
|
339
|
+
type: integer
|
|
340
|
+
minimum: 1
|
|
341
|
+
maximum: 500
|
|
342
|
+
default: 100
|
|
343
|
+
- $ref: "#/components/parameters/ActiveOrganization"
|
|
344
|
+
responses:
|
|
345
|
+
"200":
|
|
346
|
+
description: Results
|
|
347
|
+
content:
|
|
348
|
+
application/json:
|
|
349
|
+
schema:
|
|
350
|
+
type: object
|
|
351
|
+
required:
|
|
352
|
+
- success
|
|
353
|
+
- data
|
|
354
|
+
properties:
|
|
355
|
+
success:
|
|
356
|
+
type: boolean
|
|
357
|
+
example: true
|
|
358
|
+
data:
|
|
359
|
+
type: object
|
|
360
|
+
properties:
|
|
361
|
+
data:
|
|
362
|
+
type: array
|
|
363
|
+
items:
|
|
364
|
+
$ref: "#/components/schemas/CheckResult"
|
|
365
|
+
total:
|
|
366
|
+
type: integer
|
|
367
|
+
"400":
|
|
368
|
+
$ref: "#/components/responses/ValidationError"
|
|
369
|
+
"401":
|
|
370
|
+
$ref: "#/components/responses/Unauthorized"
|
|
371
|
+
"403":
|
|
372
|
+
$ref: "#/components/responses/Forbidden"
|
|
373
|
+
"404":
|
|
374
|
+
$ref: "#/components/responses/NotFound"
|
|
375
|
+
/api/v1/monitors/{id}/report:
|
|
376
|
+
parameters:
|
|
377
|
+
- name: id
|
|
378
|
+
in: path
|
|
379
|
+
required: true
|
|
380
|
+
schema:
|
|
381
|
+
type: string
|
|
382
|
+
description: Monitor id
|
|
383
|
+
get:
|
|
384
|
+
tags:
|
|
385
|
+
- Reports
|
|
386
|
+
operationId: getMonitorReport
|
|
387
|
+
summary: Availability report for one monitor
|
|
388
|
+
description: "Availability report for one monitor over the last `days` UTC days: uptime, downtime, response times, a daily series and incidents."
|
|
389
|
+
parameters:
|
|
390
|
+
- name: days
|
|
391
|
+
in: query
|
|
392
|
+
required: false
|
|
393
|
+
schema:
|
|
394
|
+
type: integer
|
|
395
|
+
enum:
|
|
396
|
+
- 1
|
|
397
|
+
- 7
|
|
398
|
+
- 30
|
|
399
|
+
- 90
|
|
400
|
+
default: 7
|
|
401
|
+
description: Report window in UTC days, ending today
|
|
402
|
+
- $ref: "#/components/parameters/ActiveOrganization"
|
|
403
|
+
responses:
|
|
404
|
+
"200":
|
|
405
|
+
description: Report
|
|
406
|
+
content:
|
|
407
|
+
application/json:
|
|
408
|
+
schema:
|
|
409
|
+
type: object
|
|
410
|
+
required:
|
|
411
|
+
- success
|
|
412
|
+
- data
|
|
413
|
+
properties:
|
|
414
|
+
success:
|
|
415
|
+
type: boolean
|
|
416
|
+
example: true
|
|
417
|
+
data:
|
|
418
|
+
$ref: "#/components/schemas/MonitorReport"
|
|
419
|
+
"400":
|
|
420
|
+
$ref: "#/components/responses/ValidationError"
|
|
421
|
+
"401":
|
|
422
|
+
$ref: "#/components/responses/Unauthorized"
|
|
423
|
+
"403":
|
|
424
|
+
$ref: "#/components/responses/Forbidden"
|
|
425
|
+
"404":
|
|
426
|
+
$ref: "#/components/responses/NotFound"
|
|
427
|
+
/api/v1/report:
|
|
428
|
+
get:
|
|
429
|
+
tags:
|
|
430
|
+
- Reports
|
|
431
|
+
operationId: getReportOverview
|
|
432
|
+
summary: Availability report across all monitors
|
|
433
|
+
description: Availability report across all of the caller's monitors over the last `days` UTC days.
|
|
434
|
+
parameters:
|
|
435
|
+
- name: days
|
|
436
|
+
in: query
|
|
437
|
+
required: false
|
|
438
|
+
schema:
|
|
439
|
+
type: integer
|
|
440
|
+
enum:
|
|
441
|
+
- 1
|
|
442
|
+
- 7
|
|
443
|
+
- 30
|
|
444
|
+
- 90
|
|
445
|
+
default: 7
|
|
446
|
+
description: Report window in UTC days, ending today
|
|
447
|
+
- $ref: "#/components/parameters/ActiveOrganization"
|
|
448
|
+
responses:
|
|
449
|
+
"200":
|
|
450
|
+
description: Report
|
|
451
|
+
content:
|
|
452
|
+
application/json:
|
|
453
|
+
schema:
|
|
454
|
+
type: object
|
|
455
|
+
required:
|
|
456
|
+
- success
|
|
457
|
+
- data
|
|
458
|
+
properties:
|
|
459
|
+
success:
|
|
460
|
+
type: boolean
|
|
461
|
+
example: true
|
|
462
|
+
data:
|
|
463
|
+
$ref: "#/components/schemas/ReportOverview"
|
|
464
|
+
"400":
|
|
465
|
+
$ref: "#/components/responses/ValidationError"
|
|
466
|
+
"401":
|
|
467
|
+
$ref: "#/components/responses/Unauthorized"
|
|
468
|
+
"403":
|
|
469
|
+
$ref: "#/components/responses/Forbidden"
|
|
470
|
+
/api/v1/projects:
|
|
471
|
+
get:
|
|
472
|
+
tags:
|
|
473
|
+
- Projects
|
|
474
|
+
operationId: listProjects
|
|
475
|
+
summary: List projects
|
|
476
|
+
description: Projects in the caller's namespace (personal, or the active organization), newest first, each with its latest run and that run's suites.
|
|
477
|
+
parameters:
|
|
478
|
+
- $ref: "#/components/parameters/ActiveOrganization"
|
|
479
|
+
- name: name
|
|
480
|
+
in: query
|
|
481
|
+
required: false
|
|
482
|
+
description: Return only the project with this name (exact match, ignoring case).
|
|
483
|
+
schema:
|
|
484
|
+
type: string
|
|
485
|
+
maxLength: 100
|
|
486
|
+
responses:
|
|
487
|
+
"200":
|
|
488
|
+
description: Projects
|
|
489
|
+
content:
|
|
490
|
+
application/json:
|
|
491
|
+
schema:
|
|
492
|
+
type: object
|
|
493
|
+
required:
|
|
494
|
+
- success
|
|
495
|
+
- data
|
|
496
|
+
properties:
|
|
497
|
+
success:
|
|
498
|
+
type: boolean
|
|
499
|
+
example: true
|
|
500
|
+
data:
|
|
501
|
+
type: object
|
|
502
|
+
required:
|
|
503
|
+
- data
|
|
504
|
+
- total
|
|
505
|
+
- limit
|
|
506
|
+
properties:
|
|
507
|
+
data:
|
|
508
|
+
type: array
|
|
509
|
+
items:
|
|
510
|
+
$ref: "#/components/schemas/ProjectWithLatestRun"
|
|
511
|
+
total:
|
|
512
|
+
type: integer
|
|
513
|
+
limit:
|
|
514
|
+
type: integer
|
|
515
|
+
description: Maximum projects per namespace
|
|
516
|
+
"400":
|
|
517
|
+
$ref: "#/components/responses/ValidationError"
|
|
518
|
+
"401":
|
|
519
|
+
$ref: "#/components/responses/Unauthorized"
|
|
520
|
+
"403":
|
|
521
|
+
$ref: "#/components/responses/Forbidden"
|
|
522
|
+
post:
|
|
523
|
+
tags:
|
|
524
|
+
- Projects
|
|
525
|
+
operationId: createProject
|
|
526
|
+
summary: Create a project
|
|
527
|
+
description: One project tracks one repository's CI/CD quality record. `retention_days` is set from the caller's plan.
|
|
528
|
+
parameters:
|
|
529
|
+
- $ref: "#/components/parameters/ActiveOrganization"
|
|
530
|
+
requestBody:
|
|
531
|
+
required: true
|
|
532
|
+
content:
|
|
533
|
+
application/json:
|
|
534
|
+
schema:
|
|
535
|
+
$ref: "#/components/schemas/ProjectCreate"
|
|
536
|
+
responses:
|
|
537
|
+
"201":
|
|
538
|
+
description: Project created
|
|
539
|
+
content:
|
|
540
|
+
application/json:
|
|
541
|
+
schema:
|
|
542
|
+
type: object
|
|
543
|
+
required:
|
|
544
|
+
- success
|
|
545
|
+
- data
|
|
546
|
+
properties:
|
|
547
|
+
success:
|
|
548
|
+
type: boolean
|
|
549
|
+
example: true
|
|
550
|
+
data:
|
|
551
|
+
$ref: "#/components/schemas/Project"
|
|
552
|
+
"400":
|
|
553
|
+
$ref: "#/components/responses/ValidationError"
|
|
554
|
+
"401":
|
|
555
|
+
$ref: "#/components/responses/Unauthorized"
|
|
556
|
+
"403":
|
|
557
|
+
$ref: "#/components/responses/Forbidden"
|
|
558
|
+
"409":
|
|
559
|
+
description: The per-namespace project limit is reached (`LIMIT_REACHED`), or a project with this name already exists in the namespace (`CONFLICT`)
|
|
560
|
+
content:
|
|
561
|
+
application/json:
|
|
562
|
+
schema:
|
|
563
|
+
$ref: "#/components/schemas/Error"
|
|
564
|
+
/api/v1/projects/{id}:
|
|
565
|
+
parameters:
|
|
566
|
+
- name: id
|
|
567
|
+
in: path
|
|
568
|
+
required: true
|
|
569
|
+
description: Project id
|
|
570
|
+
schema:
|
|
571
|
+
type: string
|
|
572
|
+
- $ref: "#/components/parameters/ActiveOrganization"
|
|
573
|
+
get:
|
|
574
|
+
tags:
|
|
575
|
+
- Projects
|
|
576
|
+
operationId: getProject
|
|
577
|
+
summary: Get a project
|
|
578
|
+
description: One project with its settings, including the retention window.
|
|
579
|
+
responses:
|
|
580
|
+
"200":
|
|
581
|
+
description: Project
|
|
582
|
+
content:
|
|
583
|
+
application/json:
|
|
584
|
+
schema:
|
|
585
|
+
type: object
|
|
586
|
+
required:
|
|
587
|
+
- success
|
|
588
|
+
- data
|
|
589
|
+
properties:
|
|
590
|
+
success:
|
|
591
|
+
type: boolean
|
|
592
|
+
example: true
|
|
593
|
+
data:
|
|
594
|
+
$ref: "#/components/schemas/Project"
|
|
595
|
+
"401":
|
|
596
|
+
$ref: "#/components/responses/Unauthorized"
|
|
597
|
+
"403":
|
|
598
|
+
$ref: "#/components/responses/Forbidden"
|
|
599
|
+
"404":
|
|
600
|
+
$ref: "#/components/responses/NotFound"
|
|
601
|
+
delete:
|
|
602
|
+
tags:
|
|
603
|
+
- Projects
|
|
604
|
+
operationId: deleteProject
|
|
605
|
+
summary: Delete a project
|
|
606
|
+
description: Also deletes its runs and suite results.
|
|
607
|
+
responses:
|
|
608
|
+
"200":
|
|
609
|
+
description: Deleted
|
|
610
|
+
content:
|
|
611
|
+
application/json:
|
|
612
|
+
schema:
|
|
613
|
+
type: object
|
|
614
|
+
required:
|
|
615
|
+
- success
|
|
616
|
+
- data
|
|
617
|
+
properties:
|
|
618
|
+
success:
|
|
619
|
+
type: boolean
|
|
620
|
+
example: true
|
|
621
|
+
data:
|
|
622
|
+
type: object
|
|
623
|
+
properties:
|
|
624
|
+
id:
|
|
625
|
+
type: string
|
|
626
|
+
deleted:
|
|
627
|
+
type: boolean
|
|
628
|
+
"401":
|
|
629
|
+
$ref: "#/components/responses/Unauthorized"
|
|
630
|
+
"403":
|
|
631
|
+
$ref: "#/components/responses/Forbidden"
|
|
632
|
+
"404":
|
|
633
|
+
$ref: "#/components/responses/NotFound"
|
|
634
|
+
/api/v1/projects/{id}/results:
|
|
635
|
+
parameters:
|
|
636
|
+
- name: id
|
|
637
|
+
in: path
|
|
638
|
+
required: true
|
|
639
|
+
description: Project id
|
|
640
|
+
schema:
|
|
641
|
+
type: string
|
|
642
|
+
- $ref: "#/components/parameters/ActiveOrganization"
|
|
643
|
+
post:
|
|
644
|
+
tags:
|
|
645
|
+
- Projects
|
|
646
|
+
operationId: reportResult
|
|
647
|
+
summary: Report a test result
|
|
648
|
+
description: Called once per CI job with the NORMALISED summary of one report (not the raw file). The run is found or created by `run.key`; the suite is upserted by (run, `suite.kind`, `suite.name`), so a retried job replaces its own result and another job of the same pipeline adds a suite to the same run. 201 when the suite is new, 200 when it replaced an earlier report.
|
|
649
|
+
requestBody:
|
|
650
|
+
required: true
|
|
651
|
+
content:
|
|
652
|
+
application/json:
|
|
653
|
+
schema:
|
|
654
|
+
$ref: "#/components/schemas/ResultReport"
|
|
655
|
+
responses:
|
|
656
|
+
"200":
|
|
657
|
+
description: An earlier report of this suite was replaced
|
|
658
|
+
content:
|
|
659
|
+
application/json:
|
|
660
|
+
schema:
|
|
661
|
+
type: object
|
|
662
|
+
required:
|
|
663
|
+
- success
|
|
664
|
+
- data
|
|
665
|
+
properties:
|
|
666
|
+
success:
|
|
667
|
+
type: boolean
|
|
668
|
+
example: true
|
|
669
|
+
data:
|
|
670
|
+
$ref: "#/components/schemas/ResultAccepted"
|
|
671
|
+
"201":
|
|
672
|
+
description: Result stored
|
|
673
|
+
content:
|
|
674
|
+
application/json:
|
|
675
|
+
schema:
|
|
676
|
+
type: object
|
|
677
|
+
required:
|
|
678
|
+
- success
|
|
679
|
+
- data
|
|
680
|
+
properties:
|
|
681
|
+
success:
|
|
682
|
+
type: boolean
|
|
683
|
+
example: true
|
|
684
|
+
data:
|
|
685
|
+
$ref: "#/components/schemas/ResultAccepted"
|
|
686
|
+
"400":
|
|
687
|
+
$ref: "#/components/responses/ValidationError"
|
|
688
|
+
"401":
|
|
689
|
+
$ref: "#/components/responses/Unauthorized"
|
|
690
|
+
"403":
|
|
691
|
+
$ref: "#/components/responses/Forbidden"
|
|
692
|
+
"404":
|
|
693
|
+
$ref: "#/components/responses/NotFound"
|
|
694
|
+
/api/v1/projects/{id}/runs:
|
|
695
|
+
parameters:
|
|
696
|
+
- name: id
|
|
697
|
+
in: path
|
|
698
|
+
required: true
|
|
699
|
+
description: Project id
|
|
700
|
+
schema:
|
|
701
|
+
type: string
|
|
702
|
+
- $ref: "#/components/parameters/ActiveOrganization"
|
|
703
|
+
get:
|
|
704
|
+
tags:
|
|
705
|
+
- Projects
|
|
706
|
+
operationId: listRuns
|
|
707
|
+
summary: List runs
|
|
708
|
+
description: Newest first, each with its suite results.
|
|
709
|
+
parameters:
|
|
710
|
+
- name: limit
|
|
711
|
+
in: query
|
|
712
|
+
required: false
|
|
713
|
+
schema:
|
|
714
|
+
type: integer
|
|
715
|
+
minimum: 1
|
|
716
|
+
maximum: 100
|
|
717
|
+
default: 20
|
|
718
|
+
responses:
|
|
719
|
+
"200":
|
|
720
|
+
description: Runs
|
|
721
|
+
content:
|
|
722
|
+
application/json:
|
|
723
|
+
schema:
|
|
724
|
+
type: object
|
|
725
|
+
required:
|
|
726
|
+
- success
|
|
727
|
+
- data
|
|
728
|
+
properties:
|
|
729
|
+
success:
|
|
730
|
+
type: boolean
|
|
731
|
+
example: true
|
|
732
|
+
data:
|
|
733
|
+
type: object
|
|
734
|
+
required:
|
|
735
|
+
- data
|
|
736
|
+
- limit
|
|
737
|
+
properties:
|
|
738
|
+
data:
|
|
739
|
+
type: array
|
|
740
|
+
items:
|
|
741
|
+
$ref: "#/components/schemas/Run"
|
|
742
|
+
limit:
|
|
743
|
+
type: integer
|
|
744
|
+
"400":
|
|
745
|
+
$ref: "#/components/responses/ValidationError"
|
|
746
|
+
"401":
|
|
747
|
+
$ref: "#/components/responses/Unauthorized"
|
|
748
|
+
"403":
|
|
749
|
+
$ref: "#/components/responses/Forbidden"
|
|
750
|
+
"404":
|
|
751
|
+
$ref: "#/components/responses/NotFound"
|
|
752
|
+
/api/v1/projects/{id}/runs/{runId}:
|
|
753
|
+
parameters:
|
|
754
|
+
- name: id
|
|
755
|
+
in: path
|
|
756
|
+
required: true
|
|
757
|
+
description: Project id
|
|
758
|
+
schema:
|
|
759
|
+
type: string
|
|
760
|
+
- name: runId
|
|
761
|
+
in: path
|
|
762
|
+
required: true
|
|
763
|
+
description: Run id
|
|
764
|
+
schema:
|
|
765
|
+
type: string
|
|
766
|
+
- $ref: "#/components/parameters/ActiveOrganization"
|
|
767
|
+
get:
|
|
768
|
+
tags:
|
|
769
|
+
- Projects
|
|
770
|
+
operationId: getRun
|
|
771
|
+
summary: Get a run
|
|
772
|
+
description: One run with all of its suite results.
|
|
773
|
+
responses:
|
|
774
|
+
"200":
|
|
775
|
+
description: Run
|
|
776
|
+
content:
|
|
777
|
+
application/json:
|
|
778
|
+
schema:
|
|
779
|
+
type: object
|
|
780
|
+
required:
|
|
781
|
+
- success
|
|
782
|
+
- data
|
|
783
|
+
properties:
|
|
784
|
+
success:
|
|
785
|
+
type: boolean
|
|
786
|
+
example: true
|
|
787
|
+
data:
|
|
788
|
+
$ref: "#/components/schemas/Run"
|
|
789
|
+
"401":
|
|
790
|
+
$ref: "#/components/responses/Unauthorized"
|
|
791
|
+
"403":
|
|
792
|
+
$ref: "#/components/responses/Forbidden"
|
|
793
|
+
"404":
|
|
794
|
+
$ref: "#/components/responses/NotFound"
|
|
795
|
+
/api/v1/contracts:
|
|
796
|
+
parameters:
|
|
797
|
+
- $ref: "#/components/parameters/ActiveOrganization"
|
|
798
|
+
get:
|
|
799
|
+
tags:
|
|
800
|
+
- Contracts
|
|
801
|
+
operationId: listContracts
|
|
802
|
+
summary: List contracts
|
|
803
|
+
description: The outsourcing contracts of the active namespace, each with its deliverables, documents and SLA clause. Read-only for now.
|
|
804
|
+
responses:
|
|
805
|
+
"200":
|
|
806
|
+
description: Contracts
|
|
807
|
+
content:
|
|
808
|
+
application/json:
|
|
809
|
+
schema:
|
|
810
|
+
type: object
|
|
811
|
+
required:
|
|
812
|
+
- success
|
|
813
|
+
- data
|
|
814
|
+
properties:
|
|
815
|
+
success:
|
|
816
|
+
type: boolean
|
|
817
|
+
example: true
|
|
818
|
+
data:
|
|
819
|
+
type: object
|
|
820
|
+
properties:
|
|
821
|
+
data:
|
|
822
|
+
type: array
|
|
823
|
+
items:
|
|
824
|
+
$ref: "#/components/schemas/Contract"
|
|
825
|
+
total:
|
|
826
|
+
type: integer
|
|
827
|
+
"401":
|
|
828
|
+
$ref: "#/components/responses/Unauthorized"
|
|
829
|
+
"403":
|
|
830
|
+
$ref: "#/components/responses/Forbidden"
|
|
831
|
+
/api/v1/contracts/{id}:
|
|
832
|
+
parameters:
|
|
833
|
+
- name: id
|
|
834
|
+
in: path
|
|
835
|
+
required: true
|
|
836
|
+
description: Contract id
|
|
837
|
+
schema:
|
|
838
|
+
type: string
|
|
839
|
+
- $ref: "#/components/parameters/ActiveOrganization"
|
|
840
|
+
get:
|
|
841
|
+
tags:
|
|
842
|
+
- Contracts
|
|
843
|
+
operationId: getContract
|
|
844
|
+
summary: Get a contract
|
|
845
|
+
description: One contract. A contract outside the active namespace is reported as not found.
|
|
846
|
+
responses:
|
|
847
|
+
"200":
|
|
848
|
+
description: Contract
|
|
849
|
+
content:
|
|
850
|
+
application/json:
|
|
851
|
+
schema:
|
|
852
|
+
type: object
|
|
853
|
+
required:
|
|
854
|
+
- success
|
|
855
|
+
- data
|
|
856
|
+
properties:
|
|
857
|
+
success:
|
|
858
|
+
type: boolean
|
|
859
|
+
example: true
|
|
860
|
+
data:
|
|
861
|
+
$ref: "#/components/schemas/Contract"
|
|
862
|
+
"401":
|
|
863
|
+
$ref: "#/components/responses/Unauthorized"
|
|
864
|
+
"403":
|
|
865
|
+
$ref: "#/components/responses/Forbidden"
|
|
866
|
+
"404":
|
|
867
|
+
$ref: "#/components/responses/NotFound"
|
|
868
|
+
components:
|
|
869
|
+
securitySchemes:
|
|
870
|
+
BearerAuth:
|
|
871
|
+
type: http
|
|
872
|
+
scheme: bearer
|
|
873
|
+
bearerFormat: JWT or PAT
|
|
874
|
+
description: Use either an Auth0 JWT token or a Personal Access Token (PAT) starting with `nbpat_`.
|
|
875
|
+
schemas:
|
|
876
|
+
User:
|
|
877
|
+
type: object
|
|
878
|
+
properties:
|
|
879
|
+
id:
|
|
880
|
+
type: integer
|
|
881
|
+
auth0_sub:
|
|
882
|
+
type: string
|
|
883
|
+
email:
|
|
884
|
+
type: string
|
|
885
|
+
format: email
|
|
886
|
+
name:
|
|
887
|
+
type: string
|
|
888
|
+
language:
|
|
889
|
+
type: string
|
|
890
|
+
enum:
|
|
891
|
+
- ja
|
|
892
|
+
- en
|
|
893
|
+
plan:
|
|
894
|
+
type: string
|
|
895
|
+
enum:
|
|
896
|
+
- free
|
|
897
|
+
- pro
|
|
898
|
+
- family
|
|
899
|
+
- enterprise
|
|
900
|
+
subscription_status:
|
|
901
|
+
type: string
|
|
902
|
+
enum:
|
|
903
|
+
- active
|
|
904
|
+
- canceled
|
|
905
|
+
- past_due
|
|
906
|
+
- trialing
|
|
907
|
+
nullable: true
|
|
908
|
+
subscription_expires_at:
|
|
909
|
+
type: string
|
|
910
|
+
format: date-time
|
|
911
|
+
nullable: true
|
|
912
|
+
UserResponse:
|
|
913
|
+
type: object
|
|
914
|
+
properties:
|
|
915
|
+
data:
|
|
916
|
+
$ref: "#/components/schemas/User"
|
|
917
|
+
Error:
|
|
918
|
+
type: object
|
|
919
|
+
properties:
|
|
920
|
+
error:
|
|
921
|
+
type: object
|
|
922
|
+
properties:
|
|
923
|
+
code:
|
|
924
|
+
type: string
|
|
925
|
+
message:
|
|
926
|
+
type: string
|
|
927
|
+
CheckError:
|
|
928
|
+
type: string
|
|
929
|
+
nullable: true
|
|
930
|
+
enum:
|
|
931
|
+
- timeout
|
|
932
|
+
- connection_failed
|
|
933
|
+
- unexpected_status
|
|
934
|
+
- keyword_not_found
|
|
935
|
+
- null
|
|
936
|
+
description: Why a check failed; null when it passed
|
|
937
|
+
MonitorSettings:
|
|
938
|
+
type: object
|
|
939
|
+
properties:
|
|
940
|
+
name:
|
|
941
|
+
type: string
|
|
942
|
+
maxLength: 100
|
|
943
|
+
url:
|
|
944
|
+
type: string
|
|
945
|
+
format: uri
|
|
946
|
+
maxLength: 2048
|
|
947
|
+
method:
|
|
948
|
+
type: string
|
|
949
|
+
enum:
|
|
950
|
+
- GET
|
|
951
|
+
- HEAD
|
|
952
|
+
default: GET
|
|
953
|
+
interval_minutes:
|
|
954
|
+
type: integer
|
|
955
|
+
enum:
|
|
956
|
+
- 5
|
|
957
|
+
- 10
|
|
958
|
+
- 15
|
|
959
|
+
- 30
|
|
960
|
+
- 60
|
|
961
|
+
default: 5
|
|
962
|
+
timeout_ms:
|
|
963
|
+
type: integer
|
|
964
|
+
minimum: 1000
|
|
965
|
+
maximum: 30000
|
|
966
|
+
default: 10000
|
|
967
|
+
expected_status:
|
|
968
|
+
type: integer
|
|
969
|
+
nullable: true
|
|
970
|
+
minimum: 100
|
|
971
|
+
maximum: 599
|
|
972
|
+
description: Exact status that counts as up; null means any 2xx or 3xx
|
|
973
|
+
keyword:
|
|
974
|
+
type: string
|
|
975
|
+
nullable: true
|
|
976
|
+
maxLength: 200
|
|
977
|
+
description: Text the response body must contain (GET only)
|
|
978
|
+
enabled:
|
|
979
|
+
type: boolean
|
|
980
|
+
default: true
|
|
981
|
+
MonitorCreate:
|
|
982
|
+
allOf:
|
|
983
|
+
- $ref: "#/components/schemas/MonitorSettings"
|
|
984
|
+
required:
|
|
985
|
+
- name
|
|
986
|
+
- url
|
|
987
|
+
MonitorUpdate:
|
|
988
|
+
allOf:
|
|
989
|
+
- $ref: "#/components/schemas/MonitorSettings"
|
|
990
|
+
minProperties: 1
|
|
991
|
+
description: Any subset of the settings
|
|
992
|
+
Monitor:
|
|
993
|
+
type: object
|
|
994
|
+
properties:
|
|
995
|
+
id:
|
|
996
|
+
type: string
|
|
997
|
+
name:
|
|
998
|
+
type: string
|
|
999
|
+
url:
|
|
1000
|
+
type: string
|
|
1001
|
+
method:
|
|
1002
|
+
type: string
|
|
1003
|
+
enum:
|
|
1004
|
+
- GET
|
|
1005
|
+
- HEAD
|
|
1006
|
+
interval_minutes:
|
|
1007
|
+
type: integer
|
|
1008
|
+
timeout_ms:
|
|
1009
|
+
type: integer
|
|
1010
|
+
expected_status:
|
|
1011
|
+
type: integer
|
|
1012
|
+
nullable: true
|
|
1013
|
+
keyword:
|
|
1014
|
+
type: string
|
|
1015
|
+
nullable: true
|
|
1016
|
+
enabled:
|
|
1017
|
+
type: boolean
|
|
1018
|
+
state:
|
|
1019
|
+
type: string
|
|
1020
|
+
enum:
|
|
1021
|
+
- pending
|
|
1022
|
+
- up
|
|
1023
|
+
- down
|
|
1024
|
+
state_since:
|
|
1025
|
+
type: string
|
|
1026
|
+
format: date-time
|
|
1027
|
+
nullable: true
|
|
1028
|
+
last_checked_at:
|
|
1029
|
+
type: string
|
|
1030
|
+
format: date-time
|
|
1031
|
+
nullable: true
|
|
1032
|
+
last_status_code:
|
|
1033
|
+
type: integer
|
|
1034
|
+
nullable: true
|
|
1035
|
+
last_response_ms:
|
|
1036
|
+
type: integer
|
|
1037
|
+
nullable: true
|
|
1038
|
+
last_error:
|
|
1039
|
+
$ref: "#/components/schemas/CheckError"
|
|
1040
|
+
created_at:
|
|
1041
|
+
type: string
|
|
1042
|
+
format: date-time
|
|
1043
|
+
updated_at:
|
|
1044
|
+
type: string
|
|
1045
|
+
format: date-time
|
|
1046
|
+
organization_id:
|
|
1047
|
+
type: integer
|
|
1048
|
+
nullable: true
|
|
1049
|
+
description: Owning organization; null for a personal monitor.
|
|
1050
|
+
example: null
|
|
1051
|
+
MonitorWithUptime:
|
|
1052
|
+
allOf:
|
|
1053
|
+
- $ref: "#/components/schemas/Monitor"
|
|
1054
|
+
- type: object
|
|
1055
|
+
properties:
|
|
1056
|
+
uptime_7d:
|
|
1057
|
+
type: number
|
|
1058
|
+
nullable: true
|
|
1059
|
+
description: Percent, null before the first check
|
|
1060
|
+
CheckResult:
|
|
1061
|
+
type: object
|
|
1062
|
+
properties:
|
|
1063
|
+
id:
|
|
1064
|
+
type: integer
|
|
1065
|
+
monitor_id:
|
|
1066
|
+
type: string
|
|
1067
|
+
checked_at:
|
|
1068
|
+
type: string
|
|
1069
|
+
format: date-time
|
|
1070
|
+
ok:
|
|
1071
|
+
type: boolean
|
|
1072
|
+
status_code:
|
|
1073
|
+
type: integer
|
|
1074
|
+
nullable: true
|
|
1075
|
+
response_ms:
|
|
1076
|
+
type: integer
|
|
1077
|
+
error:
|
|
1078
|
+
$ref: "#/components/schemas/CheckError"
|
|
1079
|
+
Totals:
|
|
1080
|
+
type: object
|
|
1081
|
+
properties:
|
|
1082
|
+
checks:
|
|
1083
|
+
type: integer
|
|
1084
|
+
failures:
|
|
1085
|
+
type: integer
|
|
1086
|
+
uptime_pct:
|
|
1087
|
+
type: number
|
|
1088
|
+
nullable: true
|
|
1089
|
+
description: Percent, two decimals; null when no checks ran
|
|
1090
|
+
avg_response_ms:
|
|
1091
|
+
type: integer
|
|
1092
|
+
nullable: true
|
|
1093
|
+
description: Successful checks only
|
|
1094
|
+
max_response_ms:
|
|
1095
|
+
type: integer
|
|
1096
|
+
nullable: true
|
|
1097
|
+
description: Successful checks only
|
|
1098
|
+
DailyPoint:
|
|
1099
|
+
allOf:
|
|
1100
|
+
- $ref: "#/components/schemas/Totals"
|
|
1101
|
+
- type: object
|
|
1102
|
+
properties:
|
|
1103
|
+
day:
|
|
1104
|
+
type: string
|
|
1105
|
+
format: date
|
|
1106
|
+
description: UTC date
|
|
1107
|
+
Incident:
|
|
1108
|
+
type: object
|
|
1109
|
+
properties:
|
|
1110
|
+
id:
|
|
1111
|
+
type: integer
|
|
1112
|
+
monitor_id:
|
|
1113
|
+
type: string
|
|
1114
|
+
started_at:
|
|
1115
|
+
type: string
|
|
1116
|
+
format: date-time
|
|
1117
|
+
ended_at:
|
|
1118
|
+
type: string
|
|
1119
|
+
format: date-time
|
|
1120
|
+
nullable: true
|
|
1121
|
+
ongoing:
|
|
1122
|
+
type: boolean
|
|
1123
|
+
duration_seconds:
|
|
1124
|
+
type: integer
|
|
1125
|
+
description: Clipped to the report window; open incidents run to now
|
|
1126
|
+
status_code:
|
|
1127
|
+
type: integer
|
|
1128
|
+
nullable: true
|
|
1129
|
+
error:
|
|
1130
|
+
$ref: "#/components/schemas/CheckError"
|
|
1131
|
+
MonitorReport:
|
|
1132
|
+
allOf:
|
|
1133
|
+
- $ref: "#/components/schemas/Totals"
|
|
1134
|
+
- type: object
|
|
1135
|
+
properties:
|
|
1136
|
+
monitor:
|
|
1137
|
+
$ref: "#/components/schemas/Monitor"
|
|
1138
|
+
days:
|
|
1139
|
+
type: integer
|
|
1140
|
+
from:
|
|
1141
|
+
type: string
|
|
1142
|
+
format: date-time
|
|
1143
|
+
to:
|
|
1144
|
+
type: string
|
|
1145
|
+
format: date-time
|
|
1146
|
+
incident_count:
|
|
1147
|
+
type: integer
|
|
1148
|
+
total_downtime_seconds:
|
|
1149
|
+
type: integer
|
|
1150
|
+
incidents:
|
|
1151
|
+
type: array
|
|
1152
|
+
items:
|
|
1153
|
+
$ref: "#/components/schemas/Incident"
|
|
1154
|
+
description: Newest first, at most 100
|
|
1155
|
+
daily:
|
|
1156
|
+
type: array
|
|
1157
|
+
items:
|
|
1158
|
+
$ref: "#/components/schemas/DailyPoint"
|
|
1159
|
+
description: One entry per UTC day of the window, empty days included
|
|
1160
|
+
ReportOverview:
|
|
1161
|
+
allOf:
|
|
1162
|
+
- $ref: "#/components/schemas/Totals"
|
|
1163
|
+
- type: object
|
|
1164
|
+
properties:
|
|
1165
|
+
days:
|
|
1166
|
+
type: integer
|
|
1167
|
+
from:
|
|
1168
|
+
type: string
|
|
1169
|
+
format: date-time
|
|
1170
|
+
to:
|
|
1171
|
+
type: string
|
|
1172
|
+
format: date-time
|
|
1173
|
+
incident_count:
|
|
1174
|
+
type: integer
|
|
1175
|
+
total_downtime_seconds:
|
|
1176
|
+
type: integer
|
|
1177
|
+
incidents:
|
|
1178
|
+
type: array
|
|
1179
|
+
items:
|
|
1180
|
+
$ref: "#/components/schemas/Incident"
|
|
1181
|
+
description: Newest first, at most 100
|
|
1182
|
+
daily:
|
|
1183
|
+
type: array
|
|
1184
|
+
items:
|
|
1185
|
+
$ref: "#/components/schemas/DailyPoint"
|
|
1186
|
+
description: One entry per UTC day of the window, empty days included
|
|
1187
|
+
monitor_count:
|
|
1188
|
+
type: integer
|
|
1189
|
+
down_now:
|
|
1190
|
+
type: integer
|
|
1191
|
+
monitors:
|
|
1192
|
+
type: array
|
|
1193
|
+
items:
|
|
1194
|
+
allOf:
|
|
1195
|
+
- $ref: "#/components/schemas/Totals"
|
|
1196
|
+
- type: object
|
|
1197
|
+
properties:
|
|
1198
|
+
monitor:
|
|
1199
|
+
$ref: "#/components/schemas/Monitor"
|
|
1200
|
+
incident_count:
|
|
1201
|
+
type: integer
|
|
1202
|
+
total_downtime_seconds:
|
|
1203
|
+
type: integer
|
|
1204
|
+
ProjectCreate:
|
|
1205
|
+
type: object
|
|
1206
|
+
required:
|
|
1207
|
+
- name
|
|
1208
|
+
properties:
|
|
1209
|
+
name:
|
|
1210
|
+
type: string
|
|
1211
|
+
maxLength: 100
|
|
1212
|
+
description: Unique within the namespace, ignoring case. The CLI finds or creates a project by this name.
|
|
1213
|
+
repo:
|
|
1214
|
+
type: string
|
|
1215
|
+
nullable: true
|
|
1216
|
+
maxLength: 200
|
|
1217
|
+
description: "Where the code lives, as `owner/name` (or `group/subgroup/project`, optionally prefixed by a host). Informational: several projects may share one repository, and it may be omitted."
|
|
1218
|
+
example: nasebanal/nb-target-api
|
|
1219
|
+
Project:
|
|
1220
|
+
type: object
|
|
1221
|
+
required:
|
|
1222
|
+
- id
|
|
1223
|
+
- name
|
|
1224
|
+
- retention_days
|
|
1225
|
+
- created_at
|
|
1226
|
+
- updated_at
|
|
1227
|
+
properties:
|
|
1228
|
+
id:
|
|
1229
|
+
type: string
|
|
1230
|
+
organization_id:
|
|
1231
|
+
type: integer
|
|
1232
|
+
nullable: true
|
|
1233
|
+
description: Owning organization; null = personal
|
|
1234
|
+
name:
|
|
1235
|
+
type: string
|
|
1236
|
+
repo:
|
|
1237
|
+
type: string
|
|
1238
|
+
nullable: true
|
|
1239
|
+
retention_days:
|
|
1240
|
+
type: integer
|
|
1241
|
+
description: Runs older than this are deleted daily. Follows the reporter's plan, refreshed on every report.
|
|
1242
|
+
created_at:
|
|
1243
|
+
type: string
|
|
1244
|
+
format: date-time
|
|
1245
|
+
updated_at:
|
|
1246
|
+
type: string
|
|
1247
|
+
format: date-time
|
|
1248
|
+
ProjectWithLatestRun:
|
|
1249
|
+
allOf:
|
|
1250
|
+
- $ref: "#/components/schemas/Project"
|
|
1251
|
+
- type: object
|
|
1252
|
+
properties:
|
|
1253
|
+
latest_run:
|
|
1254
|
+
allOf:
|
|
1255
|
+
- $ref: "#/components/schemas/Run"
|
|
1256
|
+
nullable: true
|
|
1257
|
+
SuiteTests:
|
|
1258
|
+
type: object
|
|
1259
|
+
properties:
|
|
1260
|
+
total:
|
|
1261
|
+
type: integer
|
|
1262
|
+
minimum: 0
|
|
1263
|
+
nullable: true
|
|
1264
|
+
passed:
|
|
1265
|
+
type: integer
|
|
1266
|
+
minimum: 0
|
|
1267
|
+
nullable: true
|
|
1268
|
+
failed:
|
|
1269
|
+
type: integer
|
|
1270
|
+
minimum: 0
|
|
1271
|
+
nullable: true
|
|
1272
|
+
skipped:
|
|
1273
|
+
type: integer
|
|
1274
|
+
minimum: 0
|
|
1275
|
+
nullable: true
|
|
1276
|
+
SuiteFailure:
|
|
1277
|
+
type: object
|
|
1278
|
+
required:
|
|
1279
|
+
- name
|
|
1280
|
+
properties:
|
|
1281
|
+
name:
|
|
1282
|
+
type: string
|
|
1283
|
+
maxLength: 300
|
|
1284
|
+
message:
|
|
1285
|
+
type: string
|
|
1286
|
+
nullable: true
|
|
1287
|
+
maxLength: 500
|
|
1288
|
+
Suite:
|
|
1289
|
+
type: object
|
|
1290
|
+
required:
|
|
1291
|
+
- id
|
|
1292
|
+
- kind
|
|
1293
|
+
- tool
|
|
1294
|
+
- name
|
|
1295
|
+
- status
|
|
1296
|
+
properties:
|
|
1297
|
+
id:
|
|
1298
|
+
type: string
|
|
1299
|
+
kind:
|
|
1300
|
+
type: string
|
|
1301
|
+
enum:
|
|
1302
|
+
- unit
|
|
1303
|
+
- e2e
|
|
1304
|
+
- load
|
|
1305
|
+
- contract
|
|
1306
|
+
- security
|
|
1307
|
+
tool:
|
|
1308
|
+
type: string
|
|
1309
|
+
enum:
|
|
1310
|
+
- vitest
|
|
1311
|
+
- pytest
|
|
1312
|
+
- playwright
|
|
1313
|
+
- specmatic
|
|
1314
|
+
- zap
|
|
1315
|
+
- locust
|
|
1316
|
+
example: vitest
|
|
1317
|
+
name:
|
|
1318
|
+
type: string
|
|
1319
|
+
description: Tells apart several suites of one kind in a run; empty when single
|
|
1320
|
+
status:
|
|
1321
|
+
type: string
|
|
1322
|
+
enum:
|
|
1323
|
+
- passed
|
|
1324
|
+
- failed
|
|
1325
|
+
tests:
|
|
1326
|
+
$ref: "#/components/schemas/SuiteTests"
|
|
1327
|
+
duration_ms:
|
|
1328
|
+
type: integer
|
|
1329
|
+
minimum: 0
|
|
1330
|
+
nullable: true
|
|
1331
|
+
coverage:
|
|
1332
|
+
type: object
|
|
1333
|
+
properties:
|
|
1334
|
+
lines_pct:
|
|
1335
|
+
type: number
|
|
1336
|
+
nullable: true
|
|
1337
|
+
branches_pct:
|
|
1338
|
+
type: number
|
|
1339
|
+
nullable: true
|
|
1340
|
+
metrics:
|
|
1341
|
+
type: object
|
|
1342
|
+
nullable: true
|
|
1343
|
+
additionalProperties:
|
|
1344
|
+
type: number
|
|
1345
|
+
description: Kind-specific numbers
|
|
1346
|
+
failures:
|
|
1347
|
+
type: array
|
|
1348
|
+
nullable: true
|
|
1349
|
+
items:
|
|
1350
|
+
$ref: "#/components/schemas/SuiteFailure"
|
|
1351
|
+
updated_at:
|
|
1352
|
+
type: string
|
|
1353
|
+
format: date-time
|
|
1354
|
+
Run:
|
|
1355
|
+
type: object
|
|
1356
|
+
required:
|
|
1357
|
+
- id
|
|
1358
|
+
- key
|
|
1359
|
+
- status
|
|
1360
|
+
- suites
|
|
1361
|
+
- created_at
|
|
1362
|
+
properties:
|
|
1363
|
+
id:
|
|
1364
|
+
type: string
|
|
1365
|
+
key:
|
|
1366
|
+
type: string
|
|
1367
|
+
description: The caller's identity for the pipeline run
|
|
1368
|
+
commit_sha:
|
|
1369
|
+
type: string
|
|
1370
|
+
nullable: true
|
|
1371
|
+
branch:
|
|
1372
|
+
type: string
|
|
1373
|
+
nullable: true
|
|
1374
|
+
ci_url:
|
|
1375
|
+
type: string
|
|
1376
|
+
nullable: true
|
|
1377
|
+
started_at:
|
|
1378
|
+
type: string
|
|
1379
|
+
format: date-time
|
|
1380
|
+
nullable: true
|
|
1381
|
+
created_at:
|
|
1382
|
+
type: string
|
|
1383
|
+
format: date-time
|
|
1384
|
+
status:
|
|
1385
|
+
type: string
|
|
1386
|
+
enum:
|
|
1387
|
+
- passed
|
|
1388
|
+
- failed
|
|
1389
|
+
- empty
|
|
1390
|
+
description: failed if any suite failed; passed if there is at least one suite and none failed
|
|
1391
|
+
suites:
|
|
1392
|
+
type: array
|
|
1393
|
+
items:
|
|
1394
|
+
$ref: "#/components/schemas/Suite"
|
|
1395
|
+
ResultReport:
|
|
1396
|
+
type: object
|
|
1397
|
+
required:
|
|
1398
|
+
- run
|
|
1399
|
+
- suite
|
|
1400
|
+
properties:
|
|
1401
|
+
run:
|
|
1402
|
+
type: object
|
|
1403
|
+
required:
|
|
1404
|
+
- key
|
|
1405
|
+
properties:
|
|
1406
|
+
key:
|
|
1407
|
+
type: string
|
|
1408
|
+
maxLength: 128
|
|
1409
|
+
description: Stable per pipeline run, e.g. the CI run id plus attempt. Every job of one run must send the same key.
|
|
1410
|
+
example: 12345678-1
|
|
1411
|
+
commit_sha:
|
|
1412
|
+
type: string
|
|
1413
|
+
maxLength: 64
|
|
1414
|
+
branch:
|
|
1415
|
+
type: string
|
|
1416
|
+
maxLength: 255
|
|
1417
|
+
ci_url:
|
|
1418
|
+
type: string
|
|
1419
|
+
maxLength: 2048
|
|
1420
|
+
description: http(s) URL of the CI run
|
|
1421
|
+
started_at:
|
|
1422
|
+
type: string
|
|
1423
|
+
format: date-time
|
|
1424
|
+
suite:
|
|
1425
|
+
type: object
|
|
1426
|
+
required:
|
|
1427
|
+
- kind
|
|
1428
|
+
- tool
|
|
1429
|
+
- status
|
|
1430
|
+
properties:
|
|
1431
|
+
kind:
|
|
1432
|
+
type: string
|
|
1433
|
+
enum:
|
|
1434
|
+
- unit
|
|
1435
|
+
- e2e
|
|
1436
|
+
- load
|
|
1437
|
+
- contract
|
|
1438
|
+
- security
|
|
1439
|
+
tool:
|
|
1440
|
+
type: string
|
|
1441
|
+
maxLength: 50
|
|
1442
|
+
enum:
|
|
1443
|
+
- vitest
|
|
1444
|
+
- pytest
|
|
1445
|
+
- playwright
|
|
1446
|
+
- specmatic
|
|
1447
|
+
- zap
|
|
1448
|
+
- locust
|
|
1449
|
+
description: "The producing tool. Supported per kind: unit = vitest | pytest, e2e = playwright, contract = specmatic, security = zap, load = locust. Any other tool, or a tool paired with the wrong kind, is rejected with 400. Matching is case-insensitive."
|
|
1450
|
+
example: playwright
|
|
1451
|
+
name:
|
|
1452
|
+
type: string
|
|
1453
|
+
maxLength: 100
|
|
1454
|
+
status:
|
|
1455
|
+
type: string
|
|
1456
|
+
enum:
|
|
1457
|
+
- passed
|
|
1458
|
+
- failed
|
|
1459
|
+
description: Decided by the reporter, which alone knows the tool's pass/fail semantics
|
|
1460
|
+
tests:
|
|
1461
|
+
type: object
|
|
1462
|
+
properties:
|
|
1463
|
+
total:
|
|
1464
|
+
type: integer
|
|
1465
|
+
minimum: 0
|
|
1466
|
+
passed:
|
|
1467
|
+
type: integer
|
|
1468
|
+
minimum: 0
|
|
1469
|
+
failed:
|
|
1470
|
+
type: integer
|
|
1471
|
+
minimum: 0
|
|
1472
|
+
skipped:
|
|
1473
|
+
type: integer
|
|
1474
|
+
minimum: 0
|
|
1475
|
+
description: passed + failed + skipped must not exceed total
|
|
1476
|
+
duration_ms:
|
|
1477
|
+
type: integer
|
|
1478
|
+
minimum: 0
|
|
1479
|
+
coverage:
|
|
1480
|
+
type: object
|
|
1481
|
+
properties:
|
|
1482
|
+
lines_pct:
|
|
1483
|
+
type: number
|
|
1484
|
+
minimum: 0
|
|
1485
|
+
maximum: 100
|
|
1486
|
+
branches_pct:
|
|
1487
|
+
type: number
|
|
1488
|
+
minimum: 0
|
|
1489
|
+
maximum: 100
|
|
1490
|
+
metrics:
|
|
1491
|
+
type: object
|
|
1492
|
+
maxProperties: 20
|
|
1493
|
+
additionalProperties:
|
|
1494
|
+
type: number
|
|
1495
|
+
description: "snake_case keys, finite numbers. Conventional keys: load -> p95_ms, rps, error_rate_pct; security -> critical, high, medium, low, info; contract -> coverage_pct."
|
|
1496
|
+
example:
|
|
1497
|
+
p95_ms: 240
|
|
1498
|
+
rps: 120.5
|
|
1499
|
+
failures:
|
|
1500
|
+
type: array
|
|
1501
|
+
maxItems: 20
|
|
1502
|
+
items:
|
|
1503
|
+
$ref: "#/components/schemas/SuiteFailure"
|
|
1504
|
+
description: The first failures only
|
|
1505
|
+
ResultAccepted:
|
|
1506
|
+
type: object
|
|
1507
|
+
required:
|
|
1508
|
+
- run_id
|
|
1509
|
+
- suite_id
|
|
1510
|
+
- replaced
|
|
1511
|
+
properties:
|
|
1512
|
+
run_id:
|
|
1513
|
+
type: string
|
|
1514
|
+
suite_id:
|
|
1515
|
+
type: string
|
|
1516
|
+
replaced:
|
|
1517
|
+
type: boolean
|
|
1518
|
+
ContractCreditTier:
|
|
1519
|
+
type: object
|
|
1520
|
+
required:
|
|
1521
|
+
- below_pct
|
|
1522
|
+
- credit_pct
|
|
1523
|
+
properties:
|
|
1524
|
+
below_pct:
|
|
1525
|
+
type: number
|
|
1526
|
+
description: Below this uptime percentage the credit applies
|
|
1527
|
+
credit_pct:
|
|
1528
|
+
type: number
|
|
1529
|
+
description: Share of the monthly fee credited back
|
|
1530
|
+
ContractSla:
|
|
1531
|
+
type: object
|
|
1532
|
+
required:
|
|
1533
|
+
- uptime_target_pct
|
|
1534
|
+
- monthly_fee
|
|
1535
|
+
- credit_tiers
|
|
1536
|
+
properties:
|
|
1537
|
+
uptime_target_pct:
|
|
1538
|
+
type: number
|
|
1539
|
+
monthly_fee:
|
|
1540
|
+
type: integer
|
|
1541
|
+
credit_tiers:
|
|
1542
|
+
type: array
|
|
1543
|
+
items:
|
|
1544
|
+
$ref: "#/components/schemas/ContractCreditTier"
|
|
1545
|
+
ContractDeliverable:
|
|
1546
|
+
type: object
|
|
1547
|
+
required:
|
|
1548
|
+
- id
|
|
1549
|
+
- name
|
|
1550
|
+
- project_id
|
|
1551
|
+
- version
|
|
1552
|
+
- due
|
|
1553
|
+
- amount
|
|
1554
|
+
- paid
|
|
1555
|
+
properties:
|
|
1556
|
+
id:
|
|
1557
|
+
type: string
|
|
1558
|
+
name:
|
|
1559
|
+
type: string
|
|
1560
|
+
project_id:
|
|
1561
|
+
type: string
|
|
1562
|
+
nullable: true
|
|
1563
|
+
description: The project this deliverable is a version of; null once that project is deleted
|
|
1564
|
+
version:
|
|
1565
|
+
type: string
|
|
1566
|
+
nullable: true
|
|
1567
|
+
description: The delivered version, if it has been delivered
|
|
1568
|
+
due:
|
|
1569
|
+
type: string
|
|
1570
|
+
format: date
|
|
1571
|
+
amount:
|
|
1572
|
+
type: integer
|
|
1573
|
+
description: Released on acceptance
|
|
1574
|
+
paid:
|
|
1575
|
+
type: boolean
|
|
1576
|
+
ContractDocument:
|
|
1577
|
+
type: object
|
|
1578
|
+
required:
|
|
1579
|
+
- name
|
|
1580
|
+
- kind
|
|
1581
|
+
- date
|
|
1582
|
+
properties:
|
|
1583
|
+
name:
|
|
1584
|
+
type: string
|
|
1585
|
+
kind:
|
|
1586
|
+
type: string
|
|
1587
|
+
enum:
|
|
1588
|
+
- contract
|
|
1589
|
+
- spec
|
|
1590
|
+
- sla
|
|
1591
|
+
- acceptance
|
|
1592
|
+
date:
|
|
1593
|
+
type: string
|
|
1594
|
+
format: date
|
|
1595
|
+
Contract:
|
|
1596
|
+
type: object
|
|
1597
|
+
required:
|
|
1598
|
+
- id
|
|
1599
|
+
- title
|
|
1600
|
+
- kind
|
|
1601
|
+
- status
|
|
1602
|
+
- orderer
|
|
1603
|
+
- vendor
|
|
1604
|
+
- start
|
|
1605
|
+
- end
|
|
1606
|
+
- amount
|
|
1607
|
+
- oas_url
|
|
1608
|
+
- sla_project_id
|
|
1609
|
+
- sla
|
|
1610
|
+
- related
|
|
1611
|
+
- deliverables
|
|
1612
|
+
- documents
|
|
1613
|
+
- created_at
|
|
1614
|
+
- updated_at
|
|
1615
|
+
properties:
|
|
1616
|
+
id:
|
|
1617
|
+
type: string
|
|
1618
|
+
title:
|
|
1619
|
+
type: string
|
|
1620
|
+
description: Bilingual, "ja / en"
|
|
1621
|
+
kind:
|
|
1622
|
+
type: string
|
|
1623
|
+
enum:
|
|
1624
|
+
- development
|
|
1625
|
+
- maintenance
|
|
1626
|
+
status:
|
|
1627
|
+
type: string
|
|
1628
|
+
enum:
|
|
1629
|
+
- draft
|
|
1630
|
+
- active
|
|
1631
|
+
- completed
|
|
1632
|
+
orderer:
|
|
1633
|
+
type: string
|
|
1634
|
+
vendor:
|
|
1635
|
+
type: string
|
|
1636
|
+
start:
|
|
1637
|
+
type: string
|
|
1638
|
+
format: date
|
|
1639
|
+
end:
|
|
1640
|
+
type: string
|
|
1641
|
+
format: date
|
|
1642
|
+
amount:
|
|
1643
|
+
type: integer
|
|
1644
|
+
oas_url:
|
|
1645
|
+
type: string
|
|
1646
|
+
format: uri
|
|
1647
|
+
nullable: true
|
|
1648
|
+
description: The OpenAPI document this contract refers to, as a plain URL
|
|
1649
|
+
sla_project_id:
|
|
1650
|
+
type: string
|
|
1651
|
+
nullable: true
|
|
1652
|
+
description: "Operations contracts: the project whose uptime the SLA clause covers"
|
|
1653
|
+
sla:
|
|
1654
|
+
allOf:
|
|
1655
|
+
- $ref: "#/components/schemas/ContractSla"
|
|
1656
|
+
nullable: true
|
|
1657
|
+
related:
|
|
1658
|
+
type: object
|
|
1659
|
+
nullable: true
|
|
1660
|
+
description: "How this contract relates to another one: it follows a development contract, or is a change order on top of a running one"
|
|
1661
|
+
properties:
|
|
1662
|
+
id:
|
|
1663
|
+
type: string
|
|
1664
|
+
relation:
|
|
1665
|
+
type: string
|
|
1666
|
+
enum:
|
|
1667
|
+
- follows
|
|
1668
|
+
- change_order
|
|
1669
|
+
deliverables:
|
|
1670
|
+
type: array
|
|
1671
|
+
items:
|
|
1672
|
+
$ref: "#/components/schemas/ContractDeliverable"
|
|
1673
|
+
documents:
|
|
1674
|
+
type: array
|
|
1675
|
+
items:
|
|
1676
|
+
$ref: "#/components/schemas/ContractDocument"
|
|
1677
|
+
created_at:
|
|
1678
|
+
type: string
|
|
1679
|
+
format: date-time
|
|
1680
|
+
updated_at:
|
|
1681
|
+
type: string
|
|
1682
|
+
format: date-time
|
|
1683
|
+
responses:
|
|
1684
|
+
Unauthorized:
|
|
1685
|
+
description: Authentication required or invalid token
|
|
1686
|
+
content:
|
|
1687
|
+
application/json:
|
|
1688
|
+
schema:
|
|
1689
|
+
$ref: "#/components/schemas/Error"
|
|
1690
|
+
example:
|
|
1691
|
+
error:
|
|
1692
|
+
code: AUTH_ERROR
|
|
1693
|
+
message: No authentication token provided
|
|
1694
|
+
ValidationError:
|
|
1695
|
+
description: The request body or a query parameter is invalid
|
|
1696
|
+
content:
|
|
1697
|
+
application/json:
|
|
1698
|
+
schema:
|
|
1699
|
+
$ref: "#/components/schemas/Error"
|
|
1700
|
+
example:
|
|
1701
|
+
success: false
|
|
1702
|
+
error:
|
|
1703
|
+
code: VALIDATION_ERROR
|
|
1704
|
+
message: url must point to a public host
|
|
1705
|
+
NotFound:
|
|
1706
|
+
description: No such monitor, or it belongs to someone else
|
|
1707
|
+
content:
|
|
1708
|
+
application/json:
|
|
1709
|
+
schema:
|
|
1710
|
+
$ref: "#/components/schemas/Error"
|
|
1711
|
+
example:
|
|
1712
|
+
success: false
|
|
1713
|
+
error:
|
|
1714
|
+
code: NOT_FOUND
|
|
1715
|
+
message: Monitor not found
|
|
1716
|
+
Forbidden:
|
|
1717
|
+
description: The caller does not belong to the active organization (`FORBIDDEN`)
|
|
1718
|
+
content:
|
|
1719
|
+
application/json:
|
|
1720
|
+
schema:
|
|
1721
|
+
$ref: "#/components/schemas/Error"
|
|
1722
|
+
parameters:
|
|
1723
|
+
ActiveOrganization:
|
|
1724
|
+
name: X-Active-Organization-Id
|
|
1725
|
+
in: header
|
|
1726
|
+
required: false
|
|
1727
|
+
schema:
|
|
1728
|
+
type: string
|
|
1729
|
+
example: "7"
|
|
1730
|
+
description: "Namespace the request acts in: an organization id, or `personal` (also the default when absent or malformed). Inside an organization every member shares the same monitors, reports and output settings. An organization the caller does not belong to is refused with 403 `FORBIDDEN`."
|