{"openapi":"3.1.0","info":{"title":"TeamYou External API","version":"2.9.0","description":"REST contract for the TeamYou external API (`/api/external/v1`).\n\n**Recommended: use the TeamYou skill** — it is the supported path. The skill installs from\nthe link below, identifies every request, and registers your agent in one step.\n\nRaw HTTP works today, but client-identification enforcement is being rolled out. Once it is\nenabled, a call with no recognized `X-TeamYou-Client` is rejected with a 403\n`client_identification_required` (carrying `skill_install_url`, `registerUrl`, and `docs_url`).\nProvisioned tool integrations are the planned non-skill path; until then, install the skill.\nIf an automated call is unexpectedly rejected, stop and report it rather than changing how the\nclient identifies itself.\n\n**MCP.** The same operations are also served over the Model Context Protocol at\n`https://www.teamyou.com/mcp` — same scopes, same handlers; the tool catalogue is generated from\nthis contract. Authentication follows the client: OAuth for the ones that speak it (Claude\nCode, Claude Desktop / claude.ai, Cursor, Codex, ChatGPT), and `Authorization: Bearer\nty_<key>` for header-only clients.\nA read-only server is at `https://www.teamyou.com/mcp/readonly`: only the reading tools are offered, a\nsign-in there asks for `read` alone, and a key presented there can change nothing whatever\nscopes it holds.\nhttps://www.teamyou.com/mcp/install says which is which and carries the configuration for each.\n\nAll endpoints require `Authorization: Bearer ty_<key>` except `GET /openapi.json`. Any 2xx body\nmay also carry an optional `agent_ecosystem_notice` when the calling skill client is outdated.\n\n**Scopes.** Each API key carries a fixed set of scopes chosen when it was created. Every\noperation below publishes what it needs as `x-teamyou-scope` — a string, or an array when an\noperation composes two writes and requires ALL of them; a key without one gets a 403\n`insufficient_scope` carrying `required_scope` and `granted_scopes`. That denial is NOT\nretryable — scopes cannot be edited after creation, so the fix is a new key, not another\nattempt. Scopes are separate from the account-wide AI preferences and compose with them as\nAND: a call needs the scope on its key AND the preference on the account.","x-teamyou-skill":{"installUrl":"https://www.teamyou.com/api/skill/install","docsUrl":"https://www.teamyou.com/api/external/v1/openapi.json","recommended":true}},"servers":[{"url":"https://www.teamyou.com/api/external/v1"}],"security":[{"bearerAuth":[]}],"tags":[{"name":"Discovery"},{"name":"Topics"},{"name":"Details"},{"name":"Edges"},{"name":"Search"},{"name":"Tasks"},{"name":"Projects"},{"name":"Areas","description":"Cross-pillar contexts that group Knowledge + Work (topics, tasks, projects, docs, urls) and nest via `within`, with a read-time membership rollup."},{"name":"Agents"},{"name":"Agent Drive"},{"name":"Preferences"},{"name":"Routines"},{"name":"Instructions"},{"name":"Agent Drive (deprecated paths)"},{"name":"Tasks (deprecated paths)"}],"paths":{"/openapi.json":{"get":{"tags":["Discovery"],"summary":"OpenAPI 3.1 contract","description":"Public machine-readable contract. No authentication required.","security":[],"responses":{"200":{"description":"The OpenAPI 3.1 document.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/topics":{"get":{"tags":["Topics"],"summary":"List topics","x-cli":{"service":"graph","action":"topics-list","usage":""},"x-mcp":{"expose":true},"x-teamyou-scope":"read","responses":{"200":{"description":"Topics for the authenticated user, most-recently-updated first.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"topics":{"type":"array","items":{"$ref":"#/components/schemas/Topic"}}},"required":["topics"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGate"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}}},"post":{"tags":["Topics"],"summary":"Create a topic","description":"Atomic with optional inline edges (max 50). Creation does not require the AI-update preference.","x-cli":{"service":"graph","action":"topics-create","usage":"<name> <description> [--summary <text>]"},"x-mcp":{"expose":true},"x-teamyou-scope":"knowledge:write","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTopicRequest"}}}},"responses":{"201":{"description":"Created topic (inline edges are not echoed).","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"topic":{"$ref":"#/components/schemas/Topic"}},"required":["topic"]}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGateWithoutAIPreference"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/topics/{id}":{"get":{"tags":["Topics"],"summary":"Get a topic with details + edges","x-cli":{"service":"graph","action":"topics-get","usage":"<topic_id>"},"x-mcp":{"expose":true},"x-teamyou-scope":"read","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","minLength":1},"description":"Topic id"}],"responses":{"200":{"description":"Topic with inlined details and normalized edges.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"topic":{"$ref":"#/components/schemas/TopicWithDetails"}},"required":["topic"]}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGate"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}}},"put":{"tags":["Topics"],"summary":"Update a topic","x-cli":{"service":"graph","action":"topics-update","usage":"<topic_id> [--name <text>] [--description <text>] [--summary <text>]"},"x-mcp":{"expose":true},"x-teamyou-scope":"knowledge:write","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","minLength":1},"description":"Topic id"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateTopicRequest"}}}},"responses":{"200":{"description":"Updated topic.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"topic":{"$ref":"#/components/schemas/Topic"}},"required":["topic"]}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGate"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}}},"delete":{"tags":["Topics"],"summary":"Delete a topic (and its details)","x-cli":{"service":"graph","action":"topics-delete","usage":"<topic_id>"},"x-mcp":{"expose":true},"x-teamyou-scope":"knowledge:write","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","minLength":1},"description":"Topic id"}],"responses":{"200":{"description":"Deleted.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]}},"required":["success"]}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGate"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/topics/{id}/details":{"get":{"tags":["Details"],"summary":"List details for a topic","description":"Returns an empty list (200) if the topic is missing or not owned — does not 404.","x-cli":{"service":"graph","action":"details-list","usage":"<topic_id>"},"x-mcp":{"expose":true},"x-teamyou-scope":"read","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","minLength":1},"description":"Topic id"}],"responses":{"200":{"description":"Details for the topic.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"details":{"type":"array","items":{"$ref":"#/components/schemas/TopicDetail"}}},"required":["details"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGate"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}}},"post":{"tags":["Details"],"summary":"Add details (batch, max 50)","x-cli":{"service":"graph","action":"details-add","usage":"<topic_id> <detail1> [detail2] [detail3] ..."},"x-mcp":{"expose":true},"x-teamyou-scope":"knowledge:write","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","minLength":1},"description":"Topic id"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddDetailsRequest"}}}},"responses":{"201":{"description":"Created details (each embedded for semantic search).","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"details":{"type":"array","items":{"$ref":"#/components/schemas/TopicDetail"}}},"required":["details"]}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGate"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/topics/{id}/details/{detailId}":{"put":{"tags":["Details"],"summary":"Update a detail","x-cli":{"service":"graph","action":"details-update","usage":"<topic_id> <detail_id> <text>"},"x-mcp":{"expose":true},"x-teamyou-scope":"knowledge:write","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","minLength":1},"description":"Topic id"},{"name":"detailId","in":"path","required":true,"schema":{"type":"string","minLength":1},"description":"Detail id"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateDetailRequest"}}}},"responses":{"200":{"description":"Updated detail.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"detail":{"$ref":"#/components/schemas/TopicDetail"}},"required":["detail"]}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGate"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}}},"delete":{"tags":["Details"],"summary":"Delete a detail","x-cli":{"service":"graph","action":"details-delete","usage":"<topic_id> <detail_id>"},"x-mcp":{"expose":true},"x-teamyou-scope":"knowledge:write","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","minLength":1},"description":"Topic id"},{"name":"detailId","in":"path","required":true,"schema":{"type":"string","minLength":1},"description":"Detail id"}],"responses":{"200":{"description":"Deleted.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]}},"required":["success"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGate"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/edges":{"get":{"tags":["Edges"],"summary":"List edges touching a topic","x-cli":{"service":"graph","action":"edges-list","usage":"<topic_id>"},"x-mcp":{"expose":true},"x-teamyou-scope":"read","parameters":[{"name":"topicId","in":"query","required":true,"schema":{"type":"string","minLength":1},"description":"Topic id (required)."}],"responses":{"200":{"description":"Edges normalized to the topic perspective.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"edges":{"type":"array","items":{"$ref":"#/components/schemas/ResolvedEdge"}}},"required":["edges"]}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGate"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}}},"post":{"tags":["Edges"],"summary":"Create an edge","description":"201 when created; 200 when an inverse-direction equivalent already exists (idempotent). Creation does not require the AI-update preference.","x-cli":{"service":"graph","action":"edges-create","aliases":["edges-link"],"usage":"<source_topic_id> <target_topic_id> <label> [--mirror-label <text>]"},"x-mcp":{"expose":true},"x-teamyou-scope":"knowledge:write","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEdgeRequest"}}}},"responses":{"200":{"description":"Idempotent — existing inverse edge returned.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"edge":{"$ref":"#/components/schemas/Edge"}},"required":["edge"]}}}},"201":{"description":"Newly created edge.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"edge":{"$ref":"#/components/schemas/Edge"}},"required":["edge"]}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGateWithoutAIPreference"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/edges/{id}":{"patch":{"tags":["Edges"],"summary":"Update edge labels","x-cli":{"service":"graph","action":"edges-update","usage":"<edge_id> [--label <text>] [--mirror-label <text>]"},"x-mcp":{"expose":true},"x-teamyou-scope":"knowledge:write","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","minLength":1},"description":"Edge id"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PatchEdgeRequest"}}}},"responses":{"200":{"description":"Updated edge.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"edge":{"$ref":"#/components/schemas/Edge"}},"required":["edge"]}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGate"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}}},"delete":{"tags":["Edges"],"summary":"Delete an edge","x-cli":{"service":"graph","action":"edges-delete","usage":"<edge_id>"},"x-mcp":{"expose":true},"x-teamyou-scope":"knowledge:write","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","minLength":1},"description":"Edge id"}],"responses":{"200":{"description":"Deleted.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]}},"required":["success"]}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGate"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/search/topics":{"post":{"tags":["Search"],"summary":"Semantic topic search","x-cli":{"service":"graph","action":"search-topics","usage":"<query> [precision]"},"x-mcp":{"expose":true},"x-teamyou-scope":"read","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchRequest"}}}},"responses":{"200":{"description":"Ranked topic results (may include one-hop graph neighbors).","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"results":{"type":"array","items":{"$ref":"#/components/schemas/TopicSearchResult"}}},"required":["results"]}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGate"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/search/details":{"post":{"tags":["Search"],"summary":"Semantic detail search","x-cli":{"service":"graph","action":"search-details","usage":"<query> [precision]"},"x-mcp":{"expose":true},"x-teamyou-scope":"read","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchRequest"}}}},"responses":{"200":{"description":"Ranked detail results.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"results":{"type":"array","items":{"$ref":"#/components/schemas/DetailSearchResult"}}},"required":["results"]}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGate"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/search/all":{"post":{"tags":["Search"],"summary":"Search across all types","description":"Use this before acting on a vague question about what the user already has: one ranked list across topics, details, tasks, projects, areas and Agent Drive documents.\n\nEach type is searched by meaning (vector), words (full-text) and spelling (trigram). The matches of each arm are pooled across types and fused ONCE by weighted RRF with a small recency boost, so a hit that matched on several arms outranks a single-arm hit of any type. Projects and areas have no vector arm. `score` is comparable within one response only; `methods` names the arms that matched.\n\nEach result carries its `type`, an absolute `url` and `structure` - where it sits: a detail's topic, a task's project and topic, a project's areas, a document's projects. Follow `structure` to the neighbours of a hit rather than searching again.\n\n`counts` is the number of candidates per type BEFORE the cut to `limit`. One store failing does not fail the request: the failed type is named in `warnings` (`store_unavailable`) and is absent from `counts` and `results`. Nor does an unavailable query embedding: every type is then searched by words and spelling only, with an `embedding_unavailable` warning.\n\n`types` narrows the search; omit it for every type. `scope` (mine | shared | all) applies to documents only. An empty `query` is allowed only with `orderBy: recency`, and then lists the most recently updated items with `score` null and `methods` empty; an empty query with `relevance` is a 400. With a non-empty query, `orderBy: recency` selects candidates by relevance and returns them newest first. The per-type endpoints (`/search/topics`, `/search/details`, `/search/documents`) remain for type-specific fields and filters such as `pathPrefix` and `where`.","x-cli":{"service":"search","action":"search","usage":"<query> [--types t1,t2] [--scope mine|shared|all] [--precision high|medium|low] [--order-by relevance|recency] [--limit N]"},"x-mcp":{"expose":true,"service":"search","action":"search","name":"search","title":"Search"},"x-teamyou-scope":"read","requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchAllRequest"}}}},"responses":{"200":{"description":"One ranked, typed list.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/SearchAllResponse"}],"description":"May also include an optional `agent_ecosystem_notice` (see schema)."}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGate"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/search/related":{"post":{"tags":["Search"],"summary":"Items one hop from an item","description":"Use this to see what one item is connected to, instead of searching again: the items one hop away, each with its relation.\n\ntopic: its edge-linked topics (with the edge `label`) and its details. detail: its topic. task: its project and topic. project: the areas holding it, its tasks, and the documents and topics it references. area: its projects. document: the caller's projects that reference it. Parents and peers come before children, so a long child list cannot crowd them out. Archived tasks, projects and areas are left out, except a task's own project.\n\nEach result has the `search/all` hit shape without `score` and `methods`, plus `relation`, read as \"<this item> <relation> <anchor>\". A document is admitted only when the caller owns it or holds a live grant on it.\n\nAn id that does not exist, belongs to someone else, or names a document the caller cannot open is the same 404 whatever the cause.","x-cli":{"service":"search","action":"related","usage":"<type> <id> [--limit N]"},"x-mcp":{"expose":true,"service":"search","action":"related","name":"search","title":"Search"},"x-teamyou-scope":"read","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchRelatedRequest"}}}},"responses":{"200":{"description":"The neighbours, one hop away.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/SearchRelatedResponse"}],"description":"May also include an optional `agent_ecosystem_notice` (see schema)."}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGate"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/tasks":{"get":{"tags":["Tasks"],"summary":"List tasks","x-cli":{"service":"tasks","action":"list","usage":"[--status todo|done] [--archived] [--priority high|medium|low|none] [--order-by createdAt|updatedAt|dueDate|priority] [--limit N]"},"x-mcp":{"expose":true},"x-teamyou-scope":"read","parameters":[{"name":"status","in":"query","schema":{"type":"string","enum":["todo","done"]}},{"name":"priority","in":"query","schema":{"type":"string","enum":["high","medium","low","none"]}},{"name":"archived","in":"query","schema":{"type":"string","enum":["true","false"]}},{"name":"orderBy","in":"query","schema":{"type":"string","enum":["createdAt","updatedAt","dueDate","priority"]}},{"name":"orderDirection","in":"query","schema":{"type":"string","enum":["asc","desc"]}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":100}}],"responses":{"200":{"description":"Tasks for the authenticated user.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"tasks":{"type":"array","items":{"$ref":"#/components/schemas/Task"}},"todos":{"type":"array","items":{"$ref":"#/components/schemas/Task"},"deprecated":true,"description":"Deprecated: the same array as `tasks`, under its retired key. Read `tasks`."}},"required":["tasks","todos"]}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGate"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}}},"post":{"tags":["Tasks"],"summary":"Create a task","x-cli":{"service":"tasks","action":"create","usage":"<title> [--description <text>] [--status todo|done] [--priority high|medium|low|none] [--due-date <ISO8601>] [--topic-id <id>] [--project-id <id>] [--after <task_id>] [--before <task_id>]"},"x-mcp":{"expose":true},"x-teamyou-scope":"work:write","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTaskRequest"}}}},"responses":{"201":{"description":"Created task.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"task":{"$ref":"#/components/schemas/Task"},"todo":{"allOf":[{"$ref":"#/components/schemas/Task"}],"deprecated":true,"description":"Deprecated: the same object as `task`, under its retired key. Read `task`."}},"required":["task","todo"]}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGate"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/tasks/{id}":{"get":{"tags":["Tasks"],"summary":"Get a task","x-cli":{"service":"tasks","action":"get","usage":"<task_id>"},"x-mcp":{"expose":true},"x-teamyou-scope":"read","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","minLength":1},"description":"Task id"}],"responses":{"200":{"description":"The task.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"task":{"$ref":"#/components/schemas/Task"},"todo":{"allOf":[{"$ref":"#/components/schemas/Task"}],"deprecated":true,"description":"Deprecated: the same object as `task`, under its retired key. Read `task`."}},"required":["task","todo"]}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGate"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}}},"put":{"tags":["Tasks"],"summary":"Update a task","x-cli":{"service":"tasks","action":"update","usage":"<task_id> [--title <text>] [--description <text>] [--status todo|done] [--priority PRIORITY] [--due-date <ISO8601>] [--archived] [--topic-id <id>] [--no-topic] [--project-id <id>] [--no-project] [--after <task_id>] [--before <task_id>]"},"x-mcp":{"expose":true},"x-teamyou-scope":"work:write","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","minLength":1},"description":"Task id"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateTaskRequest"}}}},"responses":{"200":{"description":"Updated task.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"task":{"$ref":"#/components/schemas/Task"},"todo":{"allOf":[{"$ref":"#/components/schemas/Task"}],"deprecated":true,"description":"Deprecated: the same object as `task`, under its retired key. Read `task`."}},"required":["task","todo"]}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGate"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}}},"delete":{"tags":["Tasks"],"summary":"Delete a task","x-cli":{"service":"tasks","action":"delete","usage":"<task_id>"},"x-mcp":{"expose":true},"x-teamyou-scope":"work:write","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","minLength":1},"description":"Task id"}],"responses":{"200":{"description":"Deleted.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]}},"required":["success"]}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGate"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/tasks/{id}/complete":{"post":{"tags":["Tasks"],"summary":"Mark a task done","x-cli":{"service":"tasks","action":"complete","usage":"<task_id>"},"x-mcp":{"expose":true},"x-teamyou-scope":"work:write","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","minLength":1},"description":"Task id"}],"responses":{"200":{"description":"Completed task.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"task":{"$ref":"#/components/schemas/Task"},"todo":{"allOf":[{"$ref":"#/components/schemas/Task"}],"deprecated":true,"description":"Deprecated: the same object as `task`, under its retired key. Read `task`."}},"required":["task","todo"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGate"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/projects":{"get":{"tags":["Projects"],"summary":"List projects","x-cli":{"service":"projects","action":"list","usage":"[--status active|waiting|done|archived] [--limit N]"},"x-mcp":{"expose":true},"x-teamyou-scope":"read","parameters":[{"name":"status","in":"query","schema":{"type":"string","enum":["active","waiting","done","archived"]}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100}}],"responses":{"200":{"description":"Projects for the authenticated user, most-recently-updated first.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"projects":{"type":"array","items":{"$ref":"#/components/schemas/Project"}}},"required":["projects"]}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGate"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}}},"post":{"tags":["Projects"],"summary":"Create a project, optionally with its plan and references","description":"Creates a project. Optional `tasks` and `refs` arrays let one call stand up a whole body of work instead of 1+N+M round trips - the project, every task and every reference are written in a SINGLE transaction, so a failure anywhere leaves nothing behind (no half-built project to clean up). Array order is the order in both arrays; there are no per-item positions. Create-only: no upsert, no dedupe, no idempotency key, no partial success. The response is always the hydrated project (plan + refs + progress), whether or not children were sent, so no follow-up read is needed.","x-cli":{"service":"projects","action":"create","usage":"<name> [--goal <text>] [--status active|waiting|done|archived] [--waiting-on <text>] [--notes <text>] [--due-date <YYYY-MM-DD>] [--task <title>]... [--ref <type>:<value>]... [--from-json <file>]"},"x-mcp":{"expose":true},"x-teamyou-scope":"work:write","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}}},"responses":{"201":{"description":"Created project, hydrated.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"project":{"$ref":"#/components/schemas/ProjectHydrated"}},"required":["project"]}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGate"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/projects/{id}":{"get":{"tags":["Projects"],"summary":"Get a project (one-call hydrate)","description":"Returns the project with its ordered task plan, hydrated references, a progress rollup, and `nextAction` in a single request — the agent orientation read. `nextAction` is the first incomplete, non-archived task by plan position (null when there is none); it is computed per read and never stored, so do not write it back. Dangling refs resolve defensively as { resolved: false, reason: \"missing\" } rather than failing.","x-cli":{"service":"projects","action":"get","usage":"<project_id>"},"x-mcp":{"expose":true},"x-teamyou-scope":"read","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","minLength":1},"description":"Project id"}],"responses":{"200":{"description":"Project with plan, refs, and progress.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"project":{"$ref":"#/components/schemas/ProjectHydrated"}},"required":["project"]}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGate"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}}},"put":{"tags":["Projects"],"summary":"Update a project","x-cli":{"service":"projects","action":"update","usage":"<project_id> [--name <text>] [--goal <text>] [--status active|waiting|done|archived] [--waiting-on <text>] [--notes <text>] [--due-date <YYYY-MM-DD>] [--no-goal] [--no-waiting-on] [--no-notes] [--no-due-date]"},"x-mcp":{"expose":true},"x-teamyou-scope":"work:write","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","minLength":1},"description":"Project id"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateProjectRequest"}}}},"responses":{"200":{"description":"Updated project.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"project":{"$ref":"#/components/schemas/Project"}},"required":["project"]}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGate"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}}},"delete":{"tags":["Projects"],"summary":"Delete a project","description":"Orphans the project's tasks (nulls their projectId + plan position) and cascades its references. The tasks themselves are not deleted.","x-cli":{"service":"projects","action":"delete","usage":"<project_id>"},"x-mcp":{"expose":true},"x-teamyou-scope":"work:write","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","minLength":1},"description":"Project id"}],"responses":{"200":{"description":"Deleted.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]}},"required":["success"]}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGate"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/projects/{id}/refs":{"post":{"tags":["Projects"],"summary":"Add a reference to a project","description":"Links a project to a topic/task/project/doc/url. Re-adding an existing target returns 409. `area`/`entity` targets are rejected (D5).","x-cli":{"service":"projects","action":"refs-add","usage":"<project_id> --target-type topic|task|project|doc|url [--target-id <id>] [--url <url>] [--title <text>] [--after <ref_id>] [--before <ref_id>]"},"x-mcp":{"expose":true},"x-teamyou-scope":"work:write","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","minLength":1},"description":"Project id"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddProjectRefRequest"}}}},"responses":{"201":{"description":"Created reference (hydrated — carries the target's resolved display name).","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"ref":{"$ref":"#/components/schemas/HydratedRef"}},"required":["ref"]}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGate"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/projects/{id}/documents":{"post":{"tags":["Projects"],"summary":"Write a document and link it to a project","description":"Writes a markdown document to Agent Drive and links it to the project as a `doc` reference in one call. Requires BOTH `agent-drive:write` (the document) and `work:write` (the reference) — it is the one operation that composes two writes, and a key missing either gets a 403 before anything is written. Builds on the Agent Drive upsert, and document paths are GLOBAL per user rather than scoped to a project: re-posting the same path replaces that one document everywhere it is referenced, so namespace the path (e.g. `projects/<project-id>/<file>`) when two projects push files with the same local name. Idempotent — 201 when the reference is created, 200 when the document was already linked (never 409). Reads always resolve the reference display name from the live document title, so the reference is indistinguishable from one added with refs-add. Returns document metadata only (no content echo). Deleting the document later leaves the reference dangling and reads report it unresolved.","x-cli":{"service":"projects","action":"doc-push","usage":"<project_id> <file> [--path <path>] [--title <text>] [--ref-title <text>] [--after <ref_id>] [--before <ref_id>]"},"x-mcp":{"expose":true,"groupScope":"work:write"},"x-teamyou-scope":["agent-drive:write","work:write"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","minLength":1},"description":"Project id"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddProjectDocumentRequest"}}}},"responses":{"200":{"description":"Document written; it was already linked to this project, so the existing reference is returned unchanged.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"document":{"$ref":"#/components/schemas/AgentDocumentSummary"},"ref":{"$ref":"#/components/schemas/HydratedRef"},"url":{"type":"string"}},"required":["document","ref","url"]}}}},"201":{"description":"Document written and linked (hydrated reference).","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"document":{"$ref":"#/components/schemas/AgentDocumentSummary"},"ref":{"$ref":"#/components/schemas/HydratedRef"},"url":{"type":"string"}},"required":["document","ref","url"]}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGate"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/projects/{id}/refs/{refId}":{"patch":{"tags":["Projects"],"summary":"Reorder a project reference","x-cli":{"service":"projects","action":"refs-reorder","usage":"<project_id> <ref_id> [--after <ref_id>] [--before <ref_id>]"},"x-mcp":{"expose":true},"x-teamyou-scope":"work:write","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","minLength":1},"description":"Project id"},{"name":"refId","in":"path","required":true,"schema":{"type":"string","minLength":1},"description":"Reference id"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReorderRefRequest"}}}},"responses":{"200":{"description":"Reordered reference.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"ref":{"$ref":"#/components/schemas/ContainerRef"}},"required":["ref"]}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGate"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}}},"delete":{"tags":["Projects"],"summary":"Remove a project reference","x-cli":{"service":"projects","action":"refs-remove","usage":"<project_id> <ref_id>"},"x-mcp":{"expose":true},"x-teamyou-scope":"work:write","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","minLength":1},"description":"Project id"},{"name":"refId","in":"path","required":true,"schema":{"type":"string","minLength":1},"description":"Reference id"}],"responses":{"200":{"description":"Deleted.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]}},"required":["success"]}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGate"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/areas":{"get":{"tags":["Areas"],"summary":"List areas","x-cli":{"service":"areas","action":"list","usage":"[--include-archived] [--limit N]"},"x-mcp":{"expose":true},"x-teamyou-scope":"read","parameters":[{"name":"includeArchived","in":"query","schema":{"type":"string","enum":["true","false"]}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100}}],"responses":{"200":{"description":"Areas for the authenticated user, most-recently-updated first.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"areas":{"type":"array","items":{"$ref":"#/components/schemas/Area"}}},"required":["areas"]}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGate"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}}},"post":{"tags":["Areas"],"summary":"Create an area","x-cli":{"service":"areas","action":"create","usage":"<name> [--description <text>] [--archived]"},"x-mcp":{"expose":true},"x-teamyou-scope":"work:write","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAreaRequest"}}}},"responses":{"201":{"description":"Created area.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"area":{"$ref":"#/components/schemas/Area"}},"required":["area"]}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGate"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/areas/{id}":{"get":{"tags":["Areas"],"summary":"Get an area contents rollup","description":"Returns the area with its direct members and sub-area links. Every member and sub-area carries a flat `display` — its human name — for every targetType; read that rather than reaching into `target`. With ?depth=full, also returns `rolledUp` — members contributed by nested sub-areas, per source — plus `counts` { direct, rolledUp } backing the `directly N · via M` label. depth=direct (the default) is the cheap read; full opts into a read-time traversal (never stored). Dangling refs resolve defensively as { resolved: false, reason: \"missing\" } and their `display` falls back to the stored label, url, or id.","x-cli":{"service":"areas","action":"get","usage":"<area_id> [--depth direct|full]"},"x-mcp":{"expose":true},"x-teamyou-scope":"read","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","minLength":1},"description":"Area id"},{"name":"depth","in":"query","schema":{"type":"string","enum":["direct","full"],"default":"direct"}}],"responses":{"200":{"description":"Area with direct members, sub-areas, and (depth=full) the rollup.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"area":{"$ref":"#/components/schemas/AreaContents"}},"required":["area"]}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGate"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}}},"put":{"tags":["Areas"],"summary":"Update an area","x-cli":{"service":"areas","action":"update","usage":"<area_id> [--name <text>] [--description <text>] [--no-description] [--archived] [--no-archived]"},"x-mcp":{"expose":true},"x-teamyou-scope":"work:write","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","minLength":1},"description":"Area id"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateAreaRequest"}}}},"responses":{"200":{"description":"Updated area.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"area":{"$ref":"#/components/schemas/Area"}},"required":["area"]}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGate"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}}},"delete":{"tags":["Areas"],"summary":"Delete an area","description":"Deletes the area and cascades the references it holds (its members and sub-area links) in-transaction. Refs that TARGET this area from a parent are left inert and resolve as missing at hydrate time.","x-cli":{"service":"areas","action":"delete","usage":"<area_id>"},"x-mcp":{"expose":true},"x-teamyou-scope":"work:write","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","minLength":1},"description":"Area id"}],"responses":{"200":{"description":"Deleted.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]}},"required":["success"]}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGate"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/areas/{id}/refs":{"post":{"tags":["Areas"],"summary":"Add a reference to an area (or nest a sub-area)","description":"Links an area to a topic/task/project/doc/url, or nests a sub-area with targetType=area (`within`). Re-adding an existing target returns 409 conflict. A nest that would close a cycle (or a self-loop) returns 409 cycle_detected — never a 500.","x-cli":{"service":"areas","action":"refs-add","usage":"<area_id> --target-type topic|task|project|area|doc|url [--target-id <id>] [--url <url>] [--title <text>] [--after <ref_id>] [--before <ref_id>]"},"x-mcp":{"expose":true},"x-teamyou-scope":"work:write","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","minLength":1},"description":"Area id"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddAreaRefRequest"}}}},"responses":{"201":{"description":"Created reference (hydrated — carries the target's resolved display name).","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"ref":{"$ref":"#/components/schemas/HydratedRef"}},"required":["ref"]}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGate"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/areas/{id}/refs/{refId}":{"patch":{"tags":["Areas"],"summary":"Reorder an area reference","x-cli":{"service":"areas","action":"refs-reorder","usage":"<area_id> <ref_id> [--after <ref_id>] [--before <ref_id>]"},"x-mcp":{"expose":true},"x-teamyou-scope":"work:write","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","minLength":1},"description":"Area id"},{"name":"refId","in":"path","required":true,"schema":{"type":"string","minLength":1},"description":"Reference id"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReorderRefRequest"}}}},"responses":{"200":{"description":"Reordered reference.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"ref":{"$ref":"#/components/schemas/ContainerRef"}},"required":["ref"]}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGate"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}}},"delete":{"tags":["Areas"],"summary":"Remove an area reference","description":"Removes a member or un-nests a sub-area link (DB-equivalent). Removal is always cycle-safe.","x-cli":{"service":"areas","action":"refs-remove","usage":"<area_id> <ref_id>"},"x-mcp":{"expose":true},"x-teamyou-scope":"work:write","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","minLength":1},"description":"Area id"},{"name":"refId","in":"path","required":true,"schema":{"type":"string","minLength":1},"description":"Reference id"}],"responses":{"200":{"description":"Deleted.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]}},"required":["success"]}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGate"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/agents/register":{"post":{"tags":["Agents"],"summary":"Register / refresh agent identity","description":"Display-only identity. Caller-declared mode is keyed on (user, slug). Provisioned OpenClaw mode accepts openclawInstanceId, verifies the authenticated key belongs to that clawctl instance, derives the canonical slug server-side, and reconciles grandfathered identities. Returns 200 idempotently. Skill version comes from the X-TeamYou-Version header (the legacy X-TeamYou-Skill-Version is still accepted for back-compat); variant from X-TeamYou-Skill-Variant. Not gated by registration; subject to the min-skill-version floor.","x-cli":{"service":"agent","action":"register","usage":"[--slug <slug> | --openclaw-instance-id <instance-id>] [--kind claude|codex|perplexity|openclaw|other] [--name <display name>] [--model <model>]"},"x-mcp":{"expose":"extended"},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterAgentRequest"}}}},"responses":{"200":{"description":"Registered agent + workspace summary. Malformed optional manifest fields are dropped and reported in warnings.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"agent":{"$ref":"#/components/schemas/RegisteredAgent"},"user":{"type":"object","properties":{"id":{"type":"string"}},"required":["id"]},"workspace":{"type":"object","properties":{"topicsCount":{"type":"integer"},"openTasksCount":{"type":"integer","description":"Tasks whose status is not done."},"openTodosCount":{"type":"integer","deprecated":true,"description":"Deprecated: the same number as `openTasksCount`, under its retired key. Read `openTasksCount`."}},"required":["topicsCount","openTasksCount","openTodosCount"]},"warnings":{"type":"array","items":{"type":"string"}}},"required":["agent","user","workspace","warnings"]}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/SkillGate"},"409":{"$ref":"#/components/responses/AgentIdentityConflict"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/agents/me":{"get":{"tags":["Agents"],"summary":"Get this key’s registered agent","description":"Returns { agent: null } if the key has no linked agent. Not gated.","x-cli":{"service":"agent","action":"whoami","usage":""},"x-mcp":{"expose":"extended"},"responses":{"200":{"description":"Registered agent (or null).","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"agent":{"oneOf":[{"$ref":"#/components/schemas/AgentIdentity"},{"type":"null"}]}},"required":["agent"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/agents/ack":{"get":{"tags":["Agents"],"summary":"Acknowledge the version-update nudge (relent one call)","description":"Consumes a one-time ACK token from a client_update_nudge (403) response: relents this single call for the calling key and records the ack (the human-visible receipt). The token must belong to this key and be unconsumed — a re-hit or foreign token returns 400 ack_invalid. Bare requireApiKey (not registration-gated). Always available — the nudge’s relent escape is never removed. The response carries the cost (nag_interval, nag_acks_so_far) so acking is never made to look free. Note that a plain retry of the original request usually succeeds on its own: acking is the way to release the call immediately, not the only way to make progress.","x-cli":{"service":"agent","action":"ack","usage":"<token>"},"parameters":[{"name":"token","in":"query","required":true,"schema":{"type":"string","minLength":1},"description":"The one-time nak_* token from the nag response."},{"name":"mode","in":"query","schema":{"type":"string","enum":["human","auto"]},"description":"How this deferral was decided. Omitted or \"human\" means a person chose to postpone: it counts toward tier graduation and toward the owner-visible \"this agent can acknowledge\" signal. Use \"auto\" when an unattended client is relenting on its own — it releases the call identically but is recorded separately and escalates nothing, so a cron that defers to keep running cannot drive itself to a harsher reminder tier. Report it honestly; \"auto\" is not a way to silence the reminder, only to keep it from compounding."}],"responses":{"200":{"description":"Call relented.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"acknowledged":{"type":"boolean","enum":[true]},"verified_version":{"oneOf":[{"type":"string"},{"type":"null"}]},"required_version":{"oneOf":[{"type":"string"},{"type":"null"}]},"upgrade_url":{"oneOf":[{"type":"string"},{"type":"null"}]},"nag_interval":{"type":"integer"},"nag_acks_so_far":{"type":"integer"},"ack_mode":{"type":"string","enum":["human","auto"]},"detail":{"type":"string"}},"required":["acknowledged","verified_version","required_version","upgrade_url","nag_interval","nag_acks_so_far","ack_mode","detail"]}}}},"400":{"$ref":"#/components/responses/AckInvalid"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/ApiKeyForbidden"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/agent-drive":{"get":{"tags":["Agent Drive"],"summary":"List documents","description":"Markdown documents (metadata only — no content), most-recently-updated first. By default lists only what the authenticated user OWNS; pass scope=shared to list only documents other people have shared with them, scope=all for both, or scope=accessed for the access-derived library — cross-user documents you or your agents have actually opened. Deleted (archived) documents are excluded by default; pass archived=true to list ONLY those. There is no way to list both at once. Optionally scoped to a folder with pathPrefix, which returns every document beneath that prefix plus the prefix’s immediate child folders. Folders are derived from path segments — there is no folders resource to create or rename, and the archived switch scopes them too, so a folder holding only deleted documents does not appear in the live tree. Folders and pathPrefix apply to your OWN documents only: paths are unique per owner, so shared-in documents have no place in your folder tree and any scope that includes them returns an empty folders array. Paged: the default limit is 100 (max 200), and `pagination.hasMore` tells you when to ask for the next offset. Every row carries the document’s derived metadata (its parsed front matter), and `where=key:value` narrows the list by it — repeatable and AND-ed, supported on every scope except accessed.","x-cli":{"service":"agent-drive","action":"list","usage":"[--scope mine|shared|all|accessed] [--prefix <path>] [--where key:value]... [--archived] [--limit N] [--offset N]"},"x-mcp":{"expose":true},"x-teamyou-scope":"read","parameters":[{"name":"scope","in":"query","schema":{"type":"string","enum":["mine","shared","all","accessed"],"default":"mine"},"description":"Which documents to list. mine (default) = only your own, exactly as this endpoint behaved before scope existed. shared = ONLY documents another user has granted to you, never your own, each carrying a sharedBy object naming its owner. all = both, merged newest-first. accessed = your LIBRARY: cross-user documents you or your agents have opened, whether by link or by grant, each carrying an accessed object naming the document owner, how you got in, and which of your agents last opened it. Shared-in and accessed documents are not yours: you cannot write to their paths, and access ends the moment the owner revokes it. Library entries are re-checked on every request, so one whose access has been revoked is simply absent from the list rather than returned as an id you cannot fetch — which is also why pagination.hasMore, not the length of documents, tells you whether to ask for another page. Note that accessed is NOT searchable yet: POST /search/documents rejects it."},{"name":"archived","in":"query","schema":{"type":"string","enum":["true","false"]},"description":"Omitted or false lists live documents; true lists only deleted (recoverable) ones. Applies to your own documents; shared-in documents are always live (a document its owner deleted disappears from your list entirely)."},{"name":"pathPrefix","in":"query","schema":{"type":"string"},"description":"Folder to scope to, e.g. \"memory/\". Canonicalized the same way a written path is; a trailing \"/\" is optional. Matched case-insensitively. Omit for all of Agent Drive."},{"name":"where","in":"query","schema":{"type":"array","items":{"type":"string"}},"explode":true,"style":"form","description":"Repeat (query) or list (body) to AND up to 10 clauses. Split on the FIRST colon, so a value may contain colons: key is letters/digits/_/- up to 64 chars, value up to 200. A clause matches a field equal to the value OR an array containing it, so tags:research finds \"tags: [research, ops]\"; a value that is exactly a number or true/false is also tried typed, so priority:3 finds an unquoted 3. No ranges, no OR, no nested paths. Filtering only NARROWS what the scope returns. Not supported with scope=accessed."},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":200,"default":100}},{"name":"offset","in":"query","schema":{"type":"integer","minimum":0,"default":0}}],"responses":{"200":{"description":"Documents (metadata), the child folders of pathPrefix, and the page window.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"documents":{"type":"array","items":{"$ref":"#/components/schemas/AgentDocumentSummary"}},"folders":{"type":"array","items":{"$ref":"#/components/schemas/AgentDocumentFolder"},"description":"Immediate child folders of pathPrefix. ALWAYS empty unless scope=mine — see the scope parameter."},"pathPrefix":{"type":"string","description":"The canonical prefix that was applied (\"\" for all of Agent Drive)."},"scope":{"type":"string","enum":["mine","shared","all"],"description":"The scope that was applied."},"pagination":{"$ref":"#/components/schemas/DocumentPage"}},"required":["documents","folders","pathPrefix","scope","pagination"]}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGate"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}}},"post":{"tags":["Agent Drive"],"summary":"Write (upsert-by-path) a document","description":"Create or replace a markdown document keyed on its path. Re-posting the same path replaces the whole document. The path is canonicalized and matched case-insensitively (see the path field), so the stored path may differ from what you send — read it back off the returned document, and note that a push differing only in casing counts as replacing, not creating. Owner is the API-key user; the calling agent becomes createdByAgentId on the first write and lastModifiedByAgentId on every later one. Returns documentUrl, the document's canonical /agent-drive/{id} URL — its only URL, and its share URL once the owner makes it visible (url is a deprecated alias for the same value). Documents are private by default and this endpoint cannot change that. Writing a new path is ungated; replacing an existing one is an AI update and returns 403 AI_UPDATE_DISABLED when the owner has aiUpdateEnabled off — including a byte-identical re-push, so a denial cannot be used to probe stored content. Posting to a deleted path resurrects that document (same id, original creator preserved) and resets its visibility to private — reviving a document never re-shares it. contentType is not accepted here: sending it is ignored, not rejected. Status: 201 when the document was created OR its content/title changed; 200 with unchanged=true when the post was byte-identical to what is stored, in which case nothing is written and updatedAt keeps its stored value so a re-push does not reorder the list. If the owner has set a folder visibility rule covering the path (\"documents created under reports/ start public\"), a NEWLY CREATED document is stamped with it and the response carries folderRule saying what happened — but only if this key also holds the share scope; without that scope the document is created private and folderRule.applied is false. Replacing a document never applies a rule.","x-cli":{"service":"agent-drive","action":"push","usage":"<file> [--path <path>] [--title <text>]"},"x-mcp":{"expose":true},"x-teamyou-scope":"agent-drive:write","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WriteDocumentRequest"}}}},"responses":{"200":{"description":"Unchanged — byte-identical to the stored document; nothing was written.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"document":{"$ref":"#/components/schemas/AgentDocument"},"documentUrl":{"type":"string","description":"The document's canonical /agent-drive/{id} URL — its only URL, and its share URL. Who else can open it is decided by the document's visibility (private / anyone with the link / anyone signed in): private by default, changeable by the owner in the TeamYou web app or via PUT /agent-drive/{id}/visibility with the share scope. Writing a document never changes its visibility, so this URL stays owner-only until someone deliberately shares it."},"url":{"type":"string","deprecated":true,"description":"DEPRECATED alias for documentUrl, carrying the identical value. The name was misleading — it is not a share URL. Read documentUrl instead; this field will be removed once older skill versions are fenced off."},"unchanged":{"type":"boolean","enum":[true]}},"required":["document","documentUrl","url","unchanged"]}}}},"201":{"description":"Written document + its private reader URL.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"document":{"$ref":"#/components/schemas/AgentDocument"},"documentUrl":{"type":"string","description":"The document's canonical /agent-drive/{id} URL — its only URL, and its share URL. Who else can open it is decided by the document's visibility (private / anyone with the link / anyone signed in): private by default, changeable by the owner in the TeamYou web app or via PUT /agent-drive/{id}/visibility with the share scope. Writing a document never changes its visibility, so this URL stays owner-only until someone deliberately shares it."},"url":{"type":"string","deprecated":true,"description":"DEPRECATED alias for documentUrl, carrying the identical value. The name was misleading — it is not a share URL. Read documentUrl instead; this field will be removed once older skill versions are fenced off."},"unchanged":{"type":"boolean","enum":[false]},"folderRule":{"type":"object","description":"Present ONLY when the owner has a folder visibility rule covering the path of a document this request CREATED — absent on every replace, and absent when no rule covers the path. The owner sets these in the TeamYou web app: \"documents created under reports/ start public\". The deepest matching folder wins, so a rule on reports/drafts/ overrides one on reports/. Rules apply at CREATION only: replacing an existing document never re-applies one, and an existing document's visibility is never changed by a rule (the owner has a separate, explicit bulk action for that). applied=false means the document was created PRIVATE and the rule was skipped — read reason.","properties":{"prefix":{"type":"string","description":"The folder the rule is written on, with a trailing slash, e.g. \"reports/\"."},"visibility":{"type":"string","enum":["private","public","authenticated"],"description":"What the rule says a document created here should be."},"applied":{"type":"boolean","description":"Whether the document was actually created with that visibility. False means it was created private instead."},"reason":{"type":"string","enum":["drive_share_scope_required","agent_sharing_blocked"],"description":"Why the rule was skipped. The write SUCCEEDED either way and the document is private; only the rule did not fire. \"drive_share_scope_required\": this API key does not hold the share scope, so it may not put a document in front of anyone — ask the key's owner to add the \"Share on your behalf\" permission in TeamYou settings, then re-push. \"agent_sharing_blocked\": the key is fine, but the account-wide \"Block agent sharing\" switch (Settings → AI permissions) is ON, which stops every agent from changing who can open a document — the owner turns it off there, and no change to any key helps. Present only when applied is false."}},"required":["prefix","visibility","applied"]}},"required":["document","documentUrl","url","unchanged"]}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGate"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/agent-drive/{id}":{"get":{"tags":["Agent Drive"],"summary":"Read a document","description":"Full document including content, from whichever of three sources applies — and the access field says which. Reads (1) your own documents, (2) any document another TeamYou user shared with YOU by name, since a grant admits the person and your agents read as you, and (3) any PUBLIC document whose id you already have, exactly as an anonymous fetch of /agent-drive/{id}/raw would. A shared-in document comes back with access 'grant' and a sharedBy object naming its owner; treat it as theirs, not yours, and do not write to its path. A public document comes back with access 'public' and NO sharedBy — it was published to nobody in particular, so its owner is not identified. Reading a public id is not discovery: GET /agent-drive and the search scopes remain owner-and-grant scoped, so you can read a public document someone hands you but cannot find one you were not given. Find shared-in documents with GET /agent-drive?scope=shared or POST /search/documents with scope shared; a plain GET /agent-drive still lists only what you own, so syncing Agent Drive never sweeps up somebody else's files unless you ask it to. Grant access lasts exactly as long as the grant, and public access exactly as long as the document stays public — either can be taken back at any moment, and the next read 404s. 404 if the id is missing, not owned, not shared with you, and not public: all four are indistinguishable, so this is never a way to learn that someone else's document exists.","x-cli":{"service":"agent-drive","action":"pull","usage":"<id> [--out <file>]"},"x-mcp":{"expose":true},"x-teamyou-scope":"read","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","minLength":1},"description":"Document id"}],"responses":{"200":{"description":"The document.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"document":{"$ref":"#/components/schemas/AgentDocument"},"access":{"type":"string","enum":["owner","grant","public"],"description":"Which source answered: 'owner' (your own document), 'grant' (another user shared it with you by name), or 'public' (anyone with the id can read it). Branch on this rather than on the presence of sharedBy — only 'owner' means the document is yours to write to."},"sharedBy":{"oneOf":[{"$ref":"#/components/schemas/SharedByUser"},{"type":"null"}],"description":"Present only when access is 'grant' — another user granted you this document by name. Absent for your own documents AND for public ones: a public document was published to nobody in particular, so its owner is deliberately not identified here."}},"required":["document","access"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGate"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}}},"delete":{"tags":["Agent Drive"],"summary":"Delete a document","description":"Delete a document. The content is archived rather than destroyed and stays recoverable indefinitely: list tombstones with GET /agent-drive?archived=true and bring one back with POST /agent-drive/{id}/restore. A deleted document is otherwise indistinguishable from one that never existed — GET /agent-drive/{id} returns 404 and so does a second DELETE of the same id. Returns 403 AI_DELETE_DISABLED when the owner has aiDeleteEnabled off; the gate runs before the lookup, so a denial never reveals whether the id exists.","x-cli":{"service":"agent-drive","action":"delete","usage":"<id>"},"x-mcp":{"expose":true},"x-teamyou-scope":"agent-drive:write","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","minLength":1},"description":"Document id"}],"responses":{"200":{"description":"Deleted.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"deleted":{"type":"boolean","enum":[true]},"id":{"type":"string"}},"required":["deleted","id"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGate"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/agent-drive/{id}/visibility":{"put":{"tags":["Agent Drive"],"summary":"Set who can open a document","description":"Set a document's visibility: \"private\" (only the owner), \"public\" (anyone with the link, no sign-in), or \"authenticated\" (any signed-in TeamYou user). Setting \"private\" IS the revoke — there is no separate unshare endpoint, because there is no token to destroy. /agent-drive/{id} is the document's only URL and also its share URL, so sharing changes what that address does rather than producing a second one; turning sharing off and on again re-enables THE SAME URL for anyone who kept it, exactly as Google Docs does. Requires the share scope. A key minted in Settings only holds it if the owner ticked it; an OAuth connector receives it with the rest of the consent screen, which is why the account-wide “Block agent sharing” switch exists and is off by default - holding the scope is not enough on its own. Every change is recorded with the acting agent and shown to the owner in the web share dialog, and the owner can override any setting an agent made. 404 when the id is missing, not owned, or DELETED — an archived document cannot be pre-set to public and then restored into exposure. Gated by TWO account-wide switches and BOTH must be open: aiUpdateEnabled (403 AI_UPDATE_DISABLED) and aiShareEnabled (403 AI_SHARE_DISABLED), which is the owner’s “Block agent sharing” setting and is off by default; the gate runs before the lookup, so a denial never reveals whether the id exists. Returns the stored visibility plus both URLs: documentUrl for a person, rawUrl for handing the markdown straight to another agent.","x-cli":{"service":"agent-drive","action":"share","usage":"<path-or-id> [--audience public|authenticated]","also":[{"action":"unshare","usage":"<path-or-id>","note":"sets visibility back to private"}]},"x-mcp":{"expose":true,"action":"visibility"},"x-teamyou-scope":"share","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","minLength":1},"description":"Document id"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetDocumentVisibilityRequest"}}}},"responses":{"200":{"description":"The stored visibility and the document’s URLs.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"visibility":{"type":"string","enum":["private","public","authenticated"]},"documentUrl":{"type":"string","description":"The document's canonical /agent-drive/{id} URL — its only URL, and its share URL. Who else can open it is decided by the document's visibility (private / anyone with the link / anyone signed in): private by default, changeable by the owner in the TeamYou web app or via PUT /agent-drive/{id}/visibility with the share scope. Writing a document never changes its visibility, so this URL stays owner-only until someone deliberately shares it."},"rawUrl":{"type":"string","description":"The document's raw-markdown URL (/agent-drive/{id}/raw), which obeys the same visibility. Hand this to another agent instead of teaching it to append /raw."}},"required":["visibility","documentUrl","rawUrl"]}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGate"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/agent-drive/{id}/grants":{"post":{"tags":["Agent Drive"],"summary":"Share a document with a person","description":"Share a document with ONE person by email — the third kind of share, beside public and signed-in visibility. If the address belongs to a TeamYou account they can open the document immediately; if not, an invite is stored and binds automatically when they sign up with that (verified) address. Either way the response is the same {shared:true}: this endpoint deliberately never tells you whether the address has an account, so it cannot be used to probe who has one. The person, and their agents reading as them, can then open /agent-drive/{id} — a narrower share than making it public. Requires the share scope, the same one PUT /agent-drive/{id}/visibility needs. Holding it is not enough on its own: the account-wide “Block agent sharing” switch is off by default and blocks every agent regardless of key. The grant is recorded with the acting agent and shown to the owner in the web share dialog, and the owner can revoke it there at any time. Revoke via DELETE on this same path. 404 when the id is missing, not owned, or DELETED. 400 when the email is malformed or resolves to your own account (you already own it). Gated by TWO account-wide switches and BOTH must be open: aiUpdateEnabled (403 AI_UPDATE_DISABLED) and aiShareEnabled (403 AI_SHARE_DISABLED), which is the owner’s “Block agent sharing” setting and is off by default; the gate runs before the lookup, so a denial never reveals whether the id exists.","x-cli":{"service":"agent-drive","action":"grant","usage":"<path-or-id> --email <address>","also":[{"action":"ungrant","usage":"<path-or-id> --email <address>","note":"removes that person’s access"}]},"x-mcp":{"expose":true},"x-teamyou-scope":"share","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","minLength":1},"description":"Document id"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentGrantRequest"}}}},"responses":{"200":{"description":"The share landed — with no signal of whether the address has an account.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"shared":{"type":"boolean","description":"Always true on success."},"email":{"type":"string","description":"The normalized (lowercased) address the grant was recorded against — an echo of what you sent, not a lookup result."},"documentUrl":{"type":"string","description":"The document's canonical /agent-drive/{id} URL — its only URL, and its share URL. Who else can open it is decided by the document's visibility (private / anyone with the link / anyone signed in): private by default, changeable by the owner in the TeamYou web app or via PUT /agent-drive/{id}/visibility with the share scope. Writing a document never changes its visibility, so this URL stays owner-only until someone deliberately shares it."}},"required":["shared","email","documentUrl"]}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGate"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}}},"delete":{"tags":["Agent Drive"],"summary":"Stop sharing a document with a person","description":"Remove one person's access, by the same email you granted it with — the undo for POST on this path. Their access ends on the next request; there is nothing cached and nothing to expire. revoked:true means a live grant was removed, revoked:false means the document is yours but nobody was shared on that address (a second ungrant is a no-op, not an error, so retrying is safe). Requires the share scope. 404 when the id is missing, not owned, or DELETED — the same uniform answer every Agent Drive route gives, so this is never a way to learn a document exists. Gated by TWO account-wide switches and BOTH must be open: aiUpdateEnabled (403 AI_UPDATE_DISABLED) and aiShareEnabled (403 AI_SHARE_DISABLED), which is the owner’s “Block agent sharing” setting and is off by default; the gate runs before the lookup, so a denial never reveals whether the id exists.","x-mcp":{"expose":true,"service":"agent-drive","action":"ungrant"},"x-teamyou-scope":"share","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","minLength":1},"description":"Document id"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentGrantRequest"}}}},"responses":{"200":{"description":"Whether a live grant was removed.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"revoked":{"type":"boolean","description":"true if a live grant on that address was removed; false if the document is yours but no one was shared on it (an idempotent no-op)."}},"required":["revoked"]}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGate"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/agent-drive/{id}/restore":{"post":{"tags":["Agent Drive"],"summary":"Restore a deleted document","description":"Bring a deleted (archived) document back into Agent Drive, content byte-identical and with its original creator intact. Visibility is reset to private: deleting is how an owner pulls a document off the internet, so restoring never re-shares it at the same URL. Find the id with GET /agent-drive?archived=true. 404 when the id is missing, not owned, or NOT deleted — restoring an already-live document is not a silent success. This mutates an existing document, so it is gated by aiUpdateEnabled (403 AI_UPDATE_DISABLED), not aiDeleteEnabled.","x-cli":{"service":"agent-drive","action":"restore","usage":"<id>"},"x-mcp":{"expose":true},"x-teamyou-scope":"agent-drive:write","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","minLength":1},"description":"Document id"}],"responses":{"200":{"description":"Restored document + its private reader URL.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"document":{"$ref":"#/components/schemas/AgentDocument"},"documentUrl":{"type":"string","description":"The document's canonical /agent-drive/{id} URL — its only URL, and its share URL. Who else can open it is decided by the document's visibility (private / anyone with the link / anyone signed in): private by default, changeable by the owner in the TeamYou web app or via PUT /agent-drive/{id}/visibility with the share scope. Writing a document never changes its visibility, so this URL stays owner-only until someone deliberately shares it."},"url":{"type":"string","deprecated":true,"description":"DEPRECATED alias for documentUrl, carrying the identical value. The name was misleading — it is not a share URL. Read documentUrl instead; this field will be removed once older skill versions are fenced off."}},"required":["document","documentUrl","url"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGate"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/search/documents":{"post":{"tags":["Agent Drive"],"summary":"Search documents","description":"Hybrid search over Agent Drive: semantic (vector) + full-text + trigram, fused by weighted RRF with a recency boost, returning one result per document. Search runs over CHUNKS, so content anywhere in a document is findable — not just its opening — and each result names the chunk that matched via snippet/headingPath/chunkIndex. A chunkIndex of 0 means the title or path matched rather than the body. By default searches only your own documents; scope=shared searches ONLY documents other people have shared with you, and scope=all searches both and fuses them into one ranked list. Newly written documents are indexed in the background, so a document pushed a moment ago may take a few seconds to become searchable. Deleted (archived) documents are never returned. `score` is a fused relevance score, NOT a cosine similarity: compare it within one response and never across two. `where` narrows the candidate set of every arm by the documents’ derived metadata before fusion, so it combines with the query rather than filtering its results afterwards.","x-cli":{"service":"agent-drive","action":"search","usage":"<query> [precision] [--scope mine|shared|all] [--path-prefix <prefix>] [--where key:value]... [--limit N]"},"x-mcp":{"expose":true},"x-teamyou-scope":"read","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchDocumentsRequest"}}}},"responses":{"200":{"description":"Ranked document results.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"results":{"type":"array","items":{"$ref":"#/components/schemas/DocumentSearchResult"}}},"required":["results"]}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGate"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/preferences":{"get":{"tags":["Preferences"],"summary":"Get effective user preferences","x-mcp":{"expose":"extended","service":"preferences","action":"get"},"x-teamyou-scope":"read","responses":{"200":{"description":"Effective preferences for the API key user.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Preferences"}],"description":"May also include an optional `agent_ecosystem_notice` (see schema)."}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGate"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/heartbeat":{"get":{"tags":["Routines"],"summary":"Get heartbeat config (with actions)","x-cli":{"service":"routines","action":"heartbeat-get","usage":"","feature":"routines"},"x-mcp":{"expose":"extended"},"x-feature":"routines","x-teamyou-scope":"read","responses":{"200":{"description":"Heartbeat with actions, or null.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"heartbeat":{"oneOf":[{"$ref":"#/components/schemas/HeartbeatWithActions"},{"type":"null"}]}},"required":["heartbeat"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGate"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}}},"post":{"tags":["Routines"],"summary":"Create/update heartbeat config","description":"Upsert. Returns the bare heartbeat row (no actions). Does not start/stop the workflow.","x-cli":{"service":"routines","action":"heartbeat-config","usage":"[--status disabled|active|paused|error] [--frequency-minutes N]","feature":"routines"},"x-mcp":{"expose":"extended"},"x-feature":"routines","x-teamyou-scope":"agent:write","requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HeartbeatUpsertRequest"}}}},"responses":{"200":{"description":"Saved heartbeat (without actions).","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"heartbeat":{"$ref":"#/components/schemas/Heartbeat"}},"required":["heartbeat"]}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGate"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}}},"delete":{"tags":["Routines"],"summary":"Disable heartbeat","description":"Idempotent — no 404 when none exists.","x-cli":{"service":"routines","action":"heartbeat-delete","usage":"","feature":"routines"},"x-mcp":{"expose":"extended"},"x-feature":"routines","x-teamyou-scope":"agent:write","responses":{"200":{"description":"Disabled.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[true]}},"required":["ok"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGate"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/heartbeat/start":{"post":{"tags":["Routines"],"summary":"Start heartbeat","x-cli":{"service":"routines","action":"heartbeat-start","usage":"","feature":"routines"},"x-mcp":{"expose":"extended"},"x-feature":"routines","x-teamyou-scope":"agent:write","responses":{"200":{"description":"Started; workflow run id.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"runId":{"type":"string"}},"required":["runId"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGate"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/heartbeat/stop":{"post":{"tags":["Routines"],"summary":"Stop heartbeat","x-cli":{"service":"routines","action":"heartbeat-stop","usage":"","feature":"routines"},"x-mcp":{"expose":"extended"},"x-feature":"routines","x-teamyou-scope":"agent:write","responses":{"200":{"description":"Stopped.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[true]}},"required":["ok"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGate"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/heartbeat/trigger":{"post":{"tags":["Routines"],"summary":"Trigger one heartbeat cycle","description":"Runs synchronously. 400 if no heartbeat configured.","x-cli":{"service":"routines","action":"heartbeat-trigger","usage":"","feature":"routines"},"x-mcp":{"expose":"extended"},"x-feature":"routines","x-teamyou-scope":"agent:write","responses":{"200":{"description":"Execution result.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"result":{"$ref":"#/components/schemas/HeartbeatExecutionResult"}},"required":["result"]}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGate"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/heartbeat/history":{"get":{"tags":["Routines"],"summary":"Heartbeat execution history","x-cli":{"service":"routines","action":"heartbeat-history","usage":"[--limit N] [--offset N]","feature":"routines"},"x-mcp":{"expose":"extended"},"x-feature":"routines","x-teamyou-scope":"read","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"default":50}},{"name":"offset","in":"query","schema":{"type":"integer","minimum":0,"default":0}}],"responses":{"200":{"description":"Executions, newest first.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"history":{"type":"array","items":{"$ref":"#/components/schemas/HeartbeatExecution"}}},"required":["history"]}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGate"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/heartbeat/actions":{"get":{"tags":["Routines"],"summary":"List heartbeat actions","x-cli":{"service":"routines","action":"heartbeat-actions-list","usage":"","feature":"routines"},"x-mcp":{"expose":"extended"},"x-feature":"routines","x-teamyou-scope":"read","responses":{"200":{"description":"Actions (empty if no heartbeat).","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"actions":{"type":"array","items":{"$ref":"#/components/schemas/HeartbeatAction"}}},"required":["actions"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGate"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}}},"post":{"tags":["Routines"],"summary":"Create a heartbeat action","description":"Auto-provisions a disabled heartbeat when heartbeatId is omitted and none exists.","x-cli":{"service":"routines","action":"heartbeat-actions-create","usage":"<name> --action-type check_tasks|openclaw_command|custom_webhook [--heartbeat-id ID] [--description TEXT] [--priority N] [--disabled] [--config-json '{...}']","feature":"routines"},"x-mcp":{"expose":"extended"},"x-feature":"routines","x-teamyou-scope":"agent:write","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HeartbeatActionCreateRequest"}}}},"responses":{"201":{"description":"Created action.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"action":{"$ref":"#/components/schemas/HeartbeatAction"}},"required":["action"]}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGate"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/heartbeat/actions/{id}":{"patch":{"tags":["Routines"],"summary":"Update a heartbeat action","x-cli":{"service":"routines","action":"heartbeat-actions-update","usage":"<action_id> [--name TEXT] [--action-type TYPE] [--description TEXT] [--priority N] [--enabled|--disabled] [--config-json '{...}']","feature":"routines"},"x-mcp":{"expose":"extended"},"x-feature":"routines","x-teamyou-scope":"agent:write","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","minLength":1},"description":"Action id"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HeartbeatActionUpdateRequest"}}}},"responses":{"200":{"description":"Updated action.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"action":{"$ref":"#/components/schemas/HeartbeatAction"}},"required":["action"]}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGate"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}}},"delete":{"tags":["Routines"],"summary":"Delete a heartbeat action","x-cli":{"service":"routines","action":"heartbeat-actions-delete","usage":"<action_id>","feature":"routines"},"x-mcp":{"expose":"extended"},"x-feature":"routines","x-teamyou-scope":"agent:write","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","minLength":1},"description":"Action id"}],"responses":{"200":{"description":"Deleted.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[true]}},"required":["ok"]}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGate"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/scheduled-actions":{"get":{"tags":["Routines"],"summary":"List scheduled actions","x-cli":{"service":"routines","action":"scheduled-actions-list","usage":"","feature":"routines"},"x-mcp":{"expose":"extended"},"x-feature":"routines","x-teamyou-scope":"read","responses":{"200":{"description":"Scheduled actions + quota.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"scheduledActions":{"type":"array","items":{"$ref":"#/components/schemas/ScheduledAction"}},"currentCount":{"type":"integer"},"limit":{"type":"integer"},"remaining":{"type":"integer"}},"required":["scheduledActions","currentCount","limit","remaining"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGate"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}}},"post":{"tags":["Routines"],"summary":"Create a scheduled action","description":"409 when the per-user slot limit is reached.","x-cli":{"service":"routines","action":"scheduled-actions-create","usage":"<name> --schedule-type one_time|cron --action-type check_tasks|openclaw_command|custom_webhook [--status active|paused|disabled] [--run-at ISO8601] [--cron-expr 'M H DOM MON DOW'] [--timezone IANA] [--config-json '{...}']","feature":"routines"},"x-mcp":{"expose":"extended"},"x-feature":"routines","x-teamyou-scope":"agent:write","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScheduledActionCreateRequest"}}}},"responses":{"201":{"description":"Created scheduled action + quota.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"scheduledAction":{"$ref":"#/components/schemas/ScheduledAction"},"currentCount":{"type":"integer"},"limit":{"type":"integer"},"remaining":{"type":"integer"}},"required":["scheduledAction","currentCount","limit","remaining"]}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGate"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/scheduled-actions/{id}":{"get":{"tags":["Routines"],"summary":"Get a scheduled action","x-cli":{"service":"routines","action":"scheduled-actions-get","usage":"<action_id>","feature":"routines"},"x-mcp":{"expose":"extended"},"x-feature":"routines","x-teamyou-scope":"read","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","minLength":1},"description":"Scheduled action id"}],"responses":{"200":{"description":"The scheduled action.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"scheduledAction":{"$ref":"#/components/schemas/ScheduledAction"}},"required":["scheduledAction"]}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGate"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}}},"patch":{"tags":["Routines"],"summary":"Update a scheduled action","x-cli":{"service":"routines","action":"scheduled-actions-update","usage":"<action_id> [--name TEXT] [--status active|paused|disabled] [--schedule-type one_time|cron] [--run-at ISO8601] [--cron-expr 'M H DOM MON DOW'] [--timezone IANA] [--action-type TYPE] [--config-json '{...}']","feature":"routines"},"x-mcp":{"expose":"extended"},"x-feature":"routines","x-teamyou-scope":"agent:write","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","minLength":1},"description":"Scheduled action id"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScheduledActionUpdateRequest"}}}},"responses":{"200":{"description":"Updated scheduled action.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"scheduledAction":{"$ref":"#/components/schemas/ScheduledAction"}},"required":["scheduledAction"]}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGate"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}}},"delete":{"tags":["Routines"],"summary":"Delete a scheduled action","description":"Idempotent — no 404 when none exists.","x-cli":{"service":"routines","action":"scheduled-actions-delete","usage":"<action_id>","feature":"routines"},"x-mcp":{"expose":"extended"},"x-feature":"routines","x-teamyou-scope":"agent:write","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","minLength":1},"description":"Scheduled action id"}],"responses":{"200":{"description":"Deleted.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[true]}},"required":["ok"]}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGate"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/scheduled-actions/{id}/pause":{"post":{"tags":["Routines"],"summary":"Pause a scheduled action","x-cli":{"service":"routines","action":"scheduled-actions-pause","usage":"<action_id>","feature":"routines"},"x-mcp":{"expose":"extended"},"x-feature":"routines","x-teamyou-scope":"agent:write","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","minLength":1},"description":"Scheduled action id"}],"responses":{"200":{"description":"Paused.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"scheduledAction":{"$ref":"#/components/schemas/ScheduledAction"}},"required":["scheduledAction"]}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGate"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/scheduled-actions/{id}/resume":{"post":{"tags":["Routines"],"summary":"Resume a scheduled action","x-cli":{"service":"routines","action":"scheduled-actions-resume","usage":"<action_id>","feature":"routines"},"x-mcp":{"expose":"extended"},"x-feature":"routines","x-teamyou-scope":"agent:write","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","minLength":1},"description":"Scheduled action id"}],"responses":{"200":{"description":"Resumed.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"scheduledAction":{"$ref":"#/components/schemas/ScheduledAction"}},"required":["scheduledAction"]}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGate"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/scheduled-actions/{id}/history":{"get":{"tags":["Routines"],"summary":"Scheduled action execution history","x-cli":{"service":"routines","action":"scheduled-actions-history","usage":"<action_id> [--limit N] [--offset N]","feature":"routines"},"x-mcp":{"expose":"extended"},"x-feature":"routines","x-teamyou-scope":"read","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","minLength":1},"description":"Scheduled action id"},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"default":50}},{"name":"offset","in":"query","schema":{"type":"integer","minimum":0,"default":0}}],"responses":{"200":{"description":"Executions, newest first.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"history":{"type":"array","items":{"$ref":"#/components/schemas/ScheduledActionExecution"}}},"required":["history"]}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGate"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/instructions":{"get":{"tags":["Instructions"],"summary":"Pull outstanding instructions","description":"Returns the calling agent's non-acknowledged instructions, newest first, and atomically flips any pending items to delivered. Idempotent — re-pulling re-returns delivered-but-unacknowledged items.","x-cli":{"service":"instructions","action":"pull","usage":"[--status pending|delivered] [--limit N] [--offset N]","feature":"instructions"},"x-mcp":{"expose":"extended"},"x-feature":"instructions","x-teamyou-scope":"read","parameters":[{"name":"status","in":"query","schema":{"type":"string","enum":["pending","delivered"]}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"default":50}},{"name":"offset","in":"query","schema":{"type":"integer","minimum":0,"default":0}}],"responses":{"200":{"description":"Outstanding instructions, newest first.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"instructions":{"type":"array","items":{"$ref":"#/components/schemas/AgentInstruction"}}},"required":["instructions"]}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGate"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}}},"post":{"tags":["Instructions"],"summary":"Queue an instruction for another agent","description":"Addresses another API key on the same account. 404 when the target key is not found or not owned.","x-cli":{"service":"instructions","action":"push","usage":"<body> --target-key KEY_ID [--anchor-type topic|task|drive --anchor-id ID]","feature":"instructions"},"x-mcp":{"expose":"extended"},"x-feature":"instructions","x-teamyou-scope":"agent:write","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentInstructionCreateRequest"}}}},"responses":{"201":{"description":"Created instruction.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"instruction":{"$ref":"#/components/schemas/AgentInstruction"}},"required":["instruction"]}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGate"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/instructions/{id}":{"patch":{"tags":["Instructions"],"summary":"Acknowledge an instruction","description":"Forward-only and idempotent. 404 when not found or not owned.","x-cli":{"service":"instructions","action":"ack","usage":"<instruction_id>","feature":"instructions"},"x-mcp":{"expose":"extended"},"x-feature":"instructions","x-teamyou-scope":"read","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","minLength":1},"description":"Instruction id"}],"responses":{"200":{"description":"Acknowledged instruction.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"instruction":{"$ref":"#/components/schemas/AgentInstruction"}},"required":["instruction"]}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGate"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/drive":{"get":{"tags":["Agent Drive (deprecated paths)"],"summary":"List documents (deprecated path)","description":"DEPRECATED PATH — use `GET /agent-drive` instead. Identical behaviour, identical request and response: this is the same handler, reached through an alias route file rather than a redirect, so a request body survives the call. Responses from this path carry `Deprecation: true` and a `Link: <…>; rel=\"successor-version\"` header naming the live path. No removal date is scheduled; those headers are where that will change first.","x-teamyou-scope":"read","parameters":[{"name":"scope","in":"query","schema":{"type":"string","enum":["mine","shared","all","accessed"],"default":"mine"},"description":"Which documents to list. mine (default) = only your own, exactly as this endpoint behaved before scope existed. shared = ONLY documents another user has granted to you, never your own, each carrying a sharedBy object naming its owner. all = both, merged newest-first. accessed = your LIBRARY: cross-user documents you or your agents have opened, whether by link or by grant, each carrying an accessed object naming the document owner, how you got in, and which of your agents last opened it. Shared-in and accessed documents are not yours: you cannot write to their paths, and access ends the moment the owner revokes it. Library entries are re-checked on every request, so one whose access has been revoked is simply absent from the list rather than returned as an id you cannot fetch — which is also why pagination.hasMore, not the length of documents, tells you whether to ask for another page. Note that accessed is NOT searchable yet: POST /search/documents rejects it."},{"name":"archived","in":"query","schema":{"type":"string","enum":["true","false"]},"description":"Omitted or false lists live documents; true lists only deleted (recoverable) ones. Applies to your own documents; shared-in documents are always live (a document its owner deleted disappears from your list entirely)."},{"name":"pathPrefix","in":"query","schema":{"type":"string"},"description":"Folder to scope to, e.g. \"memory/\". Canonicalized the same way a written path is; a trailing \"/\" is optional. Matched case-insensitively. Omit for all of Agent Drive."},{"name":"where","in":"query","schema":{"type":"array","items":{"type":"string"}},"explode":true,"style":"form","description":"Repeat (query) or list (body) to AND up to 10 clauses. Split on the FIRST colon, so a value may contain colons: key is letters/digits/_/- up to 64 chars, value up to 200. A clause matches a field equal to the value OR an array containing it, so tags:research finds \"tags: [research, ops]\"; a value that is exactly a number or true/false is also tried typed, so priority:3 finds an unquoted 3. No ranges, no OR, no nested paths. Filtering only NARROWS what the scope returns. Not supported with scope=accessed."},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":200,"default":100}},{"name":"offset","in":"query","schema":{"type":"integer","minimum":0,"default":0}}],"responses":{"200":{"description":"Documents (metadata), the child folders of pathPrefix, and the page window.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"documents":{"type":"array","items":{"$ref":"#/components/schemas/AgentDocumentSummary"}},"folders":{"type":"array","items":{"$ref":"#/components/schemas/AgentDocumentFolder"},"description":"Immediate child folders of pathPrefix. ALWAYS empty unless scope=mine — see the scope parameter."},"pathPrefix":{"type":"string","description":"The canonical prefix that was applied (\"\" for all of Agent Drive)."},"scope":{"type":"string","enum":["mine","shared","all"],"description":"The scope that was applied."},"pagination":{"$ref":"#/components/schemas/DocumentPage"}},"required":["documents","folders","pathPrefix","scope","pagination"]}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGate"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}},"deprecated":true},"post":{"tags":["Agent Drive (deprecated paths)"],"summary":"Write (upsert-by-path) a document (deprecated path)","description":"DEPRECATED PATH — use `POST /agent-drive` instead. Identical behaviour, identical request and response: this is the same handler, reached through an alias route file rather than a redirect, so a request body survives the call. Responses from this path carry `Deprecation: true` and a `Link: <…>; rel=\"successor-version\"` header naming the live path. No removal date is scheduled; those headers are where that will change first.","x-teamyou-scope":"agent-drive:write","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WriteDocumentRequest"}}}},"responses":{"200":{"description":"Unchanged — byte-identical to the stored document; nothing was written.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"document":{"$ref":"#/components/schemas/AgentDocument"},"documentUrl":{"type":"string","description":"The document's canonical /agent-drive/{id} URL — its only URL, and its share URL. Who else can open it is decided by the document's visibility (private / anyone with the link / anyone signed in): private by default, changeable by the owner in the TeamYou web app or via PUT /agent-drive/{id}/visibility with the share scope. Writing a document never changes its visibility, so this URL stays owner-only until someone deliberately shares it."},"url":{"type":"string","deprecated":true,"description":"DEPRECATED alias for documentUrl, carrying the identical value. The name was misleading — it is not a share URL. Read documentUrl instead; this field will be removed once older skill versions are fenced off."},"unchanged":{"type":"boolean","enum":[true]}},"required":["document","documentUrl","url","unchanged"]}}}},"201":{"description":"Written document + its private reader URL.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"document":{"$ref":"#/components/schemas/AgentDocument"},"documentUrl":{"type":"string","description":"The document's canonical /agent-drive/{id} URL — its only URL, and its share URL. Who else can open it is decided by the document's visibility (private / anyone with the link / anyone signed in): private by default, changeable by the owner in the TeamYou web app or via PUT /agent-drive/{id}/visibility with the share scope. Writing a document never changes its visibility, so this URL stays owner-only until someone deliberately shares it."},"url":{"type":"string","deprecated":true,"description":"DEPRECATED alias for documentUrl, carrying the identical value. The name was misleading — it is not a share URL. Read documentUrl instead; this field will be removed once older skill versions are fenced off."},"unchanged":{"type":"boolean","enum":[false]},"folderRule":{"type":"object","description":"Present ONLY when the owner has a folder visibility rule covering the path of a document this request CREATED — absent on every replace, and absent when no rule covers the path. The owner sets these in the TeamYou web app: \"documents created under reports/ start public\". The deepest matching folder wins, so a rule on reports/drafts/ overrides one on reports/. Rules apply at CREATION only: replacing an existing document never re-applies one, and an existing document's visibility is never changed by a rule (the owner has a separate, explicit bulk action for that). applied=false means the document was created PRIVATE and the rule was skipped — read reason.","properties":{"prefix":{"type":"string","description":"The folder the rule is written on, with a trailing slash, e.g. \"reports/\"."},"visibility":{"type":"string","enum":["private","public","authenticated"],"description":"What the rule says a document created here should be."},"applied":{"type":"boolean","description":"Whether the document was actually created with that visibility. False means it was created private instead."},"reason":{"type":"string","enum":["drive_share_scope_required","agent_sharing_blocked"],"description":"Why the rule was skipped. The write SUCCEEDED either way and the document is private; only the rule did not fire. \"drive_share_scope_required\": this API key does not hold the share scope, so it may not put a document in front of anyone — ask the key's owner to add the \"Share on your behalf\" permission in TeamYou settings, then re-push. \"agent_sharing_blocked\": the key is fine, but the account-wide \"Block agent sharing\" switch (Settings → AI permissions) is ON, which stops every agent from changing who can open a document — the owner turns it off there, and no change to any key helps. Present only when applied is false."}},"required":["prefix","visibility","applied"]}},"required":["document","documentUrl","url","unchanged"]}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGate"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}},"deprecated":true}},"/drive/{id}":{"get":{"tags":["Agent Drive (deprecated paths)"],"summary":"Read a document (deprecated path)","description":"DEPRECATED PATH — use `GET /agent-drive/{id}` instead. Identical behaviour, identical request and response: this is the same handler, reached through an alias route file rather than a redirect, so a request body survives the call. Responses from this path carry `Deprecation: true` and a `Link: <…>; rel=\"successor-version\"` header naming the live path. No removal date is scheduled; those headers are where that will change first.","x-teamyou-scope":"read","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","minLength":1},"description":"Document id"}],"responses":{"200":{"description":"The document.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"document":{"$ref":"#/components/schemas/AgentDocument"},"access":{"type":"string","enum":["owner","grant","public"],"description":"Which source answered: 'owner' (your own document), 'grant' (another user shared it with you by name), or 'public' (anyone with the id can read it). Branch on this rather than on the presence of sharedBy — only 'owner' means the document is yours to write to."},"sharedBy":{"oneOf":[{"$ref":"#/components/schemas/SharedByUser"},{"type":"null"}],"description":"Present only when access is 'grant' — another user granted you this document by name. Absent for your own documents AND for public ones: a public document was published to nobody in particular, so its owner is deliberately not identified here."}},"required":["document","access"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGate"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}},"deprecated":true},"delete":{"tags":["Agent Drive (deprecated paths)"],"summary":"Delete a document (deprecated path)","description":"DEPRECATED PATH — use `DELETE /agent-drive/{id}` instead. Identical behaviour, identical request and response: this is the same handler, reached through an alias route file rather than a redirect, so a request body survives the call. Responses from this path carry `Deprecation: true` and a `Link: <…>; rel=\"successor-version\"` header naming the live path. No removal date is scheduled; those headers are where that will change first.","x-teamyou-scope":"agent-drive:write","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","minLength":1},"description":"Document id"}],"responses":{"200":{"description":"Deleted.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"deleted":{"type":"boolean","enum":[true]},"id":{"type":"string"}},"required":["deleted","id"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGate"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}},"deprecated":true}},"/drive/{id}/visibility":{"put":{"tags":["Agent Drive (deprecated paths)"],"summary":"Set who can open a document (deprecated path)","description":"DEPRECATED PATH — use `PUT /agent-drive/{id}/visibility` instead. Identical behaviour, identical request and response: this is the same handler, reached through an alias route file rather than a redirect, so a request body survives the call. Responses from this path carry `Deprecation: true` and a `Link: <…>; rel=\"successor-version\"` header naming the live path. No removal date is scheduled; those headers are where that will change first.","x-teamyou-scope":"share","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","minLength":1},"description":"Document id"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetDocumentVisibilityRequest"}}}},"responses":{"200":{"description":"The stored visibility and the document’s URLs.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"visibility":{"type":"string","enum":["private","public","authenticated"]},"documentUrl":{"type":"string","description":"The document's canonical /agent-drive/{id} URL — its only URL, and its share URL. Who else can open it is decided by the document's visibility (private / anyone with the link / anyone signed in): private by default, changeable by the owner in the TeamYou web app or via PUT /agent-drive/{id}/visibility with the share scope. Writing a document never changes its visibility, so this URL stays owner-only until someone deliberately shares it."},"rawUrl":{"type":"string","description":"The document's raw-markdown URL (/agent-drive/{id}/raw), which obeys the same visibility. Hand this to another agent instead of teaching it to append /raw."}},"required":["visibility","documentUrl","rawUrl"]}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGate"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}},"deprecated":true}},"/drive/{id}/grants":{"post":{"tags":["Agent Drive (deprecated paths)"],"summary":"Share a document with a person (deprecated path)","description":"DEPRECATED PATH — use `POST /agent-drive/{id}/grants` instead. Identical behaviour, identical request and response: this is the same handler, reached through an alias route file rather than a redirect, so a request body survives the call. Responses from this path carry `Deprecation: true` and a `Link: <…>; rel=\"successor-version\"` header naming the live path. No removal date is scheduled; those headers are where that will change first.","x-teamyou-scope":"share","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","minLength":1},"description":"Document id"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentGrantRequest"}}}},"responses":{"200":{"description":"The share landed — with no signal of whether the address has an account.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"shared":{"type":"boolean","description":"Always true on success."},"email":{"type":"string","description":"The normalized (lowercased) address the grant was recorded against — an echo of what you sent, not a lookup result."},"documentUrl":{"type":"string","description":"The document's canonical /agent-drive/{id} URL — its only URL, and its share URL. Who else can open it is decided by the document's visibility (private / anyone with the link / anyone signed in): private by default, changeable by the owner in the TeamYou web app or via PUT /agent-drive/{id}/visibility with the share scope. Writing a document never changes its visibility, so this URL stays owner-only until someone deliberately shares it."}},"required":["shared","email","documentUrl"]}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGate"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}},"deprecated":true},"delete":{"tags":["Agent Drive (deprecated paths)"],"summary":"Stop sharing a document with a person (deprecated path)","description":"DEPRECATED PATH — use `DELETE /agent-drive/{id}/grants` instead. Identical behaviour, identical request and response: this is the same handler, reached through an alias route file rather than a redirect, so a request body survives the call. Responses from this path carry `Deprecation: true` and a `Link: <…>; rel=\"successor-version\"` header naming the live path. No removal date is scheduled; those headers are where that will change first.","x-teamyou-scope":"share","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","minLength":1},"description":"Document id"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentGrantRequest"}}}},"responses":{"200":{"description":"Whether a live grant was removed.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"revoked":{"type":"boolean","description":"true if a live grant on that address was removed; false if the document is yours but no one was shared on it (an idempotent no-op)."}},"required":["revoked"]}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGate"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}},"deprecated":true}},"/drive/{id}/restore":{"post":{"tags":["Agent Drive (deprecated paths)"],"summary":"Restore a deleted document (deprecated path)","description":"DEPRECATED PATH — use `POST /agent-drive/{id}/restore` instead. Identical behaviour, identical request and response: this is the same handler, reached through an alias route file rather than a redirect, so a request body survives the call. Responses from this path carry `Deprecation: true` and a `Link: <…>; rel=\"successor-version\"` header naming the live path. No removal date is scheduled; those headers are where that will change first.","x-teamyou-scope":"agent-drive:write","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","minLength":1},"description":"Document id"}],"responses":{"200":{"description":"Restored document + its private reader URL.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"document":{"$ref":"#/components/schemas/AgentDocument"},"documentUrl":{"type":"string","description":"The document's canonical /agent-drive/{id} URL — its only URL, and its share URL. Who else can open it is decided by the document's visibility (private / anyone with the link / anyone signed in): private by default, changeable by the owner in the TeamYou web app or via PUT /agent-drive/{id}/visibility with the share scope. Writing a document never changes its visibility, so this URL stays owner-only until someone deliberately shares it."},"url":{"type":"string","deprecated":true,"description":"DEPRECATED alias for documentUrl, carrying the identical value. The name was misleading — it is not a share URL. Read documentUrl instead; this field will be removed once older skill versions are fenced off."}},"required":["document","documentUrl","url"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGate"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}},"deprecated":true}},"/todos":{"get":{"tags":["Tasks (deprecated paths)"],"summary":"List tasks (deprecated path)","x-teamyou-scope":"read","parameters":[{"name":"status","in":"query","schema":{"type":"string","enum":["todo","done"]}},{"name":"priority","in":"query","schema":{"type":"string","enum":["high","medium","low","none"]}},{"name":"archived","in":"query","schema":{"type":"string","enum":["true","false"]}},{"name":"orderBy","in":"query","schema":{"type":"string","enum":["createdAt","updatedAt","dueDate","priority"]}},{"name":"orderDirection","in":"query","schema":{"type":"string","enum":["asc","desc"]}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":100}}],"responses":{"200":{"description":"Tasks for the authenticated user.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"tasks":{"type":"array","items":{"$ref":"#/components/schemas/Task"}},"todos":{"type":"array","items":{"$ref":"#/components/schemas/Task"},"deprecated":true,"description":"Deprecated: the same array as `tasks`, under its retired key. Read `tasks`."}},"required":["tasks","todos"]}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGate"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}},"description":"DEPRECATED PATH — use `GET /tasks` instead. Identical behaviour, identical request and response: this is the same handler, reached through an alias route file rather than a redirect, so a request body survives the call. Responses from this path carry `Deprecation: true` and a `Link: <…>; rel=\"successor-version\"` header naming the live path. No removal date is scheduled; those headers are where that will change first.","deprecated":true},"post":{"tags":["Tasks (deprecated paths)"],"summary":"Create a task (deprecated path)","x-teamyou-scope":"work:write","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTaskRequest"}}}},"responses":{"201":{"description":"Created task.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"task":{"$ref":"#/components/schemas/Task"},"todo":{"allOf":[{"$ref":"#/components/schemas/Task"}],"deprecated":true,"description":"Deprecated: the same object as `task`, under its retired key. Read `task`."}},"required":["task","todo"]}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGate"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}},"description":"DEPRECATED PATH — use `POST /tasks` instead. Identical behaviour, identical request and response: this is the same handler, reached through an alias route file rather than a redirect, so a request body survives the call. Responses from this path carry `Deprecation: true` and a `Link: <…>; rel=\"successor-version\"` header naming the live path. No removal date is scheduled; those headers are where that will change first.","deprecated":true}},"/todos/{id}":{"get":{"tags":["Tasks (deprecated paths)"],"summary":"Get a task (deprecated path)","x-teamyou-scope":"read","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","minLength":1},"description":"Task id"}],"responses":{"200":{"description":"The task.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"task":{"$ref":"#/components/schemas/Task"},"todo":{"allOf":[{"$ref":"#/components/schemas/Task"}],"deprecated":true,"description":"Deprecated: the same object as `task`, under its retired key. Read `task`."}},"required":["task","todo"]}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGate"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}},"description":"DEPRECATED PATH — use `GET /tasks/{id}` instead. Identical behaviour, identical request and response: this is the same handler, reached through an alias route file rather than a redirect, so a request body survives the call. Responses from this path carry `Deprecation: true` and a `Link: <…>; rel=\"successor-version\"` header naming the live path. No removal date is scheduled; those headers are where that will change first.","deprecated":true},"put":{"tags":["Tasks (deprecated paths)"],"summary":"Update a task (deprecated path)","x-teamyou-scope":"work:write","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","minLength":1},"description":"Task id"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateTaskRequest"}}}},"responses":{"200":{"description":"Updated task.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"task":{"$ref":"#/components/schemas/Task"},"todo":{"allOf":[{"$ref":"#/components/schemas/Task"}],"deprecated":true,"description":"Deprecated: the same object as `task`, under its retired key. Read `task`."}},"required":["task","todo"]}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGate"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}},"description":"DEPRECATED PATH — use `PUT /tasks/{id}` instead. Identical behaviour, identical request and response: this is the same handler, reached through an alias route file rather than a redirect, so a request body survives the call. Responses from this path carry `Deprecation: true` and a `Link: <…>; rel=\"successor-version\"` header naming the live path. No removal date is scheduled; those headers are where that will change first.","deprecated":true},"delete":{"tags":["Tasks (deprecated paths)"],"summary":"Delete a task (deprecated path)","x-teamyou-scope":"work:write","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","minLength":1},"description":"Task id"}],"responses":{"200":{"description":"Deleted.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]}},"required":["success"]}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGate"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}},"description":"DEPRECATED PATH — use `DELETE /tasks/{id}` instead. Identical behaviour, identical request and response: this is the same handler, reached through an alias route file rather than a redirect, so a request body survives the call. Responses from this path carry `Deprecation: true` and a `Link: <…>; rel=\"successor-version\"` header naming the live path. No removal date is scheduled; those headers are where that will change first.","deprecated":true}},"/todos/{id}/complete":{"post":{"tags":["Tasks (deprecated paths)"],"summary":"Mark a task done (deprecated path)","x-teamyou-scope":"work:write","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","minLength":1},"description":"Task id"}],"responses":{"200":{"description":"Completed task.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"task":{"$ref":"#/components/schemas/Task"},"todo":{"allOf":[{"$ref":"#/components/schemas/Task"}],"deprecated":true,"description":"Deprecated: the same object as `task`, under its retired key. Read `task`."}},"required":["task","todo"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AgentGate"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"}},"description":"DEPRECATED PATH — use `POST /tasks/{id}/complete` instead. Identical behaviour, identical request and response: this is the same handler, reached through an alias route file rather than a redirect, so a request body survives the call. Responses from this path carry `Deprecation: true` and a `Link: <…>; rel=\"successor-version\"` header naming the live path. No removal date is scheduled; those headers are where that will change first.","deprecated":true}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"API key: `Authorization: Bearer ty_<key>`."}},"schemas":{"ProblemDetails":{"type":"object","description":"RFC 9457 Problem Details, served as application/problem+json. Carries a stable machine-readable `code` plus error-specific extension members.","properties":{"type":{"type":"string","format":"uri","description":"Stable problem-type identifier URI; resolves to this contract with an #error-<code> fragment."},"title":{"type":"string","description":"Short, stable summary of the problem type."},"status":{"type":"integer"},"code":{"type":"string","description":"Stable machine-readable error code, e.g. validation_error, invalid_json, not_found, conflict, agent_not_registered, client_identification_required, skill_update_required, client_update_nudge, insufficient_scope, ack_invalid, rate_limit_exceeded, quota_exceeded, product_limit_exceeded, internal_error."},"detail":{"type":"string","description":"Instance-specific human-readable explanation."},"instance":{"type":"string","description":"Optional URI identifying this specific occurrence."}},"required":["type","title","status","code"],"additionalProperties":true},"AgentEcosystemNotice":{"type":"object","properties":{"type":{"type":"string","enum":["skill_update_available"]},"reported_version":{"type":["string","null"]},"latest_version":{"type":"string"},"install_url":{"type":"string"},"recommended_action":{"type":"string"}},"required":["type","latest_version","install_url","recommended_action"]},"Topic":{"type":"object","properties":{"id":{"type":"string"},"userId":{"type":"string"},"name":{"type":"string"},"oneSentenceDescription":{"type":"string"},"summary":{"type":"string"},"consolidatedDetails":{"type":["array","null"],"items":{"type":"string"}},"outline":{"type":["string","null"]},"customViewInstructions":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","userId","name","oneSentenceDescription","summary","createdAt","updatedAt"]},"TopicDetail":{"type":"object","properties":{"id":{"type":"string"},"userId":{"type":"string"},"topicId":{"type":"string"},"detail":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","userId","topicId","detail","createdAt","updatedAt"]},"ResolvedEdge":{"type":"object","properties":{"id":{"type":"string"},"linkedTopicId":{"type":"string"},"linkedTopicName":{"type":"string"},"label":{"type":"string"},"direction":{"type":"string","enum":["outgoing","incoming","bidirectional"]},"createdAt":{"type":"string","format":"date-time"}},"required":["id","linkedTopicId","linkedTopicName","label","direction","createdAt"]},"TopicWithDetails":{"allOf":[{"$ref":"#/components/schemas/Topic"},{"type":"object","properties":{"details":{"type":"array","items":{"$ref":"#/components/schemas/TopicDetail"}},"edges":{"type":"array","items":{"$ref":"#/components/schemas/ResolvedEdge"}}},"required":["details","edges"]}]},"Edge":{"type":"object","properties":{"id":{"type":"string"},"userId":{"type":"string"},"sourceId":{"type":"string"},"targetId":{"type":"string"},"label":{"type":"string"},"mirrorLabel":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","userId","sourceId","targetId","label","mirrorLabel","createdAt","updatedAt"]},"EdgeProvenance":{"type":"object","properties":{"fromTopicId":{"type":"string"},"fromTopicName":{"type":"string"},"label":{"type":"string"},"direction":{"type":"string"}},"required":["fromTopicId","fromTopicName","label","direction"]},"TopicSearchResult":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"oneSentenceDescription":{"type":"string"},"summary":{"type":"string"},"score":{"type":"number","description":"Fused relevance score; compare within one response."},"similarity":{"type":"number","description":"Deprecated legacy field; best raw arm score, 0 when absent."},"methods":{"type":"array","items":{"type":"string"}},"linkedVia":{"type":"array","items":{"$ref":"#/components/schemas/EdgeProvenance"},"description":"Present only on graph-injected (one-hop) neighbors."},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","name","oneSentenceDescription","summary","score","similarity","methods","createdAt","updatedAt"]},"DetailSearchResult":{"type":"object","properties":{"id":{"type":"string"},"topicId":{"type":"string"},"topicName":{"type":"string"},"detail":{"type":"string"},"score":{"type":"number"},"similarity":{"type":"number"},"methods":{"type":"array","items":{"type":"string"}},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","topicId","topicName","detail","score","similarity","methods","createdAt","updatedAt"]},"DocumentSearchResult":{"type":"object","properties":{"source":{"type":"string","enum":["drive","drive-shared"],"description":"Provenance tag, so a client merging several result lists can label where a hit came from. \"drive\" is your own document; \"drive-shared\" is another user's document you hold a live grant on. You only ever see \"drive-shared\" on a request that asked for scope shared or all."},"id":{"type":"string"},"title":{"type":"string"},"path":{"type":"string"},"url":{"type":"string","description":"The document's canonical /agent-drive/{id} URL — its only URL, and its share URL. Openable by others only if the document has been made public or signed-in-visible (by its owner, or by an agent holding the share scope); private by default."},"score":{"type":"number","description":"Fused relevance score (higher is better, not a cosine). Compare WITHIN one response only."},"methods":{"type":"array","items":{"type":"string"},"description":"Which arms matched: vector, fts, trigram."},"snippet":{"type":"string","description":"Trimmed text of the best-matching chunk."},"headingPath":{"type":"string","description":"Heading trail of that chunk, e.g. \"Monday > Blockers\". Empty string when it sits above any heading."},"chunkIndex":{"type":"integer","description":"Which chunk matched. 0 is the synthetic header chunk holding the title and path, so a chunkIndex of 0 means the title/path matched rather than the body."},"byteSize":{"type":["integer","null"]},"sharedBy":{"$ref":"#/components/schemas/SharedByUser","description":"Present on every \"drive-shared\" result and absent on your own, so you never have to infer whose document a hit is. The path is the path in THEIR Agent Drive; do not write to it, and expect the document to disappear from results the moment they revoke."},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["source","id","title","path","url","score","methods","snippet","headingPath","chunkIndex","createdAt","updatedAt"]},"SearchAllStructureRef":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"]},"SearchAllStructure":{"type":"object","additionalProperties":false,"description":"Where the hit sits, keyed by its type. detail: { topic }. task: { project, topic }, each null when the task has none. project: { areas } (the areas that contain it). document: { projects } (the projects that reference it). topic and area: {} (use their own id). A document's projects leave out archived projects; a task still names its project even when that project is archived.","properties":{"topic":{"oneOf":[{"$ref":"#/components/schemas/SearchAllStructureRef"},{"type":"null"}],"description":"On detail (never null) and task hits."},"project":{"oneOf":[{"$ref":"#/components/schemas/SearchAllStructureRef"},{"type":"null"}],"description":"On task hits."},"areas":{"type":"array","items":{"$ref":"#/components/schemas/SearchAllStructureRef"},"description":"On project hits."},"projects":{"type":"array","items":{"$ref":"#/components/schemas/SearchAllStructureRef"},"description":"On document hits."}}},"SearchAllResult":{"type":"object","properties":{"type":{"type":"string","enum":["topic","detail","task","project","area","document"]},"id":{"type":"string"},"title":{"type":"string","description":"The item's name. A detail has no name, so its title is its text cut to 80 characters."},"snippet":{"type":"string","description":"A short excerpt: a topic description, a detail text, a task title with status and due date, a project goal, an area description, or the best-matching document chunk."},"score":{"type":["number","null"],"description":"Fused relevance (higher is better, not a cosine). Compare within one response only. null on an empty-query recency listing."},"methods":{"type":"array","items":{"type":"string","enum":["vector","fts","trigram"]},"description":"Which arms matched: vector (meaning), fts (words), trigram (spelling). More arms usually means a stronger match. Empty on an empty-query recency listing."},"url":{"type":"string","description":"Absolute URL of the item in the TeamYou web app. A detail links to its topic, a task to the tasks page."},"structure":{"$ref":"#/components/schemas/SearchAllStructure"},"sharedBy":{"$ref":"#/components/schemas/SharedByUser","description":"document hits shared with you only: who shared it (as on /search/documents). Absent on your own documents and on every other type."},"updatedAt":{"type":"string","format":"date-time"}},"required":["type","id","title","snippet","score","methods","url","structure","updatedAt"]},"SearchRelatedResult":{"type":"object","properties":{"type":{"type":"string","enum":["topic","detail","task","project","area","document"]},"id":{"type":"string"},"title":{"type":"string"},"snippet":{"type":"string"},"url":{"type":"string"},"structure":{"$ref":"#/components/schemas/SearchAllStructure"},"sharedBy":{"$ref":"#/components/schemas/SharedByUser","description":"document hits shared with you only: who shared it. Absent otherwise."},"updatedAt":{"type":"string","format":"date-time"},"relation":{"type":"string","enum":["detail_of","linked_topic","topic_of","project_of","task_of","document_in","topic_in","project_in","contains"],"description":"Read as \"<this item> <relation> <anchor>\". detail_of: a detail of the anchor topic. linked_topic: a topic an edge links to the anchor (see label). topic_of / project_of: the topic or project the anchor detail or task belongs to. task_of, document_in, topic_in: a task filed in, or a document or topic referenced by, the anchor project. project_in: a project in the anchor area. contains: an area holding the anchor project, or a project referencing the anchor document."},"label":{"type":"string","description":"linked_topic only: the edge label, read from the anchor side."}},"required":["type","id","title","snippet","url","structure","updatedAt","relation"]},"SearchRelatedResponse":{"type":"object","properties":{"results":{"type":"array","items":{"$ref":"#/components/schemas/SearchRelatedResult"}}},"required":["results"]},"SearchAllStoreWarning":{"type":"object","properties":{"code":{"type":"string","enum":["store_unavailable"]},"type":{"type":"string","enum":["topic","detail","task","project","area","document"]},"message":{"type":"string"}},"required":["code","type","message"],"additionalProperties":false,"description":"One store failed. That type is missing from results and counts; the other types still answered."},"SearchAllEmbeddingWarning":{"type":"object","properties":{"code":{"type":"string","enum":["embedding_unavailable"]},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false,"description":"The query embedding could not be generated, so every type was searched without meaning-based (vector) matching: results are keyword (fts) and fuzzy (trigram) matches only."},"SearchAllWarning":{"oneOf":[{"$ref":"#/components/schemas/SearchAllStoreWarning"},{"$ref":"#/components/schemas/SearchAllEmbeddingWarning"}],"discriminator":{"propertyName":"code","mapping":{"store_unavailable":"#/components/schemas/SearchAllStoreWarning","embedding_unavailable":"#/components/schemas/SearchAllEmbeddingWarning"}}},"SearchAllResponse":{"type":"object","properties":{"results":{"type":"array","items":{"$ref":"#/components/schemas/SearchAllResult"}},"counts":{"type":"object","additionalProperties":false,"properties":{"topic":{"type":"integer","minimum":0},"detail":{"type":"integer","minimum":0},"task":{"type":"integer","minimum":0},"project":{"type":"integer","minimum":0},"area":{"type":"integer","minimum":0},"document":{"type":"integer","minimum":0}},"description":"Candidates found per requested type BEFORE the cut to limit, so a count above what results shows means there is more of that type. 0 means the type was searched and nothing matched. A type that failed is ABSENT here and named in warnings."},"warnings":{"type":"array","items":{"$ref":"#/components/schemas/SearchAllWarning"},"description":"Present only when something degraded. store_unavailable: that type failed and is missing from results and counts; the other types still answered. embedding_unavailable: results are keyword and fuzzy matches only. Retrying later may succeed."}},"required":["results","counts"]},"Task":{"type":"object","properties":{"id":{"type":"string"},"userId":{"type":"string"},"topicId":{"type":["string","null"]},"projectId":{"type":["string","null"]},"position":{"type":["string","null"]},"title":{"type":"string"},"status":{"type":"string","enum":["todo","done"]},"isArchived":{"type":"boolean"},"dueDate":{"type":["string","null"],"format":"date-time"},"priority":{"type":"string","enum":["high","medium","low","none"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","userId","title","status","isArchived","priority","createdAt","updatedAt"]},"Project":{"type":"object","properties":{"id":{"type":"string"},"userId":{"type":"string"},"name":{"type":"string"},"goal":{"type":["string","null"]},"status":{"type":"string","enum":["active","waiting","done","archived"]},"waitingOn":{"type":["string","null"]},"preset":{"type":["string","null"]},"notes":{"type":["string","null"],"description":"Narrative markdown body: what this project is, in prose. Stored and returned verbatim; the server does not parse or render it."},"dueDate":{"type":["string","null"],"format":"date","pattern":"^\\d{4}-\\d{2}-\\d{2}$","description":"Calendar day (YYYY-MM-DD) the project is aimed at. A soft target: it does not affect status and drives no behavior. Note the shape differs from `Task.dueDate`, which is a date-time instant."},"completedAt":{"type":["string","null"],"format":"date-time","readOnly":true,"description":"When the project status became `done`. Set by the server on that transition and cleared when the status leaves `done`; not client-writable."},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","userId","name","status","createdAt","updatedAt"]},"ProjectProgress":{"type":"object","properties":{"total":{"type":"integer","description":"Non-archived tasks in the plan."},"done":{"type":"integer","description":"Non-archived tasks with status=done."},"percent":{"type":"integer","description":"done/total as a 0..100 integer (0 when total is 0)."}},"required":["total","done","percent"]},"ContainerRef":{"type":"object","properties":{"id":{"type":"string"},"userId":{"type":"string"},"containerType":{"type":"string","enum":["project","area"]},"containerId":{"type":"string"},"targetType":{"type":"string","enum":["topic","todo","project","area","url","doc","entity"]},"targetId":{"type":["string","null"]},"url":{"type":["string","null"]},"title":{"type":["string","null"]},"position":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","userId","containerType","containerId","targetType","position","createdAt","updatedAt"]},"HydratedTarget":{"oneOf":[{"type":"object","properties":{"resolved":{"type":"boolean","enum":[true]},"targetType":{"type":"string","enum":["topic","todo","project","area","url","doc"]},"display":{"type":"string","description":"Resolved display label for the target."}},"required":["resolved","targetType","display"]},{"type":"object","properties":{"resolved":{"type":"boolean","enum":[false]},"reason":{"type":"string","enum":["missing","unsupported"]}},"required":["resolved","reason"]}],"description":"Defensively-resolved target of a container ref. `missing` = the target row was deleted (dangling ref); `unsupported` = a target type not resolvable yet."},"HydratedRef":{"allOf":[{"$ref":"#/components/schemas/ContainerRef"},{"type":"object","properties":{"target":{"$ref":"#/components/schemas/HydratedTarget"},"display":{"type":"string","description":"ALWAYS-PRESENT human label for this reference - read this to show or log a member by name. Resolves in order: the target's live name (topic/project/area name, task/document title, or a url ref's `title` falling back to its url), then the label stored on the reference (`title`), then the raw `url`/`targetId`. Never null and never invented, for every targetType and for dangling refs alike. `target.display` is the narrower structured form: it exists only on the resolved branch."}},"required":["target","display"]}]},"ProjectHydrated":{"allOf":[{"$ref":"#/components/schemas/Project"},{"type":"object","properties":{"plan":{"type":"array","items":{"$ref":"#/components/schemas/Task"},"description":"The project's ordered task plan."},"refs":{"type":"array","items":{"$ref":"#/components/schemas/HydratedRef"},"description":"The project's hydrated references."},"progress":{"$ref":"#/components/schemas/ProjectProgress"},"lastActivityAt":{"type":"string","format":"date-time","description":"Newest of the project and plan updatedAt timestamps."},"nextAction":{"oneOf":[{"$ref":"#/components/schemas/Task"},{"type":"null"}],"description":"The first incomplete, non-archived task in the plan by position - the GTD next action. Null when every task is done or the plan is empty. Computed per read; never stored."}},"required":["plan","refs","progress","lastActivityAt","nextAction"]}]},"PlanPosition":{"type":"object","properties":{"after":{"type":"string","minLength":1,"description":"Place after this task."},"before":{"type":"string","minLength":1,"description":"Place before this task."}},"description":"Neighbor task IDs bounding the insertion point in a project plan; omit both (or send {}) to append. Never a raw position string."},"RefPosition":{"type":"object","properties":{"after":{"type":"string","minLength":1,"description":"Place after this ref."},"before":{"type":"string","minLength":1,"description":"Place before this ref."}},"description":"Neighbor ref IDs bounding the insertion point within a container; omit both to append."},"Area":{"type":"object","properties":{"id":{"type":"string"},"userId":{"type":"string"},"name":{"type":"string"},"description":{"type":["string","null"]},"isArchived":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","userId","name","isArchived","createdAt","updatedAt"]},"AreaRollupSource":{"type":"object","properties":{"areaId":{"type":"string"},"areaName":{"type":"string"},"members":{"type":"array","items":{"$ref":"#/components/schemas/HydratedRef"},"description":"Members the source sub-area contributes to the rollup."}},"required":["areaId","areaName","members"]},"AreaContents":{"allOf":[{"$ref":"#/components/schemas/Area"},{"type":"object","properties":{"members":{"type":"array","items":{"$ref":"#/components/schemas/HydratedRef"},"description":"The area's DIRECT non-area members (hydrated)."},"subAreas":{"type":"array","items":{"$ref":"#/components/schemas/HydratedRef"},"description":"The area's DIRECT area→area (within) links (hydrated)."},"rolledUp":{"type":"array","items":{"$ref":"#/components/schemas/AreaRollupSource"},"description":"Members contributed by nested sub-areas, per source. Empty for depth=direct; computed at read time, never stored."},"counts":{"type":"object","properties":{"direct":{"type":"integer","description":"Count of direct members (backs the `directly N` label)."},"rolledUp":{"type":"integer","description":"Count of members rolled up from sub-areas (backs the `via M` label)."}},"required":["direct","rolledUp"]}},"required":["members","subAreas","rolledUp","counts"]}]},"AgentDocument":{"type":"object","properties":{"id":{"type":"string"},"ownerType":{"type":"string","enum":["user"]},"ownerId":{"type":"string"},"createdByAgentId":{"type":["string","null"],"description":"Agent that CREATED the document. Set on insert and never changed — not by an overwrite from another agent, not by delete/restore."},"lastModifiedByAgentId":{"type":["string","null"],"description":"Agent that last changed content or title. Unchanged by an unchanged (no-op) write and by delete/restore."},"title":{"type":"string"},"path":{"type":"string"},"storageBackend":{"type":"string","enum":["db"]},"contentType":{"type":"string","description":"IANA media type of the stored document. Always \"text/markdown\" today; binary types arrive with the object-storage tail. Response-only — the write endpoint does not accept it."},"content":{"type":["string","null"]},"storageKey":{"type":["string","null"]},"contentHash":{"type":["string","null"]},"byteSize":{"type":["integer","null"]},"metadata":{"type":["object","null"],"additionalProperties":true,"description":"Structured metadata PARSED from the document's leading YAML front matter, refreshed on every write. Read-only and derived — there is no field to set it with, deliberately: the front-matter block in content is the single source, so a pull returns exactly the bytes that were pushed and there is no second channel to disagree with them. Write a block to attach metadata; remove the block and this goes back to null on the next write. null means the document has no front matter, or has a block that did not parse (unterminated, invalid YAML, or not a mapping) — the two are not distinguished. The body is stored untouched either way. Conventional keys, not enforced and not the only ones allowed: status, type, and tags (an array). Filter on any of them with the where parameter on GET /agent-drive and POST /search/documents."},"archivedAt":{"type":["string","null"],"format":"date-time","description":"Non-null when the document has been deleted (recoverable). Archived documents are absent from the default list and from GET /agent-drive/{id}."},"visibility":{"type":"string","enum":["private","public","authenticated"],"description":"Who can open the document at its /agent-drive/{id} URL. READ-ONLY here: private is the default, and changing it is a separate, separately-scoped request — PUT /agent-drive/{id}/visibility with the share scope, or the owner in the web app. The write path neither accepts nor honours this field, so publishing is never a side effect of saving content."},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","ownerType","ownerId","title","path","storageBackend","contentType","visibility","createdAt","updatedAt"]},"SharedByUser":{"type":"object","properties":{"userId":{"type":"string"},"name":{"type":["string","null"],"description":"The owner's display name, their email when no name is set, or null."}},"required":["userId"]},"AccessedLibraryEntry":{"type":"object","properties":{"owner":{"$ref":"#/components/schemas/SharedByUser","description":"The document's owner. Named because on somebody else's document, whose it is identifies it — not where it sits in their Agent Drive."},"via":{"type":"string","enum":["link","grant"],"description":"How you got in the last time you opened it. \"link\" covers both public and signed-in-only documents — from the reader's side they are one story, and the tier is the owner's to change at any moment. \"grant\" means the owner named you specifically."},"byAgent":{"type":["string","null"],"description":"The agent that READ it most recently, by display name, or null when no agent has. Opening the document yourself no longer clears this: your own opens and your agents’ reads are tracked as separate channels, so both facts survive independently."},"firstAccessedAt":{"type":"string","format":"date-time"},"lastAccessedAt":{"type":"string","format":"date-time","description":"The most recent access in EITHER channel — the sort key for this listing. Use the per-channel timestamps below to say WHO; this one only says when anything last happened."},"lastHumanAccessAt":{"type":["string","null"],"format":"date-time","description":"When YOU last opened it in a browser, or null if you never have (an agent may have read it without you looking)."},"humanAccessCount":{"type":"integer"},"lastAgentAccessAt":{"type":["string","null"],"format":"date-time","description":"When one of your agents last read it through the API, or null if none has. Independent of your own opens — reading it yourself does not reset or clear this."},"agentAccessCount":{"type":"integer"}},"required":["owner","via","byAgent","firstAccessedAt","lastAccessedAt","lastHumanAccessAt","humanAccessCount","lastAgentAccessAt","agentAccessCount"]},"AgentDocumentSummary":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"path":{"type":"string"},"byteSize":{"type":["integer","null"]},"sharedBy":{"$ref":"#/components/schemas/SharedByUser","description":"Present ONLY on a document another user shared with you (scope=shared or scope=all). Absent on your own documents — its presence is the signal that this document is not yours to overwrite, and that access ends when the owner revokes it. The path shown is the path in THEIR Agent Drive, not a path in yours."},"accessed":{"$ref":"#/components/schemas/AccessedLibraryEntry","description":"Present ONLY on a library row (scope=accessed). Says whose document this is, how you got in, and which of your agents last opened it. Distinct from sharedBy on purpose: sharedBy means somebody chose to give you this document, while this can just as easily be a public link one of your agents followed, which its owner knows nothing about."},"contentType":{"type":"string","description":"IANA media type. Always \"text/markdown\" today."},"createdByAgentId":{"type":["string","null"]},"lastModifiedByAgentId":{"type":["string","null"]},"archivedAt":{"type":["string","null"],"format":"date-time"},"metadata":{"type":["object","null"],"additionalProperties":true,"description":"Structured metadata PARSED from the document's leading YAML front matter, refreshed on every write. Read-only and derived — there is no field to set it with, deliberately: the front-matter block in content is the single source, so a pull returns exactly the bytes that were pushed and there is no second channel to disagree with them. Write a block to attach metadata; remove the block and this goes back to null on the next write. null means the document has no front matter, or has a block that did not parse (unterminated, invalid YAML, or not a mapping) — the two are not distinguished. The body is stored untouched either way. Conventional keys, not enforced and not the only ones allowed: status, type, and tags (an array). Filter on any of them with the where parameter on GET /agent-drive and POST /search/documents."},"visibility":{"type":"string","enum":["private","public","authenticated"],"description":"Who can open the document at its /agent-drive/{id} URL. READ-ONLY here: private is the default, and changing it is a separate, separately-scoped request — PUT /agent-drive/{id}/visibility with the share scope, or the owner in the web app. The write path neither accepts nor honours this field, so publishing is never a side effect of saving content."},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","title","path","contentType","visibility","createdAt","updatedAt"]},"AgentDocumentFolder":{"type":"object","properties":{"prefix":{"type":"string","description":"Full canonical prefix including its trailing \"/\" — pass it back as pathPrefix to list the folder."},"name":{"type":"string","description":"This level’s segment only, for display."},"documentCount":{"type":"integer","description":"Documents anywhere beneath the folder, not just directly inside it."}},"required":["prefix","name","documentCount"]},"DocumentPage":{"type":"object","properties":{"limit":{"type":"integer"},"offset":{"type":"integer"},"total":{"type":"integer","description":"Documents matching the filter, ignoring limit/offset."},"hasMore":{"type":"boolean"}},"required":["limit","offset","total","hasMore"]},"WriteDocumentRequest":{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":255,"description":"The document's LABEL — lists, the breadcrumb, link previews, the reader's file header. Never printed as a heading: write the heading in content, and do not repeat the title there."},"path":{"type":"string","minLength":1,"maxLength":1024,"description":"Relative logical path/key, and the upsert key — re-pushing the same path replaces the document. CANONICALIZED on write, so the stored path may differ from what you send: \"\\\" becomes \"/\", empty and \".\" segments are dropped, and Unicode is normalized to NFC. Rejected: absolute paths (leading \"/\" or a drive letter), \"..\" segments, control characters, more than 16 segments, a segment over 255 bytes, over 1024 bytes total (measured as UTF-8, not characters), and — for portability to Windows and macOS sync targets — the characters < > : \" | ? * and the reserved device names CON, PRN, AUX, NUL, COM1-9, LPT1-9. Paths are matched CASE-INSENSITIVELY but stored case-preserving: pushing \"Notes/x.md\" over an existing \"notes/x.md\" replaces that document and keeps its original casing. The response returns the stored document, so the canonical path is always observable."},"content":{"type":"string","maxLength":1000000,"description":"Markdown source (~1 MB ceiling), stored byte-for-byte. A leading YAML front-matter block (\"---\" on the FIRST line, fields, \"---\") is parsed into metadata on every write and is what where filters on — there is no separate metadata field, on purpose. The block stays in the content and renders as a metadata row, not as body text."}},"required":["title","path","content"]},"SetDocumentVisibilityRequest":{"type":"object","properties":{"visibility":{"type":"string","enum":["private","public","authenticated"],"description":"Who can open the document at its /agent-drive/{id} URL. \"private\" is owner-only and is how you REVOKE; \"public\" admits anyone with the link, signed in or not; \"authenticated\" admits any signed-in TeamYou user (signup is open, so this identifies viewers rather than restricting them — it is not an org boundary). Required, with no default: a body that omitted it and defaulted to something would turn a malformed request into an accidental publication."}},"required":["visibility"]},"DocumentGrantRequest":{"type":"object","properties":{"email":{"type":"string","description":"The recipient's email address. If it belongs to a TeamYou account they get access immediately; if not, an invite is stored and binds when they sign up with that (verified) address — and this endpoint tells you neither which happened, deliberately, so it can never be used to check whether an address has an account."}},"required":["email"]},"McpServerInfo":{"type":"object","properties":{"name":{"type":"string"},"url":{"type":"string"},"transport":{"type":"string"}},"required":["name"]},"DeclaredSkill":{"type":"object","properties":{"name":{"type":"string"},"version":{"type":"string"}},"required":["name"]},"RegisteredAgent":{"type":"object","properties":{"id":{"type":"string"},"slug":{"type":"string"},"displayName":{"type":["string","null"]},"kind":{"type":"string","enum":["claude","codex","perplexity","openclaw","other"]},"status":{"type":"string","enum":["pending","active"]},"registeredAt":{"type":"string","format":"date-time"}},"required":["id","slug","kind","status","registeredAt"]},"AgentIdentity":{"type":"object","properties":{"id":{"type":"string"},"slug":{"type":"string"},"displayName":{"type":["string","null"]},"kind":{"type":"string","enum":["claude","codex","perplexity","openclaw","other"]},"status":{"type":"string","enum":["pending","active"]},"registeredAt":{"type":"string","format":"date-time"},"lastSeenModel":{"type":["string","null"]},"lastSeenSkillVersion":{"type":["string","null"]},"lastSeenSkillVariant":{"type":["string","null"]},"mcpServers":{"type":["array","null"],"items":{"$ref":"#/components/schemas/McpServerInfo"}},"declaredSkills":{"type":["array","null"],"items":{"$ref":"#/components/schemas/DeclaredSkill"}},"a2aCard":{"type":["object","null"],"additionalProperties":true},"lastSeenAt":{"type":["string","null"],"format":"date-time"}},"required":["id","slug","kind","status","registeredAt"]},"Preferences":{"type":"object","properties":{"preferences":{"type":"object","properties":{"defaultModels":{"type":"object","properties":{"language":{"type":"string"},"embedding":{"type":"string"},"image":{"type":["string","null"]},"video":{"type":["string","null"]}},"required":["language","embedding"]},"aiUpdateEnabled":{"type":"boolean"},"aiDeleteEnabled":{"type":"boolean"},"aiShareEnabled":{"type":"boolean"},"dismissedCards":{"type":"object","additionalProperties":{"type":"string","format":"date-time"}}},"required":["defaultModels","aiUpdateEnabled","aiDeleteEnabled","aiShareEnabled","dismissedCards"]},"hasStoredPreferences":{"type":"boolean"}},"required":["preferences","hasStoredPreferences"]},"CheckTasksConfig":{"type":"object","properties":{"notifyOnOverdue":{"type":"boolean"},"notifyOnDueSoon":{"type":"boolean"},"dueSoonHours":{"type":"integer","minimum":1},"deliveryChannel":{"type":"string","enum":["in_app","email","openclaw"]}}},"OpenClawCommandConfig":{"type":"object","properties":{"agentId":{"type":"string"},"prompt":{"type":"string","minLength":1},"maxTokens":{"type":"integer","minimum":1}},"required":["prompt"]},"CustomWebhookConfig":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"method":{"type":"string","enum":["GET","POST","PUT","PATCH","DELETE"]},"headers":{"type":"object","additionalProperties":{"type":"string"}},"body":{},"timeoutMs":{"type":"integer","minimum":1}},"required":["url"]},"ActionConfig":{"oneOf":[{"$ref":"#/components/schemas/CheckTasksConfig"},{"$ref":"#/components/schemas/OpenClawCommandConfig"},{"$ref":"#/components/schemas/CustomWebhookConfig"}],"description":"Shape depends on actionType: check_tasks (stored and echoed as its deprecated spelling) | openclaw_command | custom_webhook."},"Heartbeat":{"type":"object","properties":{"id":{"type":"string"},"userId":{"type":"string"},"status":{"type":"string","enum":["disabled","active","paused","error"]},"frequencyMinutes":{"type":"integer"},"workflowRunId":{"type":["string","null"]},"lastHeartbeatAt":{"type":["string","null"],"format":"date-time"},"nextHeartbeatAt":{"type":["string","null"],"format":"date-time"},"errorMessage":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","userId","status","frequencyMinutes","createdAt","updatedAt"]},"HeartbeatAction":{"type":"object","properties":{"id":{"type":"string"},"userId":{"type":"string"},"heartbeatId":{"type":"string"},"actionType":{"type":"string","enum":["check_todos","execute_routine","openclaw_command","custom_webhook"]},"name":{"type":"string"},"description":{"type":["string","null"]},"isEnabled":{"type":"boolean"},"priority":{"type":"integer"},"config":{"type":["object","null"],"additionalProperties":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","userId","heartbeatId","actionType","name","isEnabled","priority","createdAt","updatedAt"]},"HeartbeatWithActions":{"allOf":[{"$ref":"#/components/schemas/Heartbeat"},{"type":"object","properties":{"actions":{"type":"array","items":{"$ref":"#/components/schemas/HeartbeatAction"}}},"required":["actions"]}]},"HeartbeatActionResult":{"type":"object","properties":{"actionId":{"type":"string"},"actionType":{"type":"string"},"name":{"type":"string"},"status":{"type":"string","enum":["success","error","skipped"]},"startedAt":{"type":"string"},"completedAt":{"type":"string"},"summary":{"type":"string"},"errorMessage":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["actionId","actionType","name","status","startedAt","completedAt"]},"HeartbeatExecution":{"type":"object","properties":{"id":{"type":"string"},"userId":{"type":"string"},"heartbeatId":{"type":"string"},"status":{"type":"string","enum":["running","success","error"]},"startedAt":{"type":"string","format":"date-time"},"completedAt":{"type":["string","null"],"format":"date-time"},"actionResults":{"type":["array","null"],"items":{"$ref":"#/components/schemas/HeartbeatActionResult"}},"summary":{"type":["string","null"]},"errorMessage":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","userId","heartbeatId","status","startedAt","createdAt","updatedAt"]},"HeartbeatExecutionResult":{"type":"object","properties":{"executionId":{"type":"string"},"status":{"type":"string","enum":["running","success","error"]},"startedAt":{"type":"string","format":"date-time"},"completedAt":{"type":"string","format":"date-time"},"summary":{"type":"string"},"actionResults":{"type":"array","items":{"$ref":"#/components/schemas/HeartbeatActionResult"}},"errorMessage":{"type":"string"}},"required":["executionId","status","startedAt","completedAt","summary","actionResults"]},"ScheduledAction":{"type":"object","properties":{"id":{"type":"string"},"userId":{"type":"string"},"name":{"type":"string"},"status":{"type":"string","enum":["active","paused","disabled","completed","error"]},"scheduleType":{"type":"string","enum":["one_time","cron"]},"runAt":{"type":["string","null"],"format":"date-time"},"cronExpr":{"type":["string","null"]},"timezone":{"type":["string","null"]},"actionType":{"type":"string","enum":["check_todos","execute_routine","openclaw_command","custom_webhook"]},"actionConfig":{"type":["object","null"],"additionalProperties":true},"workflowRunId":{"type":["string","null"]},"slot":{"type":"integer"},"lastRunAt":{"type":["string","null"],"format":"date-time"},"nextRunAt":{"type":["string","null"],"format":"date-time"},"lastResultStatus":{"type":["string","null"],"enum":["success","error","skipped",null]},"lastErrorMessage":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","userId","name","status","scheduleType","actionType","slot","createdAt","updatedAt"]},"ScheduledActionExecution":{"type":"object","properties":{"id":{"type":"string"},"scheduledActionId":{"type":"string"},"userId":{"type":"string"},"workflowRunId":{"type":["string","null"]},"scheduledFor":{"type":"string","format":"date-time"},"startedAt":{"type":"string","format":"date-time"},"completedAt":{"type":["string","null"],"format":"date-time"},"status":{"type":"string","enum":["running","success","error","skipped"]},"summary":{"type":["string","null"]},"errorMessage":{"type":["string","null"]},"actionResult":{"oneOf":[{"$ref":"#/components/schemas/HeartbeatActionResult"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","scheduledActionId","userId","scheduledFor","startedAt","status","createdAt","updatedAt"]},"AgentInstruction":{"type":"object","properties":{"id":{"type":"string"},"targetApiKeyId":{"type":"string"},"createdByApiKeyId":{"type":["string","null"]},"anchorType":{"type":["string","null"],"enum":["topic","todo","drive",null]},"anchorId":{"type":["string","null"]},"body":{"type":"string"},"status":{"type":"string","enum":["pending","delivered","acknowledged"]},"createdAt":{"type":"string","format":"date-time"},"deliveredAt":{"type":["string","null"],"format":"date-time"},"acknowledgedAt":{"type":["string","null"],"format":"date-time"},"archivedAt":{"type":["string","null"],"format":"date-time"}},"required":["id","targetApiKeyId","createdByApiKeyId","anchorType","anchorId","body","status","createdAt","deliveredAt","acknowledgedAt","archivedAt"]},"CreateTopicRequest":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":255},"oneSentenceDescription":{"type":"string","minLength":1,"maxLength":1000},"summary":{"type":"string","maxLength":5000},"edges":{"type":"array","items":{"type":"object","properties":{"targetTopicId":{"type":"string","minLength":1},"label":{"type":"string","minLength":1,"maxLength":255},"mirrorLabel":{"type":"string","minLength":1,"maxLength":255}},"required":["targetTopicId","label"]},"maxItems":50,"description":"Optional relationships to create atomically with the topic (max 50)."}},"required":["name","oneSentenceDescription"]},"UpdateTopicRequest":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":255},"oneSentenceDescription":{"type":"string","minLength":1,"maxLength":1000},"summary":{"type":"string","maxLength":5000}},"minProperties":1,"description":"All fields optional; at least one must be provided."},"AddDetailsRequest":{"type":"object","properties":{"details":{"type":"array","items":{"type":"object","properties":{"detail":{"type":"string","minLength":1,"maxLength":5000}},"required":["detail"]},"minItems":1,"maxItems":50}},"required":["details"]},"UpdateDetailRequest":{"type":"object","properties":{"detail":{"type":"string","minLength":1,"maxLength":5000}},"required":["detail"]},"CreateEdgeRequest":{"type":"object","properties":{"sourceTopicId":{"type":"string","minLength":1},"targetTopicId":{"type":"string","minLength":1},"label":{"type":"string","minLength":1,"maxLength":255},"mirrorLabel":{"type":"string","minLength":1,"maxLength":255}},"required":["sourceTopicId","targetTopicId","label"]},"PatchEdgeRequest":{"type":"object","properties":{"label":{"type":"string","minLength":1,"maxLength":255},"mirrorLabel":{"type":"string","minLength":1,"maxLength":255}},"minProperties":1,"description":"At least one of label or mirrorLabel must be provided."},"SearchRequest":{"type":"object","properties":{"query":{"type":"string","minLength":1,"maxLength":500},"precision":{"type":"string","enum":["high","medium","low"],"default":"medium"}},"required":["query"]},"SearchDocumentsRequest":{"type":"object","properties":{"query":{"type":"string","minLength":1,"maxLength":500},"precision":{"type":"string","enum":["high","medium","low"],"default":"medium"},"pathPrefix":{"type":"string","description":"Scope the search to a folder, e.g. \"memory/\". Canonicalized exactly the way a written path is and matched case-insensitively, so the prefix you send does not have to be the stored form. A trailing \"/\" is optional and \"memory\" cannot match a sibling document named \"memory-archive.md\". Omit to search all of Agent Drive."},"limit":{"type":"integer","minimum":1,"maximum":50,"description":"Maximum documents to return. Defaults to the precision level’s own cap (high 15, medium 20, low 25); a larger value also widens how many candidates are retrieved."},"scope":{"type":"string","enum":["mine","shared","all"],"default":"mine","description":"Which documents to search. mine (default) = only your own, exactly as this endpoint behaved before scope existed. shared = ONLY documents other people have granted to you — use this to answer \"what did someone share with me about X\" without wading through your own Agent Drive documents. all = both, fused into one ranked list. Shared-in hits come back with source \"drive-shared\" and a sharedBy object. Access is checked on every request, so a revoked document is gone from the very next search."},"where":{"type":"array","items":{"type":"string"},"description":"Repeat (query) or list (body) to AND up to 10 clauses. Split on the FIRST colon, so a value may contain colons: key is letters/digits/_/- up to 64 chars, value up to 200. A clause matches a field equal to the value OR an array containing it, so tags:research finds \"tags: [research, ops]\"; a value that is exactly a number or true/false is also tried typed, so priority:3 finds an unquoted 3. No ranges, no OR, no nested paths. Filtering only NARROWS what the scope returns. Not supported with scope=accessed."}},"required":["query"]},"SearchAllRequest":{"type":"object","properties":{"query":{"type":"string","maxLength":500,"default":"","description":"What to look for. Empty only with orderBy recency."},"types":{"type":"array","items":{"type":"string","enum":["topic","detail","task","project","area","document"]},"minItems":1,"uniqueItems":true,"description":"Only these types. Omit for all."},"scope":{"type":"string","enum":["mine","shared","all"],"default":"mine","description":"Documents only: yours, shared with you, or both."},"precision":{"type":"string","enum":["high","medium","low"],"default":"medium"},"orderBy":{"type":"string","enum":["relevance","recency"],"default":"relevance"},"limit":{"type":"integer","minimum":1,"maximum":50,"default":20}}},"SearchRelatedRequest":{"type":"object","properties":{"type":{"type":"string","enum":["topic","detail","task","project","area","document"]},"id":{"type":"string","minLength":1,"maxLength":200},"limit":{"type":"integer","minimum":1,"maximum":50,"default":20}},"required":["type","id"]},"CreateTaskRequest":{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":500},"status":{"type":"string","enum":["todo","done"]},"priority":{"type":"string","enum":["high","medium","low","none"]},"dueDate":{"type":"string","format":"date-time"},"topicId":{"type":"string","minLength":1},"projectId":{"type":"string","minLength":1,"description":"File the new task into this project's plan."},"position":{"$ref":"#/components/schemas/PlanPosition","description":"Where in the plan to place it (requires projectId); omit to append."}},"required":["title"]},"UpdateTaskRequest":{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":500},"status":{"type":"string","enum":["todo","done"]},"priority":{"type":"string","enum":["high","medium","low","none"]},"dueDate":{"type":["string","null"],"format":"date-time"},"isArchived":{"type":"boolean"},"topicId":{"type":["string","null"],"minLength":1},"projectId":{"type":["string","null"],"minLength":1,"description":"Assign/move into this project; null removes from its project."},"position":{"$ref":"#/components/schemas/PlanPosition","description":"Reorder within the project plan; with projectId, positions on assign."}},"minProperties":1,"description":"At least one field required. dueDate/topicId/projectId accept null to clear/unlink/remove-from-project."},"InlineProjectTask":{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":500},"status":{"type":"string","enum":["todo","done"]},"priority":{"type":"string","enum":["high","medium","low","none"]},"dueDate":{"type":"string","format":"date-time"},"topicId":{"type":"string","minLength":1}},"required":["title"],"description":"A plan item created with its project. Mirrors CreateTaskRequest without projectId (the new project) or position (the array index is the plan order)."},"InlineProjectRef":{"oneOf":[{"type":"object","properties":{"targetType":{"type":"string","enum":["topic","task","todo","project","doc"],"x-deprecated-enum":["todo"]},"targetId":{"type":"string","minLength":1},"title":{"type":["string","null"],"maxLength":1000}},"required":["targetType","targetId"]},{"type":"object","properties":{"targetType":{"type":"string","enum":["url"]},"url":{"type":"string","format":"uri","maxLength":2000},"title":{"type":["string","null"],"maxLength":1000}},"required":["targetType","url"]}],"description":"A reference created with its project. FLAT: each entry IS the target object itself - it is the AddProjectRefRequest `target` union verbatim (same accepted targetType set: topic|task|project|doc|url; `area` and `entity` are rejected), WITHOUT the `target` wrapper and without a position (the array index is the order). Send `{\"targetType\":\"url\",\"url\":\"https://example.com/spec\",\"title\":\"Spec\"}`, NOT `{\"target\":{\"targetType\":\"url\",...}}` - the wrapper is the refs-add body shape and 400s here because the discriminator ends up one level too deep. For a `url` target the optional `title` IS the display name, so pass it when you have one. Example refs array: `[{\"targetType\":\"url\",\"url\":\"https://example.com/spec\",\"title\":\"Spec\"},{\"targetType\":\"topic\",\"targetId\":\"abc123\"}]`."},"CreateProjectRequest":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":255},"goal":{"type":["string","null"],"maxLength":5000},"status":{"type":"string","enum":["active","waiting","done","archived"]},"waitingOn":{"type":["string","null"],"maxLength":1000,"description":"Who or what the work is blocked on — a short name or phrase (\"Bill\", \"legal review\"), not a status update. Both project surfaces render it in a narrow fixed-width slot and truncate what does not fit, so prose written here is stored but never read. Meaningful when status=waiting, though not enforced against it: a project can carry this while active."},"preset":{"type":["string","null"],"maxLength":255,"description":"Reserved; unused in v1."},"notes":{"type":["string","null"],"maxLength":50000,"description":"Narrative markdown body: what this project is, in prose. Stored verbatim."},"dueDate":{"type":["string","null"],"format":"date","pattern":"^\\d{4}-\\d{2}-\\d{2}$","description":"Calendar day (YYYY-MM-DD) to aim at. A soft target only. Not a date-time instant, unlike a task dueDate."},"tasks":{"type":"array","items":{"$ref":"#/components/schemas/InlineProjectTask"},"maxItems":200,"description":"Optional plan to create with the project. Array order IS the plan order. Written in the same transaction as the project: all-or-nothing, so a failure anywhere creates nothing. Create-only - there is no upsert or dedupe, so two identical calls create two projects."},"todos":{"type":"array","items":{"$ref":"#/components/schemas/InlineProjectTask"},"maxItems":200,"deprecated":true,"description":"Deprecated spelling of `tasks`; send `tasks` instead. Accepted on its own, or beside `tasks` when both hold identical values - both present and different is a 400 validation_error naming both."},"refs":{"type":"array","items":{"$ref":"#/components/schemas/InlineProjectRef"},"maxItems":100,"description":"Optional references to create with the project. Each entry is a FLAT target object (`{\"targetType\":\"url\",\"url\":\"https://example.com/spec\",\"title\":\"Spec\"}`), NOT the refs-add `{\"target\":{...}}` wrapper. Array order IS the order. Same transaction and all-or-nothing semantics as `tasks`. Naming the same target twice in one array is a 400. Refs cannot target the tasks created in the same call (those ids do not exist yet) - add them afterwards with refs-add."}},"required":["name"]},"UpdateProjectRequest":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":255},"goal":{"type":["string","null"],"maxLength":5000},"status":{"type":"string","enum":["active","waiting","done","archived"]},"waitingOn":{"type":["string","null"],"maxLength":1000,"description":"Who or what the work is blocked on — a short name or phrase (\"Bill\", \"legal review\"), not a status update. Both project surfaces render it in a narrow fixed-width slot and truncate what does not fit, so prose written here is stored but never read. Meaningful when status=waiting, though not enforced against it: a project can carry this while active."},"preset":{"type":["string","null"],"maxLength":255},"notes":{"type":["string","null"],"maxLength":50000,"description":"Narrative markdown body: what this project is, in prose. Stored verbatim."},"dueDate":{"type":["string","null"],"format":"date","pattern":"^\\d{4}-\\d{2}-\\d{2}$","description":"Calendar day (YYYY-MM-DD) to aim at. A soft target only. Not a date-time instant, unlike a task dueDate."}},"minProperties":1,"description":"All fields optional; at least one must be provided. goal/waitingOn/preset/notes/dueDate accept null to clear. completedAt is server-owned and is ignored if sent."},"AddProjectRefRequest":{"type":"object","properties":{"target":{"oneOf":[{"type":"object","properties":{"targetType":{"type":"string","enum":["topic","task","todo","project","doc"],"x-deprecated-enum":["todo"]},"targetId":{"type":"string","minLength":1},"title":{"type":["string","null"],"maxLength":1000}},"required":["targetType","targetId"]},{"type":"object","properties":{"targetType":{"type":"string","enum":["url"]},"url":{"type":"string","format":"uri","maxLength":2000},"title":{"type":["string","null"],"maxLength":1000}},"required":["targetType","url"]}],"description":"The reference target. `url` targets carry a url; all others carry a targetId. Accepted targetType: topic|task|project|doc|url — `area` and `entity` are rejected by the projects API."},"position":{"$ref":"#/components/schemas/RefPosition","description":"Where in the ref list to place it; omit to append."}},"required":["target"]},"AddProjectDocumentRequest":{"type":"object","properties":{"document":{"$ref":"#/components/schemas/WriteDocumentRequest","description":"The markdown document to write (upsert-by-path), identical to the POST /agent-drive body."},"title":{"type":["string","null"],"maxLength":1000,"description":"Optional label stored on the REFERENCE (not the document) and echoed back as `ref.title`. It does NOT change the hydrated `display`, which always resolves from the live document title (falling back to its path). Defaults to null."},"position":{"$ref":"#/components/schemas/RefPosition","description":"Where in the project's ref list to place it; omit to append."}},"required":["document"]},"ReorderRefRequest":{"type":"object","properties":{"after":{"type":"string","minLength":1,"description":"Place after this ref."},"before":{"type":"string","minLength":1,"description":"Place before this ref."}},"minProperties":1,"description":"At least one of after/before (neighbor ref IDs) must be provided."},"CreateAreaRequest":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":255},"description":{"type":["string","null"],"maxLength":5000},"isArchived":{"type":"boolean"}},"required":["name"]},"UpdateAreaRequest":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":255},"description":{"type":["string","null"],"maxLength":5000},"isArchived":{"type":"boolean"}},"minProperties":1,"description":"All fields optional; at least one must be provided. description accepts null to clear."},"AddAreaRefRequest":{"type":"object","properties":{"target":{"oneOf":[{"type":"object","properties":{"targetType":{"type":"string","enum":["topic","task","todo","project","area","doc"],"x-deprecated-enum":["todo"]},"targetId":{"type":"string","minLength":1},"title":{"type":["string","null"],"maxLength":1000}},"required":["targetType","targetId"]},{"type":"object","properties":{"targetType":{"type":"string","enum":["url"]},"url":{"type":"string","format":"uri","maxLength":2000},"title":{"type":["string","null"],"maxLength":1000}},"required":["targetType","url"]}],"description":"The reference target. `url` targets carry a url; all others carry a targetId. Accepted targetType: topic|task|project|area|doc|url. An `area` target is `within` nesting — routed through the cycle guard; a nest that would close a cycle returns 409."},"position":{"$ref":"#/components/schemas/RefPosition","description":"Where in the ref list to place it; omit to append. Not applicable to an `area` nest (appended)."}},"required":["target"]},"RegisterAgentRequest":{"type":"object","properties":{"slug":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[a-zA-Z0-9][a-zA-Z0-9 _.-]*$","description":"Required in caller-declared mode. Stable identity key (user, slug). Idempotent on re-register."},"kind":{"type":"string","enum":["claude","codex","perplexity","openclaw","other"],"description":"Caller-declared mode only."},"displayName":{"type":"string","minLength":1,"maxLength":120,"description":"Caller-declared mode only."},"openclawInstanceId":{"type":"string","minLength":1,"maxLength":255,"description":"Required in provisioned OpenClaw mode. The authenticated key must be recorded on this clawctl instance; slug, kind, and displayName are then derived or preserved server-side."},"model":{"type":"string","minLength":1,"maxLength":120},"mcpServers":{"type":"array","items":{"$ref":"#/components/schemas/McpServerInfo"},"maxItems":50},"declaredSkills":{"type":"array","items":{"$ref":"#/components/schemas/DeclaredSkill"},"maxItems":200},"a2aCard":{"type":"object","additionalProperties":true}},"description":"Exactly one identity mode is required: slug, or openclawInstanceId. Provisioned OpenClaw mode rejects slug, kind, and displayName.","oneOf":[{"required":["slug"],"not":{"required":["openclawInstanceId"]}},{"required":["openclawInstanceId"],"not":{"anyOf":[{"required":["slug"]},{"required":["kind"]},{"required":["displayName"]}]}}]},"HeartbeatUpsertRequest":{"type":"object","properties":{"status":{"type":"string","enum":["disabled","active","paused","error"]},"frequencyMinutes":{"type":"integer","minimum":1}},"description":"Both optional; empty body is accepted (upsert with defaults)."},"HeartbeatActionCreateRequest":{"type":"object","properties":{"heartbeatId":{"type":"string","minLength":1},"actionType":{"type":"string","enum":["check_tasks","check_todos","openclaw_command","custom_webhook"],"x-deprecated-enum":["check_todos"]},"name":{"type":"string","minLength":1},"description":{"type":["string","null"]},"isEnabled":{"type":"boolean"},"priority":{"type":"integer"},"config":{"$ref":"#/components/schemas/ActionConfig","description":"Required for openclaw_command/custom_webhook; optional for check_tasks."}},"required":["actionType","name"]},"HeartbeatActionUpdateRequest":{"type":"object","properties":{"actionType":{"type":"string","enum":["check_tasks","check_todos","openclaw_command","custom_webhook"],"x-deprecated-enum":["check_todos"]},"name":{"type":"string","minLength":1},"description":{"type":"string"},"isEnabled":{"type":"boolean"},"priority":{"type":"integer"},"config":{"$ref":"#/components/schemas/ActionConfig"}},"minProperties":1,"description":"At least one field required."},"ScheduledActionCreateRequest":{"type":"object","properties":{"name":{"type":"string","minLength":1},"status":{"type":"string","enum":["active","paused","disabled"]},"scheduleType":{"type":"string","enum":["one_time","cron"]},"runAt":{"type":["string","null"],"format":"date-time","description":"Required for one_time; minute precision; must be in the future."},"cronExpr":{"type":["string","null"],"description":"Required for cron."},"timezone":{"type":["string","null"],"description":"IANA tz; required for cron."},"actionType":{"type":"string","enum":["check_tasks","check_todos","openclaw_command","custom_webhook"],"x-deprecated-enum":["check_todos"]},"actionConfig":{"oneOf":[{"$ref":"#/components/schemas/ActionConfig"},{"type":"null"}]}},"required":["name","scheduleType","actionType"]},"ScheduledActionUpdateRequest":{"type":"object","properties":{"name":{"type":"string","minLength":1},"status":{"type":"string","enum":["active","paused","disabled"]},"scheduleType":{"type":"string","enum":["one_time","cron"]},"runAt":{"type":["string","null"],"format":"date-time"},"cronExpr":{"type":["string","null"]},"timezone":{"type":["string","null"]},"actionType":{"type":"string","enum":["check_tasks","check_todos","openclaw_command","custom_webhook"],"x-deprecated-enum":["check_todos"]},"actionConfig":{"oneOf":[{"$ref":"#/components/schemas/ActionConfig"},{"type":"null"}]}},"minProperties":1,"description":"At least one field required."},"AgentInstructionCreateRequest":{"type":"object","properties":{"targetApiKeyId":{"type":"string","minLength":1,"description":"The API key (agent) on this account to address. 404 if not found/owned."},"body":{"type":"string","minLength":1,"maxLength":8000},"anchorType":{"type":"string","enum":["topic","task","todo","drive"],"x-deprecated-enum":["todo"],"description":"Optional; must be paired with anchorId."},"anchorId":{"type":"string","minLength":1,"description":"Source PK for the anchor; must be paired with anchorType."}},"required":["targetApiKeyId","body"],"dependentRequired":{"anchorType":["anchorId"],"anchorId":["anchorType"]}}},"responses":{"ValidationError":{"description":"Validation error — invalid body, query, or path param (code: validation_error or invalid_json). `details` carries Zod field errors; PATCH /edges also adds `formErrors`.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}},"Unauthorized":{"description":"Missing, malformed, expired, or revoked API key (code: unauthorized).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}},"RateLimited":{"description":"Rate limit exceeded (code: rate_limit_exceeded). Includes Retry-After and X-RateLimit-* headers.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until the client may retry."},"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests in the window."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the window."},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets."}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}},"AgentGate":{"description":"Forbidden. One of: api_key_user_not_found (key belongs to a user absent from this environment); client_identification_required (no recognized X-TeamYou-Client; carries skill_install_url, registerUrl, docs_url; only when TEAMYOU_GATE_REQUIRE_IDENTIFIED_CLIENT); agent_not_registered (registerUrl, skill_install_url, docs_url); skill_update_required (required_version, install_url, docs_url; possibly Deprecation/Sunset headers); client_update_nudge (a soft, relent-able staleness nudge for an agentic client below the latest release when TEAMYOU_GATE_NAG_ENABLED is on; carries verified_version, required_version, upgrade_url, ack_url, ack_token, nag_interval, nag_acks_so_far, docs_url — upgrade to end it, or fetch ack_url to relent one call at a rising cost); insufficient_scope (the API key lacks this operation’s x-teamyou-scope; carries required_scope, granted_scopes, docs_url — NOT retryable: scopes are fixed at key creation, so create a new key with the required scope instead of retrying); or an AI-preference denial AI_UPDATE_DISABLED / AI_DELETE_DISABLED (requiredPreference). Scopes and AI preferences compose as AND — passing one does not bypass the other. Gate codes only apply when the corresponding env flag is enabled.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}},"AgentGateWithoutAIPreference":{"description":"Forbidden. One of: api_key_user_not_found (key belongs to a user absent from this environment); client_identification_required (no recognized X-TeamYou-Client; carries skill_install_url, registerUrl, docs_url; only when TEAMYOU_GATE_REQUIRE_IDENTIFIED_CLIENT); agent_not_registered (registerUrl, skill_install_url, docs_url); skill_update_required (required_version, install_url, docs_url; possibly Deprecation/Sunset headers); client_update_nudge (a soft, relent-able staleness nudge for an agentic client below the latest release when TEAMYOU_GATE_NAG_ENABLED is on; carries verified_version, required_version, upgrade_url, ack_url, ack_token, nag_interval, nag_acks_so_far, docs_url); or insufficient_scope (the API key lacks this operation’s x-teamyou-scope; carries required_scope, granted_scopes, docs_url — NOT retryable: scopes are fixed at key creation).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}},"SkillGate":{"description":"Forbidden. One of: api_key_user_not_found (key belongs to a user absent from this environment); skill_update_required (skill below TEAMYOU_GATE_MIN_SKILL_VERSION; carries required_version, install_url, docs_url, possibly Deprecation/Sunset headers); or instance_key_mismatch (openclawInstanceId does not own the authenticated key).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}},"ApiKeyForbidden":{"description":"Forbidden — api_key_user_not_found (the key belongs to a user absent from this environment).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}},"AckInvalid":{"description":"Bad request — ack_invalid (the ACK token is missing, malformed, already used, or was not issued to this key). Make a gated call to receive a fresh nag and token.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}},"NotFound":{"description":"Resource not found (code: not_found).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}},"Conflict":{"description":"Conflict — e.g. duplicate edge (same direction + label) or the scheduled-action slot limit reached (code: conflict).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}},"AgentIdentityConflict":{"description":"Conflict — the authenticated provisioned key is linked to an agent identity that cannot be safely reconciled (code: agent_identity_conflict).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}},"ServerError":{"description":"Internal server error (code: internal_error).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}}}}}