Skip to contentLockpick
Docs

Every Lockpick API operation, its permission, inputs and answer, generated from the API itself. Version 1, in beta.

Version 1, in beta. Every path starts with /api/cli/v1, every request carries a key as a bearer token, and every answer is { data, error }. The whole description is also OpenAPI 3.1.

Agent API

The server operations behind the hosted MCP tools. New integrations should use these. lockpick_wait_for_scan polls GET /agent/scans/{scanId}; lockpick_evaluate_scan reads that same scan and applies the assessment policy in the client. These two composed tools have no separate HTTP endpoint. Scripts can poll the scan status and evaluate its completion time, coverage and open finding counts against their policy.

GET /agent/me

The person, workspace, scopes and expiry of this credential, and what it can start.

data

FieldTypeAlways there
userobjectYes
workspaceobjectYes
credentialobjectYes
capabilitiesobjectYes

GET /agent/allowance

Free scans left this month, their reset dates and credits.

data

FieldTypeAlways there
accessSourcecommunity, stripe (legacy billing value), pilot (legacy, internal), noneYes
accountingModepilot (legacy, internal), credits (legacy, internal), unmeteredYes
pulseobjectYes
deepobjectYes
creditBalanceinteger or nullYes
freeSiteIdstring or nullYes
freeSiteVisiblebooleanYes
canSwitchFreeSitebooleanYes

GET /agent/monitor

Browse current security intelligence and explain matches for authorized sites.

Query

FieldTypeRequired
viewlatest, sites, exploited, followingNo
kindall, vulnerability, malicious_packageNo
qstringNo
ecosystemall, npm, pypi, composer, wordpressNo
severityall, critical, high, medium, low, unknownNo
daysnumberNo
cursorstringNo
limitintegerNo
siteIdstringNo
advisoryIdstringNo

data

FieldTypeAlways there
itemslist of objectYes
nextCursorstring or nullYes
limitationslist of stringYes

Each item

FieldTypeAlways there
idstringYes
titlestringYes
sourcestringYes
kindvulnerability, malicious_packageYes
severitycritical, high, medium, low, unknownYes
provenancelist of objectYes
withdrawnAtstring or nullNo
publishedAtstringYes
exploitedbooleanYes
idslist of stringYes
techlist of objectYes
epssobject or nullNo
cvssobject or nullNo
attributionstring or nullYes
referenceslist of stringYes
packageslist of objectYes
siteslist of objectYes

GET /agent/sites

A page of sites with their latest scans.

Query

FieldTypeRequired
limitintegerNo
cursorstringNo

data

FieldTypeAlways there
itemslist of objectYes
nextCursorstring or nullYes

Each item

FieldTypeAlways there
idstringYes
namestringYes
statusstringYes
baseDomainstring or nullYes
latestPulseobject or nullYes
latestDeepobject or nullYes
latestBoxobject or nullYes
webPathstringYes
webUrlstringYes

POST /agent/sites

Add a site, or return the one with that address.

Body

FieldTypeRequired
urlstringYes
namestringNo
idempotencyKeystringYes

data

FieldTypeAlways there
siteobjectYes
createdbooleanYes

GET /agent/sites/{siteId}/status

One site's standing: its latest scans and what to do next.

data

FieldTypeAlways there
siteobjectYes
latestPulseobject or nullYes
latestDeepobject or nullYes
latestBoxobject or nullYes
lastComparisonobject or nullYes
caveatslist of stringYes
relevantlist of objectNo
relevantTotalintegerNo

POST /agent/sites/{siteId}/dependencies

Send the package names and exact versions a site pins, never code, and read which advisories affect them.

Body

FieldTypeRequired
inventoryobjectNo
packageslist of objectYes
sourceslist of package-lock.json, npm-shrinkwrap.json, pnpm-lock.yaml, yarn.lock, requirements.txt, poetry.lockYes
idempotencyKeystringYes

data

FieldTypeAlways there
siteIdstringYes
receivedAtstring or nullYes
sourceslist of package-lock.json, npm-shrinkwrap.json, pnpm-lock.yaml, yarn.lock, requirements.txt, poetry.lockYes
packageCountintegerYes
affectsYouCountintegerYes
affectsYoulist of objectYes
webUrlstringYes

