API reference

The Sentrint API lets your own tools and CI start security scans and read the results. Send a scoped API key as a Bearer token over HTTPS. Every endpoint below lists its parameters, a cURL example and its response fields. A key only reaches its owner's account, and deleting scan results needs the owner's approval in a browser.

At a glance

Base URL
https://sentrint.com/api/v1
Auth
Bearer API key
Format
JSON over HTTPS
Errors
application/problem+json
Contract
OpenAPI 3.1, 15 endpoints
Updated

Method legend

GET
Reads data. Safe to retry.
POST
Starts work, such as a scan.
DELETE
Removes data. Needs the owner's approval.

Authentication

Every request sends an API key in the Authorization header. Keys are opaque strings, not JWTs or OAuth tokens.

Authorization: Bearer <api_key>

Create a key on the API keys page. It is shown once, so put it straight into a secret manager or your CI secrets. A key lasts 90 days by default, and you can choose anything from 1 hour to 365 days. You can hold 10 active keys, and a revoked key stops working on its next request.

Keep keys on the server. Never put one in a browser or mobile bundle, a URL, source control, logs or a screenshot. Give each integration its own key with only the scopes it needs. To rotate a key, create the new one, switch the integration over, then revoke the old one.

Scopes

  • account:readOn by default
  • audit:readOpt-in
  • findings:readOn by default
  • scans:createOn by default
  • scans:deleteOpt-in
  • scans:readOn by default
  • workspaces:readOn by default

A key only sees its owner's data. There are no team members or roles yet. Browser cookies are not accepted on the JSON API, and the owner must have accepted the current terms in the browser.

Run a scan

Five calls take you from a key to a list of findings. Each step opens its full reference.

  1. 1GET/workspacesPick a workspace ID200
  2. 2POST/workspaces/{workspace_id}/scansSubmit the repository. You get back scan_id and status_url202
  3. 3GET/scans/{scan_id}Poll every 5 to 10 seconds until the scan finishes200
  4. 4GET/scans/{scan_id}/reportRead the score, grade and counts by severity200
  5. 5GET/findings?scan_id={scan_id}List the findings, 25 to a page by default200

Leave out branch to scan the default branch. Name a branch to scan its latest commit, and add commit_sha (the full 40-character SHA) to scan one exact commit on it. A commit that isn't on that branch returns 409 commit_not_on_branch before anything is charged. Through …/submissions, the submission ends failed with that error_code instead. A scan of any other branch never changes the default branch's issues, score trend or badge.

The examples below submit a scan. Set SENTRINT_API_KEY and WORKSPACE_ID in your environment first, and swap in your own repository.

cURL
curl --fail-with-body -X POST \
  "https://sentrint.com/api/v1/workspaces/$WORKSPACE_ID/scans" \
  -H "Authorization: Bearer $SENTRINT_API_KEY" \
  -H "Content-Type: application/json" \
  --data '{"repo_url":"https://github.com/your-org/your-repo","branch":"main","force":false}'
Python, standard library
import json
import os
from urllib.request import Request, urlopen

workspace = os.environ["WORKSPACE_ID"]
request = Request(
    f"https://sentrint.com/api/v1/workspaces/{workspace}/scans",
    data=json.dumps({
        "repo_url": "https://github.com/your-org/your-repo",
        "branch": "main", "force": False,
    }).encode(),
    headers={
        "Authorization": f"Bearer {os.environ['SENTRINT_API_KEY']}",
        "Content-Type": "application/json",
    }, method="POST",
)
with urlopen(request, timeout=30) as response:
    scan = json.load(response)
print(scan["scan_id"], scan["status_url"])
JavaScript, Node.js server
const response = await fetch(
  `https://sentrint.com/api/v1/workspaces/${process.env.WORKSPACE_ID}/scans`,
  {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.SENTRINT_API_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      repo_url: "https://github.com/your-org/your-repo",
      branch: "main", force: false,
    }),
    signal: AbortSignal.timeout(30_000),
  },
);
const result = await response.json();
if (!response.ok) throw new Error(`${result.code}: ${result.detail}`);
console.log(result.scan_id, result.status_url);
Repeat submissions
A live scan with the same inputs is returned as it is. A finished scan is returned too, unless you send "force": true. A reused result costs no scan credit, and a failed scan can be retried.
Limits
The usual limits still apply: one running scan per workspace, workspace locks, repository size and file limits, and your scan allowance.
Private repositories
Scans use the GitHub access linked to the owner's account. The API takes no personal access token, and no shared server credential opens private repositories. If Sentrint can't reach the repository you get repository_unavailable.
Locked guidance
If guidance is locked on your account, reports and findings come back with guidance_locked set and without suggestions, snippets, prompts or evidence.
Size caps
Workspace detail returns up to 100 repositories, and repositories_truncated tells you when there are more. Finding detail returns up to 100 evidence records.

Open an endpoint to see its scope, parameters, request examples and response. Every ID in a path is a UUID. The examples read your key and IDs from environment variables such as SENTRINT_API_KEY, WORKSPACE_ID and SCAN_ID; use IDs from your own responses.

Account1

GET/api/v1/accountGet your accountaccount:read

Get your account

Link

Plan, scans used and left this period, and scan credits.

