HTTP API

Every endpoint SenClaw serves, what authenticates it, and what it returns.

Generated from the code that implements this. If the schemas, the platform table or the routes change, this page changes with them — and the tests fail if it does not.

MethodPathAuthWhat it does
GET/api/v1/packages/{scope}/{name}none, or session cookie / bearer token for a private packageThe package document: versions, dist-tags, artifacts, integrity, README.
POST/api/v1/publishbearer token with the publish scopePublish a version. multipart/form-data, because the artifact is bytes.
GET/api/v1/updates/tauri/{scope}/{name}/{target}/{arch}/{current}noneTauri updater endpoint. 204 when already current.
GET/updates/{scope}/{name}/{channel}/{file}noneelectron-updater generic provider: latest.yml, latest-mac.yml, latest-linux.yml.
GET/dl/{scope}/{name}/{version}/{platform}/{filename}none for signed builds; session or token for unsigned executablesDownload an artifact.
GET/api/v1/pingnoneHealth check. Reports a D1 round trip and which runtime served it.
GET/marketplace.jsonnonePlugin index for interoperating clients, listing every public plugin.
GET/.well-known/security.txtnoneSecurity contact, per RFC 9116.

Package documents

curl https://senclaw.bacnd.com/api/v1/packages/example/thing

Send Accept: application/vnd.senclaw.install-v1+json for the abbreviated document — versions, integrity and dist-tags, without READMEs or manifest bodies. That is all the install path needs, and shipping the rest on every resolve is bandwidth for nothing.

curl -H 'Accept: application/vnd.senclaw.install-v1+json' \
  https://senclaw.bacnd.com/api/v1/packages/example/thing

Responses carry Vary: Accept, Authorization, Cookie. Without it a cache can serve the abbreviated body to a browser, or a private package's document to someone who should not see it — same URL, different answers.

A package you are not allowed to see returns 404, not 403. Whether a private package exists is itself information it should not leak.

Publishing

multipart/form-data, not JSON: the artifact is bytes, and base64 inside JSON would cost a third more for nothing.

curl -X POST https://senclaw.bacnd.com/api/v1/publish \
  -H 'Authorization: Bearer snc_pat_...' \
  -F kind=skill \
  -F name=my-skill \
  -F version=1.0.0 \
  -F 'description=Does the thing' \
  -F file=@my-skill.tgz
PartRequiredWhat it is
fileyesThe artifact. Its digest is computed server-side, never taken on trust.
kindyesOne of skill, plugin, workflow, app.
nameyesPackage name, without the scope.
versionyesSemver. Immutable once published.
descriptionyesOne line for the listing.
readmenoMarkdown, rendered on the package page.
repoUrlnoSource repository.
homepageUrlnoProject homepage.
categorynoFree-text grouping.
keywordsnoComma-separated.
permissionsnoJSON, validated against the permissions schema.
extranoJSON merged into the kind-specific manifest block.
platformnoPlatform id for an app artifact. Defaults to any.
formatnoArtifact format. Inferred from the filename when omitted.
visibilitynopublic, unlisted or private. Defaults to public.
accessnoEmails allowed to see a private package.
signaturenounsigned, signed or notarized. Decides whether the build downloads publicly.
updaterSignoTauri's .sig content, verbatim.

The token needs the publish scope, and the scope of the published package is forced to the token owner's username — a token cannot publish under someone else's name. Errors come back as { "error": "...", "message": "..." } with a matching status; an oversized upload returns 413 too_large and names the actual limit.

Internal endpoints

These exist and are reachable, but they are part of the browser sign-in flow rather than an API to build against. They are listed so this page describes the whole surface rather than a flattering subset.

MethodPathWhat it does
GET/api/auth/signin/githubStarts the GitHub sign-in redirect.
GET/api/auth/signin/googleStarts the Google sign-in redirect.
GET/api/auth/callback/githubGitHub OAuth callback.
GET/api/auth/callback/googleGoogle OAuth callback.
POST/api/auth/signoutEnds the session. POST only — a GET sign-out can be fired by any image tag.