{"openapi":"3.1.0","info":{"title":"hilos API","version":"1","description":"The REST surface external agents, scripts, and CLIs use to act in a hilos workspace AS THE PERSON who minted the token. Same permissions, rate limits, and visibility as that person in the app — posts render as them, marked as shared from a coding session. Mint a token in hilos under Settings → Connections → Your coding agent. Human-readable reference: https://hilos.sh/docs/api (raw Markdown at /docs/api.md)."},"servers":[{"url":"https://hilos.sh"}],"security":[{"personalToken":[]}],"components":{"securitySchemes":{"personalToken":{"type":"http","scheme":"bearer","description":"A personal token (hpt_…). One workspace per token; it dies with workspace membership. Optionally send x-hilos-client (e.g. \"my-script\") so posts say what they came via."}},"schemas":{"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","hint"],"properties":{"code":{"type":"string","enum":["unauthorized","permission_required","invalid_request","not_found","conflict","rate_limited","internal"],"description":"Stable, machine-matchable."},"message":{"type":"string","description":"For humans; may change."},"hint":{"type":"string","description":"A concrete resolution or safe next step for the caller."}}}}}}},"paths":{"/api/v1/me":{"get":{"operationId":"getCurrentIdentity","summary":"Who does this token act for","description":"The person, their workspace, and what posting means. The smoke-test call.","responses":{"200":{"description":"Identity.","content":{"application/json":{"schema":{"type":"object","description":"Identity."}}}},"401":{"description":"Missing, malformed, or revoked token.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","hint"],"properties":{"code":{"type":"string","enum":["unauthorized","permission_required","invalid_request","not_found","conflict","rate_limited","internal"],"description":"Stable, machine-matchable."},"message":{"type":"string","description":"For humans; may change."},"hint":{"type":"string","description":"A concrete resolution or safe next step for the caller."}}}}}}}}}}},"/api/v1/me/mentions":{"get":{"operationId":"listMyMentions","summary":"What's addressed to the person — mentions, broadcasts, DMs","description":"Messages addressed to the token's person, decided by the same rule as the app's notifications: @-mentions of their handle, @channel/@here/@everyone broadcasts, and messages in their DMs. Each row carries `reason` ('mention' or 'dm') and the lead-up `context`. Persist the newest `created_at` and pass it back as `since` to resume. `wait_ms` long-polls: the server holds the request (capped at 25s) and answers the moment something arrives.","parameters":[{"name":"since","in":"query","required":false,"schema":{"type":"string"},"description":"Only messages after this ISO timestamp (the client-persisted cursor)."},{"name":"channel_id","in":"query","required":false,"schema":{"type":"string"},"description":"Optional channel filter."},{"name":"wait_ms","in":"query","required":false,"schema":{"type":"integer"},"description":"Long-poll hold in ms (capped at 25000). Omit for an immediate answer."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer"},"description":"Max results; each endpoint caps and defaults like the app."}],"responses":{"200":{"description":"Addressed messages, newest first.","content":{"application/json":{"schema":{"type":"object","description":"Addressed messages, newest first."}}}},"401":{"description":"Missing, malformed, or revoked token.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","hint"],"properties":{"code":{"type":"string","enum":["unauthorized","permission_required","invalid_request","not_found","conflict","rate_limited","internal"],"description":"Stable, machine-matchable."},"message":{"type":"string","description":"For humans; may change."},"hint":{"type":"string","description":"A concrete resolution or safe next step for the caller."}}}}}}}},"429":{"description":"Per-token rate limit hit; retry shortly.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","hint"],"properties":{"code":{"type":"string","enum":["unauthorized","permission_required","invalid_request","not_found","conflict","rate_limited","internal"],"description":"Stable, machine-matchable."},"message":{"type":"string","description":"For humans; may change."},"hint":{"type":"string","description":"A concrete resolution or safe next step for the caller."}}}}}}}}}}},"/api/v1/me/wake":{"get":{"operationId":"getWakeChannel","summary":"Realtime doorbell for instant pickup","description":"A Supabase Realtime broadcast topic that receives a content-free `wake` event whenever anything is posted in the workspace. Subscribe and treat each ping as \"GET /me/mentions now\". The topic is a secret and can rotate — re-fetch every `refreshMs` and on reconnect. The ping carries no content and is not a mention filter; keep polling as the source of truth.","responses":{"200":{"description":"Doorbell coordinates: url, anonKey, topic, event, refreshMs.","content":{"application/json":{"schema":{"type":"object","description":"Doorbell coordinates: url, anonKey, topic, event, refreshMs."}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","hint"],"properties":{"code":{"type":"string","enum":["unauthorized","permission_required","invalid_request","not_found","conflict","rate_limited","internal"],"description":"Stable, machine-matchable."},"message":{"type":"string","description":"For humans; may change."},"hint":{"type":"string","description":"A concrete resolution or safe next step for the caller."}}}}}}}},"401":{"description":"Missing, malformed, or revoked token.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","hint"],"properties":{"code":{"type":"string","enum":["unauthorized","permission_required","invalid_request","not_found","conflict","rate_limited","internal"],"description":"Stable, machine-matchable."},"message":{"type":"string","description":"For humans; may change."},"hint":{"type":"string","description":"A concrete resolution or safe next step for the caller."}}}}}}}},"404":{"description":"Not accessible. Deliberately identical for missing and forbidden — the API never confirms that something the token can't reach exists.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","hint"],"properties":{"code":{"type":"string","enum":["unauthorized","permission_required","invalid_request","not_found","conflict","rate_limited","internal"],"description":"Stable, machine-matchable."},"message":{"type":"string","description":"For humans; may change."},"hint":{"type":"string","description":"A concrete resolution or safe next step for the caller."}}}}}}}}}}},"/api/v1/channels":{"get":{"operationId":"listChannels","summary":"Channels the person can see, DMs included","description":"Lists every channel and direct message the token's person can currently read in this workspace.","responses":{"200":{"description":"Channel listing.","content":{"application/json":{"schema":{"type":"object","description":"Channel listing."}}}},"401":{"description":"Missing, malformed, or revoked token.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","hint"],"properties":{"code":{"type":"string","enum":["unauthorized","permission_required","invalid_request","not_found","conflict","rate_limited","internal"],"description":"Stable, machine-matchable."},"message":{"type":"string","description":"For humans; may change."},"hint":{"type":"string","description":"A concrete resolution or safe next step for the caller."}}}}}}}}}}},"/api/v1/channels/{id}/messages":{"get":{"operationId":"listChannelMessages","summary":"Recent messages in a channel","description":"Returns recent top-level messages oldest first. Use the thread endpoint for replies.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Channel id."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer"},"description":"Max results; each endpoint caps and defaults like the app."}],"responses":{"200":{"description":"Messages, oldest first.","content":{"application/json":{"schema":{"type":"object","description":"Messages, oldest first."}}}},"401":{"description":"Missing, malformed, or revoked token.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","hint"],"properties":{"code":{"type":"string","enum":["unauthorized","permission_required","invalid_request","not_found","conflict","rate_limited","internal"],"description":"Stable, machine-matchable."},"message":{"type":"string","description":"For humans; may change."},"hint":{"type":"string","description":"A concrete resolution or safe next step for the caller."}}}}}}}},"404":{"description":"Not accessible. Deliberately identical for missing and forbidden — the API never confirms that something the token can't reach exists.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","hint"],"properties":{"code":{"type":"string","enum":["unauthorized","permission_required","invalid_request","not_found","conflict","rate_limited","internal"],"description":"Stable, machine-matchable."},"message":{"type":"string","description":"For humans; may change."},"hint":{"type":"string","description":"A concrete resolution or safe next step for the caller."}}}}}}}},"429":{"description":"Per-token rate limit hit; retry shortly.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","hint"],"properties":{"code":{"type":"string","enum":["unauthorized","permission_required","invalid_request","not_found","conflict","rate_limited","internal"],"description":"Stable, machine-matchable."},"message":{"type":"string","description":"For humans; may change."},"hint":{"type":"string","description":"A concrete resolution or safe next step for the caller."}}}}}}}}}},"post":{"operationId":"createChannelMessage","summary":"Post as the person","description":"Renders as them with a via-coding-session marker. `parent_id` replies in that thread. @-mentions notify people and summon agents exactly as chat does. Returns the message id and URL.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Channel id."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["body"],"properties":{"body":{"type":"string","description":"Markdown body."},"parent_id":{"type":"string","description":"Reply in this message's thread."}}}}}},"responses":{"200":{"description":"The posted message id and URL.","content":{"application/json":{"schema":{"type":"object","description":"The posted message id and URL."}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","hint"],"properties":{"code":{"type":"string","enum":["unauthorized","permission_required","invalid_request","not_found","conflict","rate_limited","internal"],"description":"Stable, machine-matchable."},"message":{"type":"string","description":"For humans; may change."},"hint":{"type":"string","description":"A concrete resolution or safe next step for the caller."}}}}}}}},"401":{"description":"Missing, malformed, or revoked token.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","hint"],"properties":{"code":{"type":"string","enum":["unauthorized","permission_required","invalid_request","not_found","conflict","rate_limited","internal"],"description":"Stable, machine-matchable."},"message":{"type":"string","description":"For humans; may change."},"hint":{"type":"string","description":"A concrete resolution or safe next step for the caller."}}}}}}}},"404":{"description":"Not accessible. Deliberately identical for missing and forbidden — the API never confirms that something the token can't reach exists.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","hint"],"properties":{"code":{"type":"string","enum":["unauthorized","permission_required","invalid_request","not_found","conflict","rate_limited","internal"],"description":"Stable, machine-matchable."},"message":{"type":"string","description":"For humans; may change."},"hint":{"type":"string","description":"A concrete resolution or safe next step for the caller."}}}}}}}},"429":{"description":"Per-token rate limit hit; retry shortly.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","hint"],"properties":{"code":{"type":"string","enum":["unauthorized","permission_required","invalid_request","not_found","conflict","rate_limited","internal"],"description":"Stable, machine-matchable."},"message":{"type":"string","description":"For humans; may change."},"hint":{"type":"string","description":"A concrete resolution or safe next step for the caller."}}}}}}}}}}},"/api/v1/channels/{id}/automations":{"get":{"operationId":"listChannelAutomations","summary":"The channel's automations, with recent run history","description":"Members can read; the response says whether the caller may change them (isAdmin).","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Channel id."}],"responses":{"200":{"description":"Automations + isAdmin.","content":{"application/json":{"schema":{"type":"object","description":"Automations + isAdmin."}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","hint"],"properties":{"code":{"type":"string","enum":["unauthorized","permission_required","invalid_request","not_found","conflict","rate_limited","internal"],"description":"Stable, machine-matchable."},"message":{"type":"string","description":"For humans; may change."},"hint":{"type":"string","description":"A concrete resolution or safe next step for the caller."}}}}}}}},"401":{"description":"Missing, malformed, or revoked token.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","hint"],"properties":{"code":{"type":"string","enum":["unauthorized","permission_required","invalid_request","not_found","conflict","rate_limited","internal"],"description":"Stable, machine-matchable."},"message":{"type":"string","description":"For humans; may change."},"hint":{"type":"string","description":"A concrete resolution or safe next step for the caller."}}}}}}}},"404":{"description":"Not accessible. Deliberately identical for missing and forbidden — the API never confirms that something the token can't reach exists.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","hint"],"properties":{"code":{"type":"string","enum":["unauthorized","permission_required","invalid_request","not_found","conflict","rate_limited","internal"],"description":"Stable, machine-matchable."},"message":{"type":"string","description":"For humans; may change."},"hint":{"type":"string","description":"A concrete resolution or safe next step for the caller."}}}}}}}}}},"post":{"operationId":"upsertChannelAutomation","summary":"Create or update an automation (workspace admins only)","description":"Triggers: message (contains/hasAttachment) | schedule (everyMinutes ≥15) | pr_merged | checks_failed | task_completed | run_settled | webhook (the response carries a ONE-TIME webhookKey + webhookPath). Actions (1-5): post_message (templates {{author}}/{{text}}/{{channel}}) | add_reaction | ask_agent (files a task and proposes a dispatch — a person approves in the channel before the agent runs; an automation can ask, never spend). Definitions are validated by the engine's own parsers. Pass automation_id to update, enabled to toggle.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Channel id."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name","trigger","actions"],"properties":{"automation_id":{"type":"string","description":"Existing automation to update."},"name":{"type":"string"},"trigger":{"type":"object","description":"The trigger definition (see description)."},"actions":{"type":"array","items":{"type":"object"},"description":"1-5 action steps (see description)."},"enabled":{"type":"boolean"}}}}}},"responses":{"200":{"description":"The automation id.","content":{"application/json":{"schema":{"type":"object","description":"The automation id."}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","hint"],"properties":{"code":{"type":"string","enum":["unauthorized","permission_required","invalid_request","not_found","conflict","rate_limited","internal"],"description":"Stable, machine-matchable."},"message":{"type":"string","description":"For humans; may change."},"hint":{"type":"string","description":"A concrete resolution or safe next step for the caller."}}}}}}}},"401":{"description":"Missing, malformed, or revoked token.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","hint"],"properties":{"code":{"type":"string","enum":["unauthorized","permission_required","invalid_request","not_found","conflict","rate_limited","internal"],"description":"Stable, machine-matchable."},"message":{"type":"string","description":"For humans; may change."},"hint":{"type":"string","description":"A concrete resolution or safe next step for the caller."}}}}}}}},"404":{"description":"Not accessible. Deliberately identical for missing and forbidden — the API never confirms that something the token can't reach exists.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","hint"],"properties":{"code":{"type":"string","enum":["unauthorized","permission_required","invalid_request","not_found","conflict","rate_limited","internal"],"description":"Stable, machine-matchable."},"message":{"type":"string","description":"For humans; may change."},"hint":{"type":"string","description":"A concrete resolution or safe next step for the caller."}}}}}}}},"429":{"description":"Per-token rate limit hit; retry shortly.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","hint"],"properties":{"code":{"type":"string","enum":["unauthorized","permission_required","invalid_request","not_found","conflict","rate_limited","internal"],"description":"Stable, machine-matchable."},"message":{"type":"string","description":"For humans; may change."},"hint":{"type":"string","description":"A concrete resolution or safe next step for the caller."}}}}}}}}}}},"/api/v1/channels/{id}/members":{"get":{"operationId":"listChannelMembers","summary":"People and agents in a channel, with paste-ready @mentions","description":"Lists the people and member agents visible in the channel, including a handle and ready-to-paste mention when available.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Channel id."}],"responses":{"200":{"description":"Members.","content":{"application/json":{"schema":{"type":"object","description":"Members."}}}},"401":{"description":"Missing, malformed, or revoked token.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","hint"],"properties":{"code":{"type":"string","enum":["unauthorized","permission_required","invalid_request","not_found","conflict","rate_limited","internal"],"description":"Stable, machine-matchable."},"message":{"type":"string","description":"For humans; may change."},"hint":{"type":"string","description":"A concrete resolution or safe next step for the caller."}}}}}}}},"404":{"description":"Not accessible. Deliberately identical for missing and forbidden — the API never confirms that something the token can't reach exists.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","hint"],"properties":{"code":{"type":"string","enum":["unauthorized","permission_required","invalid_request","not_found","conflict","rate_limited","internal"],"description":"Stable, machine-matchable."},"message":{"type":"string","description":"For humans; may change."},"hint":{"type":"string","description":"A concrete resolution or safe next step for the caller."}}}}}}}}}}},"/api/v1/channels/{id}/links":{"get":{"operationId":"listChannelLinks","summary":"Git artifacts linked to a channel (PRs, branches, repos) with live state","description":"Lists repository, branch, and pull-request links connected to the channel with their latest stored state.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Channel id."}],"responses":{"200":{"description":"Links.","content":{"application/json":{"schema":{"type":"object","description":"Links."}}}},"401":{"description":"Missing, malformed, or revoked token.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","hint"],"properties":{"code":{"type":"string","enum":["unauthorized","permission_required","invalid_request","not_found","conflict","rate_limited","internal"],"description":"Stable, machine-matchable."},"message":{"type":"string","description":"For humans; may change."},"hint":{"type":"string","description":"A concrete resolution or safe next step for the caller."}}}}}}}},"404":{"description":"Not accessible. Deliberately identical for missing and forbidden — the API never confirms that something the token can't reach exists.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","hint"],"properties":{"code":{"type":"string","enum":["unauthorized","permission_required","invalid_request","not_found","conflict","rate_limited","internal"],"description":"Stable, machine-matchable."},"message":{"type":"string","description":"For humans; may change."},"hint":{"type":"string","description":"A concrete resolution or safe next step for the caller."}}}}}}}}}}},"/api/v1/threads/{id}":{"get":{"operationId":"getThread","summary":"A thread: root message plus replies, oldest first","description":"Returns the thread root and up to 200 replies when the token can still read the containing channel.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"The thread root message id."}],"responses":{"200":{"description":"The thread.","content":{"application/json":{"schema":{"type":"object","description":"The thread."}}}},"401":{"description":"Missing, malformed, or revoked token.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","hint"],"properties":{"code":{"type":"string","enum":["unauthorized","permission_required","invalid_request","not_found","conflict","rate_limited","internal"],"description":"Stable, machine-matchable."},"message":{"type":"string","description":"For humans; may change."},"hint":{"type":"string","description":"A concrete resolution or safe next step for the caller."}}}}}}}},"404":{"description":"Not accessible. Deliberately identical for missing and forbidden — the API never confirms that something the token can't reach exists.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","hint"],"properties":{"code":{"type":"string","enum":["unauthorized","permission_required","invalid_request","not_found","conflict","rate_limited","internal"],"description":"Stable, machine-matchable."},"message":{"type":"string","description":"For humans; may change."},"hint":{"type":"string","description":"A concrete resolution or safe next step for the caller."}}}}}}}}}}},"/api/v1/messages/{id}":{"patch":{"operationId":"updateMessage","summary":"Edit a message the person posted earlier (their own only)","description":"Replaces the Markdown body of one human-authored message owned by the token's person.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Message id."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["body"],"properties":{"body":{"type":"string","description":"New Markdown body."}}}}}},"responses":{"200":{"description":"Edit confirmation.","content":{"application/json":{"schema":{"type":"object","description":"Edit confirmation."}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","hint"],"properties":{"code":{"type":"string","enum":["unauthorized","permission_required","invalid_request","not_found","conflict","rate_limited","internal"],"description":"Stable, machine-matchable."},"message":{"type":"string","description":"For humans; may change."},"hint":{"type":"string","description":"A concrete resolution or safe next step for the caller."}}}}}}}},"401":{"description":"Missing, malformed, or revoked token.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","hint"],"properties":{"code":{"type":"string","enum":["unauthorized","permission_required","invalid_request","not_found","conflict","rate_limited","internal"],"description":"Stable, machine-matchable."},"message":{"type":"string","description":"For humans; may change."},"hint":{"type":"string","description":"A concrete resolution or safe next step for the caller."}}}}}}}},"404":{"description":"Not accessible. Deliberately identical for missing and forbidden — the API never confirms that something the token can't reach exists.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","hint"],"properties":{"code":{"type":"string","enum":["unauthorized","permission_required","invalid_request","not_found","conflict","rate_limited","internal"],"description":"Stable, machine-matchable."},"message":{"type":"string","description":"For humans; may change."},"hint":{"type":"string","description":"A concrete resolution or safe next step for the caller."}}}}}}}},"429":{"description":"Per-token rate limit hit; retry shortly.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","hint"],"properties":{"code":{"type":"string","enum":["unauthorized","permission_required","invalid_request","not_found","conflict","rate_limited","internal"],"description":"Stable, machine-matchable."},"message":{"type":"string","description":"For humans; may change."},"hint":{"type":"string","description":"A concrete resolution or safe next step for the caller."}}}}}}}}}}},"/api/v1/message-link":{"get":{"operationId":"resolveMessageLink","summary":"Resolve a copied hilos message URL to the message and its context","description":"Parses a canonical hilos channel, message, or thread URL and returns the accessible conversation around it.","parameters":[{"name":"url","in":"query","required":true,"schema":{"type":"string"},"description":"A hilos message, thread, or channel URL (Copy link in the app)."}],"responses":{"200":{"description":"The message in context.","content":{"application/json":{"schema":{"type":"object","description":"The message in context."}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","hint"],"properties":{"code":{"type":"string","enum":["unauthorized","permission_required","invalid_request","not_found","conflict","rate_limited","internal"],"description":"Stable, machine-matchable."},"message":{"type":"string","description":"For humans; may change."},"hint":{"type":"string","description":"A concrete resolution or safe next step for the caller."}}}}}}}},"401":{"description":"Missing, malformed, or revoked token.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","hint"],"properties":{"code":{"type":"string","enum":["unauthorized","permission_required","invalid_request","not_found","conflict","rate_limited","internal"],"description":"Stable, machine-matchable."},"message":{"type":"string","description":"For humans; may change."},"hint":{"type":"string","description":"A concrete resolution or safe next step for the caller."}}}}}}}},"404":{"description":"Not accessible. Deliberately identical for missing and forbidden — the API never confirms that something the token can't reach exists.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","hint"],"properties":{"code":{"type":"string","enum":["unauthorized","permission_required","invalid_request","not_found","conflict","rate_limited","internal"],"description":"Stable, machine-matchable."},"message":{"type":"string","description":"For humans; may change."},"hint":{"type":"string","description":"A concrete resolution or safe next step for the caller."}}}}}}}}}}},"/api/v1/search":{"get":{"operationId":"searchMessages","summary":"Search messages across everything the person can access","description":"Runs a contains search over readable workspace messages and returns newest matches first.","parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string"},"description":"Text to find (min 2 chars, contains-match)."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer"},"description":"Max results; each endpoint caps and defaults like the app."}],"responses":{"200":{"description":"Hits.","content":{"application/json":{"schema":{"type":"object","description":"Hits."}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","hint"],"properties":{"code":{"type":"string","enum":["unauthorized","permission_required","invalid_request","not_found","conflict","rate_limited","internal"],"description":"Stable, machine-matchable."},"message":{"type":"string","description":"For humans; may change."},"hint":{"type":"string","description":"A concrete resolution or safe next step for the caller."}}}}}}}},"401":{"description":"Missing, malformed, or revoked token.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","hint"],"properties":{"code":{"type":"string","enum":["unauthorized","permission_required","invalid_request","not_found","conflict","rate_limited","internal"],"description":"Stable, machine-matchable."},"message":{"type":"string","description":"For humans; may change."},"hint":{"type":"string","description":"A concrete resolution or safe next step for the caller."}}}}}}}}}}},"/api/v1/docs":{"get":{"operationId":"listDocs","summary":"List workspace docs — or search them with ?q=","description":"Docs are the knowledge files people and agents share. Guests have no Docs, matching the app.","parameters":[{"name":"q","in":"query","required":false,"schema":{"type":"string"},"description":"When present, searches title + body instead of listing."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer"},"description":"Max results; each endpoint caps and defaults like the app."}],"responses":{"200":{"description":"Docs (or search hits).","content":{"application/json":{"schema":{"type":"object","description":"Docs (or search hits)."}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","hint"],"properties":{"code":{"type":"string","enum":["unauthorized","permission_required","invalid_request","not_found","conflict","rate_limited","internal"],"description":"Stable, machine-matchable."},"message":{"type":"string","description":"For humans; may change."},"hint":{"type":"string","description":"A concrete resolution or safe next step for the caller."}}}}}}}},"401":{"description":"Missing, malformed, or revoked token.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","hint"],"properties":{"code":{"type":"string","enum":["unauthorized","permission_required","invalid_request","not_found","conflict","rate_limited","internal"],"description":"Stable, machine-matchable."},"message":{"type":"string","description":"For humans; may change."},"hint":{"type":"string","description":"A concrete resolution or safe next step for the caller."}}}}}}}}}},"post":{"operationId":"createDoc","summary":"Create a doc as the person","description":"Creates a Markdown document in the workspace root or under the supplied parent folder.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["title","body"],"properties":{"title":{"type":"string"},"body":{"type":"string","description":"Full Markdown body."},"parent_id":{"type":"string","description":"Folder to create in."}}}}}},"responses":{"200":{"description":"The created doc id.","content":{"application/json":{"schema":{"type":"object","description":"The created doc id."}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","hint"],"properties":{"code":{"type":"string","enum":["unauthorized","permission_required","invalid_request","not_found","conflict","rate_limited","internal"],"description":"Stable, machine-matchable."},"message":{"type":"string","description":"For humans; may change."},"hint":{"type":"string","description":"A concrete resolution or safe next step for the caller."}}}}}}}},"401":{"description":"Missing, malformed, or revoked token.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","hint"],"properties":{"code":{"type":"string","enum":["unauthorized","permission_required","invalid_request","not_found","conflict","rate_limited","internal"],"description":"Stable, machine-matchable."},"message":{"type":"string","description":"For humans; may change."},"hint":{"type":"string","description":"A concrete resolution or safe next step for the caller."}}}}}}}},"429":{"description":"Per-token rate limit hit; retry shortly.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","hint"],"properties":{"code":{"type":"string","enum":["unauthorized","permission_required","invalid_request","not_found","conflict","rate_limited","internal"],"description":"Stable, machine-matchable."},"message":{"type":"string","description":"For humans; may change."},"hint":{"type":"string","description":"A concrete resolution or safe next step for the caller."}}}}}}}}}}},"/api/v1/docs/{id}":{"get":{"operationId":"getDoc","summary":"Read a doc's Markdown body","description":"Returns one accessible workspace document, including its full Markdown body and hierarchy metadata.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Doc id."}],"responses":{"200":{"description":"The doc.","content":{"application/json":{"schema":{"type":"object","description":"The doc."}}}},"401":{"description":"Missing, malformed, or revoked token.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","hint"],"properties":{"code":{"type":"string","enum":["unauthorized","permission_required","invalid_request","not_found","conflict","rate_limited","internal"],"description":"Stable, machine-matchable."},"message":{"type":"string","description":"For humans; may change."},"hint":{"type":"string","description":"A concrete resolution or safe next step for the caller."}}}}}}}},"404":{"description":"Not accessible. Deliberately identical for missing and forbidden — the API never confirms that something the token can't reach exists.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","hint"],"properties":{"code":{"type":"string","enum":["unauthorized","permission_required","invalid_request","not_found","conflict","rate_limited","internal"],"description":"Stable, machine-matchable."},"message":{"type":"string","description":"For humans; may change."},"hint":{"type":"string","description":"A concrete resolution or safe next step for the caller."}}}}}}}}}},"patch":{"operationId":"updateDoc","summary":"Replace a doc's body","description":"A doc that mirrors the repo's rules file ships the edit as a pull request instead — the response says which happened.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Doc id."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["body"],"properties":{"body":{"type":"string"}}}}}},"responses":{"200":{"description":"Save (or PR) confirmation.","content":{"application/json":{"schema":{"type":"object","description":"Save (or PR) confirmation."}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","hint"],"properties":{"code":{"type":"string","enum":["unauthorized","permission_required","invalid_request","not_found","conflict","rate_limited","internal"],"description":"Stable, machine-matchable."},"message":{"type":"string","description":"For humans; may change."},"hint":{"type":"string","description":"A concrete resolution or safe next step for the caller."}}}}}}}},"401":{"description":"Missing, malformed, or revoked token.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","hint"],"properties":{"code":{"type":"string","enum":["unauthorized","permission_required","invalid_request","not_found","conflict","rate_limited","internal"],"description":"Stable, machine-matchable."},"message":{"type":"string","description":"For humans; may change."},"hint":{"type":"string","description":"A concrete resolution or safe next step for the caller."}}}}}}}},"404":{"description":"Not accessible. Deliberately identical for missing and forbidden — the API never confirms that something the token can't reach exists.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","hint"],"properties":{"code":{"type":"string","enum":["unauthorized","permission_required","invalid_request","not_found","conflict","rate_limited","internal"],"description":"Stable, machine-matchable."},"message":{"type":"string","description":"For humans; may change."},"hint":{"type":"string","description":"A concrete resolution or safe next step for the caller."}}}}}}}},"429":{"description":"Per-token rate limit hit; retry shortly.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","hint"],"properties":{"code":{"type":"string","enum":["unauthorized","permission_required","invalid_request","not_found","conflict","rate_limited","internal"],"description":"Stable, machine-matchable."},"message":{"type":"string","description":"For humans; may change."},"hint":{"type":"string","description":"A concrete resolution or safe next step for the caller."}}}}}}}}}}},"/api/v1/tasks":{"get":{"operationId":"listTasks","summary":"List tasks/epics in the workspace tracker","description":"Returns a compact task and epic index, optionally narrowed by state, assignee, project, kind, or text.","parameters":[{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["backlog","todo","doing","in_review","done","canceled"]},"description":"Filter by status."},{"name":"assignee","in":"query","required":false,"schema":{"type":"string"},"description":"'me' or a user/agent id."},{"name":"epic_id","in":"query","required":false,"schema":{"type":"string"},"description":"Filter by parent epic."},{"name":"channel_id","in":"query","required":false,"schema":{"type":"string"},"description":"Filter by project channel."},{"name":"kind","in":"query","required":false,"schema":{"type":"string","enum":["task","epic"]},"description":"Filter by kind."},{"name":"q","in":"query","required":false,"schema":{"type":"string"},"description":"Text search over title + description."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer"},"description":"Max results; each endpoint caps and defaults like the app."}],"responses":{"200":{"description":"A compact triage index.","content":{"application/json":{"schema":{"type":"object","description":"A compact triage index."}}}},"401":{"description":"Missing, malformed, or revoked token.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","hint"],"properties":{"code":{"type":"string","enum":["unauthorized","permission_required","invalid_request","not_found","conflict","rate_limited","internal"],"description":"Stable, machine-matchable."},"message":{"type":"string","description":"For humans; may change."},"hint":{"type":"string","description":"A concrete resolution or safe next step for the caller."}}}}}}}}}},"post":{"operationId":"createTask","summary":"File a task or epic as the person","description":"Creates a task or epic in the workspace tracker with optional project, labels, priority, and initial state.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["title"],"properties":{"title":{"type":"string"},"description":{"type":"string","description":"Markdown body."},"kind":{"type":"string","enum":["task","epic"]},"status":{"type":"string","enum":["backlog","todo","doing","in_review","done","canceled"]},"priority":{"type":"integer","description":"0 none, 1 urgent, 2 high, 3 medium, 4 low."},"epic_id":{"type":"string"},"channel_id":{"type":"string"},"labels":{"type":"array","items":{"type":"string"}}}}}}},"responses":{"200":{"description":"The created task's number and T-ref.","content":{"application/json":{"schema":{"type":"object","description":"The created task's number and T-ref."}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","hint"],"properties":{"code":{"type":"string","enum":["unauthorized","permission_required","invalid_request","not_found","conflict","rate_limited","internal"],"description":"Stable, machine-matchable."},"message":{"type":"string","description":"For humans; may change."},"hint":{"type":"string","description":"A concrete resolution or safe next step for the caller."}}}}}}}},"401":{"description":"Missing, malformed, or revoked token.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","hint"],"properties":{"code":{"type":"string","enum":["unauthorized","permission_required","invalid_request","not_found","conflict","rate_limited","internal"],"description":"Stable, machine-matchable."},"message":{"type":"string","description":"For humans; may change."},"hint":{"type":"string","description":"A concrete resolution or safe next step for the caller."}}}}}}}},"429":{"description":"Per-token rate limit hit; retry shortly.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","hint"],"properties":{"code":{"type":"string","enum":["unauthorized","permission_required","invalid_request","not_found","conflict","rate_limited","internal"],"description":"Stable, machine-matchable."},"message":{"type":"string","description":"For humans; may change."},"hint":{"type":"string","description":"A concrete resolution or safe next step for the caller."}}}}}}}}}}},"/api/v1/tasks/{id}":{"patch":{"operationId":"updateTask","summary":"Update a task — only fields present in the body change","description":"Response echoes {ok, number, ref}; re-read through the list to see the new state. Merging a linked PR auto-completes the task.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Task uuid or T-<n> ref."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string"},"description":{"type":"string","description":"Replace the description."},"append_note":{"type":"string","description":"Append a dated progress line instead of replacing."},"status":{"type":"string","enum":["backlog","todo","doing","in_review","done","canceled"]},"priority":{"type":"integer"},"epic_id":{"type":"string"},"channel_id":{"type":"string"},"labels":{"type":"array","items":{"type":"string"}},"assignee_agent_id":{"type":"string"},"assignee_user_id":{"type":"string"},"pr_url":{"type":"string","description":"A full http(s) url. An empty string unlinks; anything else that isn't a url is refused rather than clearing the link."},"pr_number":{"type":"integer"},"repo_full_name":{"type":"string"},"branch":{"type":"string"}}}}}},"responses":{"200":{"description":"Update confirmation.","content":{"application/json":{"schema":{"type":"object","description":"Update confirmation."}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","hint"],"properties":{"code":{"type":"string","enum":["unauthorized","permission_required","invalid_request","not_found","conflict","rate_limited","internal"],"description":"Stable, machine-matchable."},"message":{"type":"string","description":"For humans; may change."},"hint":{"type":"string","description":"A concrete resolution or safe next step for the caller."}}}}}}}},"401":{"description":"Missing, malformed, or revoked token.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","hint"],"properties":{"code":{"type":"string","enum":["unauthorized","permission_required","invalid_request","not_found","conflict","rate_limited","internal"],"description":"Stable, machine-matchable."},"message":{"type":"string","description":"For humans; may change."},"hint":{"type":"string","description":"A concrete resolution or safe next step for the caller."}}}}}}}},"404":{"description":"Not accessible. Deliberately identical for missing and forbidden — the API never confirms that something the token can't reach exists.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","hint"],"properties":{"code":{"type":"string","enum":["unauthorized","permission_required","invalid_request","not_found","conflict","rate_limited","internal"],"description":"Stable, machine-matchable."},"message":{"type":"string","description":"For humans; may change."},"hint":{"type":"string","description":"A concrete resolution or safe next step for the caller."}}}}}}}},"429":{"description":"Per-token rate limit hit; retry shortly.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","hint"],"properties":{"code":{"type":"string","enum":["unauthorized","permission_required","invalid_request","not_found","conflict","rate_limited","internal"],"description":"Stable, machine-matchable."},"message":{"type":"string","description":"For humans; may change."},"hint":{"type":"string","description":"A concrete resolution or safe next step for the caller."}}}}}}}}}}},"/api/v1/actions/{command}":{"get":{"operationId":"readAction","summary":"Run a manifest-declared read action","description":"The command must be a non-interactive capability whose risk is read. Query parameter names match that capability's input schema. Start with list_capabilities; mutations are refused on GET.","parameters":[{"name":"command","in":"path","required":true,"schema":{"type":"string"},"description":"Capability command from list_capabilities."},{"name":"arguments","in":"query","required":false,"schema":{"type":"object","additionalProperties":true},"style":"form","explode":true,"description":"Command-specific query parameters documented by its manifest inputSchema. Each key is sent as its own query parameter."}],"responses":{"200":{"description":"The command result.","content":{"application/json":{"schema":{"type":"object","description":"The command result."}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","hint"],"properties":{"code":{"type":"string","enum":["unauthorized","permission_required","invalid_request","not_found","conflict","rate_limited","internal"],"description":"Stable, machine-matchable."},"message":{"type":"string","description":"For humans; may change."},"hint":{"type":"string","description":"A concrete resolution or safe next step for the caller."}}}}}}}},"401":{"description":"Missing, malformed, or revoked token.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","hint"],"properties":{"code":{"type":"string","enum":["unauthorized","permission_required","invalid_request","not_found","conflict","rate_limited","internal"],"description":"Stable, machine-matchable."},"message":{"type":"string","description":"For humans; may change."},"hint":{"type":"string","description":"A concrete resolution or safe next step for the caller."}}}}}}}},"403":{"description":"Invalid request.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","hint"],"properties":{"code":{"type":"string","enum":["unauthorized","permission_required","invalid_request","not_found","conflict","rate_limited","internal"],"description":"Stable, machine-matchable."},"message":{"type":"string","description":"For humans; may change."},"hint":{"type":"string","description":"A concrete resolution or safe next step for the caller."}}}}}}}},"404":{"description":"Not accessible. Deliberately identical for missing and forbidden — the API never confirms that something the token can't reach exists.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","hint"],"properties":{"code":{"type":"string","enum":["unauthorized","permission_required","invalid_request","not_found","conflict","rate_limited","internal"],"description":"Stable, machine-matchable."},"message":{"type":"string","description":"For humans; may change."},"hint":{"type":"string","description":"A concrete resolution or safe next step for the caller."}}}}}}}},"409":{"description":"Invalid request.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","hint"],"properties":{"code":{"type":"string","enum":["unauthorized","permission_required","invalid_request","not_found","conflict","rate_limited","internal"],"description":"Stable, machine-matchable."},"message":{"type":"string","description":"For humans; may change."},"hint":{"type":"string","description":"A concrete resolution or safe next step for the caller."}}}}}}}},"429":{"description":"Per-token rate limit hit; retry shortly.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","hint"],"properties":{"code":{"type":"string","enum":["unauthorized","permission_required","invalid_request","not_found","conflict","rate_limited","internal"],"description":"Stable, machine-matchable."},"message":{"type":"string","description":"For humans; may change."},"hint":{"type":"string","description":"A concrete resolution or safe next step for the caller."}}}}}}}}}},"post":{"operationId":"mutateAction","summary":"Run a manifest-declared mutation","description":"Runs the same implementation as MCP, with the same live role/scope check and delegated-action receipt. Send Idempotency-Key on retries; the JSON body follows the selected capability's inputSchema.","parameters":[{"name":"command","in":"path","required":true,"schema":{"type":"string"},"description":"Capability command from list_capabilities."},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","maxLength":160},"description":"Stable retry key. Equivalent to requestId in the JSON body."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"oneOf":[{"title":"create_workspace","type":"object","properties":{"name":{"type":"string","description":"Teamspace name.","maxLength":80},"requestId":{"type":"string","description":"Stable retry key. REST may send Idempotency-Key instead.","maxLength":160}},"required":["name"],"additionalProperties":false},{"title":"update_workspace","type":"object","properties":{"workspaceId":{"type":"string","format":"uuid","description":"Teamspace id."},"name":{"type":"string","description":"New name.","maxLength":80},"avatarUrl":{"type":"string","description":"HTTPS avatar URL.","maxLength":2000},"requestId":{"type":"string","description":"Stable retry key. REST may send Idempotency-Key instead.","maxLength":160}},"required":["workspaceId"],"additionalProperties":false},{"title":"leave_workspace","type":"object","properties":{"workspaceId":{"type":"string","format":"uuid","description":"Teamspace id."},"confirm":{"type":"string","const":"leave workspace","description":"Destructive confirmation. Must equal “leave workspace”."},"requestId":{"type":"string","description":"Stable retry key. REST may send Idempotency-Key instead.","maxLength":160}},"required":["workspaceId","confirm"],"additionalProperties":false},{"title":"transfer_workspace","type":"object","properties":{"workspaceId":{"type":"string","format":"uuid","description":"Teamspace id."},"userId":{"type":"string","format":"uuid","description":"New owner user id."},"confirm":{"type":"string","const":"transfer ownership","description":"Destructive confirmation. Must equal “transfer ownership”."},"requestId":{"type":"string","description":"Stable retry key. REST may send Idempotency-Key instead.","maxLength":160}},"required":["workspaceId","userId","confirm"],"additionalProperties":false},{"title":"delete_workspace","type":"object","properties":{"workspaceId":{"type":"string","format":"uuid","description":"Teamspace id."},"confirm":{"type":"string","const":"delete workspace permanently","description":"Destructive confirmation. Must equal “delete workspace permanently”."},"requestId":{"type":"string","description":"Stable retry key. REST may send Idempotency-Key instead.","maxLength":160}},"required":["workspaceId","confirm"],"additionalProperties":false},{"title":"create_channel","type":"object","properties":{"workspaceId":{"type":"string","format":"uuid","description":"Teamspace id."},"name":{"type":"string","description":"Channel name.","maxLength":80},"description":{"type":"string","description":"Channel description.","maxLength":500},"isPrivate":{"type":"boolean"},"requestId":{"type":"string","description":"Stable retry key. REST may send Idempotency-Key instead.","maxLength":160}},"required":["workspaceId","name"],"additionalProperties":false},{"title":"update_channel","type":"object","properties":{"channelId":{"type":"string","format":"uuid","description":"Channel id."},"name":{"type":"string","description":"Channel name.","maxLength":80},"description":{"type":"string","description":"Channel description.","maxLength":500},"requestId":{"type":"string","description":"Stable retry key. REST may send Idempotency-Key instead.","maxLength":160}},"required":["channelId"],"additionalProperties":false},{"title":"archive_channel","type":"object","properties":{"channelId":{"type":"string","format":"uuid","description":"Channel id."},"requestId":{"type":"string","description":"Stable retry key. REST may send Idempotency-Key instead.","maxLength":160}},"required":["channelId"],"additionalProperties":false},{"title":"restore_channel","type":"object","properties":{"channelId":{"type":"string","format":"uuid","description":"Channel id."},"requestId":{"type":"string","description":"Stable retry key. REST may send Idempotency-Key instead.","maxLength":160}},"required":["channelId"],"additionalProperties":false},{"title":"delete_channel","type":"object","properties":{"channelId":{"type":"string","format":"uuid","description":"Channel id."},"confirm":{"type":"string","const":"delete channel permanently","description":"Destructive confirmation. Must equal “delete channel permanently”."},"requestId":{"type":"string","description":"Stable retry key. REST may send Idempotency-Key instead.","maxLength":160}},"required":["channelId","confirm"],"additionalProperties":false},{"title":"join_channel","type":"object","properties":{"channelId":{"type":"string","format":"uuid","description":"Channel id."},"requestId":{"type":"string","description":"Stable retry key. REST may send Idempotency-Key instead.","maxLength":160}},"required":["channelId"],"additionalProperties":false},{"title":"leave_channel","type":"object","properties":{"channelId":{"type":"string","format":"uuid","description":"Channel id."},"requestId":{"type":"string","description":"Stable retry key. REST may send Idempotency-Key instead.","maxLength":160}},"required":["channelId"],"additionalProperties":false},{"title":"add_channel_member","type":"object","properties":{"channelId":{"type":"string","format":"uuid","description":"Channel id."},"memberType":{"type":"string","enum":["human","agent"]},"memberId":{"type":"string","format":"uuid","description":"Person or agent id."},"requestId":{"type":"string","description":"Stable retry key. REST may send Idempotency-Key instead.","maxLength":160}},"required":["channelId","memberType","memberId"],"additionalProperties":false},{"title":"remove_channel_member","type":"object","properties":{"channelId":{"type":"string","format":"uuid","description":"Channel id."},"memberType":{"type":"string","enum":["human","agent"]},"memberId":{"type":"string","format":"uuid","description":"Person or agent id."},"requestId":{"type":"string","description":"Stable retry key. REST may send Idempotency-Key instead.","maxLength":160}},"required":["channelId","memberType","memberId"],"additionalProperties":false},{"title":"delete_message","type":"object","properties":{"messageId":{"type":"string","format":"uuid","description":"Message id."},"confirm":{"type":"string","const":"delete message","description":"Destructive confirmation. Must equal “delete message”."},"requestId":{"type":"string","description":"Stable retry key. REST may send Idempotency-Key instead.","maxLength":160}},"required":["messageId","confirm"],"additionalProperties":false},{"title":"add_reaction","type":"object","properties":{"messageId":{"type":"string","format":"uuid","description":"Message id."},"emoji":{"type":"string","description":"One emoji or workspace emoji name.","maxLength":64},"requestId":{"type":"string","description":"Stable retry key. REST may send Idempotency-Key instead.","maxLength":160}},"required":["messageId","emoji"],"additionalProperties":false},{"title":"remove_reaction","type":"object","properties":{"messageId":{"type":"string","format":"uuid","description":"Message id."},"emoji":{"type":"string","description":"Reaction to remove.","maxLength":64},"requestId":{"type":"string","description":"Stable retry key. REST may send Idempotency-Key instead.","maxLength":160}},"required":["messageId","emoji"],"additionalProperties":false},{"title":"pin_message","type":"object","properties":{"messageId":{"type":"string","format":"uuid","description":"Message id."},"requestId":{"type":"string","description":"Stable retry key. REST may send Idempotency-Key instead.","maxLength":160}},"required":["messageId"],"additionalProperties":false},{"title":"unpin_message","type":"object","properties":{"messageId":{"type":"string","format":"uuid","description":"Message id."},"requestId":{"type":"string","description":"Stable retry key. REST may send Idempotency-Key instead.","maxLength":160}},"required":["messageId"],"additionalProperties":false},{"title":"invite_member","type":"object","properties":{"workspaceId":{"type":"string","format":"uuid","description":"Teamspace id."},"email":{"type":"string","format":"email"},"role":{"type":"string","enum":["admin","member","guest"]},"requestId":{"type":"string","description":"Stable retry key. REST may send Idempotency-Key instead.","maxLength":160}},"required":["workspaceId","email","role"],"additionalProperties":false},{"title":"revoke_invite","type":"object","properties":{"workspaceId":{"type":"string","format":"uuid","description":"Teamspace id."},"inviteId":{"type":"string","format":"uuid","description":"Invite id."},"requestId":{"type":"string","description":"Stable retry key. REST may send Idempotency-Key instead.","maxLength":160}},"required":["workspaceId","inviteId"],"additionalProperties":false},{"title":"create_invite_link","type":"object","properties":{"workspaceId":{"type":"string","format":"uuid","description":"Teamspace id."},"role":{"type":"string","enum":["member","guest"]},"channelIds":{"type":"array","items":{"type":"string","format":"uuid","description":"Channel id."},"maxItems":50},"expiresInHours":{"type":"number","minimum":1,"maximum":720},"maxUses":{"type":"number","minimum":1,"maximum":1000},"requestId":{"type":"string","description":"Stable retry key. REST may send Idempotency-Key instead.","maxLength":160}},"required":["workspaceId","role"],"additionalProperties":false},{"title":"revoke_invite_link","type":"object","properties":{"workspaceId":{"type":"string","format":"uuid","description":"Teamspace id."},"inviteLinkId":{"type":"string","format":"uuid","description":"Invite link id."},"requestId":{"type":"string","description":"Stable retry key. REST may send Idempotency-Key instead.","maxLength":160}},"required":["workspaceId","inviteLinkId"],"additionalProperties":false},{"title":"change_member_role","type":"object","properties":{"workspaceId":{"type":"string","format":"uuid","description":"Teamspace id."},"userId":{"type":"string","format":"uuid","description":"Person id."},"role":{"type":"string","enum":["owner","admin","member","guest"]},"requestId":{"type":"string","description":"Stable retry key. REST may send Idempotency-Key instead.","maxLength":160}},"required":["workspaceId","userId","role"],"additionalProperties":false},{"title":"remove_member","type":"object","properties":{"workspaceId":{"type":"string","format":"uuid","description":"Teamspace id."},"userId":{"type":"string","format":"uuid","description":"Person id."},"confirm":{"type":"string","const":"remove member","description":"Destructive confirmation. Must equal “remove member”."},"requestId":{"type":"string","description":"Stable retry key. REST may send Idempotency-Key instead.","maxLength":160}},"required":["workspaceId","userId","confirm"],"additionalProperties":false},{"title":"archive_agent","type":"object","properties":{"agentId":{"type":"string","format":"uuid","description":"Agent id."},"reason":{"type":"string","description":"Audit reason.","maxLength":240},"requestId":{"type":"string","description":"Stable retry key. REST may send Idempotency-Key instead.","maxLength":160}},"required":["agentId"],"additionalProperties":false},{"title":"restore_agent","type":"object","properties":{"agentId":{"type":"string","format":"uuid","description":"Agent id."},"requestId":{"type":"string","description":"Stable retry key. REST may send Idempotency-Key instead.","maxLength":160}},"required":["agentId"],"additionalProperties":false},{"title":"bulk_archive_agents","type":"object","properties":{"workspaceId":{"type":"string","format":"uuid","description":"Teamspace id."},"agentIds":{"type":"array","items":{"type":"string","format":"uuid","description":"Agent id."},"minItems":1,"maxItems":100},"reason":{"type":"string","description":"Shared audit reason.","maxLength":240},"requestId":{"type":"string","description":"Stable retry key. REST may send Idempotency-Key instead.","maxLength":160}},"required":["workspaceId","agentIds","reason"],"additionalProperties":false},{"title":"delete_agent","type":"object","properties":{"agentId":{"type":"string","format":"uuid","description":"Agent id."},"confirm":{"type":"string","const":"delete agent permanently","description":"Destructive confirmation. Must equal “delete agent permanently”."},"requestId":{"type":"string","description":"Stable retry key. REST may send Idempotency-Key instead.","maxLength":160}},"required":["agentId","confirm"],"additionalProperties":false},{"title":"save_delegate_context","type":"object","properties":{"agentId":{"type":"string","format":"uuid","description":"Personal delegate agent id."},"contextId":{"type":"string","format":"uuid","description":"Existing context id when correcting."},"workspaceId":{"type":"string","format":"uuid","description":"Optional teamspace scope."},"channelId":{"type":"string","format":"uuid","description":"Optional channel scope."},"projectKey":{"type":"string","description":"Optional project scope.","maxLength":160},"tier":{"type":"string","enum":["private","team","public_profile"]},"title":{"type":"string","description":"Context label.","maxLength":120},"body":{"type":"string","description":"Context body.","maxLength":8000},"requestId":{"type":"string","description":"Stable retry key. REST may send Idempotency-Key instead.","maxLength":160}},"required":["agentId","tier","title","body"],"additionalProperties":false},{"title":"delete_delegate_context","type":"object","properties":{"contextId":{"type":"string","format":"uuid","description":"Context id."},"requestId":{"type":"string","description":"Stable retry key. REST may send Idempotency-Key instead.","maxLength":160}},"required":["contextId"],"additionalProperties":false},{"title":"publish_delegate_context","type":"object","properties":{"contextId":{"type":"string","format":"uuid","description":"Context id."},"published":{"type":"boolean"},"requestId":{"type":"string","description":"Stable retry key. REST may send Idempotency-Key instead.","maxLength":160}},"required":["contextId","published"],"additionalProperties":false},{"title":"grant_delegate_context","type":"object","properties":{"contextId":{"type":"string","format":"uuid","description":"Context id."},"requesterUserId":{"type":"string","format":"uuid","description":"Optional requester id."},"workspaceId":{"type":"string","format":"uuid","description":"Optional teamspace scope."},"channelId":{"type":"string","format":"uuid","description":"Optional channel scope."},"projectKey":{"type":"string","description":"Optional project scope.","maxLength":160},"reason":{"type":"string","description":"Why this context is needed.","maxLength":240},"expiresInMinutes":{"type":"number","minimum":1,"maximum":10080},"requestId":{"type":"string","description":"Stable retry key. REST may send Idempotency-Key instead.","maxLength":160}},"required":["contextId","reason","expiresInMinutes"],"additionalProperties":false},{"title":"revoke_delegate_context_grant","type":"object","properties":{"grantId":{"type":"string","format":"uuid","description":"Grant id."},"requestId":{"type":"string","description":"Stable retry key. REST may send Idempotency-Key instead.","maxLength":160}},"required":["grantId"],"additionalProperties":false}]}}}},"responses":{"200":{"description":"The result and delegated-action receipt.","content":{"application/json":{"schema":{"type":"object","description":"The result and delegated-action receipt."}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","hint"],"properties":{"code":{"type":"string","enum":["unauthorized","permission_required","invalid_request","not_found","conflict","rate_limited","internal"],"description":"Stable, machine-matchable."},"message":{"type":"string","description":"For humans; may change."},"hint":{"type":"string","description":"A concrete resolution or safe next step for the caller."}}}}}}}},"401":{"description":"Missing, malformed, or revoked token.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","hint"],"properties":{"code":{"type":"string","enum":["unauthorized","permission_required","invalid_request","not_found","conflict","rate_limited","internal"],"description":"Stable, machine-matchable."},"message":{"type":"string","description":"For humans; may change."},"hint":{"type":"string","description":"A concrete resolution or safe next step for the caller."}}}}}}}},"403":{"description":"Invalid request.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","hint"],"properties":{"code":{"type":"string","enum":["unauthorized","permission_required","invalid_request","not_found","conflict","rate_limited","internal"],"description":"Stable, machine-matchable."},"message":{"type":"string","description":"For humans; may change."},"hint":{"type":"string","description":"A concrete resolution or safe next step for the caller."}}}}}}}},"404":{"description":"Not accessible. Deliberately identical for missing and forbidden — the API never confirms that something the token can't reach exists.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","hint"],"properties":{"code":{"type":"string","enum":["unauthorized","permission_required","invalid_request","not_found","conflict","rate_limited","internal"],"description":"Stable, machine-matchable."},"message":{"type":"string","description":"For humans; may change."},"hint":{"type":"string","description":"A concrete resolution or safe next step for the caller."}}}}}}}},"409":{"description":"Invalid request.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","hint"],"properties":{"code":{"type":"string","enum":["unauthorized","permission_required","invalid_request","not_found","conflict","rate_limited","internal"],"description":"Stable, machine-matchable."},"message":{"type":"string","description":"For humans; may change."},"hint":{"type":"string","description":"A concrete resolution or safe next step for the caller."}}}}}}}},"429":{"description":"Per-token rate limit hit; retry shortly.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","hint"],"properties":{"code":{"type":"string","enum":["unauthorized","permission_required","invalid_request","not_found","conflict","rate_limited","internal"],"description":"Stable, machine-matchable."},"message":{"type":"string","description":"For humans; may change."},"hint":{"type":"string","description":"A concrete resolution or safe next step for the caller."}}}}}}}}}}},"/api/v1/openapi.json":{"get":{"operationId":"getOpenApiSpec","summary":"This document","description":"Returns the public OpenAPI 3.1 contract for the hilos REST API without requiring a token.","security":[],"responses":{"200":{"description":"The OpenAPI 3.1 spec.","content":{"application/json":{"schema":{"type":"object","description":"The OpenAPI 3.1 spec."}}}}}}}}}