Scope
account:read
Success
200
Response fields
FieldTypeDetails
iduuidRequired
loginstringRequired
planstringRequired
included_scans_remainingintegerRequired
scan_creditsintegerRequired
scans_used_in_periodintegerRequired
scan_limit_in_periodinteger | nullRequired
periodstringRequired
HTTP status codes
StatusMeaning
200Successful Response
400Repository exceeds the configured size or scannable file limit.
401Missing, malformed, expired or revoked API key.
403Missing scope, current terms, workspace permission or owner deletion approval.
404Resource missing or unavailable to this account.
409Scan or approval state conflicts with this operation.
413Request body exceeds 16 KiB.
422Invalid request, filter, date range or pagination cursor.
429Rate limit or scan quota exceeded. Retry-After accompanies rate limits.
503Authentication/rate infrastructure or repository access is unavailable.
500Unexpected server error. Keep the request ID for support.
curl --fail-with-body --request GET \
  "https://sentrint.com/api/v1/account" \
  --header "Authorization: Bearer $SENTRINT_API_KEY" \
  --header "Accept: application/json"
{
  "body": null,
  "headers": {
    "Accept": "application/json",
    "Authorization": "Bearer $SENTRINT_API_KEY"
  },
  "method": "GET",
  "path": "/api/v1/account",
  "path_parameters": {},
  "query_parameters": {}
}
{
  "id": "00000000-0000-4000-8000-000000000001",
  "included_scans_remaining": 0,
  "login": "example",
  "period": "example",
  "plan": "example",
  "scan_credits": 0,
  "scan_limit_in_period": 0,
  "scans_used_in_period": 0
}

Workspaces2

GET/api/v1/workspacesList workspacesworkspaces:read

List workspaces

Link

Workspaces on the key owner's account. Start here to get a workspace ID.

Scope
workspaces:read
Success
200
Parameters
ParameterInTypeDetails
limitOptionalqueryintegerDefault: 25
Minimum: 1; Maximum: 100
cursorOptionalquerystring | null
Response fields
FieldTypeDetails
dataWorkspaceOut[]Required
next_cursorstring | nullOptional
HTTP status codes
StatusMeaning
200Successful Response
422Invalid request, filter, date range or pagination cursor.
400Repository exceeds the configured size or scannable file limit.
401Missing, malformed, expired or revoked API key.
403Missing scope, current terms, workspace permission or owner deletion approval.
404Resource missing or unavailable to this account.
409Scan or approval state conflicts with this operation.
413Request body exceeds 16 KiB.
429Rate limit or scan quota exceeded. Retry-After accompanies rate limits.
503Authentication/rate infrastructure or repository access is unavailable.
500Unexpected server error. Keep the request ID for support.
curl --fail-with-body --request GET \
  "https://sentrint.com/api/v1/workspaces" \
  --header "Authorization: Bearer $SENTRINT_API_KEY" \
  --header "Accept: application/json" \
  --get \
  --data-urlencode limit=25
{
  "body": null,
  "headers": {
    "Accept": "application/json",
    "Authorization": "Bearer $SENTRINT_API_KEY"
  },
  "method": "GET",
  "path": "/api/v1/workspaces",
  "path_parameters": {},
  "query_parameters": {
    "cursor": "\u003cnext_cursor\u003e",
    "limit": 25
  }
}
{
  "data": [],
  "next_cursor": "example"
}
GET/api/v1/workspaces/{workspace_id}Get a workspaceworkspaces:read

Get a workspace

Link

One workspace and up to 100 of its repositories.

Scope
workspaces:read
Success
200
Parameters
ParameterInTypeDetails
workspace_idRequiredpathuuid
Response fields
FieldTypeDetails
iduuidRequired
namestringRequired
created_atdate-timeRequired
tracked_repository_countintegerRequired
repositoriesRepositoryOut[]Optional
repositories_truncatedbooleanOptional
HTTP status codes
StatusMeaning
200Successful Response
422Invalid request, filter, date range or pagination cursor.
400Repository exceeds the configured size or scannable file limit.
401Missing, malformed, expired or revoked API key.
403Missing scope, current terms, workspace permission or owner deletion approval.
404Resource missing or unavailable to this account.
409Scan or approval state conflicts with this operation.
413Request body exceeds 16 KiB.
429Rate limit or scan quota exceeded. Retry-After accompanies rate limits.
503Authentication/rate infrastructure or repository access is unavailable.
500Unexpected server error. Keep the request ID for support.
curl --fail-with-body --request GET \
  "https://sentrint.com/api/v1/workspaces/$WORKSPACE_ID" \
  --header "Authorization: Bearer $SENTRINT_API_KEY" \
  --header "Accept: application/json"
{
  "body": null,
  "headers": {
    "Accept": "application/json",
    "Authorization": "Bearer $SENTRINT_API_KEY"
  },
  "method": "GET",
  "path": "/api/v1/workspaces/{workspace_id}",
  "path_parameters": {
    "workspace_id": "00000000-0000-4000-8000-000000000001"
  },
  "query_parameters": {}
}
{
  "created_at": "2026-09-30T12:00:00Z",
  "id": "00000000-0000-4000-8000-000000000001",
  "name": "example",
  "repositories": [],
  "repositories_truncated": false,
  "tracked_repository_count": 0
}

Scans4

POST/api/v1/workspaces/{workspace_id}/scansSubmit a scanscans:create

Submit a scan

Link

Checks the repository with GitHub, then queues the scan and returns its ID.