POST /agent/sites/{siteId}/pulse

Start a Pulse on a site.

Body

FieldTypeRequired
idempotencyKeystringYes
baselineScanIdstringNo

data

FieldTypeAlways there
scanobjectYes
chargedobjectYes
allowanceobjectYes
replayedbooleanYes

POST /agent/sites/{siteId}/deep-verifications

Issue a DNS or file ownership proof before a Deep scan.

Body

FieldTypeRequired
methoddns, file, metaYes
idempotencyKeystringYes

data

FieldTypeAlways there
verificationIdstringYes
siteIdstringYes
originstringYes
methoddns, file, metaYes
statepending, verified, expired, exhausted, revokedYes
expiresAtstringYes
verifiedUntilstring or nullYes
attemptsRemainingintegerYes
retryAfterSecondsinteger or nullYes
valuestringYes
locationstringYes

POST /agent/sites/{siteId}/deep-verifications/{verificationId}/verify

Check a published ownership proof. Each check uses one of its attempts.

data

FieldTypeAlways there
verificationIdstringYes
siteIdstringYes
originstringYes
methoddns, file, metaYes
statepending, verified, expired, exhausted, revokedYes
expiresAtstringYes
verifiedUntilstring or nullYes
attemptsRemainingintegerYes
retryAfterSecondsinteger or nullYes

POST /agent/sites/{siteId}/deep-operations

Prepare a Deep scan and get the link where the person approves it.

Body

FieldTypeRequired
verificationIdstringYes
idempotencyKeystringYes

data

FieldTypeAlways there
operationIdstringYes
siteIdstringYes
originstringYes
assessmentLevelstringYes
verificationIdstringYes
costobjectYes
allowanceobjectYes
approvalStatepending, approved, expired, deniedYes
approvalUrlstringYes
expiresAtstringYes

POST /agent/deep-operations/{operationId}/start

Start a Deep scan the person approved.

data

FieldTypeAlways there
scanobjectYes
chargedobjectYes
allowanceobjectYes
replayedbooleanYes

POST /agent/free-site-switch

Remove a site so this month's free Pulse can move to another.

Body

FieldTypeRequired
removeSiteIdstringYes
checkIdstringNo
idempotencyKeystringYes
confirmRemovalbooleanYes

data

FieldTypeAlways there
removedSiteIdstringYes
removedSiteHoststringYes
replacementSiteIdstring or nullYes
allowanceobjectYes
restoreUrlstringYes
startedScanIdstring or nullYes
chargedobjectYes
replayedbooleanYes

GET /agent/scans

A page of scans, newest first, with filters.

Query

FieldTypeRequired
siteIdstringNo
kindpulse, box (Deep, legacy name)No
assessmentLevelpulse, standard, deepNo
statusqueued, running, cancelling, succeeded, incomplete, failed, cancelledNo
limitintegerNo
cursorstringNo

data

FieldTypeAlways there
itemslist of objectYes
nextCursorstring or nullYes

Each item

FieldTypeAlways there
idstringYes
kindpulse, box (Deep, legacy name)Yes
projectIdstringYes
targetstringYes
statusqueued, running, cancelling, succeeded, incomplete, failed, cancelledYes
modeautonomous, authenticated, active or nullYes
createdAtstring or nullYes
finishedAtstring or nullYes
webPathstringYes
assessmentLevelpulse, standard, deep or nullYes
headlineobjectYes
webUrlstringYes
suggestedPollAfterSecondsinteger or nullYes

GET /agent/scans/{scanId}

One scan with its status and headline.

data

FieldTypeAlways there
idstringYes
kindpulse, box (Deep, legacy name)Yes
projectIdstringYes
targetstringYes
statusqueued, running, cancelling, succeeded, incomplete, failed, cancelledYes
modeautonomous, authenticated, active or nullYes
createdAtstring or nullYes
finishedAtstring or nullYes
webPathstringYes
assessmentLevelpulse, standard, deep or nullYes
headlineobjectYes
webUrlstringYes
suggestedPollAfterSecondsinteger or nullYes
baselineRunIdstring or nullYes
openobjectYes
findingCountintegerYes
progressobject or nullYes
coverageobjectYes
caveatslist of stringYes
outcomeobject or nullYes
exposureCheckobjectNo

