Depot compliance
Registers the compliance routes on mux.
This page is generated from the Depot route table. Every operation carries the permission it needs and the anchor an agent can link to.
GET /api/v1/compliance/evidence-packs
Section titled “GET /api/v1/compliance/evidence-packs”GETcompliance:readtenant facehosteditmspremoteIdempotent
From an MSP console, prefix the path with /api/v1/clients/{clientID} to reach one client.
Source: [object Object]
List compliance evidence packs
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
dir | query | string, one of asc, desc | No | Sort direction. |
framework | query | string | No | |
page | query | integer | No | One-based page number. Defaults to 1. |
pageSize | query | integer | No | Rows per page, 1 to 200. Defaults to 50. |
q | query | string | No | Free-text search term. |
sort | query | string, one of framework, generated, period, size | No | Sort key. |
status | query | string, one of plain, sealed | No | Comma-separated set. An unrecognised value is refused. |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/json, PagedResultEvidencePackView | Success. |
400 | application/problem+json, ProblemDetails | One or more validation errors occurred. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold compliance:read. |
500 | application/problem+json, ProblemDetails | No client store in request context. |
200 response body
| Field | Type | Description |
|---|---|---|
itemsrequired | array of EvidencePackView | |
items[].advisoryrequired | boolean | |
items[].contentSha256required | string | |
items[].contentTyperequired | string | |
items[].createdAtrequired | string (date-time) | |
items[].fileNamerequired | string | |
items[].frameworkrequired | string | |
items[].frameworkNamerequired | string | |
items[].generatedAtrequired | string (date-time) | |
items[].generatedBy | string | |
items[].periodEndrequired | string | |
items[].periodStartrequired | string | |
items[].publicIdrequired | string | |
items[].sizeBytesrequired | integer | int64. |
items[].summaryrequired | EvidencePackSummary | evidencePackSummary is the headline of a stored pack, read back out of its own manifest. |
items[].summary.chainsrequired | array of EvidencePackChainSummary | |
items[].summary.chains[].anchorId | integer | int64. |
items[].summary.chains[].brokenAt | integer | int64. |
items[].summary.chains[].chainrequired | string | |
items[].summary.chains[].entriesrequired | integer | |
items[].summary.chains[].entriesInPeriodrequired | integer | |
items[].summary.chains[].intactrequired | boolean | |
items[].summary.chains[].statusrequired | string | |
items[].summary.compliancePercent | number or null | double. |
items[].summary.controlCountrequired | integer | |
items[].summary.countsrequired | Counts | Counts is a tally of verdicts over some population - one setting across a fleet, one control, one whole framework. |
items[].summary.counts.compliantrequired | integer | |
items[].summary.counts.exceptedrequired | integer | |
items[].summary.counts.gaprequired | integer | |
items[].summary.counts.notApplicablerequired | integer | |
items[].summary.counts.notMeasuredrequired | integer | |
items[].summary.endpointCountrequired | integer | |
items[].summary.exceptionCountrequired | integer | |
items[].summary.policySnapshotCountrequired | integer | |
items[].summary.settingCountrequired | integer | |
items[].summary.truncatedrequired | boolean | |
pagerequired | integer | |
pageSizerequired | integer | |
totalrequired | integer |
Request samples
Section titled “Request samples”# Sign in first. outpost_console is a session cookie, so send it with every request.# This operation is idempotent. Repeating it does not repeat its effect.curl -X GET 'https://depot.example.com/api/v1/compliance/evidence-packs?dir=asc&framework=<framework>&page=0&pageSize=0&q=<q>&sort=framework' \ -H 'X-CSRF-Token: <csrf-token>' \ -H 'Accept: application/json' \ -b 'outpost_console=<console-session>'# Sign in first. outpost_console is a session cookie, so send it with every request.# This operation is idempotent. Repeating it does not repeat its effect.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$response = Invoke-RestMethod ` -Method Get ` -Uri 'https://depot.example.com/api/v1/compliance/evidence-packs?dir=asc&framework=<framework>&page=0&pageSize=0&q=<q>&sort=framework' ` -Headers $headers
$response | ConvertTo-Json -Depth 10# Sign in first. outpost_console is a session cookie, so send it with every request.# This operation is idempotent. Repeating it does not repeat its effect.
import requests
url = "https://depot.example.com/api/v1/compliance/evidence-packs"params = { "dir": "asc", "framework": "<framework>", "page": "0", "pageSize": "0", "q": "<q>", "sort": "framework",}headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json",}cookies = { "outpost_console": "<console-session>",}
response = requests.get(url, params=params, headers=headers, cookies=cookies, timeout=30)response.raise_for_status()print(response.json())// Sign in first. outpost_console is a session cookie, so send it with every request.// This operation is idempotent. Repeating it does not repeat its effect.package main
import ( "fmt" "io" "log" "net/http")
func main() { req, err := http.NewRequest(http.MethodGet, "https://depot.example.com/api/v1/compliance/evidence-packs?dir=asc&framework=<framework>&page=0&pageSize=0&q=<q>&sort=framework", nil) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// Sign in first. outpost_console is a session cookie, so send it with every request.// This operation is idempotent. Repeating it does not repeat its effect.// The session cookie is set by signing in. A script cannot set it itself.
const url = new URL("https://depot.example.com/api/v1/compliance/evidence-packs");url.searchParams.set("dir", "asc");url.searchParams.set("framework", "<framework>");url.searchParams.set("page", "0");url.searchParams.set("pageSize", "0");url.searchParams.set("q", "<q>");url.searchParams.set("sort", "framework");
const response = await fetch(url, { method: "GET", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", }, credentials: "include",});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// Sign in first. outpost_console is a session cookie, so send it with every request.// This operation is idempotent. Repeating it does not repeat its effect.
using System;using System.Net.Http;
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://depot.example.com/api/v1/compliance/evidence-packs?dir=asc&framework=<framework>&page=0&pageSize=0&q=<q>&sort=framework");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());POST /api/v1/compliance/evidence-packs
Section titled “POST /api/v1/compliance/evidence-packs”POSTcompliance:managetenant facehosteditmspremote
From an MSP console, prefix the path with /api/v1/clients/{clientID} to reach one client.
Source: [object Object]
generateComplianceEvidencePack renders one pack and files it.
Request body
Section titled “Request body”Required, sent as application/json.
| Field | Type | Description |
|---|---|---|
frameworkrequired | string | |
periodEndrequired | string | |
periodStartrequired | string |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
201 | application/json, EvidencePackView | Created. |
400 | application/problem+json, ProblemDetails | The request body is not valid JSON. |
401 | application/problem+json, ProblemDetails | Authentication is required: a compliance exception has to record who asked for it. |
403 | application/problem+json, ProblemDetails | The identity does not hold compliance:manage. |
500 | application/problem+json, ProblemDetails | No client store in request context. |
503 | application/problem+json, ProblemDetails | Evidence packs need storage, and no storage profile is configured on this Depot. |
201 response body
| Field | Type | Description |
|---|---|---|
advisoryrequired | boolean | |
contentSha256required | string | |
contentTyperequired | string | |
createdAtrequired | string (date-time) | |
fileNamerequired | string | |
frameworkrequired | string | |
frameworkNamerequired | string | |
generatedAtrequired | string (date-time) | |
generatedBy | string | |
periodEndrequired | string | |
periodStartrequired | string | |
publicIdrequired | string | |
sizeBytesrequired | integer | int64. |
summaryrequired | EvidencePackSummary | evidencePackSummary is the headline of a stored pack, read back out of its own manifest. |
summary.chainsrequired | array of EvidencePackChainSummary | |
summary.chains[].anchorId | integer | int64. |
summary.chains[].brokenAt | integer | int64. |
summary.chains[].chainrequired | string | |
summary.chains[].entriesrequired | integer | |
summary.chains[].entriesInPeriodrequired | integer | |
summary.chains[].intactrequired | boolean | |
summary.chains[].statusrequired | string | |
summary.compliancePercent | number or null | double. |
summary.controlCountrequired | integer | |
summary.countsrequired | Counts | Counts is a tally of verdicts over some population - one setting across a fleet, one control, one whole framework. |
summary.counts.compliantrequired | integer | |
summary.counts.exceptedrequired | integer | |
summary.counts.gaprequired | integer | |
summary.counts.notApplicablerequired | integer | |
summary.counts.notMeasuredrequired | integer | |
summary.endpointCountrequired | integer | |
summary.exceptionCountrequired | integer | |
summary.policySnapshotCountrequired | integer | |
summary.settingCountrequired | integer | |
summary.truncatedrequired | boolean |
Request samples
Section titled “Request samples”# Sign in first. outpost_console is a session cookie, so send it with every request.curl -X POST 'https://depot.example.com/api/v1/compliance/evidence-packs' \ -H 'X-CSRF-Token: <csrf-token>' \ -H 'Accept: application/json' \ -H 'Content-Type: application/json' \ -b 'outpost_console=<console-session>' \ --data '{ "framework": "string", "periodEnd": "string", "periodStart": "string"}'# Sign in first. outpost_console is a session cookie, so send it with every request.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Content-Type' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$body = @'{ "framework": "string", "periodEnd": "string", "periodStart": "string"}'@
$response = Invoke-RestMethod ` -Method Post ` -Uri 'https://depot.example.com/api/v1/compliance/evidence-packs' ` -Headers $headers ` -ContentType 'application/json' ` -Body $body
$response | ConvertTo-Json -Depth 10# Sign in first. outpost_console is a session cookie, so send it with every request.
import requests
url = "https://depot.example.com/api/v1/compliance/evidence-packs"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json",}cookies = { "outpost_console": "<console-session>",}payload = { "framework": "string", "periodEnd": "string", "periodStart": "string",}
response = requests.post(url, headers=headers, cookies=cookies, json=payload, timeout=30)response.raise_for_status()print(response.json())// Sign in first. outpost_console is a session cookie, so send it with every request.package main
import ( "bytes" "fmt" "io" "log" "net/http")
func main() { body := []byte(`{ "framework": "string", "periodEnd": "string", "periodStart": "string"}`)
req, err := http.NewRequest(http.MethodPost, "https://depot.example.com/api/v1/compliance/evidence-packs", bytes.NewReader(body)) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.Header.Set("Content-Type", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// Sign in first. outpost_console is a session cookie, so send it with every request.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/compliance/evidence-packs";
const response = await fetch(url, { method: "POST", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json", }, credentials: "include", body: JSON.stringify({ "framework": "string", "periodEnd": "string", "periodStart": "string" }),});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// Sign in first. outpost_console is a session cookie, so send it with every request.
using System;using System.Net.Http;using System.Text;
using var client = new HttpClient();
const string body = """{ "framework": "string", "periodEnd": "string", "periodStart": "string"}""";
var request = new HttpRequestMessage(HttpMethod.Post, "https://depot.example.com/api/v1/compliance/evidence-packs");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");request.Content = new StringContent(body, Encoding.UTF8, "application/json");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());DELETE /api/v1/compliance/evidence-packs/{publicId}
Section titled “DELETE /api/v1/compliance/evidence-packs/{publicId}”DELETEcompliance:managetenant facehosteditmspremoteIdempotent
From an MSP console, prefix the path with /api/v1/clients/{clientID} to reach one client.
Source: [object Object]
deleteComplianceEvidencePack retires one pack by hand.
THE ROW GOES FIRST AND THE OBJECTS SECOND, which is the sweeper’s order and for the sweeper’s reason: bytes that outlive their row are an orphan the storage accountant reports, while a row whose bytes are gone is a download that 404s and reads to a customer as lost evidence.
The delete is audited on the operator chain. A document that has already been handed to a third party disappearing from the record is precisely the event an auditor would want to see minuted, and the row records who removed it.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
publicId | path | string | Yes | A uuid. |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
204 | None | Success, with no body. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold compliance:manage. |
404 | application/problem+json, ProblemDetails | No resource matches that id. |
500 | application/problem+json, ProblemDetails | No client store in request context. |
Request samples
Section titled “Request samples”# Sign in first. outpost_console is a session cookie, so send it with every request.# This operation is idempotent. Repeating it does not repeat its effect.curl -X DELETE 'https://depot.example.com/api/v1/compliance/evidence-packs/<publicId>' \ -H 'X-CSRF-Token: <csrf-token>' \ -H 'Accept: application/json' \ -b 'outpost_console=<console-session>'# Sign in first. outpost_console is a session cookie, so send it with every request.# This operation is idempotent. Repeating it does not repeat its effect.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$response = Invoke-RestMethod ` -Method Delete ` -Uri 'https://depot.example.com/api/v1/compliance/evidence-packs/<publicId>' ` -Headers $headers
$response | ConvertTo-Json -Depth 10# Sign in first. outpost_console is a session cookie, so send it with every request.# This operation is idempotent. Repeating it does not repeat its effect.
import requests
url = "https://depot.example.com/api/v1/compliance/evidence-packs/<publicId>"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json",}cookies = { "outpost_console": "<console-session>",}
response = requests.delete(url, headers=headers, cookies=cookies, timeout=30)response.raise_for_status()print(response.json())// Sign in first. outpost_console is a session cookie, so send it with every request.// This operation is idempotent. Repeating it does not repeat its effect.package main
import ( "fmt" "io" "log" "net/http")
func main() { req, err := http.NewRequest(http.MethodDelete, "https://depot.example.com/api/v1/compliance/evidence-packs/<publicId>", nil) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// Sign in first. outpost_console is a session cookie, so send it with every request.// This operation is idempotent. Repeating it does not repeat its effect.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/compliance/evidence-packs/<publicId>";
const response = await fetch(url, { method: "DELETE", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", }, credentials: "include",});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// Sign in first. outpost_console is a session cookie, so send it with every request.// This operation is idempotent. Repeating it does not repeat its effect.
using System;using System.Net.Http;
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Delete, "https://depot.example.com/api/v1/compliance/evidence-packs/<publicId>");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());GET /api/v1/compliance/evidence-packs/{publicId}/download
Section titled “GET /api/v1/compliance/evidence-packs/{publicId}/download”GETcompliance:readtenant facehosteditmspremoteIdempotentdownloadNot fully resolved
From an MSP console, prefix the path with /api/v1/clients/{clientID} to reach one client.
What this page does not know
- response
These are parts of the route the extractor could not read from the source. Everything else on this page came straight from it.
Source: [object Object]
downloadComplianceEvidencePack streams the stored PDF.
It serves the real content type rather than attachments.go’s forced application/octet-stream, and that difference is deliberate. The rule there exists because the bytes were UPLOADED by somebody and could be an HTML document that would run on the console’s origin. These bytes were RENDERED BY THIS PROCESS from a template it owns, so the type is a fact rather than a claim. The disposition is still “attachment” and nosniff is still set: a compliance document belongs in the reader’s filing system, not in a tab.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
publicId | path | string | Yes | A uuid. |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/octet-stream, string (binary) | Success. The body shape was not resolved; see x-outpost-unresolved. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold compliance:read. |
404 | application/problem+json, ProblemDetails | No resource matches that id. |
500 | application/problem+json, ProblemDetails | No client store in request context. |
502 | application/problem+json, ProblemDetails | The document could not be read from storage. |
503 | application/problem+json, ProblemDetails | Evidence packs need storage, and no storage profile is configured on this Depot. |
Request samples
Section titled “Request samples”# Sign in first. outpost_console is a session cookie, so send it with every request.# This operation is idempotent. Repeating it does not repeat its effect.curl -X GET 'https://depot.example.com/api/v1/compliance/evidence-packs/<publicId>/download' \ -H 'X-CSRF-Token: <csrf-token>' \ -H 'Accept: application/json' \ -b 'outpost_console=<console-session>'# Sign in first. outpost_console is a session cookie, so send it with every request.# This operation is idempotent. Repeating it does not repeat its effect.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$response = Invoke-RestMethod ` -Method Get ` -Uri 'https://depot.example.com/api/v1/compliance/evidence-packs/<publicId>/download' ` -Headers $headers
$response | ConvertTo-Json -Depth 10# Sign in first. outpost_console is a session cookie, so send it with every request.# This operation is idempotent. Repeating it does not repeat its effect.
import requests
url = "https://depot.example.com/api/v1/compliance/evidence-packs/<publicId>/download"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json",}cookies = { "outpost_console": "<console-session>",}
response = requests.get(url, headers=headers, cookies=cookies, timeout=30)response.raise_for_status()print(response.json())// Sign in first. outpost_console is a session cookie, so send it with every request.// This operation is idempotent. Repeating it does not repeat its effect.package main
import ( "fmt" "io" "log" "net/http")
func main() { req, err := http.NewRequest(http.MethodGet, "https://depot.example.com/api/v1/compliance/evidence-packs/<publicId>/download", nil) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// Sign in first. outpost_console is a session cookie, so send it with every request.// This operation is idempotent. Repeating it does not repeat its effect.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/compliance/evidence-packs/<publicId>/download";
const response = await fetch(url, { method: "GET", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", }, credentials: "include",});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// Sign in first. outpost_console is a session cookie, so send it with every request.// This operation is idempotent. Repeating it does not repeat its effect.
using System;using System.Net.Http;
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://depot.example.com/api/v1/compliance/evidence-packs/<publicId>/download");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());GET /api/v1/compliance/exceptions
Section titled “GET /api/v1/compliance/exceptions”GETcompliance:readtenant facehosteditmspremoteIdempotent
From an MSP console, prefix the path with /api/v1/clients/{clientID} to reach one client.
Source: [object Object]
listComplianceExceptions answers the register.
ponytail: the store returns every matching row and this pages the slice, so a client with ten thousand exceptions materializes ten thousand. The register is a human-reviewed list bounded by how many gaps an organisation is willing to sign for, and the count is in the tens. What matters is that the total below is the FILTERED total - it is the length of what the filter returned, not of the table - so paging cannot promise a page that is not there. The upgrade when a tenant proves that wrong is a paged store method beside this one, which is what the two callers in internal/evidencepack need this one left alone for.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
dir | query | string, one of asc, desc | No | Sort direction. |
framework | query | string | No | |
page | query | integer | No | One-based page number. Defaults to 1. |
pageSize | query | integer | No | Rows per page, 1 to 200. Defaults to 50. |
q | query | string | No | Free-text search term. |
scopeType | query | string | No | |
settingKey | query | string | No | |
sort | query | string, one of created, expires, framework, setting, status | No | Sort key. |
status | query | string | No |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/json, PagedResultComplianceExceptionView | Success. |
400 | application/problem+json, ProblemDetails | One or more validation errors occurred. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold compliance:read. |
500 | application/problem+json, ProblemDetails | No client store in request context. |
200 response body
| Field | Type | Description |
|---|---|---|
itemsrequired | array of ComplianceExceptionView | |
items[].approvedAt | string (date-time) or null | |
items[].approvedBy | string | |
items[].createdAtrequired | string (date-time) | |
items[].expiresAtrequired | string (date-time) | |
items[].frameworkrequired | string | |
items[].justificationrequired | string | |
items[].publicIdrequired | string | |
items[].requestedByrequired | string | |
items[].revokedAt | string (date-time) or null | |
items[].revokedBy | string | |
items[].scopeId | string | |
items[].scopeTyperequired | string | |
items[].settingKeyrequired | string | |
items[].statusrequired | string | |
items[].updatedAtrequired | string (date-time) | |
pagerequired | integer | |
pageSizerequired | integer | |
totalrequired | integer |
Request samples
Section titled “Request samples”# Sign in first. outpost_console is a session cookie, so send it with every request.# This operation is idempotent. Repeating it does not repeat its effect.curl -X GET 'https://depot.example.com/api/v1/compliance/exceptions?dir=asc&framework=<framework>&page=0&pageSize=0&q=<q>&scopeType=<scopeType>' \ -H 'X-CSRF-Token: <csrf-token>' \ -H 'Accept: application/json' \ -b 'outpost_console=<console-session>'# Sign in first. outpost_console is a session cookie, so send it with every request.# This operation is idempotent. Repeating it does not repeat its effect.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$response = Invoke-RestMethod ` -Method Get ` -Uri 'https://depot.example.com/api/v1/compliance/exceptions?dir=asc&framework=<framework>&page=0&pageSize=0&q=<q>&scopeType=<scopeType>' ` -Headers $headers
$response | ConvertTo-Json -Depth 10# Sign in first. outpost_console is a session cookie, so send it with every request.# This operation is idempotent. Repeating it does not repeat its effect.
import requests
url = "https://depot.example.com/api/v1/compliance/exceptions"params = { "dir": "asc", "framework": "<framework>", "page": "0", "pageSize": "0", "q": "<q>", "scopeType": "<scopeType>",}headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json",}cookies = { "outpost_console": "<console-session>",}
response = requests.get(url, params=params, headers=headers, cookies=cookies, timeout=30)response.raise_for_status()print(response.json())// Sign in first. outpost_console is a session cookie, so send it with every request.// This operation is idempotent. Repeating it does not repeat its effect.package main
import ( "fmt" "io" "log" "net/http")
func main() { req, err := http.NewRequest(http.MethodGet, "https://depot.example.com/api/v1/compliance/exceptions?dir=asc&framework=<framework>&page=0&pageSize=0&q=<q>&scopeType=<scopeType>", nil) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// Sign in first. outpost_console is a session cookie, so send it with every request.// This operation is idempotent. Repeating it does not repeat its effect.// The session cookie is set by signing in. A script cannot set it itself.
const url = new URL("https://depot.example.com/api/v1/compliance/exceptions");url.searchParams.set("dir", "asc");url.searchParams.set("framework", "<framework>");url.searchParams.set("page", "0");url.searchParams.set("pageSize", "0");url.searchParams.set("q", "<q>");url.searchParams.set("scopeType", "<scopeType>");
const response = await fetch(url, { method: "GET", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", }, credentials: "include",});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// Sign in first. outpost_console is a session cookie, so send it with every request.// This operation is idempotent. Repeating it does not repeat its effect.
using System;using System.Net.Http;
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://depot.example.com/api/v1/compliance/exceptions?dir=asc&framework=<framework>&page=0&pageSize=0&q=<q>&scopeType=<scopeType>");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());POST /api/v1/compliance/exceptions
Section titled “POST /api/v1/compliance/exceptions”POSTcompliance:readtenant facehosteditmspremote
From an MSP console, prefix the path with /api/v1/clients/{clientID} to reach one client.
Source: [object Object]
Create compliance exception
Request body
Section titled “Request body”Required, sent as application/json.
| Field | Type | Description |
|---|---|---|
expiresAtrequired | string (date-time) | |
frameworkrequired | string | |
justificationrequired | string | |
scopeIdrequired | string | |
scopeTyperequired | string | |
settingKeyrequired | string |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
201 | application/json, ComplianceExceptionView | Created. |
400 | application/problem+json, ProblemDetails | The request body is not valid JSON. |
401 | application/problem+json, ProblemDetails | Authentication is required: a compliance exception has to record who asked for it. |
403 | application/problem+json, ProblemDetails | The identity does not hold compliance:read. |
404 | application/problem+json, ProblemDetails | No setting matches that key. |
409 | application/problem+json, ProblemDetails | That exception is not a combination this client’s schema allows. |
500 | application/problem+json, ProblemDetails | No client store in request context. |
201 response body
| Field | Type | Description |
|---|---|---|
approvedAt | string (date-time) or null | |
approvedBy | string | |
createdAtrequired | string (date-time) | |
expiresAtrequired | string (date-time) | |
frameworkrequired | string | |
justificationrequired | string | |
publicIdrequired | string | |
requestedByrequired | string | |
revokedAt | string (date-time) or null | |
revokedBy | string | |
scopeId | string | |
scopeTyperequired | string | |
settingKeyrequired | string | |
statusrequired | string | |
updatedAtrequired | string (date-time) |
Request samples
Section titled “Request samples”# Sign in first. outpost_console is a session cookie, so send it with every request.curl -X POST 'https://depot.example.com/api/v1/compliance/exceptions' \ -H 'X-CSRF-Token: <csrf-token>' \ -H 'Accept: application/json' \ -H 'Content-Type: application/json' \ -b 'outpost_console=<console-session>' \ --data '{ "expiresAt": "2026-01-01T00:00:00Z", "framework": "string", "justification": "string", "scopeId": "string", "scopeType": "string", "settingKey": "string"}'# Sign in first. outpost_console is a session cookie, so send it with every request.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Content-Type' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$body = @'{ "expiresAt": "2026-01-01T00:00:00Z", "framework": "string", "justification": "string", "scopeId": "string", "scopeType": "string", "settingKey": "string"}'@
$response = Invoke-RestMethod ` -Method Post ` -Uri 'https://depot.example.com/api/v1/compliance/exceptions' ` -Headers $headers ` -ContentType 'application/json' ` -Body $body
$response | ConvertTo-Json -Depth 10# Sign in first. outpost_console is a session cookie, so send it with every request.
import requests
url = "https://depot.example.com/api/v1/compliance/exceptions"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json",}cookies = { "outpost_console": "<console-session>",}payload = { "expiresAt": "2026-01-01T00:00:00Z", "framework": "string", "justification": "string", "scopeId": "string", "scopeType": "string", "settingKey": "string",}
response = requests.post(url, headers=headers, cookies=cookies, json=payload, timeout=30)response.raise_for_status()print(response.json())// Sign in first. outpost_console is a session cookie, so send it with every request.package main
import ( "bytes" "fmt" "io" "log" "net/http")
func main() { body := []byte(`{ "expiresAt": "2026-01-01T00:00:00Z", "framework": "string", "justification": "string", "scopeId": "string", "scopeType": "string", "settingKey": "string"}`)
req, err := http.NewRequest(http.MethodPost, "https://depot.example.com/api/v1/compliance/exceptions", bytes.NewReader(body)) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.Header.Set("Content-Type", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// Sign in first. outpost_console is a session cookie, so send it with every request.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/compliance/exceptions";
const response = await fetch(url, { method: "POST", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json", }, credentials: "include", body: JSON.stringify({ "expiresAt": "2026-01-01T00:00:00Z", "framework": "string", "justification": "string", "scopeId": "string", "scopeType": "string", "settingKey": "string" }),});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// Sign in first. outpost_console is a session cookie, so send it with every request.
using System;using System.Net.Http;using System.Text;
using var client = new HttpClient();
const string body = """{ "expiresAt": "2026-01-01T00:00:00Z", "framework": "string", "justification": "string", "scopeId": "string", "scopeType": "string", "settingKey": "string"}""";
var request = new HttpRequestMessage(HttpMethod.Post, "https://depot.example.com/api/v1/compliance/exceptions");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");request.Content = new StringContent(body, Encoding.UTF8, "application/json");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());POST /api/v1/compliance/exceptions/{publicId}/approve
Section titled “POST /api/v1/compliance/exceptions/{publicId}/approve”POSTcompliance:managetenant facehosteditmspremoteIdempotent
From an MSP console, prefix the path with /api/v1/clients/{clientID} to reach one client.
Source: [object Object]
Approve compliance exception
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
publicId | path | string | Yes | A uuid. |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/json, ComplianceExceptionView | Success. |
401 | application/problem+json, ProblemDetails | Authentication is required: a compliance exception has to record who asked for it. |
403 | application/problem+json, ProblemDetails | The identity does not hold compliance:manage. |
404 | application/problem+json, ProblemDetails | No resource matches that id. |
409 | application/problem+json, ProblemDetails | An exception has to be approved by somebody other than the operator who requested it. |
500 | application/problem+json, ProblemDetails | No client store in request context. |
200 response body
| Field | Type | Description |
|---|---|---|
approvedAt | string (date-time) or null | |
approvedBy | string | |
createdAtrequired | string (date-time) | |
expiresAtrequired | string (date-time) | |
frameworkrequired | string | |
justificationrequired | string | |
publicIdrequired | string | |
requestedByrequired | string | |
revokedAt | string (date-time) or null | |
revokedBy | string | |
scopeId | string | |
scopeTyperequired | string | |
settingKeyrequired | string | |
statusrequired | string | |
updatedAtrequired | string (date-time) |
Request samples
Section titled “Request samples”# Sign in first. outpost_console is a session cookie, so send it with every request.# This operation is idempotent. Repeating it does not repeat its effect.curl -X POST 'https://depot.example.com/api/v1/compliance/exceptions/<publicId>/approve' \ -H 'X-CSRF-Token: <csrf-token>' \ -H 'Accept: application/json' \ -b 'outpost_console=<console-session>'# Sign in first. outpost_console is a session cookie, so send it with every request.# This operation is idempotent. Repeating it does not repeat its effect.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$response = Invoke-RestMethod ` -Method Post ` -Uri 'https://depot.example.com/api/v1/compliance/exceptions/<publicId>/approve' ` -Headers $headers
$response | ConvertTo-Json -Depth 10# Sign in first. outpost_console is a session cookie, so send it with every request.# This operation is idempotent. Repeating it does not repeat its effect.
import requests
url = "https://depot.example.com/api/v1/compliance/exceptions/<publicId>/approve"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json",}cookies = { "outpost_console": "<console-session>",}
response = requests.post(url, headers=headers, cookies=cookies, timeout=30)response.raise_for_status()print(response.json())// Sign in first. outpost_console is a session cookie, so send it with every request.// This operation is idempotent. Repeating it does not repeat its effect.package main
import ( "fmt" "io" "log" "net/http")
func main() { req, err := http.NewRequest(http.MethodPost, "https://depot.example.com/api/v1/compliance/exceptions/<publicId>/approve", nil) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// Sign in first. outpost_console is a session cookie, so send it with every request.// This operation is idempotent. Repeating it does not repeat its effect.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/compliance/exceptions/<publicId>/approve";
const response = await fetch(url, { method: "POST", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", }, credentials: "include",});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// Sign in first. outpost_console is a session cookie, so send it with every request.// This operation is idempotent. Repeating it does not repeat its effect.
using System;using System.Net.Http;
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Post, "https://depot.example.com/api/v1/compliance/exceptions/<publicId>/approve");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());POST /api/v1/compliance/exceptions/{publicId}/revoke
Section titled “POST /api/v1/compliance/exceptions/{publicId}/revoke”POSTcompliance:managetenant facehosteditmspremoteIdempotent
From an MSP console, prefix the path with /api/v1/clients/{clientID} to reach one client.
Source: [object Object]
Revoke compliance exception
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
publicId | path | string | Yes | A uuid. |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/json, ComplianceExceptionView | Success. |
401 | application/problem+json, ProblemDetails | Authentication is required: a compliance exception has to record who asked for it. |
403 | application/problem+json, ProblemDetails | The identity does not hold compliance:manage. |
404 | application/problem+json, ProblemDetails | No resource matches that id. |
409 | application/problem+json, ProblemDetails | This exception cannot be revoked: it has already been revoked or has expired. |
500 | application/problem+json, ProblemDetails | No client store in request context. |
200 response body
| Field | Type | Description |
|---|---|---|
approvedAt | string (date-time) or null | |
approvedBy | string | |
createdAtrequired | string (date-time) | |
expiresAtrequired | string (date-time) | |
frameworkrequired | string | |
justificationrequired | string | |
publicIdrequired | string | |
requestedByrequired | string | |
revokedAt | string (date-time) or null | |
revokedBy | string | |
scopeId | string | |
scopeTyperequired | string | |
settingKeyrequired | string | |
statusrequired | string | |
updatedAtrequired | string (date-time) |
Request samples
Section titled “Request samples”# Sign in first. outpost_console is a session cookie, so send it with every request.# This operation is idempotent. Repeating it does not repeat its effect.curl -X POST 'https://depot.example.com/api/v1/compliance/exceptions/<publicId>/revoke' \ -H 'X-CSRF-Token: <csrf-token>' \ -H 'Accept: application/json' \ -b 'outpost_console=<console-session>'# Sign in first. outpost_console is a session cookie, so send it with every request.# This operation is idempotent. Repeating it does not repeat its effect.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$response = Invoke-RestMethod ` -Method Post ` -Uri 'https://depot.example.com/api/v1/compliance/exceptions/<publicId>/revoke' ` -Headers $headers
$response | ConvertTo-Json -Depth 10# Sign in first. outpost_console is a session cookie, so send it with every request.# This operation is idempotent. Repeating it does not repeat its effect.
import requests
url = "https://depot.example.com/api/v1/compliance/exceptions/<publicId>/revoke"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json",}cookies = { "outpost_console": "<console-session>",}
response = requests.post(url, headers=headers, cookies=cookies, timeout=30)response.raise_for_status()print(response.json())// Sign in first. outpost_console is a session cookie, so send it with every request.// This operation is idempotent. Repeating it does not repeat its effect.package main
import ( "fmt" "io" "log" "net/http")
func main() { req, err := http.NewRequest(http.MethodPost, "https://depot.example.com/api/v1/compliance/exceptions/<publicId>/revoke", nil) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// Sign in first. outpost_console is a session cookie, so send it with every request.// This operation is idempotent. Repeating it does not repeat its effect.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/compliance/exceptions/<publicId>/revoke";
const response = await fetch(url, { method: "POST", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", }, credentials: "include",});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// Sign in first. outpost_console is a session cookie, so send it with every request.// This operation is idempotent. Repeating it does not repeat its effect.
using System;using System.Net.Http;
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Post, "https://depot.example.com/api/v1/compliance/exceptions/<publicId>/revoke");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());POST /api/v1/compliance/gaps/alerts
Section titled “POST /api/v1/compliance/gaps/alerts”POSTcompliance:managetenant facehosteditmspremote
From an MSP console, prefix the path with /api/v1/clients/{clientID} to reach one client.
Source: [object Object]
Create compliance gap alerts
Request body
Section titled “Request body”Required, sent as application/json.
| Field | Type | Description |
|---|---|---|
agentIdsrequired | array of string | |
frameworkrequired | string | |
levelrequired | string | |
settingKeyrequired | string |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
201 | application/json, object | Created. |
400 | application/problem+json, ProblemDetails | The request body is not valid JSON. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold compliance:manage. |
404 | application/problem+json, ProblemDetails | Endpoint or control not found. |
409 | application/problem+json, ProblemDetails | Could not raise the remediation alert. |
500 | application/problem+json, ProblemDetails | No client store in request context. |
Request samples
Section titled “Request samples”# Sign in first. outpost_console is a session cookie, so send it with every request.curl -X POST 'https://depot.example.com/api/v1/compliance/gaps/alerts' \ -H 'X-CSRF-Token: <csrf-token>' \ -H 'Accept: application/json' \ -H 'Content-Type: application/json' \ -b 'outpost_console=<console-session>' \ --data '{ "agentIds": [ "string" ], "framework": "string", "level": "string", "settingKey": "string"}'# Sign in first. outpost_console is a session cookie, so send it with every request.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Content-Type' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$body = @'{ "agentIds": [ "string" ], "framework": "string", "level": "string", "settingKey": "string"}'@
$response = Invoke-RestMethod ` -Method Post ` -Uri 'https://depot.example.com/api/v1/compliance/gaps/alerts' ` -Headers $headers ` -ContentType 'application/json' ` -Body $body
$response | ConvertTo-Json -Depth 10# Sign in first. outpost_console is a session cookie, so send it with every request.
import requests
url = "https://depot.example.com/api/v1/compliance/gaps/alerts"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json",}cookies = { "outpost_console": "<console-session>",}payload = { "agentIds": [ "string", ], "framework": "string", "level": "string", "settingKey": "string",}
response = requests.post(url, headers=headers, cookies=cookies, json=payload, timeout=30)response.raise_for_status()print(response.json())// Sign in first. outpost_console is a session cookie, so send it with every request.package main
import ( "bytes" "fmt" "io" "log" "net/http")
func main() { body := []byte(`{ "agentIds": [ "string" ], "framework": "string", "level": "string", "settingKey": "string"}`)
req, err := http.NewRequest(http.MethodPost, "https://depot.example.com/api/v1/compliance/gaps/alerts", bytes.NewReader(body)) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.Header.Set("Content-Type", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// Sign in first. outpost_console is a session cookie, so send it with every request.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/compliance/gaps/alerts";
const response = await fetch(url, { method: "POST", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json", }, credentials: "include", body: JSON.stringify({ "agentIds": [ "string" ], "framework": "string", "level": "string", "settingKey": "string" }),});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// Sign in first. outpost_console is a session cookie, so send it with every request.
using System;using System.Net.Http;using System.Text;
using var client = new HttpClient();
const string body = """{ "agentIds": [ "string" ], "framework": "string", "level": "string", "settingKey": "string"}""";
var request = new HttpRequestMessage(HttpMethod.Post, "https://depot.example.com/api/v1/compliance/gaps/alerts");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");request.Content = new StringContent(body, Encoding.UTF8, "application/json");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());POST /api/v1/compliance/gaps/ticket
Section titled “POST /api/v1/compliance/gaps/ticket”POSTcompliance:managetenant facehosteditmspremote
From an MSP console, prefix the path with /api/v1/clients/{clientID} to reach one client.
Source: [object Object]
Create compliance gap ticket
Request body
Section titled “Request body”Required, sent as application/json.
| Field | Type | Description |
|---|---|---|
agentIdsrequired | array of string | |
frameworkrequired | string | |
levelrequired | string | |
settingKeyrequired | string |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
201 | application/json, GapTicketResult | Created. |
400 | application/problem+json, ProblemDetails | The request body is not valid JSON. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold compliance:manage. |
404 | application/problem+json, ProblemDetails | No baseline matches that framework, setting and control. |
409 | application/problem+json, ProblemDetails | That ticket is not a combination this client’s schema allows. |
500 | application/problem+json, ProblemDetails | No client store in request context. |
201 response body
| Field | Type | Description |
|---|---|---|
affectedEndpointsrequired | integer | |
numberrequired | integer | int64. |
referencerequired | string | |
tag | string | |
taggedrequired | boolean | |
ticketPublicIdrequired | string |
Request samples
Section titled “Request samples”# Sign in first. outpost_console is a session cookie, so send it with every request.curl -X POST 'https://depot.example.com/api/v1/compliance/gaps/ticket' \ -H 'X-CSRF-Token: <csrf-token>' \ -H 'Accept: application/json' \ -H 'Content-Type: application/json' \ -b 'outpost_console=<console-session>' \ --data '{ "agentIds": [ "string" ], "framework": "string", "level": "string", "settingKey": "string"}'# Sign in first. outpost_console is a session cookie, so send it with every request.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Content-Type' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$body = @'{ "agentIds": [ "string" ], "framework": "string", "level": "string", "settingKey": "string"}'@
$response = Invoke-RestMethod ` -Method Post ` -Uri 'https://depot.example.com/api/v1/compliance/gaps/ticket' ` -Headers $headers ` -ContentType 'application/json' ` -Body $body
$response | ConvertTo-Json -Depth 10# Sign in first. outpost_console is a session cookie, so send it with every request.
import requests
url = "https://depot.example.com/api/v1/compliance/gaps/ticket"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json",}cookies = { "outpost_console": "<console-session>",}payload = { "agentIds": [ "string", ], "framework": "string", "level": "string", "settingKey": "string",}
response = requests.post(url, headers=headers, cookies=cookies, json=payload, timeout=30)response.raise_for_status()print(response.json())// Sign in first. outpost_console is a session cookie, so send it with every request.package main
import ( "bytes" "fmt" "io" "log" "net/http")
func main() { body := []byte(`{ "agentIds": [ "string" ], "framework": "string", "level": "string", "settingKey": "string"}`)
req, err := http.NewRequest(http.MethodPost, "https://depot.example.com/api/v1/compliance/gaps/ticket", bytes.NewReader(body)) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.Header.Set("Content-Type", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// Sign in first. outpost_console is a session cookie, so send it with every request.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/compliance/gaps/ticket";
const response = await fetch(url, { method: "POST", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json", }, credentials: "include", body: JSON.stringify({ "agentIds": [ "string" ], "framework": "string", "level": "string", "settingKey": "string" }),});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// Sign in first. outpost_console is a session cookie, so send it with every request.
using System;using System.Net.Http;using System.Text;
using var client = new HttpClient();
const string body = """{ "agentIds": [ "string" ], "framework": "string", "level": "string", "settingKey": "string"}""";
var request = new HttpRequestMessage(HttpMethod.Post, "https://depot.example.com/api/v1/compliance/gaps/ticket");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");request.Content = new StringContent(body, Encoding.UTF8, "application/json");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());GET /api/v1/compliance/posture
Section titled “GET /api/v1/compliance/posture”GETcompliance:readtenant facehosteditmspremoteIdempotent
From an MSP console, prefix the path with /api/v1/clients/{clientID} to reach one client.
Source: [object Object]
listCompliancePosture answers every framework this client has DECLARED, with its totals.
Declared, not every framework that exists. A console offering eleven rows of zeroes to a customer who has adopted one scheme would bury the one line that matters, and “we are not measured against PCI” is already said by PCI’s absence. The per-framework route below still answers for an undeclared framework, so a picker can ask “what would CJIS look like” without this list having to pre-empt it.
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/json, Summary | Success. |
400 | application/problem+json, ProblemDetails | One or more validation errors occurred. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold compliance:read. |
500 | application/problem+json, ProblemDetails | No client store in request context. |
200 response body
| Field | Type | Description |
|---|---|---|
endpointCountrequired | integer | |
frameworksrequired | array of FrameworkSummary | |
frameworks[].advisoryrequired | boolean | |
frameworks[].compliancePercent | number or null | double. |
frameworks[].controlCountrequired | integer | |
frameworks[].countsrequired | Counts | Counts is a tally of verdicts over some population - one setting across a fleet, one control, one whole framework. |
frameworks[].counts.compliantrequired | integer | |
frameworks[].counts.exceptedrequired | integer | |
frameworks[].counts.gaprequired | integer | |
frameworks[].counts.notApplicablerequired | integer | |
frameworks[].counts.notMeasuredrequired | integer | |
frameworks[].endpointCountrequired | integer | |
frameworks[].frameworkrequired | string | |
frameworks[].settingCountrequired | integer | |
generatedAtrequired | string (date-time) | |
truncatedrequired | boolean |
Request samples
Section titled “Request samples”# Sign in first. outpost_console is a session cookie, so send it with every request.# This operation is idempotent. Repeating it does not repeat its effect.curl -X GET 'https://depot.example.com/api/v1/compliance/posture' \ -H 'X-CSRF-Token: <csrf-token>' \ -H 'Accept: application/json' \ -b 'outpost_console=<console-session>'# Sign in first. outpost_console is a session cookie, so send it with every request.# This operation is idempotent. Repeating it does not repeat its effect.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$response = Invoke-RestMethod ` -Method Get ` -Uri 'https://depot.example.com/api/v1/compliance/posture' ` -Headers $headers
$response | ConvertTo-Json -Depth 10# Sign in first. outpost_console is a session cookie, so send it with every request.# This operation is idempotent. Repeating it does not repeat its effect.
import requests
url = "https://depot.example.com/api/v1/compliance/posture"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json",}cookies = { "outpost_console": "<console-session>",}
response = requests.get(url, headers=headers, cookies=cookies, timeout=30)response.raise_for_status()print(response.json())// Sign in first. outpost_console is a session cookie, so send it with every request.// This operation is idempotent. Repeating it does not repeat its effect.package main
import ( "fmt" "io" "log" "net/http")
func main() { req, err := http.NewRequest(http.MethodGet, "https://depot.example.com/api/v1/compliance/posture", nil) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// Sign in first. outpost_console is a session cookie, so send it with every request.// This operation is idempotent. Repeating it does not repeat its effect.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/compliance/posture";
const response = await fetch(url, { method: "GET", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", }, credentials: "include",});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// Sign in first. outpost_console is a session cookie, so send it with every request.// This operation is idempotent. Repeating it does not repeat its effect.
using System;using System.Net.Http;
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://depot.example.com/api/v1/compliance/posture");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());GET /api/v1/compliance/posture/{framework}
Section titled “GET /api/v1/compliance/posture/{framework}”GETcompliance:readtenant facehosteditmspremoteIdempotent
From an MSP console, prefix the path with /api/v1/clients/{clientID} to reach one client.
Source: [object Object]
getCompliancePosture answers one framework, broken down by control.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
framework | path | string | Yes |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/json, FrameworkPosture | Success. |
400 | application/problem+json, ProblemDetails | One or more validation errors occurred. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold compliance:read. |
404 | application/problem+json, ProblemDetails | Framework must be one of “soc2”, “cjis”, “pci_dss”, “hipaa”, “nist_800_171”, “nist_800_53”, “cmmc_l2”, “iso_27001”, “stig”, “ms_baseline”, “cis”. |
500 | application/problem+json, ProblemDetails | No client store in request context. |
200 response body
| Field | Type | Description |
|---|---|---|
advisoryrequired | boolean | |
compliancePercent | number or null | double. |
controlCountrequired | integer | |
controlsrequired | array of ControlPosture | |
controls[].compliancePercent | number or null | double. |
controls[].countsrequired | Counts | Counts is a tally of verdicts over some population - one setting across a fleet, one control, one whole framework. |
controls[].counts.compliantrequired | integer | |
controls[].counts.exceptedrequired | integer | |
controls[].counts.gaprequired | integer | |
controls[].counts.notApplicablerequired | integer | |
controls[].counts.notMeasuredrequired | integer | |
controls[].levelrequired | string | |
controls[].settingsrequired | array of SettingPosture | |
controls[].settings[].citation | string | |
controls[].settings[].compliancePercent | number or null | double. |
controls[].settings[].countsrequired | Counts | Counts is a tally of verdicts over some population - one setting across a fleet, one control, one whole framework. |
controls[].settings[].counts.compliantrequired | integer | |
controls[].settings[].counts.exceptedrequired | integer | |
controls[].settings[].counts.gaprequired | integer | |
controls[].settings[].counts.notApplicablerequired | integer | |
controls[].settings[].counts.notMeasuredrequired | integer | |
controls[].settings[].description | string | |
controls[].settings[].enforcementrequired | string | |
controls[].settings[].expectedrequired | any | Arbitrary JSON. |
controls[].settings[].settingKeyrequired | string | |
countsrequired | Counts | Counts is a tally of verdicts over some population - one setting across a fleet, one control, one whole framework. |
counts.compliantrequired | integer | |
counts.exceptedrequired | integer | |
counts.gaprequired | integer | |
counts.notApplicablerequired | integer | |
counts.notMeasuredrequired | integer | |
endpointCountrequired | integer | |
frameworkrequired | string | |
generatedAtrequired | string (date-time) | |
settingCountrequired | integer | |
truncatedrequired | boolean |
Request samples
Section titled “Request samples”# Sign in first. outpost_console is a session cookie, so send it with every request.# This operation is idempotent. Repeating it does not repeat its effect.curl -X GET 'https://depot.example.com/api/v1/compliance/posture/<framework>' \ -H 'X-CSRF-Token: <csrf-token>' \ -H 'Accept: application/json' \ -b 'outpost_console=<console-session>'# Sign in first. outpost_console is a session cookie, so send it with every request.# This operation is idempotent. Repeating it does not repeat its effect.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$response = Invoke-RestMethod ` -Method Get ` -Uri 'https://depot.example.com/api/v1/compliance/posture/<framework>' ` -Headers $headers
$response | ConvertTo-Json -Depth 10# Sign in first. outpost_console is a session cookie, so send it with every request.# This operation is idempotent. Repeating it does not repeat its effect.
import requests
url = "https://depot.example.com/api/v1/compliance/posture/<framework>"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json",}cookies = { "outpost_console": "<console-session>",}
response = requests.get(url, headers=headers, cookies=cookies, timeout=30)response.raise_for_status()print(response.json())// Sign in first. outpost_console is a session cookie, so send it with every request.// This operation is idempotent. Repeating it does not repeat its effect.package main
import ( "fmt" "io" "log" "net/http")
func main() { req, err := http.NewRequest(http.MethodGet, "https://depot.example.com/api/v1/compliance/posture/<framework>", nil) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// Sign in first. outpost_console is a session cookie, so send it with every request.// This operation is idempotent. Repeating it does not repeat its effect.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/compliance/posture/<framework>";
const response = await fetch(url, { method: "GET", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", }, credentials: "include",});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// Sign in first. outpost_console is a session cookie, so send it with every request.// This operation is idempotent. Repeating it does not repeat its effect.
using System;using System.Net.Http;
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://depot.example.com/api/v1/compliance/posture/<framework>");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());GET /api/v1/compliance/posture/{framework}/controls/{level}
Section titled “GET /api/v1/compliance/posture/{framework}/controls/{level}”GETcompliance:readtenant facehosteditmspremoteIdempotent
From an MSP console, prefix the path with /api/v1/clients/{clientID} to reach one client.
Source: [object Object]
getComplianceControl answers one control, per machine.
The {level} segment is a framework’s own control identifier and its shape varies wildly between schemes: “CC6.8” for SOC 2, “164.312(a)(2)(iv)” for HIPAA, “WNDF-AV-000010” for a STIG. Go’s ServeMux hands it over already percent-decoded, so a console that escapes the segment gets the literal back, and nothing here needs to parse it - it is matched against the catalog by equality and never interpreted.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
framework | path | string | Yes | |
level | path | string | Yes |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/json, ControlDetail | Success. |
400 | application/problem+json, ProblemDetails | One or more validation errors occurred. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold compliance:read. |
404 | application/problem+json, ProblemDetails | Framework must be one of “soc2”, “cjis”, “pci_dss”, “hipaa”, “nist_800_171”, “nist_800_53”, “cmmc_l2”, “iso_27001”, “stig”, “ms_baseline”, “cis”. |
500 | application/problem+json, ProblemDetails | No client store in request context. |
200 response body
| Field | Type | Description |
|---|---|---|
advisoryrequired | boolean | |
compliancePercent | number or null | double. |
countsrequired | Counts | Counts is a tally of verdicts over some population - one setting across a fleet, one control, one whole framework. |
counts.compliantrequired | integer | |
counts.exceptedrequired | integer | |
counts.gaprequired | integer | |
counts.notApplicablerequired | integer | |
counts.notMeasuredrequired | integer | |
endpointsrequired | array of EndpointVerdict | |
endpoints[].agentIdrequired | string | |
endpoints[].annotation | string, one of , blocked_on_escrow, converging, drift, failed, plan_capability_unavailable, stale, uncomparable, unreported, unsupported | |
endpoints[].exceptionId | string | |
endpoints[].expectedrequired | any | Arbitrary JSON. |
endpoints[].hostnamerequired | string | |
endpoints[].observedrequired | any | Arbitrary JSON. |
endpoints[].openTicketRef | string | |
endpoints[].osFamily | string | |
endpoints[].reportedAt | string (date-time) or null | |
endpoints[].settingKeyrequired | string | |
endpoints[].status | string | |
endpoints[].verdictrequired | string, one of compliant, excepted, gap, not_applicable, not_measured | |
frameworkrequired | string | |
generatedAtrequired | string (date-time) | |
levelrequired | string | |
settingsrequired | array of SettingPosture | |
settings[].citation | string | |
settings[].compliancePercent | number or null | double. |
settings[].countsrequired | Counts | Counts is a tally of verdicts over some population - one setting across a fleet, one control, one whole framework. |
settings[].counts.compliantrequired | integer | |
settings[].counts.exceptedrequired | integer | |
settings[].counts.gaprequired | integer | |
settings[].counts.notApplicablerequired | integer | |
settings[].counts.notMeasuredrequired | integer | |
settings[].description | string | |
settings[].enforcementrequired | string | |
settings[].expectedrequired | any | Arbitrary JSON. |
settings[].settingKeyrequired | string | |
truncatedrequired | boolean |
Request samples
Section titled “Request samples”# Sign in first. outpost_console is a session cookie, so send it with every request.# This operation is idempotent. Repeating it does not repeat its effect.curl -X GET 'https://depot.example.com/api/v1/compliance/posture/<framework>/controls/<level>' \ -H 'X-CSRF-Token: <csrf-token>' \ -H 'Accept: application/json' \ -b 'outpost_console=<console-session>'# Sign in first. outpost_console is a session cookie, so send it with every request.# This operation is idempotent. Repeating it does not repeat its effect.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$response = Invoke-RestMethod ` -Method Get ` -Uri 'https://depot.example.com/api/v1/compliance/posture/<framework>/controls/<level>' ` -Headers $headers
$response | ConvertTo-Json -Depth 10# Sign in first. outpost_console is a session cookie, so send it with every request.# This operation is idempotent. Repeating it does not repeat its effect.
import requests
url = "https://depot.example.com/api/v1/compliance/posture/<framework>/controls/<level>"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json",}cookies = { "outpost_console": "<console-session>",}
response = requests.get(url, headers=headers, cookies=cookies, timeout=30)response.raise_for_status()print(response.json())// Sign in first. outpost_console is a session cookie, so send it with every request.// This operation is idempotent. Repeating it does not repeat its effect.package main
import ( "fmt" "io" "log" "net/http")
func main() { req, err := http.NewRequest(http.MethodGet, "https://depot.example.com/api/v1/compliance/posture/<framework>/controls/<level>", nil) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// Sign in first. outpost_console is a session cookie, so send it with every request.// This operation is idempotent. Repeating it does not repeat its effect.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/compliance/posture/<framework>/controls/<level>";
const response = await fetch(url, { method: "GET", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", }, credentials: "include",});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// Sign in first. outpost_console is a session cookie, so send it with every request.// This operation is idempotent. Repeating it does not repeat its effect.
using System;using System.Net.Http;
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://depot.example.com/api/v1/compliance/posture/<framework>/controls/<level>");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());Content is licensed CC BY 4.0. Code samples are MIT. Outpost and the Outpost mark are trademarks of Outpost Business Solutions, PBC and are not covered by either license.