Scope
scans:create
Success
202
Body
JSON
Parameters
ParameterInTypeDetails
workspace_idRequiredpathuuid
JSON body
FieldTypeDetails
repo_urlRequiredstringMaximum length: 512
branchOptionalstring | null
forceOptionalbooleanDefault: false
commit_shaOptionalstring | null
Response fields
FieldTypeDetails
scan_iduuidRequired
statusstringRequired
status_urlstringRequired
reusedbooleanRequired
HTTP status codes
StatusMeaning
202Successful Response
422Invalid request, filter, date range or pagination cursor.
400Repository exceeds the configured size or scannable file limit.
401Missing, malformed, expired or revoked API key.
403Missing scope, current terms, workspace permission or owner deletion approval.
404Resource missing or unavailable to this account.
409Scan or approval state conflicts with this operation.
413Request body exceeds 16 KiB.
429Rate limit or scan quota exceeded. Retry-After accompanies rate limits.
503Authentication/rate infrastructure or repository access is unavailable.
500Unexpected server error. Keep the request ID for support.
curl --fail-with-body --request POST \
  "https://sentrint.com/api/v1/workspaces/$WORKSPACE_ID/scans" \
  --header "Authorization: Bearer $SENTRINT_API_KEY" \
  --header "Accept: application/json" \
  --header "Content-Type: application/json" \
  --data '{
  "repo_url": "https://github.com/your-org/your-repo",
  "branch": "main",
  "force": false
}'
{
  "body": {
    "branch": "main",
    "force": false,
    "repo_url": "https://github.com/your-org/your-repo"
  },
  "headers": {
    "Accept": "application/json",
    "Authorization": "Bearer $SENTRINT_API_KEY",
    "Content-Type": "application/json"
  },
  "method": "POST",
  "path": "/api/v1/workspaces/{workspace_id}/scans",
  "path_parameters": {
    "workspace_id": "00000000-0000-4000-8000-000000000001"
  },
  "query_parameters": {}
}
{
  "reused": false,
  "scan_id": "00000000-0000-4000-8000-000000000001",
  "status": "pending",
  "status_url": "/api/v1/scans/00000000-0000-4000-8000-000000000001"
}
GET/api/v1/workspaces/{workspace_id}/scansList scans in a workspacescans:read

List scans in a workspace

Link

Every scan in one workspace, a page at a time.

Scope
scans:read
Success
200
Parameters
ParameterInTypeDetails
workspace_idRequiredpathuuid
limitOptionalqueryintegerDefault: 25
Minimum: 1; Maximum: 100
cursorOptionalquerystring | null
Response fields
FieldTypeDetails
dataScanOut[]Required
next_cursorstring | nullOptional
HTTP status codes
StatusMeaning
200Successful Response
422Invalid request, filter, date range or pagination cursor.
400Repository exceeds the configured size or scannable file limit.
401Missing, malformed, expired or revoked API key.
403Missing scope, current terms, workspace permission or owner deletion approval.
404Resource missing or unavailable to this account.
409Scan or approval state conflicts with this operation.
413Request body exceeds 16 KiB.
429Rate limit or scan quota exceeded. Retry-After accompanies rate limits.
503Authentication/rate infrastructure or repository access is unavailable.
500Unexpected server error. Keep the request ID for support.
curl --fail-with-body --request GET \
  "https://sentrint.com/api/v1/workspaces/$WORKSPACE_ID/scans" \
  --header "Authorization: Bearer $SENTRINT_API_KEY" \
  --header "Accept: application/json" \
  --get \
  --data-urlencode limit=25
{
  "body": null,
  "headers": {
    "Accept": "application/json",
    "Authorization": "Bearer $SENTRINT_API_KEY"
  },
  "method": "GET",
  "path": "/api/v1/workspaces/{workspace_id}/scans",
  "path_parameters": {
    "workspace_id": "00000000-0000-4000-8000-000000000001"
  },
  "query_parameters": {
    "cursor": "\u003cnext_cursor\u003e",
    "limit": 25
  }
}
{
  "data": [],
  "next_cursor": "example"
}
GET/api/v1/scans/{scan_id}Get scan statusscans:read

Get scan status

Link

Status, commit and score for one scan. Poll this until the scan finishes.

Scope
scans:read
Success
200
Parameters
ParameterInTypeDetails
scan_idRequiredpathuuid
Response fields
FieldTypeDetails
iduuidRequired
workspace_iduuid | nullRequired
statusstringRequired
repo_urlstringRequired
commit_shastringRequired
scoreinteger | nullRequired
created_atdate-timeRequired
updated_atdate-timeRequired
HTTP status codes
StatusMeaning
200Successful Response
422Invalid request, filter, date range or pagination cursor.
400Repository exceeds the configured size or scannable file limit.
401Missing, malformed, expired or revoked API key.
403Missing scope, current terms, workspace permission or owner deletion approval.
404Resource missing or unavailable to this account.
409Scan or approval state conflicts with this operation.
413Request body exceeds 16 KiB.
429Rate limit or scan quota exceeded. Retry-After accompanies rate limits.
503Authentication/rate infrastructure or repository access is unavailable.
500Unexpected server error. Keep the request ID for support.
curl --fail-with-body --request GET \
  "https://sentrint.com/api/v1/scans/$SCAN_ID" \
  --header "Authorization: Bearer $SENTRINT_API_KEY" \
  --header "Accept: application/json"
{
  "body": null,
  "headers": {
    "Accept": "application/json",
    "Authorization": "Bearer $SENTRINT_API_KEY"
  },
  "method": "GET",
  "path": "/api/v1/scans/{scan_id}",
  "path_parameters": {
    "scan_id": "00000000-0000-4000-8000-000000000001"
  },
  "query_parameters": {}
}
{
  "commit_sha": "example",
  "created_at": "2026-09-30T12:00:00Z",
  "id": "00000000-0000-4000-8000-000000000001",
  "repo_url": "example",
  "score": 0,
  "status": "example",
  "updated_at": "2026-09-30T12:00:00Z",
  "workspace_id": "00000000-0000-4000-8000-000000000001"
}
GET/api/v1/scans/{scan_id}/reportGet a scan reportscans:read

Get a scan report

Link

Score, grade, counts by severity and the rules that fired most.