GET /agent/scans/{scanId}/findings

A page of findings of a scan.

  • Permission: read
  • MCP tool: lockpick_list_findings
  • Send x-lockpick-agent-features: finding-code to receive each finding's code (LP- and six characters, as the web report shows it). Without the header the answer has no code, the shape older clients expect.

Query

FieldTypeRequired
stateattention, information, unknown, passNo
severitycritical, high, medium, low, infoNo
allboolean or true, falseNo
limitintegerNo
cursorstringNo

data

FieldTypeAlways there
itemslist of objectYes
nextCursorstring or nullYes

Each item

FieldTypeAlways there
idstringYes
codestringNo
runIdstringYes
kindpulse, box (Deep, legacy name)Yes
severitycritical, high, medium, low, infoYes
stateattention, information, unknown, passYes
categorystringYes
titlestringYes
meaningstringYes
fixstring or nullYes
confidencestringYes
evidencelist of stringYes
sourceslist of stringYes
stepslist of stringYes
webPathstringYes
webUrlstringYes
evidenceTruststringYes
evidenceTruncatedbooleanYes
verdictconfirmed, needs_review, not_actionable or nullNo
certaintyhigh, medium, low or nullNo
exploitabilitydirect, conditional, hygiene, none or nullNo
proofobject or nullNo
proofGapstring or nullNo
urgencynow, week, later, noneNo
howSureconfirmed, likely, possible or nullNo

GET /agent/scans/{scanId}/findings/{findingId}

One finding with its redacted evidence.

  • Permission: read
  • MCP tool: lockpick_get_finding
  • Send x-lockpick-agent-features: finding-code to receive each finding's code (LP- and six characters, as the web report shows it). Without the header the answer has no code, the shape older clients expect.

data

FieldTypeAlways there
idstringYes
codestringNo
runIdstringYes
kindpulse, box (Deep, legacy name)Yes
severitycritical, high, medium, low, infoYes
stateattention, information, unknown, passYes
categorystringYes
titlestringYes
meaningstringYes
fixstring or nullYes
confidencestringYes
evidencelist of stringYes
sourceslist of stringYes
stepslist of stringYes
webPathstringYes
webUrlstringYes
evidenceTruststringYes
evidenceTruncatedbooleanYes
verdictconfirmed, needs_review, not_actionable or nullNo
certaintyhigh, medium, low or nullNo
exploitabilitydirect, conditional, hygiene, none or nullNo
proofobject or nullNo
proofGapstring or nullNo
urgencynow, week, later, noneNo
howSureconfirmed, likely, possible or nullNo

GET /agent/scans/{scanId}/repair-brief

One part of a scan's repair brief.

Query

FieldTypeRequired
findingIdstringNo
agentclaude-code, codex, cursor, vscode, opencode, lovable, bolt, replit, v0No
cursorstringNo

data

FieldTypeAlways there
scanIdstringYes
findingIdslist of stringYes
savedbooleanYes
markdownstringYes
nextCursorstring or nullYes
completebooleanYes
webUrlstringYes

GET /agent/scans/{scanId}/comparison

What changed between a scan and the one it rechecks.

  • Permission: read
  • MCP tool: lockpick_compare_scans
  • Send x-lockpick-agent-features: finding-code to receive each finding's code (LP- and six characters, as the web report shows it). Without the header the answer has no code, the shape older clients expect.

data

FieldTypeAlways there
runIdstringYes
baselineRunIdstringYes
errorstring or nullYes
changeslist of objectYes
webUrlstringYes

POST /agent/scans/{scanId}/dns-rechecks

Run the free DNS check again for a scan. Sends nothing to the site.

Body

FieldTypeRequired
findingIdstringYes
idempotencyKeystringYes

