{"openapi":"3.1.0","info":{"title":"WebSec Scanner Service API","description":"\nRequest web security scans and read their results. The scanner is non-intrusive: it only sends ordinary GET, HEAD and\nOPTIONS requests and never sends a payload that exploits anything.\n\n**Authentication.** Send your API key as `Authorization: Bearer wsk_...`. Call the API from your **backend**, never from\na browser: a key in a web page is a key anyone can read. Every key belongs to one agency and sees only that\nagency's data.\n\n**Errors.** Every error is a `application/problem+json` document with a stable `code`; branch on `code`, not on\nthe text.\nNothing you sent is echoed back in an error.\n\n**Ids.** Ids are made by the service: `cli_...` for a client, `scn_...` for a scan. Attach your own reference to a\nclient with `external_ref`.\n\n**Scans.** `POST /v1/scans` queues a scan and answers `202` at once; poll `GET /v1/scans/{scan_id}` until `status` is\n`completed` or `failed`, then read `/report` (JSON, the same report as the command line) or `/report.html`. Send an\n`Idempotency-Key` so that a retry after a timeout does not queue a second scan. You confirm, in `attestation`, that you\nare authorized to have the target scanned; the service scans public internet addresses only.\n","version":"1.1.0"},"paths":{"/healthz":{"get":{"tags":["service"],"summary":"Is the service up?","description":"No key needed. Says nothing about the data.","operationId":"getHealth","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Health"}}}},"503":{"description":"The service cannot reach its database.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/options":{"get":{"tags":["service"],"summary":"What a scan request can ask for","description":"The check groups and the limits of a crawl, so your front end can draw the same form as the demo page.","operationId":"getOptions","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Options"}}}},"401":{"description":"The API key is missing, malformed, unknown, expired or revoked.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/clients":{"post":{"tags":["clients"],"summary":"Create a client","description":"Required scope: `clients:write`. `external_ref` is your own reference, unique among your active clients.","operationId":"createClient","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClientCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Client"}}}},"401":{"description":"The API key is missing, malformed, unknown, expired or revoked.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"The API key does not have the scope this call needs.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"The request conflicts with an existing record, or the report is not ready.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"The request body is too large.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"The request is not valid; `errors` says where.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"get":{"tags":["clients"],"summary":"List your clients","description":"Required scope: `clients:read`. In order of creation, oldest first, in pages.","operationId":"listClients","security":[{"bearerAuth":[]}],"parameters":[{"name":"external_ref","in":"query","required":false,"schema":{"anyOf":[{"type":"string","pattern":"^[A-Za-z0-9._:-]{1,128}$"},{"type":"null"}],"description":"Only the client with this reference.","title":"External Ref"},"description":"Only the client with this reference."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Page size.","default":50,"title":"Limit"},"description":"Page size."},{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"`next_cursor` of the previous page.","title":"Cursor"},"description":"`next_cursor` of the previous page."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClientList"}}}},"400":{"description":"The request is malformed (for example an unusable cursor).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"The API key is missing, malformed, unknown, expired or revoked.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"The API key does not have the scope this call needs.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"The request is not valid; `errors` says where.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/clients/{client_id}":{"get":{"tags":["clients"],"summary":"Read a client","description":"Required scope: `clients:read`.","operationId":"getClient","security":[{"bearerAuth":[]}],"parameters":[{"name":"client_id","in":"path","required":true,"schema":{"type":"string","title":"Client Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Client"}}}},"401":{"description":"The API key is missing, malformed, unknown, expired or revoked.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"The API key does not have the scope this call needs.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"No such record for your agency.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"The request is not valid; `errors` says where.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"patch":{"tags":["clients"],"summary":"Change a client's name or labels","description":"Required scope: `clients:write`. `external_ref` cannot be changed.","operationId":"updateClient","security":[{"bearerAuth":[]}],"parameters":[{"name":"client_id","in":"path","required":true,"schema":{"type":"string","title":"Client Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClientUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Client"}}}},"401":{"description":"The API key is missing, malformed, unknown, expired or revoked.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"The API key does not have the scope this call needs.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"No such record for your agency.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"The request body is too large.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"The request is not valid; `errors` says where.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"delete":{"tags":["clients"],"summary":"Delete a client","description":"Required scope: `clients:write`. The client leaves every read; its `external_ref` can be used again.","operationId":"deleteClient","security":[{"bearerAuth":[]}],"parameters":[{"name":"client_id","in":"path","required":true,"schema":{"type":"string","title":"Client Id"}}],"responses":{"204":{"description":"Successful Response"},"401":{"description":"The API key is missing, malformed, unknown, expired or revoked.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"The API key does not have the scope this call needs.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"No such record for your agency.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"The request is not valid; `errors` says where.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/scans":{"post":{"tags":["scans"],"summary":"Request a scan","description":"Required scope: `scans:write`. Queues the scan and answers at once; the scan runs in the background.\n\nA repeated `Idempotency-Key` with the same body returns the first scan; with a different body it is a 409.\nErrors that say why a target is refused: `invalid_target`, `credential_not_accepted`, `target_not_allowed`\n(not a public internet address), `target_unresolvable`; and `unsupported_statement_version`, `invalid_checks`.","operationId":"createScan","security":[{"bearerAuth":[]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string","pattern":"^[A-Za-z0-9._:-]{1,64}$"},{"type":"null"}],"description":"Your own key for this request (1 to 64 of `A-Z a-z 0-9 . _ : -`), kept for 24 hours.","title":"Idempotency-Key"},"description":"Your own key for this request (1 to 64 of `A-Z a-z 0-9 . _ : -`), kept for 24 hours."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScanCreate"}}}},"responses":{"202":{"description":"The scan is queued. `Location` is its address; `Idempotent-Replayed: true` means an earlier request with the same `Idempotency-Key` already queued it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Scan"}}},"headers":{"Location":{"schema":{"type":"string"},"description":"`/v1/scans/{scan_id}`"},"Idempotent-Replayed":{"schema":{"type":"string","enum":["true"]}}}},"401":{"description":"The API key is missing, malformed, unknown, expired or revoked.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"The API key does not have the scope this call needs.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"No such record for your agency.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"The request conflicts with an existing record, or the report is not ready.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"The request body is too large.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"The request is not valid; `errors` says where.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Too many scans are waiting; retry after the time in `Retry-After`.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"get":{"tags":["scans"],"summary":"List your scans","description":"Required scope: `scans:read`. Newest first, in pages.","operationId":"listScans","security":[{"bearerAuth":[]}],"parameters":[{"name":"client_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","pattern":"^cli_[0-9a-hjkmnp-tv-z]{26}$"},{"type":"null"}],"description":"Only the scans of this client.","title":"Client Id"},"description":"Only the scans of this client."},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"enum":["queued","running","completed","failed"],"type":"string"},{"type":"null"}],"description":"Only the scans in this state.","title":"Status"},"description":"Only the scans in this state."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Page size.","default":50,"title":"Limit"},"description":"Page size."},{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"`next_cursor` of the previous page.","title":"Cursor"},"description":"`next_cursor` of the previous page."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScanList"}}}},"400":{"description":"The request is malformed (for example an unusable cursor).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"The API key is missing, malformed, unknown, expired or revoked.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"The API key does not have the scope this call needs.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"The request is not valid; `errors` says where.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/scans/{scan_id}":{"get":{"tags":["scans"],"summary":"Read a scan's state","description":"Required scope: `scans:read`. Poll this until `status` is `completed` or `failed`.","operationId":"getScan","security":[{"bearerAuth":[]}],"parameters":[{"name":"scan_id","in":"path","required":true,"schema":{"type":"string","title":"Scan Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Scan"}}}},"401":{"description":"The API key is missing, malformed, unknown, expired or revoked.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"The API key does not have the scope this call needs.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"No such record for your agency.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"The request is not valid; `errors` says where.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/scans/{scan_id}/report":{"get":{"tags":["scans"],"summary":"Read a scan's report (JSON)","description":"Required scope: `scans:read`. 409 `scan_not_finished` while queued or running, `scan_failed` if it failed.","operationId":"getScanReport","security":[{"bearerAuth":[]}],"parameters":[{"name":"scan_id","in":"path","required":true,"schema":{"type":"string","title":"Scan Id"}}],"responses":{"200":{"description":"The report: the same JSON as the command line's `--json` (`schema_version` 1.11, described by `docs/report.schema.json`). Secrets are masked.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"401":{"description":"The API key is missing, malformed, unknown, expired or revoked.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"The API key does not have the scope this call needs.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"No such record for your agency.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"The request conflicts with an existing record, or the report is not ready.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"The request is not valid; `errors` says where.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/scans/{scan_id}/report.html":{"get":{"tags":["scans"],"summary":"Read a scan's report (HTML)","description":"Required scope: `scans:read`. The same report as the JSON one, drawn as a page.","operationId":"getScanReportHtml","security":[{"bearerAuth":[]}],"parameters":[{"name":"scan_id","in":"path","required":true,"schema":{"type":"string","title":"Scan Id"}}],"responses":{"200":{"description":"A standalone HTML page (no scripts, works offline, printable).","content":{"text/html":{"schema":{"type":"string"}}}},"401":{"description":"The API key is missing, malformed, unknown, expired or revoked.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"The API key does not have the scope this call needs.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"No such record for your agency.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"The request conflicts with an existing record, or the report is not ready.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"The request is not valid; `errors` says where.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}}},"components":{"schemas":{"Attestation":{"properties":{"confirmed":{"type":"boolean","title":"Confirmed","description":"Must be true: you confirm that you are authorized to have this target scanned."},"statement_version":{"type":"string","maxLength":16,"minLength":1,"title":"Statement Version","description":"The version of the statement you are confirming, e.g. `v1`."}},"additionalProperties":false,"type":"object","required":["confirmed","statement_version"],"title":"Attestation","description":"The agency's statement that it may have this target scanned. It is kept with the scan, and it is the agency's:\nthe service provider supplies the scanner and the API, the agency vouches for its own clients."},"CheckGroup":{"properties":{"id":{"type":"string","title":"Id"},"title":{"type":"string","title":"Title"},"description":{"type":"string","title":"Description"}},"type":"object","required":["id","title","description"],"title":"CheckGroup"},"Client":{"properties":{"client_id":{"type":"string","title":"Client Id","description":"Made by the service, e.g. cli_01j9z8k2m4q7r5t6v8w0x1y2z3."},"display_name":{"type":"string","title":"Display Name"},"external_ref":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"External Ref"},"metadata":{"additionalProperties":{"anyOf":[{"type":"string"},{"type":"integer"},{"type":"number"},{"type":"boolean"}]},"type":"object","title":"Metadata"},"created_at":{"type":"string","title":"Created At","description":"UTC, ISO 8601, milliseconds."},"updated_at":{"type":"string","title":"Updated At"}},"type":"object","required":["client_id","display_name","external_ref","metadata","created_at","updated_at"],"title":"Client"},"ClientCreate":{"properties":{"display_name":{"type":"string","maxLength":200,"minLength":1,"title":"Display Name","description":"Name shown to your own staff."},"external_ref":{"anyOf":[{"type":"string","pattern":"^[A-Za-z0-9._:-]{1,128}$"},{"type":"null"}],"title":"External Ref","description":"Your own reference for this client, unique among your active clients. Fixed once set."},"metadata":{"additionalProperties":{"anyOf":[{"type":"string"},{"type":"integer"},{"type":"number"},{"type":"boolean"}]},"type":"object","title":"Metadata","description":"Free labels (text, numbers, true/false). Never put secrets here."}},"additionalProperties":false,"type":"object","required":["display_name"],"title":"ClientCreate"},"ClientList":{"properties":{"items":{"items":{"$ref":"#/components/schemas/Client"},"type":"array","title":"Items"},"next_cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Cursor","description":"Pass it as `cursor` to get the next page; null when there is no more."}},"type":"object","required":["items","next_cursor"],"title":"ClientList"},"ClientUpdate":{"properties":{"display_name":{"anyOf":[{"type":"string","maxLength":200,"minLength":1},{"type":"null"}],"title":"Display Name"},"metadata":{"anyOf":[{"additionalProperties":{"anyOf":[{"type":"string"},{"type":"integer"},{"type":"number"},{"type":"boolean"}]},"type":"object"},{"type":"null"}],"title":"Metadata","description":"Replaces the labels when given (send {} to clear them)."}},"additionalProperties":false,"type":"object","title":"ClientUpdate"},"CrawlLimits":{"properties":{"max_depth":{"type":"integer","title":"Max Depth"},"max_pages":{"type":"integer","title":"Max Pages"},"max_duration":{"type":"number","title":"Max Duration"},"respect_robots":{"type":"boolean","title":"Respect Robots","description":"Always true: a crawl follows robots.txt."}},"type":"object","required":["max_depth","max_pages","max_duration","respect_robots"],"title":"CrawlLimits"},"Health":{"properties":{"status":{"type":"string","title":"Status"},"service_version":{"type":"string","title":"Service Version"}},"type":"object","required":["status","service_version"],"title":"Health"},"Options":{"properties":{"api_version":{"type":"string","title":"Api Version"},"scanner_version":{"type":"string","title":"Scanner Version"},"report_schema_version":{"type":"string","title":"Report Schema Version"},"check_groups":{"items":{"$ref":"#/components/schemas/CheckGroup"},"type":"array","title":"Check Groups"},"crawl":{"$ref":"#/components/schemas/CrawlLimits"}},"type":"object","required":["api_version","scanner_version","report_schema_version","check_groups","crawl"],"title":"Options","description":"What a scan request can ask for, so a front end can draw the same form as the demo page."},"Problem":{"properties":{"type":{"type":"string","title":"Type","description":"urn:websec:problem:<code>"},"title":{"type":"string","title":"Title"},"status":{"type":"integer","title":"Status"},"detail":{"type":"string","title":"Detail"},"code":{"type":"string","title":"Code","description":"Stable, machine-readable. Branch on this, not on the text."},"request_id":{"type":"string","title":"Request Id","description":"Quote it when you ask for support."},"errors":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Errors","description":"Field problems of a 422."}},"type":"object","required":["type","title","status","detail","code","request_id"],"title":"Problem","description":"RFC 9457 problem details; this is the shape of every error."},"Scan":{"properties":{"scan_id":{"type":"string","title":"Scan Id"},"client_id":{"type":"string","title":"Client Id"},"target":{"type":"string","title":"Target","description":"As you sent it, with anything that looks like a secret masked."},"status":{"type":"string","enum":["queued","running","completed","failed"],"title":"Status"},"checks":{"items":{"type":"string"},"type":"array","title":"Checks"},"crawl":{"type":"boolean","title":"Crawl"},"created_at":{"type":"string","title":"Created At"},"started_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Started At"},"finished_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Finished At"},"summary":{"anyOf":[{"$ref":"#/components/schemas/ScanSummary"},{"type":"null"}],"description":"Present once the scan is completed."},"error":{"anyOf":[{"$ref":"#/components/schemas/ScanError"},{"type":"null"}],"description":"Present when the scan failed."},"report_available":{"type":"boolean","title":"Report Available","description":"True once `GET /v1/scans/{scan_id}/report` returns the report."}},"type":"object","required":["scan_id","client_id","target","status","checks","crawl","created_at","started_at","finished_at","summary","error","report_available"],"title":"Scan"},"ScanCreate":{"properties":{"client_id":{"type":"string","maxLength":64,"title":"Client Id","description":"One of your clients (`cli_...`)."},"target":{"type":"string","maxLength":2048,"minLength":1,"title":"Target","description":"An http(s):// URL or a host name, with no user name or password. Public addresses only."},"checks":{"anyOf":[{"items":{"type":"string"},"type":"array","maxItems":16,"minItems":1},{"type":"null"}],"title":"Checks","description":"Check group ids from `GET /v1/options`. Omit it to run every group."},"crawl":{"type":"boolean","title":"Crawl","description":"Also follow the links of the page on the same origin and check each page (operator's limits).","default":false},"attestation":{"$ref":"#/components/schemas/Attestation"}},"additionalProperties":false,"type":"object","required":["client_id","target","attestation"],"title":"ScanCreate"},"ScanError":{"properties":{"code":{"type":"string","title":"Code","description":"`scan_error` (it broke inside the service) or `interrupted` (the service stopped)."},"detail":{"type":"string","title":"Detail"}},"type":"object","required":["code","detail"],"title":"ScanError"},"ScanGate":{"properties":{"fail_on":{"type":"string","title":"Fail On"},"failed":{"type":"boolean","title":"Failed","description":"At least one finding at or above `fail_on`."},"incomplete":{"type":"boolean","title":"Incomplete","description":"The scan could not look at everything (for example the home page was unreachable)."}},"type":"object","required":["fail_on","failed","incomplete"],"title":"ScanGate"},"ScanList":{"properties":{"items":{"items":{"$ref":"#/components/schemas/Scan"},"type":"array","title":"Items"},"next_cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Cursor","description":"Pass it as `cursor` to get the next page; null when there is no more."}},"type":"object","required":["items","next_cursor"],"title":"ScanList"},"ScanSummary":{"properties":{"findings":{"type":"integer","title":"Findings"},"severity":{"additionalProperties":{"type":"integer"},"type":"object","title":"Severity","description":"Findings per severity: CRITICAL, HIGH, MEDIUM, LOW, INFO."},"gate":{"$ref":"#/components/schemas/ScanGate"},"pages_scanned":{"type":"integer","title":"Pages Scanned"}},"type":"object","required":["findings","severity","gate","pages_scanned"],"title":"ScanSummary"}},"securitySchemes":{"bearerAuth":{"type":"http","description":"`Authorization: Bearer wsk_<handle>_<secret>`","scheme":"bearer","bearerFormat":"wsk_<handle>_<secret>"}}},"tags":[{"name":"service","description":"Health and what a request can ask for."},{"name":"clients","description":"The clients of your agency. Each scan belongs to one client."},{"name":"scans","description":"Request a scan, follow it, and read its report."}]}