Scope
scans:read
Success
200
Parameters
ParameterInTypeDetails
scan_idRequiredpathuuid
Response fields
FieldTypeDetails
scan_iduuidRequired
scoreintegerRequired
gradestringRequired
criticalintegerRequired
highintegerRequired
mediumintegerRequired
lowintegerRequired
top_rulesstring[]Required
summary_textstringRequired
guidance_lockedbooleanRequired
HTTP status codes
StatusMeaning
200Successful Response
422Invalid request, filter, date range or pagination cursor.
400Repository exceeds the configured size or scannable file limit.
401Missing, malformed, expired or revoked API key.
403Missing scope, current terms, workspace permission or owner deletion approval.
404Resource missing or unavailable to this account.
409Scan or approval state conflicts with this operation.
413Request body exceeds 16 KiB.
429Rate limit or scan quota exceeded. Retry-After accompanies rate limits.
503Authentication/rate infrastructure or repository access is unavailable.
500Unexpected server error. Keep the request ID for support.
curl --fail-with-body --request GET \
  "https://sentrint.com/api/v1/scans/$SCAN_ID/report" \
  --header "Authorization: Bearer $SENTRINT_API_KEY" \
  --header "Accept: application/json"
{
  "body": null,
  "headers": {
    "Accept": "application/json",
    "Authorization": "Bearer $SENTRINT_API_KEY"
  },
  "method": "GET",
  "path": "/api/v1/scans/{scan_id}/report",
  "path_parameters": {
    "scan_id": "00000000-0000-4000-8000-000000000001"
  },
  "query_parameters": {}
}
{
  "critical": 0,
  "grade": "example",
  "guidance_locked": false,
  "high": 0,
  "low": 0,
  "medium": 0,
  "scan_id": "00000000-0000-4000-8000-000000000001",
  "score": 0,
  "summary_text": "example",
  "top_rules": []
}

Submissions2

POST/api/v1/workspaces/{workspace_id}/submissionsSubmit a scan without waitingscans:create

Submit a scan without waiting

Link

Returns at once and checks GitHub in the background. Needs an Idempotency-Key header.

Scope
scans:create
Success
202
Body
JSON
Parameters
ParameterInTypeDetails
workspace_idRequiredpathuuid
idempotency-keyRequiredheaderstringMinimum length: 8; Maximum length: 128
JSON body
FieldTypeDetails
repo_urlRequiredstringMaximum length: 512
branchOptionalstring | null
forceOptionalbooleanDefault: false
commit_shaOptionalstring | null
Response fields
FieldTypeDetails
iduuidRequired
statusstringRequired
status_urlstringRequired
scan_iduuid | nullRequired
scan_status_urlstring | nullRequired
reusedbooleanRequired
error_codestring | nullRequired
error_detailstring | nullRequired
created_atdate-timeRequired
updated_atdate-timeRequired
HTTP status codes
StatusMeaning
202Successful Response
422Invalid request, filter, date range or pagination cursor.
400Repository exceeds the configured size or scannable file limit.
401Missing, malformed, expired or revoked API key.
403Missing scope, current terms, workspace permission or owner deletion approval.
404Resource missing or unavailable to this account.
409Scan or approval state conflicts with this operation.
413Request body exceeds 16 KiB.
429Rate limit or scan quota exceeded. Retry-After accompanies rate limits.
503Authentication/rate infrastructure or repository access is unavailable.
500Unexpected server error. Keep the request ID for support.
curl --fail-with-body --request POST \
  "https://sentrint.com/api/v1/workspaces/$WORKSPACE_ID/submissions" \
  --header "Authorization: Bearer $SENTRINT_API_KEY" \
  --header "Accept: application/json" \
  --header "Content-Type: application/json" \
  --header "idempotency-key: submission-request-001" \
  --data '{
  "repo_url": "https://github.com/your-org/your-repo",
  "branch": "main",
  "force": false
}'
{
  "body": {
    "branch": "main",
    "force": false,
    "repo_url": "https://github.com/your-org/your-repo"
  },
  "headers": {
    "Accept": "application/json",
    "Authorization": "Bearer $SENTRINT_API_KEY",
    "Content-Type": "application/json",
    "idempotency-key": "submission-request-001"
  },
  "method": "POST",
  "path": "/api/v1/workspaces/{workspace_id}/submissions",
  "path_parameters": {
    "workspace_id": "00000000-0000-4000-8000-000000000001"
  },
  "query_parameters": {}
}
{
  "created_at": "2026-09-30T12:00:00Z",
  "error_code": "example",
  "error_detail": "example",
  "id": "00000000-0000-4000-8000-000000000001",
  "reused": false,
  "scan_id": "00000000-0000-4000-8000-000000000001",
  "scan_status_url": "example",
  "status": "accepted",
  "status_url": "example",
  "updated_at": "2026-09-30T12:00:00Z"
}
GET/api/v1/submissions/{submission_id}Get submission statusscans:read

Get submission status

Link

Accepted, validating, failed or scan_ready. Once ready it carries the scan ID.

Scope
scans:read
Success
200
Parameters
ParameterInTypeDetails
submission_idRequiredpathuuid
Response fields
FieldTypeDetails
iduuidRequired
statusstringRequired
status_urlstringRequired
scan_iduuid | nullRequired
scan_status_urlstring | nullRequired
reusedbooleanRequired
error_codestring | nullRequired
error_detailstring | nullRequired
created_atdate-timeRequired
updated_atdate-timeRequired
HTTP status codes
StatusMeaning
200Successful Response
422Invalid request, filter, date range or pagination cursor.
400Repository exceeds the configured size or scannable file limit.
401Missing, malformed, expired or revoked API key.
403Missing scope, current terms, workspace permission or owner deletion approval.
404Resource missing or unavailable to this account.
409Scan or approval state conflicts with this operation.
413Request body exceeds 16 KiB.
429Rate limit or scan quota exceeded. Retry-After accompanies rate limits.
503Authentication/rate infrastructure or repository access is unavailable.
500Unexpected server error. Keep the request ID for support.
curl --fail-with-body --request GET \
  "https://sentrint.com/api/v1/submissions/$SUBMISSION_ID" \
  --header "Authorization: Bearer $SENTRINT_API_KEY" \
  --header "Accept: application/json"
{
  "body": null,
  "headers": {
    "Accept": "application/json",
    "Authorization": "Bearer $SENTRINT_API_KEY"
  },
  "method": "GET",
  "path": "/api/v1/submissions/{submission_id}",
  "path_parameters": {
    "submission_id": "00000000-0000-4000-8000-000000000001"
  },
  "query_parameters": {}
}
{
  "created_at": "2026-09-30T12:00:00Z",
  "error_code": "example",
  "error_detail": "example",
  "id": "00000000-0000-4000-8000-000000000001",
  "reused": false,
  "scan_id": "00000000-0000-4000-8000-000000000001",
  "scan_status_url": "example",
  "status": "accepted",
  "status_url": "example",
  "updated_at": "2026-09-30T12:00:00Z"
}