data

FieldTypeAlways there
scanIdstringYes
findingIdslist of stringYes
pendingobject or nullYes
checkedAtstring or nullYes
outcomeslist of objectYes
nextAllowedAtstring or nullYes
failedAtstring or nullYes
originalGradeUnchangedbooleanYes

GET /agent/scans/{scanId}/dns-rechecks/latest

A scan's latest DNS check again.

data

FieldTypeAlways there
scanIdstringYes
findingIdslist of stringYes
pendingobject or nullYes
checkedAtstring or nullYes
outcomeslist of objectYes
nextAllowedAtstring or nullYes
failedAtstring or nullYes
originalGradeUnchangedbooleanYes

POST /agent/quick-checks

Start a free quick check of a homepage.

Body

FieldTypeRequired
urlstringYes
idempotencyKeystringYes

data

FieldTypeAlways there
checkIdstringYes
statusqueued, running, succeeded, failedYes
reusedbooleanYes
headlineobjectYes
summarystring or nullYes
checkslist of objectYes
webUrlstringYes
suggestedPollAfterSecondsinteger or nullYes

POST /agent/repository-checks

Check a public GitHub repository (a skill, plugin, MCP server or app) before installing it.

Body

FieldTypeRequired
urlstringYes
modeskill, appNo
depthfree, deepNo
idempotencyKeystringYes

data

FieldTypeAlways there
checkIdstringYes
statusqueued, running, succeeded, failedYes
reusedbooleanYes
repositoryobjectYes
modeskill, app or nullYes
kindstring or nullYes
verdictsafe, caution, do_not_install or nullYes
appRisklow, elevated, high or nullYes
scoreinteger or nullYes
summarystring or nullYes
plainSummarystring or nullYes
findingslist of objectYes
moreFindingsintegerYes
coverageobject or nullYes
failurenot-found, ref-not-found, empty, too-large, rate-limited, unavailable, timeout, engine-error or nullYes
webUrlstringYes
suggestedPollAfterSecondsinteger or nullYes

GET /agent/repository-checks/{checkId}

A repository check and its findings.

data

FieldTypeAlways there
checkIdstringYes
statusqueued, running, succeeded, failedYes
reusedbooleanYes
repositoryobjectYes
modeskill, app or nullYes
kindstring or nullYes
verdictsafe, caution, do_not_install or nullYes
appRisklow, elevated, high or nullYes
scoreinteger or nullYes
summarystring or nullYes
plainSummarystring or nullYes
findingslist of objectYes
moreFindingsintegerYes
coverageobject or nullYes
failurenot-found, ref-not-found, empty, too-large, rate-limited, unavailable, timeout, engine-error or nullYes
webUrlstringYes
suggestedPollAfterSecondsinteger or nullYes

GET /agent/quick-checks/{checkId}

A quick check and its result.

data

FieldTypeAlways there
checkIdstringYes
statusqueued, running, succeeded, failedYes
reusedbooleanYes
headlineobjectYes
summarystring or nullYes
checkslist of objectYes
webUrlstringYes
suggestedPollAfterSecondsinteger or nullYes

GET /agent/docs/search

Search Lockpick's public docs.

Query

FieldTypeRequired
querystringYes
limitintegerNo

data

FieldTypeAlways there
querystringYes
resultslist of objectYes

GET /agent/docs/page

One public docs page as Markdown, in parts when it is long.

Query

FieldTypeRequired
pathstringNo
cursorstringNo

data

FieldTypeAlways there
pathstringYes
titlestringYes
descriptionstring or nullYes
urlstringYes
markdownUrlstringYes
markdownstringYes
nextCursorstring or nullYes
completebooleanYes

Device sign-in

How lockpick login gets a key: it asks for a code, the person approves it in the browser, and polling returns the key.

POST /device/code

Start a device sign-in and get a code for the person to approve in the browser.

  • Permission: none, part of sign-in

Body

FieldTypeRequired
clientNamestringNo
hostnamestringNo
platformstringNo
versionstringNo
scopeslist of pulse, sites, deep, localNo

data

