Red Clippy serves a REST API at /api/v1, on the same address and from the
same process as the web panel. The panel is built on this API, so every
operation available in the browser is available to a script or an agent through
the same endpoints.
Authorization: Bearer rcl_<prefix>_<secret>
Keys are organization-scoped, so no endpoint takes an organization in its path.
Issue one under Settings > API keys or with red-clippy create-api-key.
The API also accepts the session cookie, so the same-origin SPA can call it
without a key. Cookie sessions are re-checked against the membership table on
every request, so access ends when the membership does rather than when the
cookie expires.
Three endpoints need no authentication, because they run before there is
anyone to authenticate: GET /health, GET /cvss/score, and the bootstrap
pair. The bootstrap endpoints both refuse once any user exists.
Lists are paginated:
{ "items": [ ... ], "total": 137, "page": 1, "page_size": 50 }
page starts at 1 and page_size defaults to 50 with a ceiling of 500.
Errors are JSON with a single field:
{ "error": "invalid asset kind `host` - use one of: domain, ip, url, api, mobile" }
Status When
400 Bad request. The message names the problem and, for closed vocabularies, the accepted values.
401 Missing, malformed, revoked or expired credentials.
403 Authenticated but not permitted, typically an owner-only action.
404 Not found, or belongs to another organization. The response does not distinguish the two.
409 Conflict, such as a duplicate slug or code.
500 Server error. The detail goes to the log, not the response.
Method and path Purpose
GET /healthLiveness.
GET /cvss/score?vector=...Score a CVSS 3.1 vector.
GET /bootstrapWhether first-run setup is still available.
POST /bootstrapCreate the first organization and administrator.
GET /meThe current identity, organization, and the server’s own binary path.
Method and path Purpose
GET /pentestsList, filterable by q and status.
POST /pentestsCreate.
GET /pentests/{id}Fetch.
PATCH /pentests/{id}Update.
GET /pentests/{id}/summaryCounts, recent items and phase progress in one call.
GET /pentests/{id}/severitySeverity counts.
GET /pentests/{id}/coverageCheck coverage rollup.
Method and path Purpose
GET, POST /pentests/{id}/phasesList and create.
PATCH, DELETE /pentests/{id}/phases/{phase_id}Update status and notes, or remove.
GET /pentests/{id}/checks?asset_id=NThe catalogue for one asset. Materialises it on first call.
PATCH /pentests/{id}/checks/{check_id}Set status and notes.
POST /pentests/{id}/assets/{asset_id}/checks/bulkBulk update on one asset.
Method and path Purpose
GET, POST /pentests/{id}/assetsList and create.
GET /assetsEvery asset in the organization, with its pentest.
GET, PATCH, DELETE /assets/{id}Fetch, update, delete.
DELETE /pentests/{id}/assets/by-valueDelete by value.
POST /pentests/{id}/assets/scopeSet marking by value.
POST /pentests/{id}/assets/scope/bulkSet the same marking on many values.
GET, POST /assets/{id}/aliasesList and add aliases.
DELETE /assets/{id}/aliases/{alias_id}Detach an alias.
POST /pentests/{id}/assets/promotePromote an observation to an asset.
POST /assets/{id}/demoteDemote an asset back to an observation.
GET /assets/{id}/observationsObservations attached to one asset.
GET /pentests/{id}/assets/urlsURLs under an asset.
GET /pentests/{id}/assets/urls/from-previousURLs seen for this asset in earlier engagements.
GET /pentests/{id}/assets/relatedRelated IPs and hostnames.
GET /pentests/{id}/assets/rangesDeclared ranges containing an address.
GET /pentests/{id}/assets/portsPorts for one asset.
Method and path Purpose
GET, POST /pentests/{id}/observationsList and create.
POST /pentests/{id}/observations/bulkCreate many in one transaction.
GET, PATCH, DELETE /observations/{id}Fetch, update, delete.
GET /observationsEvery observation in the organization.
GET /pentests/{id}/portsEngagement-wide port and service search.
Method and path Purpose
GET, POST /pentests/{id}/ip-rangesList and declare.
PATCH, DELETE /pentests/{id}/ip-ranges/{range_id}Update or remove.
POST /pentests/{id}/ip-ranges/applyDeclare a range and fan the scope decision out to member addresses.
GET /pentests/{id}/range-mapThe unified scope tree behind the Network page.
Method and path Purpose
GET, POST /assets/{id}/api-endpointsList and add.
POST /assets/{id}/api-endpoints/bulkAdd many.
GET /assets/{id}/api-endpoints/openapiExport an OpenAPI 3.1 document.
GET, PATCH, DELETE /api-endpoints/{id}Fetch, update, delete.
GET /api-endpoints/{id}/curlExport as a cURL command.
Method and path Purpose
GET, POST /pentests/{id}/findingsList and create.
GET /pentests/{id}/findings.xlsxExcel export for one engagement, honouring the same filters.
GET /findingsEvery finding in the organization.
GET /findings.xlsxExcel export for the organization.
GET, PATCH, DELETE /findings/{id}Fetch, update, delete.
GET, POST /findings/{id}/attachmentsList and upload evidence.
GET, DELETE /findings/{id}/attachments/{attachment_id}Download or delete one.
Method and path Purpose
GET, DELETE /pentests/{id}/filesList a folder, or delete a path.
POST /pentests/{id}/files/foldersCreate a folder.
POST /pentests/{id}/files/uploadUpload, as multipart with file, optional dir and optional name.
GET /pentests/{id}/files/downloadDownload.
POST /pentests/{id}/files/revealOpen the folder on the server host, if local_open is on.
/assets/{id}/files/...The same set, scoped to one asset, plus read and write JSON variants.
Method and path Purpose
POST /pentests/{id}/ingestImport a scanner report.
GET, POST /pentests/{id}/nmapList and attach raw nmap scans.
GET /nmap/{id}One scan with its raw output.
GET /pentests/{id}/scan-toolsThe tool registry with availability.
GET /pentests/{id}/scan-coverageFunnel progress.
GET /pentests/{id}/scan-coverage/by-rangeThe same, per declared range.
POST /pentests/{id}/scan-coverage/markMark targets as already covered.
GET, POST, DELETE /pentests/{id}/scansList, launch, bulk-delete finished.
GET, DELETE /pentests/{id}/scans/{scan_id}Fetch one with its tasks, or delete.
POST /pentests/{id}/scans/{scan_id}/cancelCancel.
POST /pentests/{id}/scans/{scan_id}/tasks/{task_id}/skipSkip one target.
Method and path Purpose
POST /edgesCreate an edge.
DELETE /edges/{id}Delete an edge.
GET /graph/neighborsNodes reachable from one node.
GET /graph/pathsPaths between two nodes.
GET /searchOrganization-wide keyword search.
Method and path Purpose
GET, PUT, DELETE /org/rt-instructionsRead, override, reset at the organization level.
GET, PUT, DELETE /pentests/{id}/rt-instructionsThe same for one engagement.
Method and path Purpose
GET, POST /orgsList your memberships, or create an organization.
PATCH, DELETE /orgs/{id}Rename or delete. Owner only.
GET, POST /orgs/{id}/membersList and add.
PATCH, DELETE /orgs/{id}/members/{user_id}Change role or remove.
POST /session/orgSwitch the active organization for a cookie session.
POST /account/passwordChange your own password.
GET, POST /api-keysList and issue.
DELETE /api-keys/{id}Revoke.
KEY=rcl_1a2b3c4d_5e6f708192a3b4c5d6e7f8091a2b3c4d5e6f7081
BASE=http://127.0.0.1:7337/api/v1
# List engagements
curl -s -H "Authorization: Bearer $KEY" "$BASE/pentests"
# Add an asset
curl -s -X POST -H "Authorization: Bearer $KEY" -H 'Content-Type: application/json' \
-d '{"kind":"domain","value":"shop.northwind.test","reachability":"up"}' \
"$BASE/pentests/1/assets"
# File a finding
curl -s -X POST -H "Authorization: Bearer $KEY" -H 'Content-Type: application/json' \
-d '{"title":"Reflected cross-site scripting in the search results page",
"severity":"high","affected_asset":"shop.northwind.test",
"cvss_vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N",
"tags":"asset:shop.northwind.test,check:WSTG-INPV-01"}' \
"$BASE/pentests/1/findings"