Findings2

GET/api/v1/findingsList findingsfindings:read

List findings

Link

Findings across your scans, filtered by severity, status, rule and more.

Scope
findings:read
Success
200
Parameters
ParameterInTypeDetails
workspace_idOptionalqueryuuid | null
scan_idOptionalqueryuuid | null
severityOptionalquerystring | nullAccepted values: CRITICAL, HIGH, LOW, MEDIUM
categoryOptionalquerystring | nullAccepted values: code, dependency, secret
rule_idOptionalquerystring | null
statusOptionalquerystring | nullAccepted values: fixed, ignored, in_progress, open
verification_stateOptionalquerystring | nullAccepted values: ai_reviewed, corroborated, detected, disproved, runtime_confirmed
qOptionalquerystring | null
limitOptionalqueryintegerDefault: 25
Minimum: 1; Maximum: 100
cursorOptionalquerystring | null
Response fields
FieldTypeDetails
dataFindingOut[]Required
next_cursorstring | nullOptional
HTTP status codes
StatusMeaning
200Successful Response
422Invalid request, filter, date range or pagination cursor.
400Repository exceeds the configured size or scannable file limit.
401Missing, malformed, expired or revoked API key.
403Missing scope, current terms, workspace permission or owner deletion approval.
404Resource missing or unavailable to this account.
409Scan or approval state conflicts with this operation.
413Request body exceeds 16 KiB.
429Rate limit or scan quota exceeded. Retry-After accompanies rate limits.
503Authentication/rate infrastructure or repository access is unavailable.
500Unexpected server error. Keep the request ID for support.
curl --fail-with-body --request GET \
  "https://sentrint.com/api/v1/findings" \
  --header "Authorization: Bearer $SENTRINT_API_KEY" \
  --header "Accept: application/json" \
  --get \
  --data-urlencode workspace_id=00000000-0000-4000-8000-000000000001 \
  --data-urlencode scan_id=00000000-0000-4000-8000-000000000001 \
  --data-urlencode severity=CRITICAL \
  --data-urlencode category=code \
  --data-urlencode rule_id=example \
  --data-urlencode status=fixed \
  --data-urlencode verification_state=ai_reviewed \
  --data-urlencode q=example \
  --data-urlencode limit=25
{
  "body": null,
  "headers": {
    "Accept": "application/json",
    "Authorization": "Bearer $SENTRINT_API_KEY"
  },
  "method": "GET",
  "path": "/api/v1/findings",
  "path_parameters": {},
  "query_parameters": {
    "category": "code",
    "cursor": "\u003cnext_cursor\u003e",
    "limit": 25,
    "q": "example",
    "rule_id": "example",
    "scan_id": "00000000-0000-4000-8000-000000000001",
    "severity": "CRITICAL",
    "status": "fixed",
    "verification_state": "ai_reviewed",
    "workspace_id": "00000000-0000-4000-8000-000000000001"
  }
}
{
  "data": [],
  "next_cursor": "example"
}
GET/api/v1/findings/{finding_id}Get a findingfindings:read

Get a finding

Link

File, line, message, fix suggestion and up to 100 evidence records. Evidence names the kind of check that saw it, never an internal tool.

Scope
findings:read
Success
200
Parameters
ParameterInTypeDetails
finding_idRequiredpathuuid
Response fields
FieldTypeDetails
iduuidRequired
scan_iduuidRequired
rule_idstringRequired
file_pathstringRequired
lineinteger | nullRequired
severitystringRequired
categorystringRequired
messagestringRequired
statusstringRequired
verification_statestring | nullRequired
suggestionstring | nullRequired
snippetstring | nullRequired
evidenceEvidenceOut[]Optional
guidance_lockedbooleanRequired
HTTP status codes
StatusMeaning
200Successful Response
422Invalid request, filter, date range or pagination cursor.
400Repository exceeds the configured size or scannable file limit.
401Missing, malformed, expired or revoked API key.
403Missing scope, current terms, workspace permission or owner deletion approval.
404Resource missing or unavailable to this account.
409Scan or approval state conflicts with this operation.
413Request body exceeds 16 KiB.
429Rate limit or scan quota exceeded. Retry-After accompanies rate limits.
503Authentication/rate infrastructure or repository access is unavailable.
500Unexpected server error. Keep the request ID for support.
curl --fail-with-body --request GET \
  "https://sentrint.com/api/v1/findings/$FINDING_ID" \
  --header "Authorization: Bearer $SENTRINT_API_KEY" \
  --header "Accept: application/json"
{
  "body": null,
  "headers": {
    "Accept": "application/json",
    "Authorization": "Bearer $SENTRINT_API_KEY"
  },
  "method": "GET",
  "path": "/api/v1/findings/{finding_id}",
  "path_parameters": {
    "finding_id": "00000000-0000-4000-8000-000000000001"
  },
  "query_parameters": {}
}
{
  "category": "example",
  "evidence": [],
  "file_path": "example",
  "guidance_locked": false,
  "id": "00000000-0000-4000-8000-000000000001",
  "line": 0,
  "message": "example",
  "rule_id": "example",
  "scan_id": "00000000-0000-4000-8000-000000000001",
  "severity": "example",
  "snippet": "example",
  "status": "example",
  "suggestion": "example",
  "verification_state": "example"
}