FieldTypeAlways there
deviceCodestringYes
userCodestringYes
verificationUristringYes
verificationUriCompletestringYes
expiresInintegerYes
intervalintegerYes

POST /device/token

Poll a device sign-in until the person approves it, then receive the key.

  • Permission: none, part of sign-in

Body

FieldTypeRequired
deviceCodestringYes

Legacy

The original CLI routes, which CLI 0.2 uses. They stay as they are, and new integrations should use the Agent API above.

Original CLI routes

POST /projects/{projectId}/local-assessments/authorize

Authorize a local assessment before repository inspection. No source or results are uploaded.

  • Permission: local

Body

FieldTypeRequired
cliVersionstringYes
scannerVersionstringYes
rulesetVersionstringYes
reportSchemaVersionstringYes
checkslist of tracked-secrets, public-environment, browser-artifacts, supabase-client, supabase-migrations, git-history, docker-files, docker-values, actions-injection, source-mapsYes

data

FieldTypeAlways there
admissionIdstringYes
projectIdstringYes
workspaceIdstringYes
policyVersionstringYes
startBystringYes
checkslist of objectYes

GET /me

The person, workspace and key behind this credential.

  • Permission: read

data

FieldTypeAlways there
userobjectYes
workspaceobjectYes
keyobjectYes

DELETE /me

Revoke the presented key.

  • Permission: any valid key

data

FieldTypeAlways there
revokedbooleanYes

GET /projects

Sites (projects) with their latest Pulse and Deep scans.

  • Permission: read

Each item in data

FieldTypeAlways there
idstringYes
namestringYes
statusstringYes
baseDomainstring or nullYes
latestPulseobject or nullYes
latestDeepobject or nullNo
latestBoxobject or nullYes
webPathstringYes
webUrlstringNo

GET /projects/{projectId}/status

One site's latest results and what changed.

  • Permission: read

data

FieldTypeAlways there
projectobjectYes
latestPulseobject or nullYes
latestDeepobject or nullNo
latestBoxobject or nullYes
lastComparisonobject or nullYes
caveatslist of stringYes

POST /projects/{projectId}/pulse

Start a Pulse on a site, or a recheck of its latest one.

  • Permission: pulse
  • Answers 201 when it works

Body

FieldTypeRequired
idempotencyKeystringYes

data

FieldTypeAlways there
idstringYes
kindpulse, box (Deep, legacy name)Yes
projectIdstringYes
targetstringYes
statusqueued, running, cancelling, succeeded, incomplete, failed, cancelledYes
modeautonomous, authenticated, active or nullYes
createdAtstring or nullYes
finishedAtstring or nullYes
webPathstringYes
assessmentLevelpulse, standard, deep or nullNo
headlineobjectNo
webUrlstringNo
suggestedPollAfterSecondsinteger or nullNo
baselineRunIdstring or nullYes
openobjectYes
findingCountintegerYes
progressobject or nullYes
coverageobjectYes
caveatslist of stringYes
outcomeobject or nullNo
exposureCheckobject or nullNo

POST /projects/{projectId}/deep

Start a release's Deep scan with a CI key made for this site with Deep allowed.

  • Permission: deep
  • Answers 201 when it works

Body

FieldTypeRequired
idempotencyKeystringYes

data

FieldTypeAlways there
idstringYes
kindpulse, box (Deep, legacy name)Yes
projectIdstringYes
targetstringYes
statusqueued, running, cancelling, succeeded, incomplete, failed, cancelledYes
modeautonomous, authenticated, active or nullYes
createdAtstring or nullYes
finishedAtstring or nullYes
webPathstringYes
assessmentLevelpulse, standard, deep or nullNo
headlineobjectNo
webUrlstringNo
suggestedPollAfterSecondsinteger or nullNo
baselineRunIdstring or nullYes
openobjectYes
findingCountintegerYes
progressobject or nullYes
coverageobjectYes
caveatslist of stringYes
outcomeobject or nullNo
exposureCheckobject or nullNo

GET /runs

Pulse and Deep scans, newest first.

  • Permission: read

Query

