Skip to content

Local API Reference

The Claspt desktop app answers a local HTTP API on 127.0.0.1 for the browser extension, the bundled MCP server, the claspt command and any script on the same machine. This page covers the rules that apply to every route. The routes themselves live in one place:

  • The API Explorer shows every route with its parameters, schemas, responses and a curl example. It is generated from the OpenAPI document, and a test in the repository fails when the app’s route table and the document differ, so it is always the current description.
  • /openapi.yaml is the document itself, for any tool that reads OpenAPI 3.1.

The explorer cannot send requests: the app answers loopback requests only and refuses browser origins other than the Claspt extension. Copy the curl example instead.

Base URLhttp://127.0.0.1:9315 (the port is in Settings › Integrations › Local API)
AuthenticationAuthorization: Bearer <key> on every request
TransportPlain HTTP over loopback. Nothing listens on any other interface.
BodiesJSON, except 204 No Content
Feature detectionGET /api/status returns a features map. Check it rather than comparing versions.
SurfaceWho uses itSees
Local API (this page)The extension, the MCP server, the CLI, scripts on the same machineDecrypted pages and secret blocks, subject to scope and approval
MCP serverAI toolsThe same local API, with the same key, scope, approval, rate limit and log
Claspt Sync (Pro)Other desktops and the phoneEncrypted content only. It has no page or secret operations.

The phone has no local API; it reads the vault through Claspt Sync.

Every client has its own key, issued once and stored as a hash. Three ways to get one:

  • claspt mcp install <tool> for an AI tool: one shared key for the tools on this machine, or --separate for a key of the tool’s own.
  • Pair another browser in the app, for the extension.
  • Settings › Integrations › API Clients, for a script.

The prefix names the scope:

PrefixScopePages, memory, searchSecret valuesSecret writesApproval
clsn_NotesRead and writeRedactedRefusedNever
clss_SecretsRead and writeDecryptedAllowedAs set in the app

clsp_ is an older spelling of a Secrets key and is still accepted. Keys are compared in constant time. Pick the narrowest scope that does the job.

Every error is a JSON envelope:

{
"error": {
"code": "NOT_FOUND",
"message": "Page not found: credentials/missing.md",
"details": { "path": "credentials/missing.md" }
}
}
StatusCodeMeaning
400BAD_REQUESTMalformed body, invalid query, unknown enum value
400INVALID_PATHThe path climbs out of the vault (..) or is absolute
401UNAUTHORIZEDNo key, or a key the open vault does not know. Run claspt mcp doctor.
403VAULT_LOCKEDThe vault is locked, or the key lock is on. Unlock the app.
403SCOPE_INSUFFICIENTA Notes key asked for a secret value or a secret write
403APPROVAL_DENIEDThe owner declined, or did not answer within 30 seconds
403PAIRING_CLOSEDPairing is not open in the app
404NOT_FOUNDNo such page, folder or memory
404BLOCK_NOT_FOUNDNo secret block with that label on the page
409LABEL_CONFLICTAnother block on the page already has the requested label
412PRECONDITION_FAILEDIf-Match did not match. Fetch again and retry.
503NOT_READYThe search index is still being built
500INTERNAL_ERROREncryption, file or index failure

details is optional and route-specific. A few older responses that the envelope does not cover are plain text with the same status.

A page is addressed by path or by id, in the same place in the URL:

  • Path, relative to the vault, such as credentials/2026-04-26-103000-github.md. Stable until the page is moved or renamed. Slashes are encoded so the path fits one URL segment: credentials%2F2026-04-26-103000-github.md.
  • Id, the UUID in the page’s front matter. Stable across moves and renames. Use it when the reference is stored somewhere else.

Responses that return a page carry an ETag. It is the page’s updated_at instant, so two clients can compare it without identical file bytes.

WriteBehaviour
Without If-MatchLast write wins
With If-Match: <etag>Refused with 412 PRECONDITION_FAILED if the page changed in between. Fetch again and retry.

The extension sends If-Match on every edit and undoes its optimistic change on a 412.

A Secrets-scope read asks the owner in the app, naming the client and the page. The answer can be:

AnswerCovers
OnceThis request only
Until lockEvery Secrets-scope request from any client until the vault locks
AlwaysThis client and this page, until revoked in Settings

The request waits up to 30 seconds for an answer; silence is a refusal. Notes-scope requests never ask. Whether a Secrets key asks at all is the access mode in Settings; a Secrets key with approval off reads without a prompt, so give one only to a tool you trust.

Each client may decrypt at most 15 secrets a minute to start. Every request is recorded with the client’s name in Settings › Activity and with claspt log; values are never logged. A write that carries a recognisable key outside a secret block is refused.

For the tool-facing view of all this, see AI tools: credentials.

Listings hand back claspt://secret/<page>?block=<label>#<field> addresses beside every field, so a tool can pass a secret to claspt run or claspt inject without ever holding the value.

The app is source-available under the PolyForm Shield licence at github.com/Indivar/claspt-apps. The OpenAPI document is docs/api/openapi.yaml there, next to the test that holds it to the route table.