Deletion approval3

POST/api/v1/scans/{scan_id}/deletion-requestsRequest a deletionscans:delete

Request a deletion

Link

Returns an approval link the account owner opens in a browser.

Scope
scans:delete
Success
201
Parameters
ParameterInTypeDetails
scan_idRequiredpathuuid
Response fields
FieldTypeDetails
request_iduuidRequired
scan_iduuidRequired
statusstringRequired
expires_atdate-timeRequired
approval_urlstringRequired
HTTP status codes
StatusMeaning
201Successful Response
422Invalid request, filter, date range or pagination cursor.
400Repository exceeds the configured size or scannable file limit.
401Missing, malformed, expired or revoked API key.
403Missing scope, current terms, workspace permission or owner deletion approval.
404Resource missing or unavailable to this account.
409Scan or approval state conflicts with this operation.
413Request body exceeds 16 KiB.
429Rate limit or scan quota exceeded. Retry-After accompanies rate limits.
503Authentication/rate infrastructure or repository access is unavailable.
500Unexpected server error. Keep the request ID for support.
curl --fail-with-body --request POST \
  "https://sentrint.com/api/v1/scans/$SCAN_ID/deletion-requests" \
  --header "Authorization: Bearer $SENTRINT_API_KEY" \
  --header "Accept: application/json"
{
  "body": null,
  "headers": {
    "Accept": "application/json",
    "Authorization": "Bearer $SENTRINT_API_KEY"
  },
  "method": "POST",
  "path": "/api/v1/scans/{scan_id}/deletion-requests",
  "path_parameters": {
    "scan_id": "00000000-0000-4000-8000-000000000001"
  },
  "query_parameters": {}
}
{
  "approval_url": "https://sentrint.com/dashboard/api/deletion-approvals/00000000-0000-4000-8000-000000000001",
  "expires_at": "2026-09-30T12:10:00Z",
  "request_id": "00000000-0000-4000-8000-000000000001",
  "scan_id": "00000000-0000-4000-8000-000000000001",
  "status": "pending"
}
GET/api/v1/deletion-requests/{request_id}Get approval statusscans:delete

Get approval status

Link

Shows whether the owner has approved the deletion yet.

Scope
scans:delete
Success
200
Parameters
ParameterInTypeDetails
request_idRequiredpathuuid
Response fields
FieldTypeDetails
request_iduuidRequired
scan_iduuidRequired
statusstringRequired
expires_atdate-timeRequired
approval_urlstringRequired
HTTP status codes
StatusMeaning
200Successful Response
422Invalid request, filter, date range or pagination cursor.
400Repository exceeds the configured size or scannable file limit.
401Missing, malformed, expired or revoked API key.
403Missing scope, current terms, workspace permission or owner deletion approval.
404Resource missing or unavailable to this account.
409Scan or approval state conflicts with this operation.
413Request body exceeds 16 KiB.
429Rate limit or scan quota exceeded. Retry-After accompanies rate limits.
503Authentication/rate infrastructure or repository access is unavailable.
500Unexpected server error. Keep the request ID for support.
curl --fail-with-body --request GET \
  "https://sentrint.com/api/v1/deletion-requests/$DELETION_REQUEST_ID" \
  --header "Authorization: Bearer $SENTRINT_API_KEY" \
  --header "Accept: application/json"
{
  "body": null,
  "headers": {
    "Accept": "application/json",
    "Authorization": "Bearer $SENTRINT_API_KEY"
  },
  "method": "GET",
  "path": "/api/v1/deletion-requests/{request_id}",
  "path_parameters": {
    "request_id": "00000000-0000-4000-8000-000000000001"
  },
  "query_parameters": {}
}
{
  "approval_url": "https://sentrint.com/dashboard/api/deletion-approvals/00000000-0000-4000-8000-000000000001",
  "expires_at": "2026-09-30T12:10:00Z",
  "request_id": "00000000-0000-4000-8000-000000000001",
  "scan_id": "00000000-0000-4000-8000-000000000001",
  "status": "pending"
}
DELETE/api/v1/scans/{scan_id}Delete a scanscans:delete

Delete a scan

Link

Removes a finished scan and its findings once the owner has approved.

Scope
scans:delete
Success
204
Parameters
ParameterInTypeDetails
scan_idRequiredpathuuid
X-Deletion-ApprovalOptionalheaderuuid | null
HTTP status codes
StatusMeaning
204Successful Response
422Invalid request, filter, date range or pagination cursor.
400Repository exceeds the configured size or scannable file limit.
401Missing, malformed, expired or revoked API key.
403Missing scope, current terms, workspace permission or owner deletion approval.
404Resource missing or unavailable to this account.
409Scan or approval state conflicts with this operation.
413Request body exceeds 16 KiB.
429Rate limit or scan quota exceeded. Retry-After accompanies rate limits.
503Authentication/rate infrastructure or repository access is unavailable.
500Unexpected server error. Keep the request ID for support.
curl --fail-with-body --request DELETE \
  "https://sentrint.com/api/v1/scans/$SCAN_ID" \
  --header "Authorization: Bearer $SENTRINT_API_KEY" \
  --header "Accept: application/json" \
  --header "X-Deletion-Approval: $DELETION_REQUEST_ID"
{
  "body": null,
  "headers": {
    "Accept": "application/json",
    "Authorization": "Bearer $SENTRINT_API_KEY",
    "X-Deletion-Approval": "$DELETION_REQUEST_ID"
  },
  "method": "DELETE",
  "path": "/api/v1/scans/{scan_id}",
  "path_parameters": {
    "scan_id": "00000000-0000-4000-8000-000000000001"
  },
  "query_parameters": {}
}