FieldTypeRequired
projectIdstringNo
kindpulse, box (Deep, legacy name)No
assessmentLevelpulse, standard, deepNo
statusqueued, running, cancelling, succeeded, incomplete, failed, cancelledNo
limitintegerNo

Each item in data

FieldTypeAlways there
idstringYes
kindpulse, box (Deep, legacy name)Yes
projectIdstringYes
targetstringYes
statusqueued, running, cancelling, succeeded, incomplete, failed, cancelledYes
modeautonomous, authenticated, active or nullYes
createdAtstring or nullYes
finishedAtstring or nullYes
webPathstringYes
assessmentLevelpulse, standard, deep or nullNo
headlineobjectNo
webUrlstringNo
suggestedPollAfterSecondsinteger or nullNo

GET /runs/{runId}

One run with its headline and counts.

  • Permission: read

data

FieldTypeAlways there
idstringYes
kindpulse, box (Deep, legacy name)Yes
projectIdstringYes
targetstringYes
statusqueued, running, cancelling, succeeded, incomplete, failed, cancelledYes
modeautonomous, authenticated, active or nullYes
createdAtstring or nullYes
finishedAtstring or nullYes
webPathstringYes
assessmentLevelpulse, standard, deep or nullNo
headlineobjectNo
webUrlstringNo
suggestedPollAfterSecondsinteger or nullNo
baselineRunIdstring or nullYes
openobjectYes
findingCountintegerYes
progressobject or nullYes
coverageobjectYes
caveatslist of stringYes
outcomeobject or nullNo
exposureCheckobject or nullNo

GET /runs/{runId}/findings

Findings of a run.

  • Permission: read

Query

FieldTypeRequired
severitycritical, high, medium, low, infoNo
stateattention, information, unknown, passNo
alltrue, falseNo

Each item in data

FieldTypeAlways there
idstringYes
codestringNo
runIdstringYes
kindpulse, box (Deep, legacy name)Yes
severitycritical, high, medium, low, infoYes
stateattention, information, unknown, passYes
categorystringYes
titlestringYes
meaningstringYes
fixstring or nullYes
confidencestringYes
evidencelist of stringYes
sourceslist of stringYes
stepslist of stringYes
webPathstringYes
webUrlstringNo
verdictconfirmed, needs_review, not_actionable or nullNo
certaintyhigh, medium, low or nullNo
exploitabilitydirect, conditional, hygiene, none or nullNo
proofobject or nullNo
proofGapstring or nullNo
urgencynow, week, later, noneNo
howSureconfirmed, likely, possible or nullNo

GET /runs/{runId}/findings/{findingId}

One finding with its redacted evidence.

  • Permission: read

data

FieldTypeAlways there
idstringYes
codestringNo
runIdstringYes
kindpulse, box (Deep, legacy name)Yes
severitycritical, high, medium, low, infoYes
stateattention, information, unknown, passYes
categorystringYes
titlestringYes
meaningstringYes
fixstring or nullYes
confidencestringYes
evidencelist of stringYes
sourceslist of stringYes
stepslist of stringYes
webPathstringYes
webUrlstringNo
verdictconfirmed, needs_review, not_actionable or nullNo
certaintyhigh, medium, low or nullNo
exploitabilitydirect, conditional, hygiene, none or nullNo
proofobject or nullNo
proofGapstring or nullNo
urgencynow, week, later, noneNo
howSureconfirmed, likely, possible or nullNo

GET /runs/{runId}/repair-brief

A run's fixes as one Markdown brief.

  • Permission: read

Query

FieldTypeRequired
findingIdstringNo
agentclaude-code, codex, cursor, vscode, opencode, lovable, bolt, replit, v0No

data

FieldTypeAlways there
runIdstringYes
findingIdslist of stringYes
savedbooleanYes
markdownstringYes
webUrlstringNo

GET /runs/{runId}/comparison

What changed between a run and the one before it.

  • Permission: read

data

FieldTypeAlways there
runIdstringYes
baselineRunIdstringYes
errorstring or nullYes
changeslist of objectYes
webUrlstringNo

Was this helpful?

On this page