Every /v1 route
HTTP API
Send human sessions as cookies or workspace keys as Authorization: Bearer hk_live_….
{"error":{"code","message"}}| Method | Path | Authorization | Purpose |
|---|---|---|---|
POST |
/v1/workspaces |
human session | Create an organization and its first workspace |
GET |
/v1/vaults |
user or key | List visible workspaces; deleted=1 lists deleted |
POST |
/v1/vaults |
human session | Create a workspace; body: name |
PATCH |
/v1/vaults/:vaultId |
human owner | Rename a workspace; body: name |
DELETE |
/v1/vaults/:vaultId |
human owner | Delete a workspace; data destroyed after 30 days |
POST |
/v1/vaults/:vaultId/restore |
human org owner | Restore a deleted workspace within 30 days |
GET |
/v1/vaults/:vaultId/workspace |
viewer+ | Workspace identity, index state, capabilities |
POST |
/v1/vaults/:vaultId/corpus/query |
viewer+ | Search the code index; body names an operation |
POST |
/v1/vaults/:vaultId/corpus/refresh |
editor+ | Re-index one repository or all of them |
GET |
/v1/vaults/:vaultId/repositories |
viewer+ | Indexed repositories, plan limit, GitHub state |
PUT |
/v1/vaults/:vaultId/repositories |
editor+ | Choose the repositories to index |
GET |
/v1/vaults/:vaultId/github/repositories |
editor+ | Repositories the GitHub installation grants |
GET |
/v1/vaults/:vaultId/sandboxes |
viewer+ | Cloud sandboxes this workspace has run |
PUT |
/v1/vaults/:vaultId/sandboxes/:id |
agent+ | Report one sandbox event; body: kind, event |
GET |
/v1/organizations/:orgId/github |
org owner | GitHub connection state for an organization |
POST |
/v1/organizations/:orgId/github/install |
org owner | Start the GitHub App installation |
POST |
/v1/organizations/:orgId/github |
org owner | Finish installation; body: installationId, state, code |
DELETE |
/v1/organizations/:orgId/github |
org owner | Disconnect GitHub and drop its selections |
POST |
/v1/webhooks/github-app |
GitHub signature | Push and installation events |
GET |
/v1/vaults/:vaultId/models |
viewer+ | Hosted model catalog |
POST |
/v1/vaults/:vaultId/models/chat/completions |
viewer+ | Hosted chat completion, streaming or not |
GET |
/v1/billing |
user or key | Plan, limits, and usage |
GET |
/v1/billing/plan |
user or key | Org plan only (lightweight) |
POST |
/v1/billing/checkout |
org owner | Create checkout; body: plan |
GET |
/v1/billing/checkout/:checkoutId |
org owner | Verify a Polar checkout return |
POST |
/v1/billing/change-plan |
org owner | Change a paid plan; body: plan |
POST |
/v1/billing/keep-plan |
billing owner | Remove the scheduled plan change |
POST |
/v1/billing/transfer-owner |
billing owner | Transfer billing; body: targetMemberId |
POST |
/v1/billing/cancel |
org owner | Cancel at period end (grace period retained) |
POST |
/v1/billing/reactivate |
org owner | Undo a pending cancellation |
POST |
/v1/billing/portal |
org owner | Open the customer billing portal |
POST |
/v1/billing/webhook |
Polar signature | Billing webhook |
GET |
/v1/vaults/:vaultId/keys |
human owner | List keys |
POST |
/v1/vaults/:vaultId/keys |
human owner | Mint key |
DELETE |
/v1/vaults/:vaultId/keys/:id |
human owner | Revoke key |
GET |
/v1/vaults/:vaultId/grants |
owner | List grants |
POST |
/v1/vaults/:vaultId/grants |
human owner | Grant a member access to a workspace |
DELETE |
/v1/vaults/:vaultId/grants/:principalId |
human owner | Revoke a grant |
GET |
/v1/organizations/:orgId/members |
member | Members, pending invitations, signed-in Macs |
POST |
/v1/organizations/:orgId/invitations |
owner or admin | Invite a person; body: email, role |
DELETE |
/v1/organizations/:orgId/invitations/:id |
owner or admin | Cancel a pending invitation |
DELETE |
/v1/organizations/:orgId/devices/:keyId |
member (own) or admin | Sign a device out |
POST |
/v1/connect |
none (rate limited) | Start device sign-in; returns a user code |
POST |
/v1/connect/poll |
device code | Poll until approved; returns the minted key |
DELETE |
/v1/connect/device |
device key | Sign this device out |
GET |
/v1/connect/requests/:userCode |
human session | Read a pending device request |
POST |
/v1/connect/requests/:userCode/approve |
human session | Approve a device and mint its key |
POST |
/v1/connect/requests/:userCode/deny |
human session | Deny a device request |
The workspace and its index
Section titled “The workspace and its index”GET /v1/vaults/:vaultId/workspace describes the workspace a key or session can reach: managementUrl, organizationId, workspaceName, corpusId, corpusName, plan, and role, plus:
capabilities—{semantic, structuralSearch, repositoryFilters}.semanticis false on Hobby.index— the CocoIndex index: the number of repositories in it, file and chunk counts where the index reports them,lastSuccessAt, andembeddingVersion.
Clients use it to decide what to offer before they search: a workspace without semantic should be shown pattern search only.
Search
Section titled “Search”POST /v1/vaults/:vaultId/corpus/query takes {"organizationId":"…","operation":"…","arguments":{…}}. The organization must be the one the credential belongs to; anything else answers 404 not_found. The body is capped at 16 KiB.
| Operation | Arguments | Answer |
|---|---|---|
corpus_status |
none | {indexed, repositories, plan, limits, refresh, refreshedAt, embeddingVersion}. Read from stored state; it never wakes the index. |
list_repositories |
none | {repositories} — each with its name and indexed commit. |
grep_code |
pattern, optional path, language, repository |
{results, truncated}. Structural match against the syntax tree. |
search_code |
query, optional limit, repository, language, path |
{results} ranked by meaning. |
ask_code |
query |
{answer: null, grounding, note} — the passages to read. The answer itself is not written. |
query and a question cap at 4,000 characters, pattern at 2,000, path at 400 characters and may not start with / or contain .., repository at 200, language at 100, and limit runs from 1 to 50.
Each result carries repository, path, line, endLine, score, excerpt, and the headSha it was read at; search_code results also carry language.
Refusals:
403 plan_refused—search_codeandask_codeon Hobby: “Semantic search is included with Pro and Team.”409 no_repositories—grep_code,search_code, andask_codebefore any repository is chosen.corpus_statusanswers{indexed:false, repositories:[], plan, limits}with200, andlist_repositoriesanswers{"repositories":[]}.503 index_unavailableor503 index_warmingwithRetry-After— the index did not answer, or is coming back from rest. Retry;corpus_statuskeeps answering.
Repositories and GitHub
Section titled “Repositories and GitHub”An owner connects GitHub from the browser: POST /v1/organizations/:orgId/github/install returns the GitHub App installation URL with a signed state, and GitHub’s callback is completed by POST /v1/organizations/:orgId/github with the installation id, that state, and GitHub’s user-authorization code. DELETE on the same path disconnects the installation.
GET /v1/vaults/:vaultId/github/repositories lists what the installation grants, marking those already selected. PUT /v1/vaults/:vaultId/repositories takes the full set to index — {"repositories":[{"repository":"owner/name","branch":"main"}]} — and is the whole selection, so a repository left out is deselected and its mirror and index entries are removed. A repository the installation does not grant answers 404 repository_not_granted; more repositories than the plan indexes answers 403 plan_limit; no GitHub connection answers 409 github_not_connected.
Each selection reports repository, branch, status (mirroring, refreshing, fresh, stale, or failed), indexedSha, latestSha, stale, indexedAt, files, chunks, and error.
POST /v1/vaults/:vaultId/corpus/refresh re-indexes everything, or the one repository named in {"repository":"owner/name"}. A refresh already running answers 409 refresh_in_progress, and a second request within the refresh floor answers 429 rate_limited with Retry-After.
POST /v1/webhooks/github-app receives GitHub’s push and installation events under the App’s webhook signature. A push to an indexed branch marks that repository stale and, on Team, starts the refresh.
Cloud sandboxes
Section titled “Cloud sandboxes”GET /v1/vaults/:vaultId/sandboxes answers {"sandboxes":[…],"live":n}: the fifty most recently active runs, each with id, kind (task or triage), state, startedBy, deviceName, startedAt, lastActiveAt, endedAt and checkpoints. state is running, stopped or deleted as stored, and asleep for a run that has been silent for thirty minutes; live counts only the running ones.
PUT /v1/vaults/:vaultId/sandboxes/:id is how the helios-sandbox Worker records what it ran: body {"kind":"task"|"triage","event":"started"|"active"|"checkpointed"|"stopped"|"deleted"}, answered 204. Who ran it is read from the credential and never from the body. An event other than started for an unknown id creates the record too.
Device sign-in
Section titled “Device sign-in”A device signs itself in rather than holding a pasted key. POST /v1/connect with {deviceName, client} returns {deviceCode, userCode, verificationUrl, expiresAt, interval}; the person opens the verification URL, and GET/approve/deny on /v1/connect/requests/:userCode are the browser’s half. The device polls POST /v1/connect/poll at the returned interval until the answer is {status:"approved", baseUrl, organizationId, corpusId, key, workspaceName, corpusName, plan, role}. Codes expire, and a spent code cannot be polled twice. DELETE /v1/connect/device revokes the device’s own key; an owner or admin can sign out any device with DELETE /v1/organizations/:orgId/devices/:keyId.
Hosted models
Section titled “Hosted models”GET /v1/vaults/:vaultId/models returns the model catalog, and POST /v1/vaults/:vaultId/models/chat/completions is an OpenAI-shaped chat completion, streaming when stream is true. The spend-shaped fields are set here, not by the caller: the output cap comes from the catalog entry, n must be 1, and the paying organization is the one the key belongs to. An unset upstream answers 503.
| Plan | Workspaces | Repositories indexed | Refresh | Search by meaning | Requests/min | Requests/month |
|---|---|---|---|---|---|---|
| Hobby | 1 | 1 | on request | no | 30 | 50,000 |
| Pro | 5 | 5 | on push | yes | 120 | 500,000 |
| Team | 25 | every granted repository | on push | yes | 300 | 2,000,000 |
Rate limits
Section titled “Rate limits”Every /v1 request draws from two org-scoped meters: a per-minute burst bucket and a monthly ceiling by UTC calendar month. Responses carry X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset for the burst bucket, plus X-Quota-Limit and X-Quota-Remaining for the monthly ceiling.
Exceeding either meter returns 429 with a Retry-After header. The scope field in the body names the meter that denied the call: burst clears within the minute; monthly clears at the start of the next UTC month, so do not retry monthly denials in a loop. Device sign-in is limited by address rather than by organization, and refuses the start when the limiter cannot answer.