A 204 response has no body.

Audit events1

GET/api/v1/audit-eventsList audit eventsaudit:read

List audit events

Link

Account activity, as far back as your plan keeps it.

Scope
audit:read
Success
200
Parameters
ParameterInTypeDetails
fromOptionalquerydate-time | null
toOptionalquerydate-time | null
categoryOptionalquerystring | nullAccepted values: account, billing, mcp, repo, scan, workspace
actionOptionalquerystring | null
sourceOptionalquerystring | nullAccepted values: account, audit, payment, plan, scan_log, workspace
limitOptionalqueryintegerDefault: 25
Minimum: 1; Maximum: 100
cursorOptionalquerystring | null
Response fields
FieldTypeDetails
dataAuditOut[]Required
next_cursorstring | nullOptional
HTTP status codes
StatusMeaning
200Successful Response
422Invalid request, filter, date range or pagination cursor.
400Repository exceeds the configured size or scannable file limit.
401Missing, malformed, expired or revoked API key.
403Missing scope, current terms, workspace permission or owner deletion approval.
404Resource missing or unavailable to this account.
409Scan or approval state conflicts with this operation.
413Request body exceeds 16 KiB.
429Rate limit or scan quota exceeded. Retry-After accompanies rate limits.
503Authentication/rate infrastructure or repository access is unavailable.
500Unexpected server error. Keep the request ID for support.
curl --fail-with-body --request GET \
  "https://sentrint.com/api/v1/audit-events" \
  --header "Authorization: Bearer $SENTRINT_API_KEY" \
  --header "Accept: application/json" \
  --get \
  --data-urlencode from=2026-09-30T12:00:00Z \
  --data-urlencode to=2026-09-30T12:00:00Z \
  --data-urlencode category=account \
  --data-urlencode action=example \
  --data-urlencode source=account \
  --data-urlencode limit=25
{
  "body": null,
  "headers": {
    "Accept": "application/json",
    "Authorization": "Bearer $SENTRINT_API_KEY"
  },
  "method": "GET",
  "path": "/api/v1/audit-events",
  "path_parameters": {},
  "query_parameters": {
    "action": "example",
    "category": "account",
    "cursor": "\u003cnext_cursor\u003e",
    "from": "2026-09-30T12:00:00Z",
    "limit": 25,
    "source": "account",
    "to": "2026-09-30T12:00:00Z"
  }
}
{
  "data": [],
  "next_cursor": "example"
}

Pagination and filters

List endpoints return {"data": [...], "next_cursor": "..."}. Set limit from 1 to 100; the default is 25. For the next page, send next_cursor back as cursor, and stop when it is null. Keep the filters the same from page to page: a cursor only works for the owner, resource and filters it came from.

GET /api/v1/findings?scan_id={scan_id}&severity=HIGH&status=open&limit=25
Finding filters
workspace_id, scan_id, severity, category, rule_id, status, verification_state and q. Values are case-sensitive, and each endpoint lists the values it accepts. q searches the message, file path and rule ID, up to 120 characters; rule_id takes up to 128. If you pass both IDs, the scan must belong to that workspace.
Audit filters
from, to, category, action (up to 48 characters) and source. Dates are ISO 8601, in order, and inside your plan's audit retention. Use explicit UTC dates for a fixed window. action takes the same codes the API returns, including the log_ and payment_ ones. Only retained history comes back.

Errors

Errors come back as application/problem+json with type, title, status, code, detail and request_id. Branch on code, never on the wording of detail, and quote request_id when you contact support.

{
  "code": "invalid_api_key",
  "detail": "A valid Bearer API key is required.",
  "request_id": "example-request-id",
  "status": 401,
  "title": "Unauthorized",
  "type": "about:blank"
}
StatusCodesWhat to do
400repository_too_largeCut the repository size or the number of files that get scanned.
401invalid_api_keyCheck the Bearer header, and whether the key expired or was revoked.
403insufficient_scope, terms_required, workspace_read_only, approval_requiredAdd the scope, accept the terms, or get the owner's approval.
404workspace_not_found, scan_not_found, finding_not_found, approval_not_foundUse an ID that belongs to this account.
409workspace_conflict, scan_not_finished, approval_unavailable, scan_requires_force, rules_version_changed, commit_not_on_branchFix the state of the resource, then retry.
413, 422body_too_large, validation_error, invalid_filter, invalid_cursor, invalid_date_rangeSend valid parameters and a JSON body of 16 KiB or less.
429rate_limit_exceeded, quota_exhaustedWait for Retry-After on a rate limit. On quota, check your allowance.
503rate_limit_unavailable, repository_unavailableRetry reads with backoff. Check repository access before you submit again.

The limit for each kind of request is on the Rate limits tab of your dashboard. When you hit one, wait for the time in Retry-After and add jitter to your retries. Don't retry writes blindly. quota_exhausted means the scan allowance is used up, so waiting won't help.

An ID that doesn't exist and an ID that belongs to someone else both return 404. A deletion request can fail its approval check before the scan is looked up. No response is cached, success or error.

Delete scan results

Deleting a finished scan removes it and its findings for good. The audit record stays. Even with a scans:delete key, the account owner approves each deletion in a browser.

  1. 1
    Send POST /api/v1/scans/{scan_id}/deletion-requests. The 201 response has request_id, expires_at and approval_url.
  2. 2
    The owner opens approval_url, checks the scan and the key, confirms their linked sign-in through OAuth, then approves. GitHub may reuse a session it already has, so this is not a guaranteed fresh password or MFA prompt. The email is only a notice. It does not approve anything.
  3. 3
    Poll GET /api/v1/deletion-requests/{request_id} until its status is approved.
  4. 4
    Send DELETE /api/v1/scans/{scan_id} with the same key and an X-Deletion-Approval: {request_id} header. Success is 204 with no body.
curl --fail-with-body -X DELETE \
  "https://sentrint.com/api/v1/scans/$SCAN_ID" \
  -H "Authorization: Bearer $SENTRINT_API_KEY" \
  -H "X-Deletion-Approval: $DELETION_REQUEST_ID"

An approval lasts 10 minutes and works once, for one owner, one key and one scan. Retrying or rescanning the scan cancels it, and a used or expired approval returns 409. A running scan can't be deleted; stop it in the dashboard first. If the owner has a verified email on a linked sign-in, we send a deletion notice. The deletion stands even if that email fails.

Response schemas

The objects the endpoints return, field by field. Pick one to see its fields. A linked type opens the object it contains. The raw JSON Schema is in the OpenAPI file.

AccountOut

8 fields
FieldTypeDetails
idRequireduuid
loginRequiredstring
planRequiredstring
included_scans_remainingRequiredinteger
scan_creditsRequiredinteger
scans_used_in_periodRequiredinteger
scan_limit_in_periodRequiredinteger | null
periodRequiredstring

ApprovalOut

5 fields
FieldTypeDetails
request_idRequireduuid
scan_idRequireduuid
statusRequiredstring
expires_atRequireddate-time
approval_urlRequiredstring

AuditOut

8 fields
FieldTypeDetails
idRequiredstring
atRequireddate-time
sourceRequiredstring
categoryRequiredstring
actionRequiredstring
labelRequiredstring
targetRequiredstring | null
detailRequiredstring | null

EvidenceOut

5 fields
FieldTypeDetails
idRequireduuid
originRequiredstring
kindRequiredstring
producerRequiredstring
payloadRequiredobject

FindingDetailOut

14 fields
FieldTypeDetails
idRequireduuid
scan_idRequireduuid
rule_idRequiredstring
file_pathRequiredstring
lineRequiredinteger | null
severityRequiredstring
categoryRequiredstring
messageRequiredstring
statusRequiredstring
verification_stateRequiredstring | null
suggestionRequiredstring | null
snippetRequiredstring | null
evidenceOptionalEvidenceOut[]
guidance_lockedRequiredboolean

FindingOut

10 fields
FieldTypeDetails
idRequireduuid
scan_idRequireduuid
rule_idRequiredstring
file_pathRequiredstring
lineRequiredinteger | null
severityRequiredstring
categoryRequiredstring
messageRequiredstring
statusRequiredstring
verification_stateRequiredstring | null

HTTPValidationError

1 field
FieldTypeDetails
detailOptionalValidationError[]

Page_AuditOut_

2 fields
FieldTypeDetails
dataRequiredAuditOut[]
next_cursorOptionalstring | null

Page_FindingOut_

2 fields
FieldTypeDetails
dataRequiredFindingOut[]
next_cursorOptionalstring | null

Page_ScanOut_

2 fields
FieldTypeDetails
dataRequiredScanOut[]
next_cursorOptionalstring | null

Page_WorkspaceOut_

2 fields
FieldTypeDetails
dataRequiredWorkspaceOut[]
next_cursorOptionalstring | null

Problem

6 fields
FieldTypeDetails
typeRequiredstring
titleRequiredstring
statusRequiredinteger
codeRequiredstring
detailRequiredstring
request_idRequiredstring

ReportOut

10 fields
FieldTypeDetails
scan_idRequireduuid
scoreRequiredinteger
gradeRequiredstring
criticalRequiredinteger
highRequiredinteger
mediumRequiredinteger
lowRequiredinteger
top_rulesRequiredstring[]
summary_textRequiredstring
guidance_lockedRequiredboolean

RepositoryOut

2 fields
FieldTypeDetails
full_nameRequiredstring
repo_urlRequiredstring

ScanOut

8 fields
FieldTypeDetails
idRequireduuid
workspace_idRequireduuid | null
statusRequiredstring
repo_urlRequiredstring
commit_shaRequiredstring
scoreRequiredinteger | null
created_atRequireddate-time
updated_atRequireddate-time

ScanQueued

4 fields
FieldTypeDetails
scan_idRequireduuid
statusRequiredstring
status_urlRequiredstring
reusedRequiredboolean

ScanRequest

4 fields
FieldTypeDetails
repo_urlRequiredstringMaximum length: 512
branchOptionalstring | null
forceOptionalboolean
commit_shaOptionalstring | null

SubmissionOut

10 fields
FieldTypeDetails
idRequireduuid
statusRequiredstringaccepted, validating, failed, scan_ready
status_urlRequiredstring
scan_idRequireduuid | null
scan_status_urlRequiredstring | null
reusedRequiredboolean
error_codeRequiredstring | null
error_detailRequiredstring | null
created_atRequireddate-time
updated_atRequireddate-time

ValidationError

5 fields
FieldTypeDetails
locRequired(string | integer)[]
msgRequiredstring
typeRequiredstring
inputOptionalvalue
ctxOptionalobject

WorkspaceDetailOut

6 fields
FieldTypeDetails
idRequireduuid
nameRequiredstring
created_atRequireddate-time
tracked_repository_countRequiredinteger
repositoriesOptionalRepositoryOut[]
repositories_truncatedOptionalboolean

WorkspaceOut

3 fields
FieldTypeDetails
idRequireduuid
nameRequiredstring
created_atRequireddate-time

Postman and OpenAPI

Import the contract into your API client. The Postman collection has base_url, api_key and resource ID variables to fill in locally, and its optional query rows start switched off. Keep a filled-in environment private. Insomnia and other OpenAPI 3.1 clients can import the JSON or YAML file.