{"openapi":"3.1.0","info":{"title":"Kody API","version":"1.0.0","description":"HTTP API for a Kody account. Versioned under `/v1`; changes within v1 are additive. See https://kody.codes/docs/api-versioning.md for deprecation windows and migration policy (we do not break users; phased migration with codemods when needed).\n\nAuthenticate with `Authorization: Bearer kody_at_…`. Tokens are minted by the MCP `api` tool (`tokenCreate`) or by another token, and each carries explicit org-permission scopes. There is no write-implies-read hierarchy.\nTokens require an explicit lifetime: lifetime \"short\" (3600s idle / 86400s max) or \"long\" (1209600s idle / 7776000s max), or both idle_ttl_seconds (60-1209600) and max_lifetime_seconds (up to 7776000). Each successful request slides expires_at forward, never past max_expires_at. At most 500 active tokens per account; a new mint reclaims the active token(s) with the least remaining life (sooner of idle deadline and absolute expiry), never the caller's own token.\n\nErrors use `{ \"error\": { \"code\", \"message\", \"details\"? } }` (see components.schemas.Error). Documented 4xx/5xx responses reference that schema. Requests are rate limited per IP (600/min) and per token (300/min); HTTP 429 includes `Retry-After`. Edge-generated 429 responses also include a `RateLimit-Policy` advertisement; entitlement 429s send `Retry-After` only.\n\n`operationId` values match Kody capability names, so the same ids work with the MCP `api` tool (`{ operationId, params }`, where params hold path, query, and body fields flat).\n\nInteractive docs: https://api-docs.kody.codes\n\nScopes:\n- `package:read`: Read saved packages and package-backed resources.\n- `package:execute`: Execute saved packages.\n- `package:write`: Change saved packages and package-backed resources.\n- `package:delete`: Delete saved packages.\n- `package:publish`: Publish packages to the community catalog.\n- `package:manage_access`: Manage package access grants.\n- `app:read`: Read package apps.\n- `app:execute`: Run package apps.\n- `app:write`: Granted `app:write` in this org.\n- `app:delete`: Granted `app:delete` in this org.\n- `app:manage_access`: Granted `app:manage_access` in this org.\n- `job:read`: Read package jobs and workflow runs.\n- `job:execute`: Run package jobs.\n- `job:write`: Granted `job:write` in this org.\n- `job:delete`: Granted `job:delete` in this org.\n- `job:manage_access`: Granted `job:manage_access` in this org.\n- `secret:use`: Use secrets without reading plaintext.\n- `secret:read`: Granted `secret:read` in this org.\n- `secret:write`: Change existing secrets (plaintext is never returned).\n- `secret:delete`: Granted `secret:delete` in this org.\n- `secret:manage_access`: Granted `secret:manage_access` in this org.\n- `integration:use`: Use connected integrations.\n- `integration:read`: Read OAuth integrations and connected MCP servers.\n- `integration:write`: Granted `integration:write` in this org.\n- `integration:delete`: Granted `integration:delete` in this org.\n- `integration:manage_access`: Granted `integration:manage_access` in this org.\n- `memory:read`: Read memories and MCP server instructions.\n- `memory:write`: Change existing memories.\n- `memory:delete`: Granted `memory:delete` in this org.\n- `memory:manage_access`: Granted `memory:manage_access` in this org.\n- `email:read`: Read inboxes and messages.\n- `email:send`: Send email.\n- `email:write`: Granted `email:write` in this org.\n- `email:delete`: Granted `email:delete` in this org.\n- `email:manage_access`: Granted `email:manage_access` in this org.\n- `package:create`: Create saved packages.\n- `app:create`: Granted `app:create` in this org.\n- `job:create`: Granted `job:create` in this org.\n- `secret:create`: Create new secrets.\n- `integration:create`: Granted `integration:create` in this org.\n- `memory:create`: Create new memories.\n- `email:create`: Granted `email:create` in this org.\n- `org:read`: Read this org’s profile, members, and billing summary.\n- `org:write`: Change this org’s profile and settings.\n- `org:delete`: Delete this org.\n- `org:execute`: Run execute and local CapabilityProxy hops for this org (API tokens need this scope; CLI `kody login` OAuth is a separate credential).\n- `search:read`: Run unified Kody search.\n- `member:read`: Read org members.\n- `member:write`: Invite and change org members.\n- `member:delete`: Remove org members.\n- `team:read`: Read teams.\n- `team:write`: Create and change teams.\n- `team:delete`: Delete teams.\n- `billing:read`: Read billing and plan.\n- `billing:write`: Change billing and plan.\n- `audit:read`: Read the org audit log.\n- `token:read`: List and inspect API tokens.\n- `token:delete`: Revoke API tokens."},"externalDocs":{"description":"Interactive Kody API docs (Scalar)","url":"https://api-docs.kody.codes"},"tags":[{"name":"account","description":"Account profile, usage, waiting items, export, and feedback."},{"name":"search","description":"Unified Kody search."},{"name":"memories","description":"Memories and the MCP server-instruction overlay."},{"name":"secrets","description":"Secret metadata and writes. Secret values can be written but are never returned."},{"name":"packages","description":"Saved packages, sharing, and subscriptions."},{"name":"follows","description":"Follow a package or plain repo by @handle/name."},{"name":"repos","description":"Repos and repo sessions (edit, check, commit, publish)."},{"name":"jobs","description":"Package jobs and workflow runs."},{"name":"webhooks","description":"Package webhook URLs and deliveries."},{"name":"email","description":"Inboxes, messages, sender rules, destinations, and sending."},{"name":"integrations","description":"OAuth integrations and OAuth apps."},{"name":"mcp-servers","description":"User-added MCP servers."},{"name":"runs","description":"Execution run history and triage."},{"name":"storage","description":"Durable storage export and SQL query."},{"name":"community","description":"Public packages in the community catalog, and profile."},{"name":"tokens","description":"Scoped, short-lived API tokens."},{"name":"capability-proxy","description":"Platform I/O for a local execute venue: CapabilityProxy hops (`kody:runtime` calls) and `POST /v1/local-execute/package-graph` (stamped `kody:@…` module download). Requires `org:execute` and a scoped API token or CLI `kody login` MCP OAuth bearer."},{"name":"execute","description":"Cloud sandbox execute. `POST /v1/execute` runs a module and returns the MCP execute envelope. Requires `org:execute` and a `kody_at_` token."}],"security":[{"apiToken":[]}],"paths":{"/v1/me":{"get":{"operationId":"metaGetCurrentUser","summary":"Get harmless identity fields for the signed-in MCP user: id, username, email, display name, and the slug of the org t...","description":"Get harmless identity fields for the signed-in MCP user: id, username, email, display name, and the slug of the org this request acts in. Email is empty when the caller is a team org rather than a person. Use email and display_name as git user.email / user.name on Kody remotes when a git-remote result is not already in hand.\n\nOrg permission: none (touches no org data).","tags":["account"],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"user_id":{"type":"string"},"username":{"type":"string"},"email":{"anyOf":[{"type":"string","format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},{"type":"string","const":"","description":"Empty when the caller is a team org, not a person."}]},"display_name":{"type":"string"},"org":{"type":"object","properties":{"slug":{"type":"string","description":"Package scope and package-app subdomain."}},"required":["slug"],"additionalProperties":false}},"required":["user_id","username","email","display_name","org"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"none","x-kody-read-only":true}},"/v1/account/usage":{"get":{"operationId":"usageGet","summary":"Read entitlement usage for the org this connection is bound to (personal or team) against that org’s plan limits, inc...","description":"Read entitlement usage for the org this connection is bound to (personal or team) against that org’s plan limits, including monthly Worker compute and Rows read plus execute/outbound hard caps: per-resource current, limit, percent used, and plain-language guidance on what counts and how to reduce it.\n\nOrg permission: `billing:read`.","tags":["account"],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"plan":{"type":"string","enum":["free","standard","pro","max"]},"day":{"type":"string"},"weekStart":{"type":"string"},"resources":{"type":"array","items":{"type":"object","properties":{"resource":{"type":"string"},"label":{"type":"string"},"group":{"type":"string","enum":["monthly","daily","counts","storage","limits"]},"kind":{"type":"string","enum":["counter","per_unit_max"]},"whatCounts":{"type":"string"},"howToReduce":{"type":"string"},"current":{"type":"integer","minimum":0,"maximum":9007199254740991},"limit":{"type":"integer","minimum":0,"maximum":9007199254740991},"percent":{"type":["number","null"]},"overEightyPercent":{"type":"boolean"},"mechanic":{"type":"string"},"week":{"type":"object","properties":{"current":{"type":"integer","minimum":0,"maximum":9007199254740991},"limit":{"type":"integer","minimum":0,"maximum":9007199254740991},"percent":{"type":["number","null"]},"overEightyPercent":{"type":"boolean"}},"required":["current","limit","percent","overEightyPercent"],"additionalProperties":false}},"required":["resource","label","group","kind","whatCounts","howToReduce","current","limit","percent","overEightyPercent"],"additionalProperties":false}},"warnings":{"type":"array","items":{"type":"object","properties":{"resource":{"type":"string"},"label":{"type":"string"},"group":{"type":"string","enum":["monthly","daily","counts","storage","limits"]},"kind":{"type":"string","enum":["counter","per_unit_max"]},"whatCounts":{"type":"string"},"howToReduce":{"type":"string"},"current":{"type":"integer","minimum":0,"maximum":9007199254740991},"limit":{"type":"integer","minimum":0,"maximum":9007199254740991},"percent":{"type":["number","null"]},"overEightyPercent":{"type":"boolean"},"mechanic":{"type":"string"},"week":{"type":"object","properties":{"current":{"type":"integer","minimum":0,"maximum":9007199254740991},"limit":{"type":"integer","minimum":0,"maximum":9007199254740991},"percent":{"type":["number","null"]},"overEightyPercent":{"type":"boolean"}},"required":["current","limit","percent","overEightyPercent"],"additionalProperties":false}},"required":["resource","label","group","kind","whatCounts","howToReduce","current","limit","percent","overEightyPercent"],"additionalProperties":false}}},"required":["plan","day","weekStart","resources","warnings"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"billing:read","x-kody-read-only":true}},"/v1/account/usage/trend":{"get":{"operationId":"usageTrendGet","summary":"Read the recent daily usage trend for the org this connection is bound to (personal or team) for hosted execute and u...","description":"Read the recent daily usage trend for the org this connection is bound to (personal or team) for hosted execute and unique Worker days (plus optional job/automation daily counts), with a cheap monthly rollup series from usage_rollups for charts.\n\nOrg permission: `billing:read`.","tags":["account"],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"days":{"type":"array","items":{"type":"object","properties":{"day":{"type":"string"},"execute":{"type":"integer","minimum":0,"maximum":9007199254740991},"uniqueWorkerDays":{"type":"integer","minimum":0,"maximum":9007199254740991},"jobRuns":{"type":"integer","minimum":0,"maximum":9007199254740991},"automationInvocations":{"type":"integer","minimum":0,"maximum":9007199254740991},"packageExports":{"type":"integer","minimum":0,"maximum":9007199254740991}},"required":["day","execute","uniqueWorkerDays"],"additionalProperties":false}},"months":{"type":"array","items":{"type":"object","properties":{"month":{"type":"string"},"execute":{"type":"integer","minimum":0,"maximum":9007199254740991},"uniqueWorkerDays":{"type":"integer","minimum":0,"maximum":9007199254740991}},"required":["month","execute","uniqueWorkerDays"],"additionalProperties":false}},"retentionDays":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},"asOf":{"type":"string"}},"required":["days","retentionDays","asOf"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"billing:read","x-kody-read-only":true}},"/v1/account/usage/by-package":{"get":{"operationId":"usageByPackageGet","summary":"Read the current UTC month past-include credit attribution for the org this connection is bound to (personal or team)...","description":"Read the current UTC month past-include credit attribution for the org this connection is bound to (personal or team) by package (Where it went): Worker compute and Rows read credits only — not execute, jobs, or package exports. Optional packageId returns that package’s slice of the same period breakdown.\n\nOrg permission: `billing:read`.","tags":["account"],"parameters":[{"name":"packageId","in":"query","required":false,"description":"When set, return only this package’s row from the current-month breakdown (zero row when the package spent nothing). Omit for the full Where-it-went list including Ad hoc.","schema":{"description":"When set, return only this package’s row from the current-month breakdown (zero row when the package spent nothing). Omit for the full Where-it-went list including Ad hoc.","type":"string","minLength":1}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"month":{"type":"string"},"totalCreditsMicroUsd":{"type":"integer","minimum":0,"maximum":9007199254740991},"rows":{"type":"array","items":{"type":"object","properties":{"packageId":{"type":"string"},"name":{"type":"string"},"href":{"type":["string","null"]},"creditsMicroUsd":{"type":"integer","minimum":0,"maximum":9007199254740991},"share":{"type":"number","minimum":0},"meters":{"type":"array","items":{"type":"object","properties":{"meter":{"type":"string","enum":["unique_worker_days","durable_object_rows_read"]},"label":{"type":"string"},"creditsMicroUsd":{"type":"integer","minimum":0,"maximum":9007199254740991}},"required":["meter","label","creditsMicroUsd"],"additionalProperties":false}},"cumulative":{"type":"array","items":{"type":"object","properties":{"day":{"type":"string"},"creditsMicroUsd":{"type":"integer","minimum":0,"maximum":9007199254740991}},"required":["day","creditsMicroUsd"],"additionalProperties":false}},"isAdHoc":{"type":"boolean"}},"required":["packageId","name","href","creditsMicroUsd","share","meters","cumulative","isAdHoc"],"additionalProperties":false}}},"required":["month","totalCreditsMicroUsd","rows"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"billing:read","x-kody-read-only":true}},"/v1/account/waiting":{"get":{"operationId":"waitingSummary","summary":"List things currently waiting on the signed-in human: email verification, OAuth reconnects, your own paused automatio...","description":"List things currently waiting on the signed-in human: email verification, OAuth reconnects, your own paused automations (enablements whose run lost access it needs), expired secrets, MCP reconnects, locked-package publishes, plan caps, wizard resume, first-use setup (search, memory, execute, package, job, integration, secret, Discord membership), and an elevated open-error rate that still needs Activity triage. Ignored and resolved Activity errors do not keep that card around. This is a current-state queue, not run history — use runSummary for Activity. Vendor outages do not appear here.\n\nOrg permission: `org:read`.","tags":["account"],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"count":{"type":"integer","minimum":0,"maximum":9007199254740991},"waiting_url":{"type":"string"},"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"kind":{"type":"string","enum":["verify-email","mcp-server","integration-auth","enablement-paused","secret-expired","publish-lock","email-change","entitlement","error-rate","onboarding","first-use"]},"title":{"type":"string"},"why":{"type":"string"},"who":{"type":"string","const":"you"},"do_label":{"type":"string"},"href":{"type":"string"},"severity":{"type":"string","enum":["block","degraded","setup"]}},"required":["id","kind","title","why","who","do_label","href","severity"],"additionalProperties":false}}},"required":["count","waiting_url","items"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"org:read","x-kody-read-only":true}},"/v1/account/export":{"get":{"operationId":"accountExportManifest","summary":"Build a signed-in user data export manifest with schema version, section counts, redactions, warnings, and chunking i...","description":"Build a signed-in user data export manifest with schema version, section counts, redactions, warnings, and chunking instructions. Secret values are never exported.\n\nOrg permission: `org:read`.","tags":["account"],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"manifest":{}},"required":["manifest"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"org:read","x-kody-read-only":true}},"/v1/account/export/{section}":{"get":{"operationId":"accountExportSection","summary":"Read a paged section of the signed-in user account export.","description":"Read a paged section of the signed-in user account export. Use accountExportManifest first for section counts and warnings. Secret values are never exported.\n\nOrg permission: `org:read`.","tags":["account"],"parameters":[{"name":"section","in":"path","required":true,"schema":{"type":"string","enum":["d1_table","storage_runner","job_manager","run_records","user_meter","mailbox","repo_session_index","oauth_grants","artifact_repos","kv_keys","r2_object","durable_object_summaries"]}},{"name":"table","in":"query","required":false,"description":"Required when section is d1_table.","schema":{"description":"Required when section is d1_table.","type":"string","minLength":1}},{"name":"storage_id","in":"query","required":false,"description":"Required when section is storage_runner.","schema":{"description":"Required when section is storage_runner.","type":"string","minLength":1}},{"name":"kind","in":"query","required":false,"description":"Required when section is durable_object_summaries.","schema":{"description":"Required when section is durable_object_summaries.","type":"string","enum":["storage_runner","job_manager"]}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":500}},{"name":"start_after","in":"query","required":false,"description":"Opaque cursor from a previous accountExportSection page.","schema":{"description":"Opaque cursor from a previous accountExportSection page.","type":"string","minLength":1}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"section":{"type":"string","enum":["d1_table","storage_runner","job_manager","run_records","user_meter","mailbox","repo_session_index","oauth_grants","artifact_repos","kv_keys","r2_object","durable_object_summaries"]},"items":{"type":"array","items":{}},"truncated":{"type":"boolean"},"next_start_after":{"type":["string","null"]},"page_size":{"type":"number"},"warnings":{"type":"array","items":{"type":"string"}}},"required":["section","items","truncated","next_start_after","page_size","warnings"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"org:read","x-kody-read-only":true}},"/v1/account/feedback":{"get":{"operationId":"metaPlatformFeedbackList","summary":"List platform feedback submissions owned by the signed-in user, newest first.","description":"List platform feedback submissions owned by the signed-in user, newest first. Optional status filter (open, triaged, resolved, dismissed). Each row has id, category, summary, status, created_at, and updated_at (outcome time when resolved or dismissed). Never exposes reviewer identity, admin notes, or other users' feedback. Use metaPlatformFeedbackGet for details on one id.\n\nOrg permission: none (touches no org data).","tags":["account"],"parameters":[{"name":"page","in":"query","required":false,"description":"One-indexed feedback page. Defaults to 1.","schema":{"description":"One-indexed feedback page. Defaults to 1.","type":"integer","minimum":1,"maximum":9007199254740991}},{"name":"page_size","in":"query","required":false,"description":"Feedback records per page. Defaults to 20 and maxes at 100.","schema":{"description":"Feedback records per page. Defaults to 20 and maxes at 100.","type":"integer","minimum":1,"maximum":100}},{"name":"status","in":"query","required":false,"description":"Optional exact status filter.","schema":{"description":"Optional exact status filter.","type":"string","enum":["open","triaged","resolved","dismissed"]}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"total":{"type":"integer","minimum":0,"maximum":9007199254740991},"page":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},"page_size":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},"feedback":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"category":{"type":"string","enum":["friction","bug","experience","suggestion","cancellation","other"]},"summary":{"type":"string"},"status":{"type":"string","enum":["open","triaged","resolved","dismissed"]},"created_at":{"type":"string"},"updated_at":{"type":"string"}},"required":["id","category","summary","status","created_at","updated_at"],"additionalProperties":false}}},"required":["total","page","page_size","feedback"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"none","x-kody-read-only":true},"post":{"operationId":"metaPlatformFeedbackSubmit","summary":"Submit platform feedback only from an interactive MCP agent flow after showing the user the exact proposed summary an...","description":"Submit platform feedback only from an interactive MCP agent flow after showing the user the exact proposed summary and details, asking first, and receiving explicit approval. Open `search({ entity: \"guide:platform_friction\" })` first for the approval flow and content guidance. After submit, use metaPlatformFeedbackGet with the returned feedback_id (or metaPlatformFeedbackList) to check status — including open, triaged, resolved, and dismissed — without a full account export. The exact approved summary and details plus the account user id, username, and email may be delivered immediately to deployment admins through admin-configured notifications. Copies already delivered outside Kody may remain after Kody account deletion under the deployment operator’s retention and deletion controls. Non-interactive package code and package apps cannot submit. Do not include secrets or unrelated private content.\n\nOrg permission: none (touches no org data).","tags":["account"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"category":{"type":"string","enum":["friction","bug","experience","suggestion","cancellation","other"],"description":"Stable feedback category: \"bug\" for reproducible defects, \"friction\" for capability/guide/package text that caused a wrong turn, \"experience\" for a poor overall experience, \"suggestion\" for a problem-first improvement idea, \"cancellation\" for why the user is ending a paid subscription, \"other\" when nothing fits."},"summary":{"type":"string","minLength":1,"maxLength":200,"description":"Specific, scannable summary naming the affected area and symptom or need (1–200 characters); admins triage from this line alone, so avoid vague summaries like \"search is broken\"."},"details":{"type":"string","minLength":1,"maxLength":8000,"description":"Feedback details (1–8000 characters), one issue per submission: goal context, exact capability or package names, minimal reproduction steps, expected vs actual behavior, verbatim error text, frequency, impact, and any workaround. Do not include secrets or unrelated private content."},"user_confirmed":{"type":"boolean","const":true,"description":"Must be true only after the agent shows the exact proposed summary and details and the user explicitly approves sending them, with the account user id, username, and email, immediately to deployment admins through admin-configured notifications, after being told that copies already delivered outside Kody may remain after Kody account deletion under the deployment operator’s retention and deletion controls."}},"required":["category","summary","details","user_confirmed"]}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"feedback_id":{"type":"string","description":"Submitted feedback id. Pass to metaPlatformFeedbackGet to check status later, or use metaPlatformFeedbackList to browse the signed-in user's submissions."},"status":{"type":"string","const":"open"},"created_at":{"type":"string"}},"required":["feedback_id","status","created_at"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"none","x-kody-read-only":false}},"/v1/account/feedback/{feedback_id}":{"get":{"operationId":"metaPlatformFeedbackGet","summary":"Read one platform feedback submission owned by the signed-in user by feedback_id.","description":"Read one platform feedback submission owned by the signed-in user by feedback_id. Returns id, category, summary, details, status, created_at, and updated_at (outcome time when status is resolved or dismissed). Not-owned ids return null, same as missing. Never exposes reviewer identity or admin notes. Use after metaPlatformFeedbackSubmit, or metaPlatformFeedbackList to find an id.\n\nOrg permission: none (touches no org data).","tags":["account"],"parameters":[{"name":"feedback_id","in":"path","required":true,"description":"Platform feedback id returned by metaPlatformFeedbackSubmit.","schema":{"type":"string","minLength":1,"description":"Platform feedback id returned by metaPlatformFeedbackSubmit."}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"category":{"type":"string","enum":["friction","bug","experience","suggestion","cancellation","other"]},"summary":{"type":"string"},"status":{"type":"string","enum":["open","triaged","resolved","dismissed"]},"created_at":{"type":"string"},"updated_at":{"type":"string"},"details":{"type":"string"}},"required":["id","category","summary","status","created_at","updated_at","details"],"additionalProperties":false},{"type":"null"}]}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"none","x-kody-read-only":true}},"/v1/access/grants":{"get":{"operationId":"accessList","summary":"List live grants in the organization this request is bound to.","description":"List live grants in the organization this request is bound to. Filter by resource or subject when you already know which one you want.\n\nOrg permission: `member:read`.","tags":["account"],"parameters":[{"name":"resource_type","in":"query","required":false,"description":"secret or integration with a resource_id filter by that credential name.","schema":{"description":"secret or integration with a resource_id filter by that credential name.","type":"string","enum":["package","app","job","credential","memory","email","org","secret","integration"]}},{"name":"resource_id","in":"query","required":false,"schema":{"type":"string","minLength":1}},{"name":"subject_type","in":"query","required":false,"schema":{"type":"string","enum":["user","team"]}},{"name":"subject_id","in":"query","required":false,"schema":{"type":"string","minLength":1}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"grants":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"resource_type":{"type":"string","enum":["package","app","job","credential","memory","email","org"]},"resource_id":{"type":"string"},"subject_type":{"type":"string","enum":["user","team"]},"subject_id":{"type":"string"},"preset":{"anyOf":[{"type":"string","enum":["use","contribute","manage"]},{"type":"null"}]},"permissions":{"type":"array","items":{"type":"string"}}},"required":["id","resource_type","resource_id","subject_type","subject_id","preset","permissions"],"additionalProperties":false}}},"required":["grants"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"member:read","x-kody-read-only":true},"post":{"operationId":"accessGrant","summary":"Grant a user or team Use, Contribute, or Manage on a resource in the organization this request is bound to, or pass a...","description":"Grant a user or team Use, Contribute, or Manage on a resource in the organization this request is bound to, or pass an explicit permission list instead of a preset. Secrets, integrations, MCP servers, and vault bindings use resource_type credential with the credential_id from secretList, integrationList, mcpServerList, or secretProviderList; the grant follows the credential, not its name. resource_type secret or integration with a name still works: the name resolves to its credential once, when the grant is made. Organization grants use resource_type org and this organization id. You need manage access on that resource (or member:write for an organization grant). Only an Owner can put org:write, org:delete, member:write, or member:delete on an organization grant.\n\nOrg permission: none (touches no org data).","tags":["account"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"resource_type":{"type":"string","enum":["package","app","job","credential","memory","email","org","secret","integration"],"description":"package, app, job, credential, memory, email, or org. secret or integration take a name instead of a credential id."},"resource_id":{"type":"string","minLength":1},"subject_type":{"type":"string","enum":["user","team"]},"subject_id":{"description":"Person id or team id. Omit when passing username or team_slug.","type":"string","minLength":1},"username":{"type":"string","minLength":1},"team_slug":{"type":"string","minLength":1},"preset":{"type":"string","enum":["use","contribute","manage"]},"permissions":{"description":"Advanced grant. Do not combine with preset.","type":"array","items":{"type":"string","minLength":1}}},"required":["resource_type","resource_id","subject_type"]}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"grant":{"type":"object","properties":{"id":{"type":"string"},"resource_type":{"type":"string","enum":["package","app","job","credential","memory","email","org"]},"resource_id":{"type":"string"},"subject_type":{"type":"string","enum":["user","team"]},"subject_id":{"type":"string"},"preset":{"anyOf":[{"type":"string","enum":["use","contribute","manage"]},{"type":"null"}]},"permissions":{"type":"array","items":{"type":"string"}}},"required":["id","resource_type","resource_id","subject_type","subject_id","preset","permissions"],"additionalProperties":false}},"required":["grant"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"none","x-kody-read-only":false}},"/v1/access/grants/{grant_id}/revoke":{"post":{"operationId":"accessRevoke","summary":"Revoke one live grant in the organization this request is bound to.","description":"Revoke one live grant in the organization this request is bound to. You need manage access on that grant resource (or member:write for an organization grant).\n\nOrg permission: none (touches no org data).","tags":["account"],"parameters":[{"name":"grant_id","in":"path","required":true,"schema":{"type":"string","minLength":1}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{}}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"grant_id":{"type":"string"},"revoked":{"type":"boolean","const":true}},"required":["grant_id","revoked"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"none","x-kody-read-only":false}},"/v1/access/invites":{"post":{"operationId":"inviteCreate","summary":"Invite someone to the organization this request is bound to, by email or username.","description":"Invite someone to the organization this request is bound to, by email or username. kind membership needs member:write and adds them with a role (and optional teams). kind grant needs manage access on the resource and gives them a preset or permission list. The token is returned once, with a prompt that tells them to call inviteAccept. Invites expire in 7 days.\n\nOrg permission: none (touches no org data).","tags":["account"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","enum":["membership","grant"]},"email":{"type":"string","minLength":1},"username":{"type":"string","minLength":1},"role":{"type":"string","enum":["owner","member","billing"]},"team_ids":{"type":"array","items":{"type":"string","minLength":1}},"resource_type":{"type":"string","enum":["package","app","job","credential","memory","email","org","secret","integration"]},"resource_id":{"type":"string","minLength":1},"preset":{"type":"string","enum":["use","contribute","manage"]},"permissions":{"type":"array","items":{"type":"string","minLength":1}}},"required":["kind"]}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"invite":{"type":"object","properties":{"id":{"type":"string"},"org_id":{"type":"string"},"org_slug":{"type":"string"},"kind":{"type":"string","enum":["membership","grant"]},"role":{"anyOf":[{"type":"string","enum":["owner","member","billing"]},{"type":"null"}]},"team_ids":{"type":"array","items":{"type":"string"}},"resource_type":{"anyOf":[{"type":"string","enum":["package","app","job","credential","memory","email","org"]},{"type":"null"}]},"resource_id":{"type":["string","null"]},"preset":{"anyOf":[{"type":"string","enum":["use","contribute","manage"]},{"type":"null"}]},"permissions":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}]},"invitee_email":{"type":["string","null"]},"invitee_username":{"type":["string","null"]},"status":{"type":"string","enum":["pending","accepted","revoked","expired"]},"expires_at":{"type":"string"}},"required":["id","org_id","org_slug","kind","role","team_ids","resource_type","resource_id","preset","permissions","invitee_email","invitee_username","status","expires_at"],"additionalProperties":false},"token":{"type":"string"},"prompt":{"type":"string"}},"required":["invite","token","prompt"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"none","x-kody-read-only":false}},"/v1/access/invites/accept":{"post":{"operationId":"inviteAccept","summary":"Accept an invitation addressed to your account email or username.","description":"Accept an invitation addressed to your account email or username. Pass the token from inviteCreate. Membership invites add you to that organization. Grant invites write the grant. The prompt from inviteCreate includes the organization slug and this call.\n\nOrg permission: `org:read`.","tags":["account"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"token":{"type":"string","minLength":1}},"required":["token"]}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"invite_id":{"type":"string"},"org_id":{"type":"string"},"org_slug":{"type":"string"},"kind":{"type":"string","enum":["membership","grant"]},"status":{"type":"string","const":"accepted"}},"required":["invite_id","org_id","org_slug","kind","status"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"org:read","x-kody-read-only":false}},"/v1/access/invites/{invite_id}/revoke":{"post":{"operationId":"inviteRevoke","summary":"Revoke a pending invite in the organization this request is bound to.","description":"Revoke a pending invite in the organization this request is bound to. Membership invites need member:write. Grant invites need manage access on that resource (or member:write for an org grant). Accepted invites stay in place; remove the member or grant separately.\n\nOrg permission: none (touches no org data).","tags":["account"],"parameters":[{"name":"invite_id","in":"path","required":true,"schema":{"type":"string","minLength":1}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{}}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"invite_id":{"type":"string"},"status":{"type":"string","const":"revoked"}},"required":["invite_id","status"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"none","x-kody-read-only":false}},"/v1/orgs":{"post":{"operationId":"orgCreate","summary":"Create an organization you own.","description":"Create an organization you own. The slug becomes the permanent handle (kody.codes/@<slug>) and cannot be changed later; only the display name can. The id is new and separate from your personal organization. Calls that change the new organization need a request bound to it.\n\nOrg permission: `org:write`.","tags":["account"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"slug":{"type":"string","minLength":1,"description":"Public handle for the organization, lowercased. Permanent: it cannot be changed after creation, so pick it deliberately. The org lives at kody.codes/@<slug>."},"display_name":{"type":"string","minLength":1}},"required":["slug"]}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"org":{"type":"object","properties":{"id":{"type":"string"},"slug":{"type":"string"},"display_name":{"type":"string"}},"required":["id","slug","display_name"],"additionalProperties":false}},"required":["org"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"org:write","x-kody-read-only":false},"patch":{"operationId":"orgUpdate","summary":"Update the display name of the organization this request is bound to.","description":"Update the display name of the organization this request is bound to. The handle (slug, kody.codes/@<slug>) is permanent and cannot be changed; passing any other handle fails. Signup organizations keep the person’s account profile as their identity.\n\nOrg permission: `org:write`.","tags":["account"],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"display_name":{"type":"string","minLength":1,"maxLength":80},"slug":{"type":"string","minLength":1,"description":"Must match the current handle. Handles are permanent and cannot be changed."}}}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"org":{"type":"object","properties":{"id":{"type":"string"},"slug":{"type":"string"},"display_name":{"type":["string","null"]}},"required":["id","slug","display_name"],"additionalProperties":false}},"required":["org"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"org:write","x-kody-read-only":false}},"/v1/orgs/package-app-custom-hostnames":{"get":{"operationId":"packageAppCustomHostnameList","summary":"List custom hostnames registered for this organization’s package apps, including app-level and org-level bindings and...","description":"List custom hostnames registered for this organization’s package apps, including app-level and org-level bindings and their Cloudflare verification status.\n\nOrg permission: `org:write`.","tags":["account"],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"hostnames":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"hostname":{"type":"string"},"binding_kind":{"type":"string","enum":["app","org"]},"package_id":{"type":["string","null"]},"org_id":{"type":["string","null"]},"hostname_status":{"type":"string"},"ssl_status":{"type":"string"},"verified_at":{"type":["string","null"]},"dns_missing_since":{"type":["string","null"]},"verification":{"type":"object","properties":{"ownership_verification":{"anyOf":[{"type":"object","properties":{"type":{"type":"string"},"name":{"type":"string"},"value":{"type":"string"}},"required":["type","name","value"],"additionalProperties":false},{"type":"null"}]},"ssl_validation_records":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string"},"name":{"type":"string"},"value":{"type":"string"}},"required":["type","name","value"],"additionalProperties":false}}},"required":["ownership_verification","ssl_validation_records"],"additionalProperties":false},"created_at":{"type":"string"},"updated_at":{"type":"string"}},"required":["id","hostname","binding_kind","package_id","org_id","hostname_status","ssl_status","verified_at","dns_missing_since","verification","created_at","updated_at"],"additionalProperties":false}}},"required":["hostnames"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"org:write","x-kody-read-only":true,"x-kody-feature-flag":"package-app-custom-domains"},"post":{"operationId":"packageAppCustomHostnameAdd","summary":"Register a custom hostname for this organization’s package apps (Cloudflare for SaaS).","description":"Register a custom hostname for this organization’s package apps (Cloudflare for SaaS). App-level hostnames apply to one internet-visible public app and serve it at the host root. Org-level hostnames apply to private apps and serve them at /packages/{kodyId} on the custom host. Only org admins on a paid plan may add domains. Point DNS (usually a CNAME) at the package-app zone before verification completes. Optional ssl_method=txt pre-validates the certificate via TXT before traffic switches.\n\nOrg permission: `org:write`.","tags":["account"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"hostname":{"type":"string","minLength":1,"description":"Customer hostname to register."},"binding_kind":{"type":"string","enum":["app","org"],"description":"app = one public internet-visible app; org = private apps."},"package_id":{"description":"Required when binding_kind is app.","type":"string","minLength":1},"ssl_method":{"description":"Cloudflare SSL validation method. Default http. Use txt for pre-validation before switching traffic.","type":"string","enum":["http","txt"]}},"required":["hostname","binding_kind"]}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"hostname":{"type":"object","properties":{"id":{"type":"string"},"hostname":{"type":"string"},"binding_kind":{"type":"string","enum":["app","org"]},"package_id":{"type":["string","null"]},"org_id":{"type":["string","null"]},"hostname_status":{"type":"string"},"ssl_status":{"type":"string"},"verified_at":{"type":["string","null"]},"dns_missing_since":{"type":["string","null"]},"verification":{"type":"object","properties":{"ownership_verification":{"anyOf":[{"type":"object","properties":{"type":{"type":"string"},"name":{"type":"string"},"value":{"type":"string"}},"required":["type","name","value"],"additionalProperties":false},{"type":"null"}]},"ssl_validation_records":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string"},"name":{"type":"string"},"value":{"type":"string"}},"required":["type","name","value"],"additionalProperties":false}}},"required":["ownership_verification","ssl_validation_records"],"additionalProperties":false},"created_at":{"type":"string"},"updated_at":{"type":"string"}},"required":["id","hostname","binding_kind","package_id","org_id","hostname_status","ssl_status","verified_at","dns_missing_since","verification","created_at","updated_at"],"additionalProperties":false},"dns":{"type":"object","properties":{"type":{"type":"string","const":"CNAME"},"name":{"type":"string"},"target":{"type":["string","null"]}},"required":["type","name","target"],"additionalProperties":false},"verification":{"type":"object","properties":{"ownership_verification":{"anyOf":[{"type":"object","properties":{"type":{"type":"string"},"name":{"type":"string"},"value":{"type":"string"}},"required":["type","name","value"],"additionalProperties":false},{"type":"null"}]},"ssl_validation_records":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string"},"name":{"type":"string"},"value":{"type":"string"}},"required":["type","name","value"],"additionalProperties":false}}},"required":["ownership_verification","ssl_validation_records"],"additionalProperties":false},"billing_note":{"type":["string","null"]}},"required":["hostname","dns","verification","billing_note"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"org:write","x-kody-read-only":false,"x-kody-feature-flag":"package-app-custom-domains"}},"/v1/orgs/package-app-custom-hostnames/{id}/sync":{"post":{"operationId":"packageAppCustomHostnameSync","summary":"Refresh one custom hostname from Cloudflare for SaaS: pull hostname and SSL status, ownership TXT / SSL validation re...","description":"Refresh one custom hostname from Cloudflare for SaaS: pull hostname and SSL status, ownership TXT / SSL validation records, and update the local row. Use after the customer publishes DNS (CNAME and optional ownership/SSL TXT). Pass hostname or the row id from packageAppCustomHostnameList.\n\nOrg permission: `org:write`.","tags":["account"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","minLength":1}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"hostname":{"type":"string","minLength":1}}}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"hostname":{"type":"object","properties":{"id":{"type":"string"},"hostname":{"type":"string"},"binding_kind":{"type":"string","enum":["app","org"]},"package_id":{"type":["string","null"]},"org_id":{"type":["string","null"]},"hostname_status":{"type":"string"},"ssl_status":{"type":"string"},"verified_at":{"type":["string","null"]},"dns_missing_since":{"type":["string","null"]},"verification":{"type":"object","properties":{"ownership_verification":{"anyOf":[{"type":"object","properties":{"type":{"type":"string"},"name":{"type":"string"},"value":{"type":"string"}},"required":["type","name","value"],"additionalProperties":false},{"type":"null"}]},"ssl_validation_records":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string"},"name":{"type":"string"},"value":{"type":"string"}},"required":["type","name","value"],"additionalProperties":false}}},"required":["ownership_verification","ssl_validation_records"],"additionalProperties":false},"created_at":{"type":"string"},"updated_at":{"type":"string"}},"required":["id","hostname","binding_kind","package_id","org_id","hostname_status","ssl_status","verified_at","dns_missing_since","verification","created_at","updated_at"],"additionalProperties":false},"dns":{"type":"object","properties":{"type":{"type":"string","const":"CNAME"},"name":{"type":"string"},"target":{"type":["string","null"]}},"required":["type","name","target"],"additionalProperties":false},"verification":{"type":"object","properties":{"ownership_verification":{"anyOf":[{"type":"object","properties":{"type":{"type":"string"},"name":{"type":"string"},"value":{"type":"string"}},"required":["type","name","value"],"additionalProperties":false},{"type":"null"}]},"ssl_validation_records":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string"},"name":{"type":"string"},"value":{"type":"string"}},"required":["type","name","value"],"additionalProperties":false}}},"required":["ownership_verification","ssl_validation_records"],"additionalProperties":false}},"required":["hostname","dns","verification"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"org:write","x-kody-read-only":false,"x-kody-feature-flag":"package-app-custom-domains"}},"/v1/orgs/package-app-custom-hostnames/{id}":{"delete":{"operationId":"packageAppCustomHostnameDelete","summary":"Remove a custom hostname from this organization’s package apps and delete it from Cloudflare for SaaS.","description":"Remove a custom hostname from this organization’s package apps and delete it from Cloudflare for SaaS. Pass hostname or the row id from packageAppCustomHostnameList.\n\nOrg permission: `org:write`.","tags":["account"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","minLength":1}},{"name":"hostname","in":"query","required":false,"schema":{"type":"string","minLength":1}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"id":{"type":"string"},"hostname":{"type":"string"}},"required":["ok","id","hostname"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"org:write","x-kody-read-only":false,"x-kody-feature-flag":"package-app-custom-domains"}},"/v1/orgs/members":{"get":{"operationId":"orgMemberList","summary":"List live members of the organization this request is bound to, with username, display name, and role.","description":"List live members of the organization this request is bound to, with username, display name, and role.\n\nOrg permission: `member:read`.","tags":["account"],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"members":{"type":"array","items":{"type":"object","properties":{"user_id":{"type":"string"},"username":{"type":["string","null"]},"display_name":{"type":["string","null"]},"avatar_url":{"type":["string","null"]},"role":{"type":"string","enum":["owner","member","billing"]}},"required":["user_id","username","display_name","avatar_url","role"],"additionalProperties":false}}},"required":["members"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"member:read","x-kody-read-only":true}},"/v1/orgs/members/{user_id}":{"patch":{"operationId":"orgMemberUpdate","summary":"Change the role of a live member of the organization this request is bound to.","description":"Change the role of a live member of the organization this request is bound to. Only an Owner can grant or change the Owner role. The last Owner cannot be demoted.\n\nOrg permission: `member:write`.","tags":["account"],"parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","minLength":1}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"username":{"type":"string","minLength":1},"role":{"type":"string","enum":["owner","member","billing"]}},"required":["role"]}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"user_id":{"type":"string"},"role":{"type":"string","enum":["owner","member","billing"]}},"required":["user_id","role"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"member:write","x-kody-read-only":false},"delete":{"operationId":"orgMemberRemove","summary":"Remove a member from the organization this request is bound to.","description":"Remove a member from the organization this request is bound to. Revokes org-bound credentials, disconnects integrations they connected, and keeps their jobs running, the same as when they leave. A retry finishes that cleanup when the membership is already tombstoned. Their team memberships in this organization end too. The last Owner cannot be removed.\n\nOrg permission: `member:delete`.","tags":["account"],"parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","minLength":1}},{"name":"username","in":"query","required":false,"schema":{"type":"string","minLength":1}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"user_id":{"type":"string"},"removed":{"type":"boolean","const":true}},"required":["user_id","removed"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"member:delete","x-kody-read-only":false}},"/v1/orgs/teams":{"get":{"operationId":"teamList","summary":"List live teams in the organization this request is bound to, with live member counts.","description":"List live teams in the organization this request is bound to, with live member counts.\n\nOrg permission: `team:read`.","tags":["account"],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"teams":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"slug":{"type":"string"},"name":{"type":"string"},"description":{"type":["string","null"]},"member_count":{"type":"integer","minimum":0,"maximum":9007199254740991}},"required":["id","slug","name","description","member_count"],"additionalProperties":false}}},"required":["teams"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"team:read","x-kody-read-only":true},"post":{"operationId":"teamCreate","summary":"Create a team in the organization this request is bound to.","description":"Create a team in the organization this request is bound to. The slug is a handle unique inside the organization.\n\nOrg permission: `team:write`.","tags":["account"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"slug":{"type":"string","minLength":1},"name":{"type":"string","minLength":1},"description":{"type":"string"}},"required":["slug","name"]}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"team":{"type":"object","properties":{"id":{"type":"string"},"slug":{"type":"string"},"name":{"type":"string"}},"required":["id","slug","name"],"additionalProperties":false}},"required":["team"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"team:write","x-kody-read-only":false}},"/v1/orgs/teams/{team_id}/members":{"post":{"operationId":"teamMemberAdd","summary":"Add an organization member to a team in the organization this request is bound to.","description":"Add an organization member to a team in the organization this request is bound to. The person must already be a live member.\n\nOrg permission: `team:write`.","tags":["account"],"parameters":[{"name":"team_id","in":"path","required":true,"schema":{"type":"string","minLength":1}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"team_slug":{"type":"string","minLength":1},"user_id":{"type":"string","minLength":1},"username":{"type":"string","minLength":1}}}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"team_id":{"type":"string"},"user_id":{"type":"string"}},"required":["team_id","user_id"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"team:write","x-kody-read-only":false}},"/v1/orgs/teams/{team_id}/members/{user_id}":{"delete":{"operationId":"teamMemberRemove","summary":"Remove a person from a team in the organization this request is bound to.","description":"Remove a person from a team in the organization this request is bound to. They stay an organization member.\n\nOrg permission: `team:delete`.","tags":["account"],"parameters":[{"name":"team_id","in":"path","required":true,"schema":{"type":"string","minLength":1}},{"name":"user_id","in":"path","required":true,"schema":{"type":"string","minLength":1}},{"name":"team_slug","in":"query","required":false,"schema":{"type":"string","minLength":1}},{"name":"username","in":"query","required":false,"schema":{"type":"string","minLength":1}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"team_id":{"type":"string"},"user_id":{"type":"string"},"removed":{"type":"boolean","const":true}},"required":["team_id","user_id","removed"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"team:delete","x-kody-read-only":false}},"/v1/search":{"get":{"operationId":"search","summary":"Search Kody capabilities, saved packages, integrations, and secret references using natural language or exact user-sc...","description":"Search Kody capabilities, saved packages, integrations, and secret references using natural language or exact user-scoped package identity. An empty call returns the domain index. Pass \"domain\" to rank or list one capability domain. Use this inside package and execute runtimes when reusable code needs the same discovery surface as the public MCP search tool.\n\nOrg permission: `search:read`.","tags":["search"],"parameters":[{"name":"query","in":"query","required":false,"description":"Natural language description, or a scoped `@owner/leaf` name, current-origin account package URL, owner-matching hosted package URL, or an exact saved-package UUID (`package_id`) when the name is not known. Optional when \"domain\" is provided.","schema":{"description":"Natural language description, or a scoped `@owner/leaf` name, current-origin account package URL, owner-matching hosted package URL, or an exact saved-package UUID (`package_id`) when the name is not known. Optional when \"domain\" is provided.","type":"string","minLength":1}},{"name":"domain","in":"query","required":false,"description":"Optional capability domain id (for example \"email\" or \"mcp:linear\"). With \"query\", ranks only that domain's capabilities; without \"query\", lists the domain's capabilities.","schema":{"description":"Optional capability domain id (for example \"email\" or \"mcp:linear\"). With \"query\", ranks only that domain's capabilities; without \"query\", lists the domain's capabilities.","type":"string","minLength":1}},{"name":"limit","in":"query","required":false,"description":"Max number of ranked results to return. Defaults to 15.","schema":{"description":"Max number of ranked results to return. Defaults to 15.","type":"integer","minimum":1,"maximum":100}},{"name":"conversationId","in":"query","required":false,"description":"Optional short conversation identifier. Ties related calls together. If you already have a `conversationId` from an earlier response in the same conversation, pass it back unchanged. Otherwise omit this field to receive a server-generated ID, then reuse the returned `conversationId` on subsequent calls - this enables optimizations like reduced response size. Do not invent your own `conversationId`.","schema":{"description":"Optional short conversation identifier. Ties related calls together. If you already have a `conversationId` from an earlier response in the same conversation, pass it back unchanged. Otherwise omit this field to receive a server-generated ID, then reuse the returned `conversationId` on subsequent calls - this enables optimizations like reduced response size. Do not invent your own `conversationId`.","type":"string","minLength":1,"maxLength":64}},{"name":"includeHiddenPackages","in":"query","required":false,"description":"Include hidden packages in search results (hidden packages are excluded by default).","schema":{"description":"Include hidden packages in search results (hidden packages are excluded by default).","type":"boolean"}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"conversationId":{"type":"string"},"matches":{"type":"array","items":{}},"offline":{"type":"boolean"},"warnings":{"type":"array","items":{"type":"string"}},"guidance":{"type":"string"},"memories":{"type":"object","properties":{"surfaced":{"type":"array","items":{}},"suppressedCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"retrievalQuery":{"type":"string"},"retrieverResults":{"type":"array","items":{}},"retrieverWarnings":{"type":"array","items":{"type":"string"}}},"required":["surfaced","suppressedCount","retrievalQuery"],"additionalProperties":false},"telemetry":{"description":"List-mode ranked search telemetry. Omitted when Jev never ran (entity-style short circuits, domain overview, domain browse, exact package identity).","type":"object","properties":{"jevRerank":{"type":"object","properties":{"enabled":{"type":"boolean"},"outcome":{"type":"string","enum":["applied","fallback-error","fallback-timeout","fallback-low-confidence","fallback-empty-after-drop","skipped-offline","skipped-no-ai","skipped-flag-off","skipped-plan","skipped-small-pool","skipped-clear-winner","skipped-empty"]},"candidatesBefore":{"type":"integer","minimum":0,"maximum":9007199254740991},"candidatesAfter":{"type":"integer","minimum":0,"maximum":9007199254740991},"droppedCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"meanConfidence":{"type":["number","null"]},"top1Type":{"type":["string","null"]},"keepPath":{"description":"Adaptive keep path after Jev Score (`kept-high` | `kept-lowered` | `kept-identity` | `empty`). Present when Score ran and mean confidence cleared the floor. `kept-identity` keeps package name, kody id, or leaf hits when every Score misses the floors.","type":"string","enum":["kept-high","kept-lowered","kept-identity","empty"]},"errorReason":{"description":"Short reason when outcome is fallback-error (gateway auth/credits, incomplete Score answers). Omitted otherwise.","type":"string","maxLength":240},"model":{"description":"Workers AI model when the Jev stage ran or attempted. Omitted when the flag is off.","type":"string","const":"typesafe/jev"},"aiCallCount":{"description":"Number of Score AI.run calls (one per question batch). Present with model.","type":"integer","minimum":0,"maximum":9007199254740991},"usage":{"description":"Summed Workers AI / Gateway token usage across Score batches. Nulls when the binding omitted usage.","type":"object","properties":{"inputTokens":{"anyOf":[{"type":"number","minimum":0},{"type":"null"}]},"outputTokens":{"anyOf":[{"type":"number","minimum":0},{"type":"null"}]}},"required":["inputTokens","outputTokens"],"additionalProperties":false}},"required":["enabled","outcome","candidatesBefore","candidatesAfter","droppedCount","meanConfidence","top1Type"],"additionalProperties":false,"description":"Jev Score rerank stage for list-mode ranked search. Present when the ranked path ran or skipped the stage. Omitted for domain overview, domain browse, empty discovery, and exact-package identity."}},"required":["jevRerank"],"additionalProperties":false},"phaseTimings":{"description":"Exclusive Jev rerank wall time in milliseconds when the ranked path computed the stage.","type":"object","properties":{"jevRerankMs":{"type":"number","minimum":0}},"additionalProperties":false},"serverTiming":{"description":"Request-scoped phase timings. Same shape as execute serverTiming. Not stored. Includes jevRerank when the Jev stage ran on the ranked path.","type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"durationMs":{"type":"number","minimum":0}},"required":["name","durationMs"],"additionalProperties":false}}},"required":["conversationId","matches","offline","warnings"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"search:read","x-kody-read-only":true}},"/v1/memories":{"get":{"operationId":"metaMemorySearch","summary":"Search the signed-in person's **personal** memories (always their personal org, regardless of which org this connecti...","description":"Search the signed-in person's **personal** memories (always their personal org, regardless of which org this connection uses). Returned matches are mutable for this person unless can_mutate is false. If you are considering writing or deleting a memory, prefer metaMemoryVerify first. Do not copy a personal memory into an org package without asking the person first.\n\nOrg permission: none (touches no org data).","tags":["memories"],"parameters":[{"name":"query","in":"query","required":true,"description":"Freeform memory search query.","schema":{"type":"string","minLength":1,"description":"Freeform memory search query."}},{"name":"category","in":"query","required":false,"description":"Optional category filter. Categories are freeform strings.","schema":{"description":"Optional category filter. Categories are freeform strings.","type":"string","minLength":1,"maxLength":120}},{"name":"limit","in":"query","required":false,"description":"Maximum memories to return. Defaults to 5.","schema":{"default":5,"description":"Maximum memories to return. Defaults to 5.","type":"integer","minimum":1,"maximum":20}},{"name":"include_deleted","in":"query","required":false,"description":"Whether to include deleted memories. Defaults to false.","schema":{"description":"Whether to include deleted memories. Defaults to false.","type":"boolean"}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"query":{"type":"string"},"matches":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"category":{"type":["string","null"]},"status":{"type":"string","enum":["active","deleted","archived"]},"subject":{"type":"string"},"summary":{"type":"string"},"details":{"type":"string"},"tags":{"type":"array","items":{"type":"string"}},"source_uris":{"type":"array","items":{"type":"string","maxLength":2048,"format":"uri"}},"dedupe_key":{"type":["string","null"]},"created_at":{"type":"string"},"updated_at":{"type":"string"},"last_accessed_at":{"type":["string","null"]},"deleted_at":{"type":["string","null"]},"score":{"type":"number"},"can_mutate":{"type":"boolean"},"mutation_guidance":{"type":"string"}},"required":["id","category","status","subject","summary","details","tags","dedupe_key","created_at","updated_at","last_accessed_at","deleted_at","score","can_mutate","mutation_guidance"],"additionalProperties":false}},"warning":{"type":"string"}},"required":["query","matches","warning"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"none","x-kody-read-only":true},"post":{"operationId":"metaMemoryUpsert","summary":"Create or update a **personal** memory for the signed-in person (always their personal org, regardless of which org t...","description":"Create or update a **personal** memory for the signed-in person (always their personal org, regardless of which org this connection uses). Agents must run `metaMemoryVerify` first. Do not blindly write durable memory without verification. Do not copy a personal memory into an org package without asking the person first. Shared org knowledge belongs in documented packages and org instructions, not memory. If the candidate is really package- or export-scoped guidance, update package docs or JSDoc instead (see search({ entity: \"guide:agent_guidance\" })).\n\nOrg permission: none (touches no org data).","tags":["memories"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"memory_id":{"description":"Optional existing memory id to update. Omit this field to create a new memory record.","type":"string","minLength":1},"category":{"description":"Optional freeform category string. Suggested examples include preference, profile, workflow, relationship, or identifier.","type":"string","maxLength":80},"subject":{"type":"string","minLength":1,"maxLength":200,"description":"Short durable subject line for the memory record (max 200 characters)."},"summary":{"type":"string","minLength":1,"maxLength":500,"description":"Compact durable summary of the memory (max 500 characters)."},"details":{"description":"Optional supporting details for the durable memory record (max 2000 characters).","type":"string","maxLength":2000},"tags":{"description":"Optional short tags for retrieval and filtering.","maxItems":12,"type":"array","items":{"type":"string","minLength":1,"maxLength":80}},"source_uris":{"description":"Optional canonical source document URLs for the memory. Treat these as opaque references.","maxItems":12,"type":"array","items":{"type":"string","maxLength":2048,"format":"uri"}},"dedupe_key":{"description":"Optional stable dedupe key supplied by the agent.","type":"string","maxLength":160},"status":{"description":"Optional non-deleted status for the memory. Defaults to active.","type":"string","enum":["active","archived"]},"verified_by_agent":{"type":"boolean","description":"Must be true when writing memory. Agents must run metaMemoryVerify first and then decide whether to upsert."},"verification_reference":{"description":"Optional agent-supplied note, run id, or verification reference describing the verify step that preceded this upsert.","type":"string","maxLength":200}},"required":["subject","summary","verified_by_agent"]}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"mode":{"type":"string","enum":["created","updated"]},"memory":{"type":"object","properties":{"id":{"type":"string"},"category":{"type":["string","null"]},"status":{"type":"string","enum":["active","deleted","archived"]},"subject":{"type":"string"},"summary":{"type":"string"},"details":{"type":"string"},"tags":{"type":"array","items":{"type":"string"}},"source_uris":{"type":"array","items":{"type":"string","maxLength":2048,"format":"uri"}},"dedupe_key":{"type":["string","null"]},"created_at":{"type":"string"},"updated_at":{"type":"string"},"last_accessed_at":{"type":["string","null"]},"deleted_at":{"type":["string","null"]}},"required":["id","category","status","subject","summary","details","tags","dedupe_key","created_at","updated_at","last_accessed_at","deleted_at"],"additionalProperties":false},"warnings":{"type":"array","items":{"type":"string"}}},"required":["mode","memory","warnings"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"none","x-kody-read-only":false}},"/v1/memories/verify":{"post":{"operationId":"metaMemoryVerify","summary":"Always run this before writing or deleting **personal** memory (always the signed-in person's personal org, regardles...","description":"Always run this before writing or deleting **personal** memory (always the signed-in person's personal org, regardless of which org this connection uses). Submit the candidate, review related memories, then decide whether to upsert, delete, both, or do nothing. Do not upsert blindly. Do not copy a personal memory into an org package without asking the person first — shared org knowledge belongs in documented packages and org instructions. If the candidate is really package- or export-scoped guidance, update package docs or JSDoc instead (see search({ entity: \"guide:agent_guidance\" })).\n\nOrg permission: none (touches no org data).","tags":["memories"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"subject":{"type":"string","minLength":1,"maxLength":200,"description":"Short durable subject line for the memory record (max 200 characters)."},"summary":{"type":"string","minLength":1,"maxLength":500,"description":"Compact durable summary of the memory (max 500 characters)."},"details":{"description":"Optional supporting details for the durable memory record (max 2000 characters).","type":"string","maxLength":2000},"category":{"description":"Optional freeform category label for the memory. Suggested examples: preference, identifier, relationship, workflow, project, profile.","type":"string","minLength":1,"maxLength":80},"tags":{"description":"Optional short tags for retrieval and filtering.","maxItems":12,"type":"array","items":{"type":"string","minLength":1,"maxLength":80}},"source_uris":{"description":"Optional canonical source document URLs for the memory. Treat these as opaque references.","maxItems":12,"type":"array","items":{"type":"string","maxLength":2048,"format":"uri"}},"dedupe_key":{"description":"Optional stable agent-supplied dedupe key for the memory. Reuse when the agent wants a deterministic durable key.","type":"string","minLength":1,"maxLength":160},"limit":{"description":"Maximum related memories to return. Defaults to 5.","type":"integer","minimum":1,"maximum":20},"conversation_id":{"description":"Optional conversation id used to suppress memories that were already surfaced in the same conversation.","type":"string","minLength":1,"maxLength":64},"include_suppressed_in_conversation":{"description":"When true, include memories even if they were already surfaced for the same conversation id.","type":"boolean"}},"required":["subject","summary"]}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"candidate":{"type":"object","properties":{"subject":{"type":"string"},"summary":{"type":"string"},"category":{"type":["string","null"]},"tags":{"type":"array","items":{"type":"string"}},"source_uris":{"type":"array","items":{"type":"string","maxLength":2048,"format":"uri"}},"dedupe_key":{"type":["string","null"]}},"required":["subject","summary","category","tags","dedupe_key"],"additionalProperties":false},"related_memories":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"category":{"type":["string","null"]},"status":{"type":"string","enum":["active","deleted","archived"]},"subject":{"type":"string"},"summary":{"type":"string"},"tags":{"type":"array","items":{"type":"string"}},"source_uris":{"type":"array","items":{"type":"string","maxLength":2048,"format":"uri"}},"dedupe_key":{"type":["string","null"]},"score":{"type":"number"}},"required":["id","category","status","subject","summary","tags","dedupe_key","score"],"additionalProperties":false}},"recommended_actions":{"type":"array","items":{"type":"string","enum":["upsert","delete","upsert_and_delete","none"]}}},"required":["candidate","related_memories","recommended_actions"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"none","x-kody-read-only":true}},"/v1/memories/{memory_id}":{"get":{"operationId":"metaMemoryGet","summary":"Load one stored **personal** memory by id for the signed-in person (always their personal org, regardless of which or...","description":"Load one stored **personal** memory by id for the signed-in person (always their personal org, regardless of which org this connection uses).\n\nOrg permission: none (touches no org data).","tags":["memories"],"parameters":[{"name":"memory_id","in":"path","required":true,"description":"Stored memory id to load.","schema":{"type":"string","minLength":1,"description":"Stored memory id to load."}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"category":{"type":["string","null"]},"status":{"type":"string","enum":["active","deleted","archived"]},"subject":{"type":"string"},"summary":{"type":"string"},"details":{"type":"string"},"tags":{"type":"array","items":{"type":"string"}},"source_uris":{"type":"array","items":{"type":"string","maxLength":2048,"format":"uri"}},"dedupe_key":{"type":["string","null"]},"created_at":{"type":"string"},"updated_at":{"type":"string"},"last_accessed_at":{"type":["string","null"]},"deleted_at":{"type":["string","null"]}},"required":["id","category","status","subject","summary","details","tags","dedupe_key","created_at","updated_at","last_accessed_at","deleted_at"],"additionalProperties":false},{"type":"null"}]}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"none","x-kody-read-only":true},"delete":{"operationId":"metaMemoryDelete","summary":"Soft-delete a **personal** memory by default, or hard-delete it when `force` is true.","description":"Soft-delete a **personal** memory by default, or hard-delete it when `force` is true. Always run `metaMemoryVerify` first. Memory is personal-only; team-org legacy rows cannot be deleted through this tool.\n\nOrg permission: none (touches no org data).","tags":["memories"],"parameters":[{"name":"memory_id","in":"path","required":true,"description":"Target memory id to delete.","schema":{"type":"string","minLength":1,"description":"Target memory id to delete."}},{"name":"force","in":"query","required":false,"description":"When true, permanently delete the record. Otherwise soft-delete it by setting status to deleted.","schema":{"description":"When true, permanently delete the record. Otherwise soft-delete it by setting status to deleted.","type":"boolean"}},{"name":"verified_by_agent","in":"query","required":true,"description":"Agent assertion that `metaMemoryVerify` was run before deletion.","schema":{"type":"boolean","description":"Agent assertion that `metaMemoryVerify` was run before deletion."}},{"name":"verification_reference","in":"query","required":false,"description":"Optional agent-supplied note or reference to the verification step that justified this deletion.","schema":{"description":"Optional agent-supplied note or reference to the verification step that justified this deletion.","type":"string","minLength":1}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"force":{"type":"boolean"},"memory":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"category":{"type":["string","null"]},"status":{"type":"string","enum":["active","deleted","archived"]},"subject":{"type":"string"},"summary":{"type":"string"},"details":{"type":"string"},"tags":{"type":"array","items":{"type":"string"}},"source_uris":{"type":"array","items":{"type":"string","maxLength":2048,"format":"uri"}},"dedupe_key":{"type":["string","null"]},"created_at":{"type":"string"},"updated_at":{"type":"string"},"last_accessed_at":{"type":["string","null"]},"deleted_at":{"type":["string","null"]}},"required":["id","category","status","subject","summary","details","tags","dedupe_key","created_at","updated_at","last_accessed_at","deleted_at"],"additionalProperties":false},{"type":"null"}]},"guidance":{"type":"string"}},"required":["ok","force","memory","guidance"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"none","x-kody-read-only":false}},"/v1/mcp-server-instructions":{"get":{"operationId":"metaGetMcpServerInstructions","summary":"Read the signed-in user’s custom MCP server instructions overlay (if any).","description":"Read the signed-in user’s custom MCP server instructions overlay (if any). Empty means none. Same character limit as set. Put guidance at the right layer: see search({ entity: \"guide:agent_guidance\" }) (Where agent guidance lives / /docs/agent-guidance). Prefer memories for durable facts and preferences; the overlay is only for rare always-on session policy. Reports assembled_chars and a warning when some clients would truncate the overlay.\n\nOrg permission: `org:read`.","tags":["memories"],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"instructions":{"type":["string","null"]},"max_length":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},"assembled_chars":{"type":"integer","minimum":0,"maximum":9007199254740991},"warning":{"type":["string","null"]}},"required":["instructions","max_length","assembled_chars","warning"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"org:read","x-kody-read-only":true},"put":{"operationId":"metaSetMcpServerInstructions","summary":"Replace or clear the signed-in user’s custom MCP server instructions overlay (appended to built-in server instruction...","description":"Replace or clear the signed-in user’s custom MCP server instructions overlay (appended to built-in server instructions for new MCP connections). Put guidance at the right layer: see search({ entity: \"guide:agent_guidance\" }) (Where agent guidance lives / /docs/agent-guidance). Prefer memories for durable facts and preferences; use this overlay only for rare always-on session policy—not package inventory, export gotchas, or package docs. Pass an empty string to clear. Changes apply to new MCP sessions—reconnect the client if the host caches server instructions. Reports assembled_chars and a warning when some clients would truncate the overlay.\n\nOrg permission: `org:write`.","tags":["memories"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"instructions":{"type":"string","maxLength":4000,"description":"Full replacement text for the user overlay, or empty string to remove it."}},"required":["instructions"]}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"max_length":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},"instructions":{"type":["string","null"]},"assembled_chars":{"type":"integer","minimum":0,"maximum":9007199254740991},"warning":{"type":["string","null"]}},"required":["ok","max_length","instructions","assembled_chars","warning"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"org:write","x-kody-read-only":false}},"/v1/secrets":{"get":{"operationId":"secretList","summary":"List available secret references for the signed-in user.","description":"List available secret references for the signed-in user. Results include metadata such as names, credential ids (for accessGrant), descriptions, allowed hosts, allowed packages, and package_id for package-scoped secrets — never plaintext values. Explicit listing includes caller-owned package-scoped metadata from execute (no package runtime); using a package secret still requires package context. From a package runtime, self-authored and adopted packages see user secrets they can already read; unadopted community forks see only explicitly granted user secrets. Listing a secret does not approve a host: outbound `fetch` still resolves `{{secret:name}}` (optionally `{{secret:name|scope=user}}`) only for approved hosts. Use `kody.secretList({ scope })` inside execute-time code for the same metadata. Use `/connect/secret-set` for user-provided API key, token, and credential entry or rotation.\n\nOrg permission: `secret:use`.","tags":["secrets"],"parameters":[{"name":"scope","in":"query","required":false,"description":"Optional scope filter. When omitted, list all accessible scopes. Package-scoped metadata is included for caller-owned secrets (with package_id) even without a package runtime; session secrets stay session-bound. Using a package secret still requires package context.","schema":{"description":"Optional scope filter. When omitted, list all accessible scopes. Package-scoped metadata is included for caller-owned secrets (with package_id) even without a package runtime; session secrets stay session-bound. Using a package secret still requires package context.","type":"string","enum":["session","package","user"]}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"secrets":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"scope":{"type":"string","enum":["session","package","user"]},"description":{"type":"string"},"package_id":{"type":["string","null"]},"allowed_hosts":{"type":"array","items":{"type":"string"}},"allowed_packages":{"type":"array","items":{"type":"string"}},"created_at":{"type":"string"},"updated_at":{"type":"string"},"expires_at":{"type":["string","null"]},"ttl_ms":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]},"kind":{"description":"Credential kind, returned when this call set opt-in fields.","type":"string","enum":["secret","url","login","signing"]},"provider":{"type":["string","null"]},"inject":{"oneOf":[{"type":"object","properties":{"kind":{"type":"string","const":"header"},"name":{"type":"string","pattern":"^[!#$%&'*+\\-.^_`|~0-9A-Za-z]+$"},"format":{"type":"string","maxLength":200}},"required":["kind","name","format"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"basic"},"valueAs":{"type":"string","enum":["username","password"]},"other":{"default":"","type":"string","maxLength":200}},"required":["kind","valueAs"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"query"},"param":{"type":"string","minLength":1,"maxLength":100}},"required":["kind","param"],"additionalProperties":false}]},"credential_id":{"type":"string","description":"Stable credential id. accessGrant uses it as resource_id."}},"required":["name","scope","description","package_id","allowed_hosts","allowed_packages","created_at","updated_at","expires_at","ttl_ms","credential_id"],"additionalProperties":false}}},"required":["secrets"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"secret:use","x-kody-read-only":true}},"/v1/secrets/batch":{"post":{"operationId":"secretSetMany","summary":"Assert authorization for, and optionally atomically persist, multiple secret references for the signed-in user (API k...","description":"Assert authorization for, and optionally atomically persist, multiple secret references for the signed-in user (API keys, PATs, HMAC secrets). Use assertOnly before a multi-write that must not partially succeed. Do not use this for OAuth access or refresh tokens — `/connect/oauth` and `createAuthenticatedFetch` / `integrationTokenRefresh` persist those on the connection. Host use is authorized through secret policy approvals. Saved secrets are consumed in outbound `fetch` calls by placeholder, e.g. `{{secret:name}}`, resolved only for approved hosts.\n\nOrg permission: `secret:write`.","tags":["secrets"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"secrets":{"minItems":1,"type":"array","items":{"type":"object","properties":{"name":{"type":"string","minLength":1,"description":"Secret name to create or update."},"value":{"description":"Secret value to persist. Required unless assertOnly is true. Write-only and must never be returned to the caller.","type":"string","minLength":1},"description":{"description":"Optional human-readable description of the secret.","type":"string"},"expires_at":{"description":"Optional UTC ISO expiry (or YYYY-MM-DD). Null or empty clears expiry. Omit on update to leave the existing expiry unchanged.","type":["string","null"]},"scope":{"type":"string","enum":["session","package","user"],"description":"Storage scope that owns the secret."}},"required":["name","scope"],"additionalProperties":false},"description":"Secrets to assert and optionally persist. Order is preserved. Do not include OAuth access or refresh tokens — those persist on the connection."},"assertOnly":{"description":"When true, only authorize the writes (no values required) and do not persist. Use before a multi-write that must not partially succeed.","type":"boolean"}},"required":["secrets"]}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"assertOnly":{"type":"boolean"},"secrets":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"scope":{"type":"string","enum":["session","package","user"]},"description":{"type":"string"},"package_id":{"type":["string","null"]},"allowed_hosts":{"type":"array","items":{"type":"string"}},"allowed_packages":{"type":"array","items":{"type":"string"}},"created_at":{"type":"string"},"updated_at":{"type":"string"},"expires_at":{"type":["string","null"]},"ttl_ms":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]},"kind":{"description":"Credential kind, returned when this call set opt-in fields.","type":"string","enum":["secret","url","login","signing"]},"provider":{"type":["string","null"]},"inject":{"oneOf":[{"type":"object","properties":{"kind":{"type":"string","const":"header"},"name":{"type":"string","pattern":"^[!#$%&'*+\\-.^_`|~0-9A-Za-z]+$"},"format":{"type":"string","maxLength":200}},"required":["kind","name","format"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"basic"},"valueAs":{"type":"string","enum":["username","password"]},"other":{"default":"","type":"string","maxLength":200}},"required":["kind","valueAs"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"query"},"param":{"type":"string","minLength":1,"maxLength":100}},"required":["kind","param"],"additionalProperties":false}]}},"required":["name","scope","description","package_id","allowed_hosts","allowed_packages","created_at","updated_at","expires_at","ttl_ms"],"additionalProperties":false}}},"required":["ok","assertOnly","secrets"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"secret:write","x-kody-read-only":false}},"/v1/secrets/lock":{"post":{"operationId":"secretLock","summary":"Return a website approval URL so the account owner can grant a user-scoped secret to a saved package (one-click Allow...","description":"Return a website approval URL so the account owner can grant a user-scoped secret to a saved package (one-click Allow, same spirit as /connect/secrets host approval). This capability does not change allowed_packages. Send the approval_url to the user and wait; never treat this call as a grant. Only the owner can add a grant at /@<slug>/-/secrets/approve or the secret editor. Removing a grant is also website-only. User secrets still allow execute and self-authored / adopted packages to read unless the owner tightens further on the account page. secretSet cannot change allowed_packages.\n\nOrg permission: `secret:use`.","tags":["secrets"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"name":{"type":"string","minLength":1,"description":"User-scoped secret name to grant."},"package_id":{"type":"string","minLength":1,"description":"Saved package id that may use this secret."}},"required":["name","package_id"]}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"scope":{"type":"string","const":"user"},"allowed_packages":{"type":"array","items":{"type":"string"}},"usage_url":{"type":"string"},"status":{"type":"string","enum":["approval_required","already_granted"]},"approval_url":{"type":"string"},"message":{"type":"string"}},"required":["name","scope","allowed_packages","usage_url","status","approval_url","message"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"secret:use","x-kody-read-only":true}},"/v1/secrets/jwt":{"post":{"operationId":"secretJwtSign","summary":"Sign a JWT with a key stored in a saved secret without revealing the key.","description":"Sign a JWT with a key stored in a saved secret without revealing the key. HMAC algorithms (HS256, HS384, HS512) use key material from the secret; RS*, PS*, ES*, and EdDSA use a PKCS#8 PEM private key. This generic primitive only signs caller-provided header and claims; package or execute code should perform any OAuth token exchange separately.\n\nOrg permission: `secret:use`.","tags":["secrets"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"private_key_secret_name":{"type":"string","minLength":1,"description":"Saved signing-key secret name, or an opaque {{secret:…}} ref from packageSecrets.get. PKCS#8 PEM for RS*, PS*, ES*, and EdDSA, or HMAC key material for HS*."},"private_key_secret_scope":{"description":"Optional secret scope. When omitted, Kody checks accessible scopes in precedence order.","type":"string","enum":["session","package","user"]},"private_key_json_field":{"description":"Optional JSON object field containing the signing key, for example \"private_key\" for service-account JSON.","type":"string","minLength":1},"algorithm":{"default":"RS256","type":"string","enum":["RS256","RS384","RS512","PS256","PS384","PS512","ES256","ES384","ES512","EdDSA","HS256","HS384","HS512"]},"key_encoding":{"description":"HMAC key encoding when algorithm is HS256, HS384, or HS512. Defaults to base64 (DoorDash Drive signing_secret). Not valid for RS*, PS*, ES*, or EdDSA.","type":"string","enum":["base64","utf8","base64url"]},"header":{"description":"Optional JWT header fields. \"alg\" must match the requested algorithm when provided.","type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"claims":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{},"description":"JWT claims to sign."}},"required":["private_key_secret_name","claims"]}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"jwt":{"type":"string"},"algorithm":{"type":"string","enum":["RS256","RS384","RS512","PS256","PS384","PS512","ES256","ES384","ES512","EdDSA","HS256","HS384","HS512"]}},"required":["jwt","algorithm"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"secret:use","x-kody-read-only":true}},"/v1/secrets/{scope}/{name}":{"put":{"operationId":"secretSet","summary":"Create or update a stored secret reference for the signed-in user.","description":"Create or update a stored secret reference for the signed-in user. Use this for API keys, PATs, webhook HMAC secrets, and other static credentials already available inside trusted execution. Do not persist OAuth access or refresh tokens here — `/connect/oauth` and `createAuthenticatedFetch` / `integrationTokenRefresh` write those on the connection. Optional expires_at is a UTC ISO timestamp or YYYY-MM-DD; null clears expiry. Updates that only change description or expiry may omit value. Use `/connect/secret-set` for user-provided API key, PAT, and credential entry or rotation. Host use is authorized through secret policy approvals. Saved secrets are consumed in outbound `fetch` calls by placeholder, e.g. `{{secret:name}}`, resolved only for approved hosts.\n\nOrg permission: `secret:write`.","tags":["secrets"],"parameters":[{"name":"scope","in":"path","required":true,"description":"Storage scope that owns the secret.","schema":{"type":"string","enum":["session","package","user"],"description":"Storage scope that owns the secret."}},{"name":"name","in":"path","required":true,"description":"Secret name to create or update.","schema":{"type":"string","minLength":1,"description":"Secret name to create or update."}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"value":{"description":"Secret value to persist. Required when creating a secret. Optional on updates that only change description or expires_at. Write-only and must never be returned to the caller.","type":"string","minLength":1},"description":{"description":"Optional human-readable description of the secret.","type":"string"},"expires_at":{"description":"Optional UTC ISO expiry (or YYYY-MM-DD). Null or empty clears expiry. Omit on update to leave the existing expiry unchanged.","type":["string","null"]},"kind":{"description":"Optional credential kind (ADR 0068), set together with a value. \"secret\" (default) is a Key used by `{{secret:name}}` placeholders. \"url\", \"login\", and \"signing\" are opt-in kinds a package reads through a scoped credential client, never as raw text; they need `hosts`.","type":"string","enum":["secret","url","login","signing"]},"hosts":{"description":"Hosts an opt-in kind may be sent to: exact hosts or one wildcard level such as *.example.com. Set together with a value. Keys keep using host approvals instead.","minItems":1,"maxItems":20,"type":"array","items":{"type":"string","minLength":1,"maxLength":253}},"login_exchange":{"description":"For kind \"login\": how the login fields are exchanged for a session token. Its url must be on one of `hosts`.","type":"object","properties":{"url":{"type":"string","minLength":1},"method":{"default":"POST","type":"string","enum":["POST","PUT"]},"bodyFormat":{"type":"string","enum":["json","form"]},"body":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}},"tokenPath":{"type":"string","minLength":1},"expiresInPath":{"type":"string","minLength":1},"ttlSeconds":{"default":3600,"type":"integer","exclusiveMinimum":0,"maximum":86400}},"required":["url","bodyFormat","body","tokenPath"],"additionalProperties":false},"provider":{"description":"Optional provider slug (for example \"github\") a scoped credential client matches package needs against. Null clears it. Keys used by placeholders ignore it.","anyOf":[{"type":"string","pattern":"^[a-z0-9-]{1,64}$"},{"type":"null"}]},"inject":{"description":"Optional placement for a scoped credential client: a header with a \"{value}\" format, basic auth, or a query parameter. Defaults to `Authorization: Bearer {value}`. Placeholders ignore it.","oneOf":[{"type":"object","properties":{"kind":{"type":"string","const":"header"},"name":{"type":"string","pattern":"^[!#$%&'*+\\-.^_`|~0-9A-Za-z]+$"},"format":{"type":"string","maxLength":200}},"required":["kind","name","format"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"basic"},"valueAs":{"type":"string","enum":["username","password"]},"other":{"default":"","type":"string","maxLength":200}},"required":["kind","valueAs"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"query"},"param":{"type":"string","minLength":1,"maxLength":100}},"required":["kind","param"],"additionalProperties":false}]}}}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"scope":{"type":"string","enum":["session","package","user"]},"description":{"type":"string"},"package_id":{"type":["string","null"]},"allowed_hosts":{"type":"array","items":{"type":"string"}},"allowed_packages":{"type":"array","items":{"type":"string"}},"created_at":{"type":"string"},"updated_at":{"type":"string"},"expires_at":{"type":["string","null"]},"ttl_ms":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]},"kind":{"description":"Credential kind, returned when this call set opt-in fields.","type":"string","enum":["secret","url","login","signing"]},"provider":{"type":["string","null"]},"inject":{"oneOf":[{"type":"object","properties":{"kind":{"type":"string","const":"header"},"name":{"type":"string","pattern":"^[!#$%&'*+\\-.^_`|~0-9A-Za-z]+$"},"format":{"type":"string","maxLength":200}},"required":["kind","name","format"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"basic"},"valueAs":{"type":"string","enum":["username","password"]},"other":{"default":"","type":"string","maxLength":200}},"required":["kind","valueAs"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"query"},"param":{"type":"string","minLength":1,"maxLength":100}},"required":["kind","param"],"additionalProperties":false}]}},"required":["name","scope","description","package_id","allowed_hosts","allowed_packages","created_at","updated_at","expires_at","ttl_ms"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"secret:write","x-kody-read-only":false},"delete":{"operationId":"secretDelete","summary":"Delete an existing secret reference for the signed-in user.","description":"Delete an existing secret reference for the signed-in user. Plaintext values stay hidden. Use `/connect/secret-set` for user-provided API key, token, and credential entry or rotation. Use this to remove execute-time access to a secret.\n\nOrg permission: `secret:delete`.","tags":["secrets"],"parameters":[{"name":"scope","in":"path","required":true,"description":"Scope that owns the secret being deleted.","schema":{"type":"string","enum":["session","package","user"],"description":"Scope that owns the secret being deleted."}},{"name":"name","in":"path","required":true,"description":"Secret name to delete.","schema":{"type":"string","minLength":1,"description":"Secret name to delete."}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"deleted":{"type":"boolean"}},"required":["deleted"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"secret:delete","x-kody-read-only":false}},"/v1/credentials":{"get":{"operationId":"credentialList","summary":"List every credential you can use in this org as one shape: Keys (secrets) and the opt-in url, login, and signing kin...","description":"List every credential you can use in this org as one shape: Keys (secrets) and the opt-in url, login, and signing kinds, OAuth integrations, and MCP servers (kind \"mcp\"). Includes your own personal credentials granted to this org (scope \"personal\"). Filter by text, kind, scope, package-scoped Keys, or package locks. Metadata only: never values. To add one, send the person to /connect/credential (kind, kindMode=hint|required, name, provider, allowedHosts).\n\nOrg permission: none (touches no org data).","tags":["secrets"],"parameters":[{"name":"q","in":"query","required":false,"description":"Substring of name, provider, description, or host.","schema":{"description":"Substring of name, provider, description, or host.","type":"string"}},{"name":"kinds","in":"query","required":false,"schema":{"type":"array","items":{"type":"string","enum":["secret","oauth","mcp","url","login","signing"]}},"style":"form","explode":true},{"name":"scope","in":"query","required":false,"schema":{"type":"string","enum":["org","personal"]}},{"name":"packageScoped","in":"query","required":false,"description":"true: only package-scoped Keys; false: exclude them.","schema":{"description":"true: only package-scoped Keys; false: exclude them.","type":"boolean"}},{"name":"locked","in":"query","required":false,"description":"true: locked to any package; a package id: locked to it.","schema":{"description":"true: locked to any package; a package id: locked to it.","anyOf":[{"type":"boolean","const":true},{"type":"string","minLength":1}]}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"credentials":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Credential id (accessGrant, credentialUpdate)."},"kind":{"type":"string","enum":["secret","oauth","mcp","url","login","signing"]},"name":{"type":"string"},"scope":{"type":"string","enum":["org","personal"],"description":"personal: your own credential granted to this org."},"provider":{"type":["string","null"]},"description":{"type":"string"},"hosts":{"type":"array","items":{"type":"string"}},"inject":{"anyOf":[{"oneOf":[{"type":"object","properties":{"kind":{"type":"string","const":"header"},"name":{"type":"string"},"format":{"type":"string"}},"required":["kind","name","format"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"basic"},"valueAs":{"type":"string","enum":["username","password"]},"other":{"type":"string"}},"required":["kind","valueAs","other"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"query"},"param":{"type":"string"}},"required":["kind","param"],"additionalProperties":false}]},{"type":"null"}]},"packageId":{"description":"Set for a package-scoped Key: the package it belongs to.","type":["string","null"]},"lockedToPackageIds":{"type":"array","items":{"type":"string"},"description":"Non-empty when only these packages may use it."},"expiresAt":{"type":["string","null"]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"},"status":{"type":"string","enum":["ok","expired","needs_attention","disabled"]},"statusMessage":{"type":["string","null"]},"mcp":{"anyOf":[{"type":"object","properties":{"url":{"type":"string"},"enabled":{"type":"boolean"}},"required":["url","enabled"],"additionalProperties":false},{"type":"null"}]}},"required":["id","kind","name","scope","provider","description","hosts","inject","packageId","lockedToPackageIds","expiresAt","createdAt","updatedAt","status","statusMessage","mcp"],"additionalProperties":false}}},"required":["credentials"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"none","x-kody-read-only":true}},"/v1/credentials/{credential_id}":{"patch":{"operationId":"credentialUpdate","summary":"Set a credential's provider and/or inject (ADR 0068): which package credential needs it can satisfy, and where a scop...","description":"Set a credential's provider and/or inject (ADR 0068): which package credential needs it can satisfy, and where a scoped `credential(key)` client puts its value. Works for user-scope secrets, OAuth connections, and MCP servers by credential id; needs Write on that credential and is audited. `{{secret:name}}` placeholders ignore both fields, so existing Keys keep working unchanged. Never takes or returns a value.\n\nOrg permission: none (touches no org data).","tags":["secrets"],"parameters":[{"name":"credential_id","in":"path","required":true,"description":"Credential id from secretList, the integrations list, or packageGet credential options.","schema":{"type":"string","minLength":1,"description":"Credential id from secretList, the integrations list, or packageGet credential options."}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"provider":{"description":"Provider slug (for example \"github\") package credential needs match against. Null clears it.","anyOf":[{"type":"string","pattern":"^[a-z0-9-]{1,64}$"},{"type":"null"}]},"inject":{"description":"How a scoped credential client places a secret's value: a header with a \"{value}\" format, basic auth, or a query parameter. OAuth connections and MCP servers always use Authorization: Bearer.","oneOf":[{"type":"object","properties":{"kind":{"type":"string","const":"header"},"name":{"type":"string","pattern":"^[!#$%&'*+\\-.^_`|~0-9A-Za-z]+$"},"format":{"type":"string","maxLength":200}},"required":["kind","name","format"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"basic"},"valueAs":{"type":"string","enum":["username","password"]},"other":{"default":"","type":"string","maxLength":200}},"required":["kind","valueAs"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"query"},"param":{"type":"string","minLength":1,"maxLength":100}},"required":["kind","param"],"additionalProperties":false}]}}}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"credential_id":{"type":"string"},"credential_kind":{"type":"string","enum":["secret","integration","mcp-server"]},"name":{"type":"string"},"provider":{"type":["string","null"]},"inject":{"oneOf":[{"type":"object","properties":{"kind":{"type":"string","const":"header"},"name":{"type":"string","pattern":"^[!#$%&'*+\\-.^_`|~0-9A-Za-z]+$"},"format":{"type":"string","maxLength":200}},"required":["kind","name","format"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"basic"},"valueAs":{"type":"string","enum":["username","password"]},"other":{"default":"","type":"string","maxLength":200}},"required":["kind","valueAs"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"query"},"param":{"type":"string","minLength":1,"maxLength":100}},"required":["kind","param"],"additionalProperties":false}]}},"required":["credential_id","credential_kind","name","provider","inject"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"none","x-kody-read-only":false}},"/v1/credential-proposals":{"post":{"operationId":"credentialMappingPropose","summary":"Propose which credentials a package uses: org default mappings (defaults), your own defaults (mine), per-trigger mapp...","description":"Propose which credentials a package uses: org default mappings (defaults), your own defaults (mine), per-trigger mappings for your instance of a cron job, subscription, or webhook (triggers), and triggers to turn on with no mapping (enable). Never writes a mapping. Returns an approval URL to send to the person; nothing changes until they review it and click Approve, which applies every change at once and turns on every trigger it maps or enables. A webhook URL must be minted before it can be approved; minting alone does not turn it on. email.message.received and email.message.quarantined run only for a sender: pass sender (kind member, address, domain, or any_authenticated, and value except for any_authenticated) so the approval link names who it runs for. view.canApprove false lists what to fix first in view.changes[].error, view.enable[].error, and view.errors (unknown need or trigger, unminted webhook, missing or ambiguous credential with a createUrl, kind or provider mismatch, org defaults without package:write). Once the person approves, credentialTriggerPickSet can set those trigger picks again later. Needs package:execute on the package.\n\nOrg permission: none (touches no org data).","tags":["secrets"],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"packageId":{"description":"Saved-package UUID. Use when the scoped name is not known, or for a stable ref.","type":"string","minLength":1},"kodyId":{"description":"Package name (`@owner/leaf` or the name leaf). Prefer this when you know the name.","type":"string","minLength":1},"defaults":{"description":"Org default mappings, keyed by need key.","type":"object","propertyNames":{"type":"string","minLength":1},"additionalProperties":{"anyOf":[{"anyOf":[{"type":"object","properties":{"id":{"type":"string","minLength":1}},"required":["id"],"additionalProperties":false},{"type":"object","properties":{"name":{"type":"string","minLength":1},"scope":{"type":"string","enum":["org","personal"]}},"required":["name"],"additionalProperties":false}]},{"type":"array","items":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","minLength":1}},"required":["id"],"additionalProperties":false},{"type":"object","properties":{"name":{"type":"string","minLength":1},"scope":{"type":"string","enum":["org","personal"]}},"required":["name"],"additionalProperties":false}]}}],"description":"A credential by { name } (optionally with scope \"org\" or \"personal\") or { id }, or an array of them. [] maps the need to \"none on purpose\"."}},"mine":{"description":"Your own default mappings, keyed by need key.","type":"object","propertyNames":{"type":"string","minLength":1},"additionalProperties":{"anyOf":[{"anyOf":[{"type":"object","properties":{"id":{"type":"string","minLength":1}},"required":["id"],"additionalProperties":false},{"type":"object","properties":{"name":{"type":"string","minLength":1},"scope":{"type":"string","enum":["org","personal"]}},"required":["name"],"additionalProperties":false}]},{"type":"array","items":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","minLength":1}},"required":["id"],"additionalProperties":false},{"type":"object","properties":{"name":{"type":"string","minLength":1},"scope":{"type":"string","enum":["org","personal"]}},"required":["name"],"additionalProperties":false}]}}],"description":"A credential by { name } (optionally with scope \"org\" or \"personal\") or { id }, or an array of them. [] maps the need to \"none on purpose\"."}},"triggers":{"type":"array","items":{"type":"object","properties":{"kind":{"type":"string","enum":["cron","subscription","webhook"]},"name":{"type":"string","minLength":1,"description":"Job name, subscription topic, or webhook name."},"credentials":{"type":"object","propertyNames":{"type":"string","minLength":1},"additionalProperties":{"anyOf":[{"anyOf":[{"type":"object","properties":{"id":{"type":"string","minLength":1}},"required":["id"],"additionalProperties":false},{"type":"object","properties":{"name":{"type":"string","minLength":1},"scope":{"type":"string","enum":["org","personal"]}},"required":["name"],"additionalProperties":false}]},{"type":"array","items":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","minLength":1}},"required":["id"],"additionalProperties":false},{"type":"object","properties":{"name":{"type":"string","minLength":1},"scope":{"type":"string","enum":["org","personal"]}},"required":["name"],"additionalProperties":false}]}}],"description":"A credential by { name } (optionally with scope \"org\" or \"personal\") or { id }, or an array of them. [] maps the need to \"none on purpose\"."},"description":"Mappings for your instance of this trigger, keyed by need key."}},"required":["kind","name","credentials"],"additionalProperties":false}},"enable":{"description":"Triggers to turn on for the approver even though they map nothing, such as a webhook with no credential needs.","type":"array","items":{"type":"object","properties":{"kind":{"type":"string","enum":["cron","subscription","webhook"]},"name":{"type":"string","minLength":1,"description":"Job name, subscription topic, or webhook name."}},"required":["kind","name"],"additionalProperties":false}},"reason":{"description":"Shown to the approver as an untrusted note.","type":"string","maxLength":500},"sender":{"description":"Sender an inbound-email subscription runs for. Required when enabling email.message.received or email.message.quarantined.","type":"object","properties":{"kind":{"type":"string","enum":["member","address","domain","any_authenticated"]},"value":{"description":"Person id, email address, or bare domain. Omit for any_authenticated.","type":["string","null"]}},"required":["kind"],"additionalProperties":false}}}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"approvalUrl":{"type":"string"},"view":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"package":{"type":"object","properties":{"id":{"type":"string"},"kodyId":{"type":"string"}},"required":["id","kodyId"],"additionalProperties":false},"reason":{"type":["string","null"]},"canApprove":{"type":"boolean"},"fingerprint":{"type":"string"},"changes":{"type":"array","items":{"type":"object","properties":{"target":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","const":"default"},"layer":{"type":"string","enum":["org","mine"]}},"required":["type","layer"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"trigger"},"trigger":{"type":"object","properties":{"kind":{"type":"string","enum":["cron","subscription","webhook"]},"name":{"type":"string"}},"required":["kind","name"],"additionalProperties":false}},"required":["type","trigger"],"additionalProperties":false}]},"needKey":{"type":"string"},"need":{"anyOf":[{"type":"object","properties":{"kind":{"anyOf":[{"type":"string","enum":["secret","oauth","mcp","url","login","signing"]},{"type":"null"}]},"provider":{"type":"string"},"description":{"type":"string"},"multiple":{"type":"boolean"}},"required":["kind","provider","description","multiple"],"additionalProperties":false},{"type":"null"}]},"before":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"scope":{"type":"string","enum":["org","personal"]},"kind":{"type":"string","enum":["secret","oauth","mcp","url","login","signing"]}},"required":["id","name","scope","kind"],"additionalProperties":false}},{"type":"null"}],"description":"The stored override today; null means it inherits."},"beforeUnusableIds":{"type":"array","items":{"type":"string"},"description":"Stored credential ids left out of before because you can no longer use them (deleted or Use revoked)."},"after":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"scope":{"type":"string","enum":["org","personal"]},"kind":{"type":"string","enum":["secret","oauth","mcp","url","login","signing"]}},"required":["id","name","scope","kind"],"additionalProperties":false}},"willEnable":{"type":"boolean","description":"Approving turns this trigger on for the approver."},"error":{"anyOf":[{"type":"object","properties":{"code":{"type":"string","enum":["need_unknown","trigger_unknown","credential_not_found","credential_ambiguous","kind_mismatch","provider_mismatch","too_many","not_allowed","webhook_not_minted","webhook_other_enabler","email_approval_required"]},"message":{"type":"string"},"createUrl":{"type":"string"}},"required":["code","message"],"additionalProperties":false},{"type":"null"}]}},"required":["target","needKey","need","before","beforeUnusableIds","after","willEnable","error"],"additionalProperties":false}},"sender":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string","enum":["member","address","domain","any_authenticated"]},"value":{"type":["string","null"]}},"required":["kind","value"],"additionalProperties":false},{"type":"null"}],"description":"Sender stored when this proposal turns on an inbound-email subscription. Null when the link names no sender."},"enable":{"type":"array","items":{"type":"object","properties":{"trigger":{"type":"object","properties":{"kind":{"type":"string","enum":["cron","subscription","webhook"]},"name":{"type":"string"}},"required":["kind","name"],"additionalProperties":false},"willEnable":{"type":"boolean","description":"False when it is already on for the approver."},"error":{"anyOf":[{"type":"object","properties":{"code":{"type":"string","enum":["need_unknown","trigger_unknown","credential_not_found","credential_ambiguous","kind_mismatch","provider_mismatch","too_many","not_allowed","webhook_not_minted","webhook_other_enabler","email_approval_required"]},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false},{"type":"null"}]}},"required":["trigger","willEnable","error"],"additionalProperties":false}},"errors":{"type":"array","items":{"type":"string"}}},"required":["ok","package","reason","canApprove","fingerprint","changes","sender","enable","errors"],"additionalProperties":false},"message":{"type":"string"}},"required":["approvalUrl","view","message"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"none","x-kody-read-only":false}},"/v1/personal-credential-grants":{"get":{"operationId":"credentialOrgGrantList","summary":"List the orgs your personal credentials are granted to (ADR 0068), optionally for one credential.","description":"List the orgs your personal credentials are granted to (ADR 0068), optionally for one credential. `active` is false when a grant does not work right now: the credential's value expired, its OAuth connection is disconnected, its MCP server is disabled, or you no longer belong to the org. Lists only your own grants, never anyone else's. Never returns values.\n\nOrg permission: none (touches no org data).","tags":["secrets"],"parameters":[{"name":"credential_id","in":"query","required":false,"description":"Credential id of a secret, OAuth connection, or MCP server in your personal org (secretList or credentialList there).","schema":{"type":"string","minLength":1,"description":"Credential id of a secret, OAuth connection, or MCP server in your personal org (secretList or credentialList there)."}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"grants":{"type":"array","items":{"type":"object","properties":{"credential_id":{"type":"string"},"credential_kind":{"type":"string","enum":["secret","integration","mcp-server"]},"name":{"type":"string"},"org":{"type":"object","properties":{"id":{"type":"string"},"slug":{"type":"string"},"display_name":{"type":["string","null"]}},"required":["id","slug","display_name"],"additionalProperties":false},"created_at":{"type":"string"},"active":{"type":"boolean"}},"required":["credential_id","credential_kind","name","org","created_at","active"],"additionalProperties":false}}},"required":["grants"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"none","x-kody-read-only":true}},"/v1/personal-credential-grants/{credential_id}/{org}":{"put":{"operationId":"credentialOrgGrant","summary":"Grant one of your personal credentials (a secret, OAuth connection, or MCP server in your personal org) to an org you...","description":"Grant one of your personal credentials (a secret, OAuth connection, or MCP server in your personal org) to an org you belong to (ADR 0068). It then works in that org only in your own runs, for scoped `credential(key)` clients; nobody else there can use it, Owners and Automation included. Granting again is a no-op. Needs Write on the credential (a token needs secret:write, or integration:write for OAuth connections and MCP servers) and a live person, and is audited in your personal org. `{{secret:name}}` placeholders never resolve personal credentials. Never takes or returns a value.\n\nOrg permission: none (touches no org data).","tags":["secrets"],"parameters":[{"name":"credential_id","in":"path","required":true,"description":"Credential id of a secret, OAuth connection, or MCP server in your personal org (secretList or credentialList there).","schema":{"type":"string","minLength":1,"description":"Credential id of a secret, OAuth connection, or MCP server in your personal org (secretList or credentialList there)."}},{"name":"org","in":"path","required":true,"description":"Slug of the org. Defaults to the org this request is bound to when that is not your personal org.","schema":{"description":"Slug of the org. Defaults to the org this request is bound to when that is not your personal org.","type":"string","minLength":1}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{}}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"credential_id":{"type":"string"},"credential_kind":{"type":"string","enum":["secret","integration","mcp-server"]},"name":{"type":"string"},"org":{"type":"object","properties":{"id":{"type":"string"},"slug":{"type":"string"}},"required":["id","slug"],"additionalProperties":false},"created":{"type":"boolean","description":"False when the credential was already granted to the org."}},"required":["credential_id","credential_kind","name","org","created"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"none","x-kody-read-only":false},"delete":{"operationId":"credentialOrgRevoke","summary":"Revoke one org's grant of your personal credential (ADR 0068).","description":"Revoke one org's grant of your personal credential (ADR 0068). Your runs in that org stop resolving it right away; the credential itself stays in your personal org. Needs Write on the credential and a live person, and is audited in your personal org.\n\nOrg permission: none (touches no org data).","tags":["secrets"],"parameters":[{"name":"credential_id","in":"path","required":true,"description":"Credential id of a secret, OAuth connection, or MCP server in your personal org (secretList or credentialList there).","schema":{"type":"string","minLength":1,"description":"Credential id of a secret, OAuth connection, or MCP server in your personal org (secretList or credentialList there)."}},{"name":"org","in":"path","required":true,"description":"Slug of the org. Defaults to the org this request is bound to when that is not your personal org.","schema":{"description":"Slug of the org. Defaults to the org this request is bound to when that is not your personal org.","type":"string","minLength":1}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"credential_id":{"type":"string"},"org":{"type":"object","properties":{"id":{"type":"string"},"slug":{"type":"string"}},"required":["id","slug"],"additionalProperties":false},"revoked":{"type":"boolean","description":"False when the credential was not granted to the org."}},"required":["credential_id","org","revoked"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"none","x-kody-read-only":false}},"/v1/credential-trigger-picks":{"put":{"operationId":"credentialTriggerPickSet","summary":"Set which credentials one need uses for your instance of a trigger (cron job, subscription, or webhook), but only to ...","description":"Set which credentials one need uses for your instance of a trigger (cron job, subscription, or webhook), but only to a value you already proposed with credentialMappingPropose and the person approved from that link, for example to switch back after the pick changed. The pick is resolved and written the same way Approve writes it. Anything else is refused: propose it instead. Never turns a trigger on; a trigger that is off needs approval. Needs package:execute on the package and an agent credential (MCP OAuth client, CLI, or API token); the person's own approval page and Credentials tab do not use this.\n\nOrg permission: none (touches no org data).","tags":["secrets"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"packageId":{"description":"Saved-package UUID. Use when the scoped name is not known, or for a stable ref.","type":"string","minLength":1},"kodyId":{"description":"Package name (`@owner/leaf` or the name leaf). Prefer this when you know the name.","type":"string","minLength":1},"trigger":{"type":"object","properties":{"kind":{"type":"string","enum":["cron","subscription","webhook"]},"name":{"type":"string","minLength":1,"description":"Job name, subscription topic, or webhook name."}},"required":["kind","name"],"additionalProperties":false},"needKey":{"type":"string","minLength":1,"description":"The credential need key."},"credentials":{"anyOf":[{"anyOf":[{"type":"object","properties":{"id":{"type":"string","minLength":1}},"required":["id"],"additionalProperties":false},{"type":"object","properties":{"name":{"type":"string","minLength":1},"scope":{"type":"string","enum":["org","personal"]}},"required":["name"],"additionalProperties":false}]},{"type":"array","items":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","minLength":1}},"required":["id"],"additionalProperties":false},{"type":"object","properties":{"name":{"type":"string","minLength":1},"scope":{"type":"string","enum":["org","personal"]}},"required":["name"],"additionalProperties":false}]}}],"description":"The pick to set, as you proposed it: a credential by { name } (optionally with scope) or { id }, or an array of them. [] is \"none on purpose\"."}},"required":["trigger","needKey","credentials"]}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"trigger":{"type":"object","properties":{"kind":{"type":"string","enum":["cron","subscription","webhook"]},"name":{"type":"string"}},"required":["kind","name"],"additionalProperties":false},"needKey":{"type":"string"},"credentials":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"scope":{"type":"string","enum":["org","personal"]},"kind":{"type":"string","enum":["secret","oauth","mcp","url","login","signing"]}},"required":["id","name","scope","kind"],"additionalProperties":false}},"message":{"type":"string"}},"required":["trigger","needKey","credentials","message"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"none","x-kody-read-only":false}},"/v1/secret-providers":{"get":{"operationId":"secretProviderList","summary":"List account-bound external secret providers (credential id for accessGrant, provider id, bound package, door-key sec...","description":"List account-bound external secret providers (credential id for accessGrant, provider id, bound package, door-key secret name, non-secret config). Never returns credential values or vault items. Search does not crawl vaults.\n\nOrg permission: `secret:use`.","tags":["secrets"],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"bindings":{"type":"array","items":{"type":"object","properties":{"credential_id":{"type":"string"},"provider":{"type":"string"},"package_id":{"type":"string"},"door_secret_name":{"type":"string"},"config":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}}},"required":["credential_id","provider","package_id","door_secret_name","config"],"additionalProperties":false}}},"required":["bindings"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"secret:use","x-kody-read-only":true}},"/v1/secret-providers/{provider}":{"put":{"operationId":"secretProviderBind","summary":"Pin which saved package serves an external secret provider id for this account, plus which user secret holds the door...","description":"Pin which saved package serves an external secret provider id for this account, plus which user secret holds the door key. Declaring kody.secretProvider on a package does not bind it. Owner-controlled; does not return secret values.\n\nOrg permission: `secret:write`.","tags":["secrets"],"parameters":[{"name":"provider","in":"path","required":true,"description":"Provider id to bind, for example 1password.","schema":{"type":"string","minLength":1,"description":"Provider id to bind, for example 1password."}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"package_id":{"type":"string","minLength":1,"description":"Saved package id that declares kody.secretProvider.id for this provider."},"door_secret_name":{"type":"string","minLength":1,"description":"User-scoped Kody secret that holds the provider door key (service account token)."},"config":{"description":"Optional non-secret provider config such as a Connect base URL.","type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}}},"required":["package_id","door_secret_name"]}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"provider":{"type":"string"},"package_id":{"type":"string"},"kody_id":{"type":"string"},"door_secret_name":{"type":"string"},"config":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}}},"required":["provider","package_id","kody_id","door_secret_name","config"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"secret:write","x-kody-read-only":false},"delete":{"operationId":"secretProviderUnbind","summary":"Remove the account binding for an external secret provider id.","description":"Remove the account binding for an external secret provider id. Unbind and rebind to a different package drop every grant for that provider. Does not return secret values.\n\nOrg permission: `secret:delete`.","tags":["secrets"],"parameters":[{"name":"provider","in":"path","required":true,"description":"Provider id to unbind.","schema":{"type":"string","minLength":1,"description":"Provider id to unbind."}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"provider":{"type":"string"},"unbound":{"type":"boolean"}},"required":["provider","unbound"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"secret:delete","x-kody-read-only":false}},"/v1/secret-providers/{provider}/lock":{"post":{"operationId":"secretProviderLock","summary":"Return a website approval URL so the account owner can grant a saved package use of one external secret-provider ref ...","description":"Return a website approval URL so the account owner can grant a saved package use of one external secret-provider ref (canonical i/<item-id>/<field>: UUID or 1Password Connect 26-char id). This capability does not change grants. Send the approval_url to the user and wait. Ad hoc execute does not need this grant; saved packages do.\n\nOrg permission: `secret:use`.","tags":["secrets"],"parameters":[{"name":"provider","in":"path","required":true,"description":"Provider id, for example 1password.","schema":{"type":"string","minLength":1,"description":"Provider id, for example 1password."}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"ref":{"type":"string","minLength":1,"description":"Canonical i/<item-id>/<field> ref (UUID or 1Password Connect 26-char id), or an op:// synonym that already contains that item id."},"package_id":{"type":"string","minLength":1,"description":"Saved package id that may use this provider ref."}},"required":["ref","package_id"]}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"provider":{"type":"string"},"canonical_ref":{"type":"string"},"package_id":{"type":"string"},"usage_url":{"type":"string"},"status":{"type":"string","enum":["approval_required","already_granted"]},"approval_url":{"type":"string"},"message":{"type":"string"}},"required":["provider","canonical_ref","package_id","usage_url","status","approval_url","message"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"secret:use","x-kody-read-only":true}},"/v1/packages":{"get":{"operationId":"packageList","summary":"List saved packages for the signed-in user, including community-fork source listing provenance, so agents can discove...","description":"List saved packages for the signed-in user, including community-fork source listing provenance, so agents can discover the scoped package.json name (or package_id when the name is not known) for later execution, editing, or UI opening.\n\nOrg permission: `package:read`.","tags":["packages"],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"packages":{"type":"array","items":{"type":"object","properties":{"package_id":{"type":"string"},"kody_id":{"type":"string","description":"Package name leaf (same value as `slug`). Kept as a compatibility alias; prefer `slug` or `name`."},"slug":{"type":"string","description":"Package name leaf (the path segment after the scope). Same value as `kody_id`."},"name":{"type":"string"},"description":{"type":"string"},"tags":{"type":"array","items":{"type":"string"}},"has_app":{"type":"boolean"},"hidden":{"type":"boolean"},"visibility":{"type":"string","enum":["public","private"],"description":"Repo visibility / forkable. Public means default-branch HEAD is world-readable and forkable and the package appears on /community. Private is owner-only. Independent of internet_visible."},"internet_visible":{"type":"boolean","description":"When true, the hosted package app may be served on the public internet after capability approval. Independent of visibility/forkable. Defaults false."},"locked_at":{"description":"When set, publishes require a website click at /@{username}/{kodyId}/approve-publish. Agents may lock via packageUpdate (`changes.locked: true`). Unlocking is website-only at /@{username}/{kodyId}/settings.","type":["string","null"]},"source_id":{"type":"string"},"created_at":{"type":"string"},"updated_at":{"type":"string"},"source_listing_id":{"description":"Catalog entry id this package was forked from, or null for a self-authored package.","type":["string","null"]},"listing_current":{"description":"Whether the source catalog entry currently resolves to an active public package, or null for a self-authored package.","type":["boolean","null"]},"listing_kody_id":{"description":"Original public package name leaf recorded when this package was forked, or null for a self-authored package.","type":["string","null"]},"listing_name":{"description":"Current source listing package name when the listing is active, or null when this package is self-authored or the listing is gone.","type":["string","null"]},"origin_commit":{"description":"Listing pinned commit this fork last absorbed. Starts as the fork-time snapshot and moves when a later publish passes absorbed_upstream_commit.","type":["string","null"]},"listing_pinned_commit":{"description":"Current pinned commit of the source listing, or null when this package is self-authored or the listing is gone.","type":["string","null"]},"listing_published_at":{"description":"Last community publish time of the source listing, or null when this package is self-authored or the listing is gone.","type":["string","null"]},"listing_ahead":{"description":"True only when this community fork is outdated: the listing pin is not an ancestor of the fork tip. Null for a self-authored package. Otherwise false.","type":["boolean","null"]}},"required":["package_id","kody_id","slug","name","description","tags","has_app","hidden","visibility","internet_visible","locked_at","source_id","created_at","updated_at","source_listing_id","listing_current","listing_kody_id","listing_name","origin_commit","listing_pinned_commit","listing_published_at","listing_ahead"],"additionalProperties":false}}},"required":["packages"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"package:read","x-kody-read-only":true},"post":{"operationId":"packageSave","summary":"Create or replace a saved package by writing a complete UTF-8 text file set (no binary assets).","description":"Create or replace a saved package by writing a complete UTF-8 text file set (no binary assets). Coding agents with local filesystem/git access should prefer packageGetGitRemote (pass create: true for new packages) to clone, edit, push, and publish with packagePublishExternalPush; tool-only agents use packageSave or repo sessions. The package repo is rooted at package.json and package.json#kody is the Kody-specific metadata block. Publish requires non-empty root README.md (human-focused: what it does, prerequisites, setup, done-when, plus a concise Intent section) and AGENTS.md (agent-focused: imports, smoke tests, edge cases). Ask the user if intent is unclear. Visibility is a repo setting (`packageUpdate` / `repoUpdate`), not package.json `\"private\"`. Leftover `\"private\"` in manifests is ignored for catalog listing. New packages are created private; set `changes.visibility: \"public\"` after the user asks to list them on /community. Production package source safety policy: never replace source history, force publish, or packageSave over an existing package unless Kody has created a restorable backup snapshot and the user explicitly approved destructive overwrite. If existing source cannot be cloned or verified, stop and report the source recovery problem.\n\nOrg permission: `package:write`.","tags":["packages"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"package_id":{"description":"Optional saved package id to update in place. Omit to create a new saved package.","type":"string","minLength":1},"files":{"minItems":1,"type":"array","items":{"type":"object","properties":{"path":{"type":"string","minLength":1,"description":"Package-relative file path to write into the saved package repo."},"content":{"type":"string","description":"Full file contents for this package file. Publish requires non-empty root README.md (human-focused, including a concise Intent section) and AGENTS.md (agent-focused: imports, smoke tests, edge cases)."}},"required":["path","content"],"additionalProperties":false},"description":"Full package file set to write. Must include package.json at the repo root."},"confirm_destructive_overwrite":{"default":false,"description":"Set to true only when the user explicitly approved destructive overwrite of existing package source history. Promoting publishes replace advertised history with a new root commit (and drop leftover session refs); promotePublished:false stays additive. Restorable backups retain prior content — secret scrub of backups still needs packageDelete or an explicit purge.","type":"boolean"},"confirm_private_visibility_change":{"default":false,"description":"Set to true only when the user explicitly approved changing package.json `\"private\"`. This flag does not change repo visibility: catalog listing is `packageUpdate` `changes.visibility`. Leftover `\"private\"` in manifests is ignored for the catalog.","type":"boolean"}},"required":["files"]}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"package_id":{"type":"string"},"kody_id":{"type":"string","description":"Package name leaf (same value as `slug`). Kept as a compatibility alias; prefer `slug` or `name`."},"slug":{"type":"string","description":"Package name leaf (the path segment after the scope). Same value as `kody_id`."},"name":{"type":"string"},"description":{"type":"string"},"tags":{"type":"array","items":{"type":"string"}},"has_app":{"type":"boolean"},"hidden":{"type":"boolean"},"visibility":{"type":"string","enum":["public","private"],"description":"Repo visibility / forkable. Public means default-branch HEAD is world-readable and forkable and the package appears on /community. Private is owner-only. Independent of internet_visible."},"internet_visible":{"type":"boolean","description":"When true, the hosted package app may be served on the public internet after capability approval. Independent of visibility/forkable. Defaults false."},"locked_at":{"description":"When set, publishes require a website click at /@{username}/{kodyId}/approve-publish. Agents may lock via packageUpdate (`changes.locked: true`). Unlocking is website-only at /@{username}/{kodyId}/settings.","type":["string","null"]},"source_id":{"type":"string"},"created_at":{"type":"string"},"updated_at":{"type":"string"},"next_steps":{"type":"string","description":"Follow-up guidance for continuing package work, including the git clone-edit-push lane for coding agents and any pending package secret approvals."},"pending_secret_package_approvals":{"anyOf":[{"type":"object","properties":{"package_id":{"type":"string","description":"Saved package id that needs approvals."},"kody_id":{"type":"string","description":"Package name leaf that needs approvals (same value as `slug`)."},"slug":{"type":"string","description":"Package name leaf that needs approvals."},"secrets":{"type":"array","items":{"type":"object","properties":{"secret_name":{"type":"string"},"approval_url":{"type":"string","description":"Per-secret package approval URL in the account UI."}},"required":["secret_name","approval_url"],"additionalProperties":false},"description":"User secrets that still need package approval."},"bulk_approval_url":{"description":"One-click bulk approval URL when two or more secrets still need package approval; prefer this over individual links.","type":["string","null"]}},"required":["package_id","kody_id","slug","secrets","bulk_approval_url"],"additionalProperties":false},{"type":"null"}],"description":"Pending user-secret package approvals detected from secretMounts and secret placeholders. Null when none are pending. Do not treat the package as ready to run until the user approves these and a static-import smoke test from execute succeeds against a read-only export or dry-run input that actually uses the approved secret."}},"required":["package_id","kody_id","slug","name","description","tags","has_app","hidden","visibility","internet_visible","locked_at","source_id","created_at","updated_at","next_steps","pending_secret_package_approvals"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"package:write","x-kody-read-only":false}},"/v1/packages/{package_id}":{"get":{"operationId":"packageGet","summary":"Load one saved package metadata record for the signed-in user, including community-fork source listing provenance, th...","description":"Load one saved package metadata record for the signed-in user, including community-fork source listing provenance, the full export array, callable export contracts, and FYI metadata for associated package-scoped secrets (names and package_id, never values), and its credential needs with how each resolves for you (`credentials.needs`). For a single export contract, prefer search({ entity: \"package:{kodyId}#{subpath}\" }). Does not return README, AGENTS.md, or source files; use repoOpenSession + repoReadFile (or packageGetGitRemote) for those.\n\nOrg permission: `package:read`.","tags":["packages"],"parameters":[{"name":"package_id","in":"path","required":true,"schema":{"type":"string","minLength":1}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"package_id":{"type":"string"},"kody_id":{"type":"string","description":"Package name leaf (same value as `slug`). Kept as a compatibility alias; prefer `slug` or `name`."},"slug":{"type":"string","description":"Package name leaf (the path segment after the scope). Same value as `kody_id`."},"name":{"type":"string"},"description":{"type":"string"},"tags":{"type":"array","items":{"type":"string"}},"has_app":{"type":"boolean"},"hidden":{"type":"boolean"},"visibility":{"type":"string","enum":["public","private"],"description":"Repo visibility / forkable. Public means default-branch HEAD is world-readable and forkable and the package appears on /community. Private is owner-only. Independent of internet_visible."},"internet_visible":{"type":"boolean","description":"When true, the hosted package app may be served on the public internet after capability approval. Independent of visibility/forkable. Defaults false."},"locked_at":{"description":"When set, publishes require a website click at /@{username}/{kodyId}/approve-publish. Agents may lock via packageUpdate (`changes.locked: true`). Unlocking is website-only at /@{username}/{kodyId}/settings.","type":["string","null"]},"source_id":{"type":"string"},"created_at":{"type":"string"},"updated_at":{"type":"string"},"source_listing_id":{"description":"Catalog entry id this package was forked from, or null for a self-authored package.","type":["string","null"]},"listing_current":{"description":"Whether the source catalog entry currently resolves to an active public package, or null for a self-authored package.","type":["boolean","null"]},"listing_kody_id":{"description":"Original public package name leaf recorded when this package was forked, or null for a self-authored package.","type":["string","null"]},"listing_name":{"description":"Current source listing package name when the listing is active, or null when this package is self-authored or the listing is gone.","type":["string","null"]},"origin_commit":{"description":"Listing pinned commit this fork last absorbed. Starts as the fork-time snapshot and moves when a later publish passes absorbed_upstream_commit.","type":["string","null"]},"listing_pinned_commit":{"description":"Current pinned commit of the source listing, or null when this package is self-authored or the listing is gone.","type":["string","null"]},"listing_published_at":{"description":"Last community publish time of the source listing, or null when this package is self-authored or the listing is gone.","type":["string","null"]},"listing_ahead":{"description":"True only when this community fork is outdated: the listing pin is not an ancestor of the fork tip. Null for a self-authored package. Otherwise false.","type":["boolean","null"]},"published_commit":{"description":"Current published Artifacts commit for this package source (same field as `repoShowPublishNote` defaults to). Null when nothing has been published yet.","type":["string","null"]},"exports":{"type":"array","items":{"type":"object","properties":{"subpath":{"type":"string","description":"Package export subpath from package.json exports."},"import_specifier":{"type":"string","description":"Ready-to-use kody: import specifier for this export."},"runtime_target":{"description":"Package-relative runtime source path for this export.","type":["string","null"]},"types_path":{"description":"Package-relative types source path for this export, when declared.","type":["string","null"]},"description":{"description":"Export description parsed from JSDoc when available.","type":["string","null"]},"type_definition":{"description":"Primary export type signature parsed from source when available. Null when the export has more than one callable function; use `functions` in that case.","type":["string","null"]},"functions":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string","description":"Exported function name. Default exports use the name \"default\"."},"description":{"description":"Function JSDoc description when available.","type":["string","null"]},"type_definition":{"description":"Function type signature parsed from source when available.","type":["string","null"]}},"required":["name","description","type_definition"],"additionalProperties":false},"description":"Callable functions extracted from this export. Namespace modules that export several helpers list each one here."},"referenced_types":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"kind":{"type":"string","enum":["type","interface","enum"]},"definition":{"type":"string","description":"Source text of the referenced type, interface, or enum."}},"required":["name","kind","definition"],"additionalProperties":false},"description":"Type, interface, and enum definitions referenced by this export's callable functions."}},"required":["subpath","import_specifier","runtime_target","types_path","description","type_definition","functions","referenced_types"],"additionalProperties":false}},"package_secrets":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"scope":{"type":"string","enum":["session","package","user"]},"description":{"type":"string"},"package_id":{"type":["string","null"]},"allowed_hosts":{"type":"array","items":{"type":"string"}},"allowed_packages":{"type":"array","items":{"type":"string"}},"created_at":{"type":"string"},"updated_at":{"type":"string"},"expires_at":{"type":["string","null"]},"ttl_ms":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]},"kind":{"description":"Credential kind, returned when this call set opt-in fields.","type":"string","enum":["secret","url","login","signing"]},"provider":{"type":["string","null"]},"inject":{"oneOf":[{"type":"object","properties":{"kind":{"type":"string","const":"header"},"name":{"type":"string","pattern":"^[!#$%&'*+\\-.^_`|~0-9A-Za-z]+$"},"format":{"type":"string","maxLength":200}},"required":["kind","name","format"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"basic"},"valueAs":{"type":"string","enum":["username","password"]},"other":{"default":"","type":"string","maxLength":200}},"required":["kind","valueAs"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"query"},"param":{"type":"string","minLength":1,"maxLength":100}},"required":["kind","param"],"additionalProperties":false}]}},"required":["name","scope","description","package_id","allowed_hosts","allowed_packages","created_at","updated_at","expires_at","ttl_ms"],"additionalProperties":false},"description":"FYI metadata for package-scoped secrets owned by this package, including package_id. Never plaintext values. These are not execute-usable via search; using them still requires package context."},"credentials":{"type":"object","properties":{"needs":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string"},"kind":{"description":"When set, only credentials of this kind match. When omitted, any fetch-capable credential (secret, oauth, login) for the provider matches.","type":"string","enum":["secret","oauth","mcp","url","login","signing"]},"provider":{"type":"string"},"description":{"type":"string"},"multiple":{"type":"boolean"},"from":{"description":"The imported package that declares this need, when inherited.","type":"string"},"status":{"type":"string","enum":["ready","ambiguous","unbound"],"description":"ready: exactly one of your credentials matches the need (kind filter and provider) and resolves with no call map entry. ambiguous: several match; pick one with a call map. unbound: none match."},"autoPick":{"description":"The credential name used when no call map entry is given.","type":["string","null"]},"yourOptions":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"scope":{"type":"string","enum":["org","personal"]},"org":{"type":"string"},"hosts":{"type":"array","items":{"type":"string"}}},"required":["name","scope","hosts"],"additionalProperties":false},"description":"Credentials you can Use that a call map may pick: the matches, plus matching-kind credentials with no provider (set their provider to auto-resolve)."}},"required":["key","provider","description","multiple","status","autoPick","yourOptions"],"additionalProperties":false}}},"required":["needs"],"additionalProperties":false,"description":"Credential needs (ADR 0068): the published `kody.credentials` closure, including needs inherited from statically imported packages (`from`), each with how it resolves for you. Options list only credentials you can Use; never values."}},"required":["package_id","kody_id","slug","name","description","tags","has_app","hidden","visibility","internet_visible","locked_at","source_id","created_at","updated_at","source_listing_id","listing_current","listing_kody_id","listing_name","origin_commit","listing_pinned_commit","listing_published_at","listing_ahead","published_commit","exports","package_secrets","credentials"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"package:read","x-kody-read-only":true},"patch":{"operationId":"packageUpdate","summary":"Update mutable settings for a saved package: hidden search-discovery, publish lock (`changes.locked: true`; agents ca...","description":"Update mutable settings for a saved package: hidden search-discovery, publish lock (`changes.locked: true`; agents cannot unlock), repo visibility / forkable (`changes.visibility`), and internet-visible app serving (`changes.internet_visible`). Making a package public lists it on /community with full source and fork. Before setting visibility public, review source, README, Intent, description, tags, examples, and hardcoded identifiers for overly personal material. If anything looks personal or household-specific, do not publish yet — tell the user what you found, suggest how to generalize, and wait for explicit go-ahead. No MIT, logo, or Intent platform gates. Making it private unlists it (public URLs 404; forks keep their copies) — pass confirm_name matching the package slug after the owner typed that name. Internet-visible is independent of forkable and requires owner capability approval on the website. Canonical package metadata such as name, description, and tags remains derived from package.json. Visibility is not package.json#private.\n\nOrg permission: `package:write`.","tags":["packages"],"parameters":[{"name":"package_id","in":"path","required":true,"description":"Saved package id.","schema":{"type":"string","minLength":1,"description":"Saved package id."}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"changes":{"type":"object","properties":{"hidden":{"description":"When true, hide the package from ranked search discovery by default.","type":"boolean"},"locked":{"description":"When true, lock publishes so later agent publishes need a website click. Agents can lock but cannot unlock; send the owner to the package page (/@{username}/{kodyId}) to unlock.","type":"boolean"},"visibility":{"description":"Repo visibility / forkable. Public means default-branch HEAD is world-readable and forkable and the package appears on /community. Before setting public, review the package for overly personal content (package_authoring visibility). If anything looks personal, stop, tell the user, suggest generalizing, and wait for explicit go-ahead. Private is owner-only. Changing to private unlists the catalog entry; existing forks keep their copies. Independent of internet_visible.","type":"string","enum":["public","private"]},"internet_visible":{"description":"Internet-visible app serving. Independent of visibility/forkable. Setting true makes the package internet-visible right away when either (1) self-publish applies (the resolved capability set is empty, nothing in the dependency tree declares a credential or another capability, a security audit with verdict pass is recorded for the current published commit + fingerprint, and the caller may package:publish), or (2) the owner already approved the current capability set (matching pin) — then went_public is approved without another Approve click. An unpublished package is refused with an error: publish it first. Otherwise agents cannot approve the capability set: it returns an approval_url for the owner website and self_publish_blocker (or self_publish_error when applying a matching pin failed) says why. When the published version has no security audit, it also returns security_audit: run that audit and record it with packageSecurityAuditRecord using security_audit.args. Recording verdict pass re-evaluates the pending request and self-publishes when everything else allows it; otherwise hand the owner approval_url. Calling this again with internet_visible true also re-evaluates. Setting false turns off public app serving (requires confirm_name).","type":"boolean"}},"additionalProperties":false},"confirm_name":{"description":"Required when changes.visibility is private or changes.internet_visible is false. Must equal the package slug (URL name). Confirm with the user first.","type":"string","minLength":1}},"required":["changes"]}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"package":{"type":"object","properties":{"package_id":{"type":"string"},"kody_id":{"type":"string","description":"Package name leaf (same value as `slug`). Kept as a compatibility alias; prefer `slug` or `name`."},"slug":{"type":"string","description":"Package name leaf (the path segment after the scope). Same value as `kody_id`."},"name":{"type":"string"},"description":{"type":"string"},"tags":{"type":"array","items":{"type":"string"}},"has_app":{"type":"boolean"},"hidden":{"type":"boolean"},"visibility":{"type":"string","enum":["public","private"],"description":"Repo visibility / forkable. Public means default-branch HEAD is world-readable and forkable and the package appears on /community. Private is owner-only. Independent of internet_visible."},"internet_visible":{"type":"boolean","description":"When true, the hosted package app may be served on the public internet after capability approval. Independent of visibility/forkable. Defaults false."},"locked_at":{"description":"When set, publishes require a website click at /@{username}/{kodyId}/approve-publish. Agents may lock via packageUpdate (`changes.locked: true`). Unlocking is website-only at /@{username}/{kodyId}/settings.","type":["string","null"]},"source_id":{"type":"string"},"created_at":{"type":"string"},"updated_at":{"type":"string"}},"required":["package_id","kody_id","slug","name","description","tags","has_app","hidden","visibility","internet_visible","locked_at","source_id","created_at","updated_at"],"additionalProperties":false},"approval_url":{"description":"Present when internet_visible was requested and is waiting on owner Approve (went_public). One Approve on that page records the capability set and turns internet-visible on.","type":"string"},"internet_visible_pending":{"description":"True when other package changes applied but internet-visible is waiting on owner Approve.","type":"boolean"},"security_audit":{"description":"Present when internet-visible is pending and the published version has no security audit. Do this before handing the owner approval_url: audit, then record with packageSecurityAuditRecord.","type":"object","properties":{"next_step":{"type":"string"},"operation":{"type":"string","const":"packageSecurityAuditRecord"},"http_route":{"type":"string"},"args":{"type":"object","properties":{"package_id":{"type":"string"},"published_commit":{"type":"string"},"fingerprint":{"type":"string"}},"required":["package_id","published_commit","fingerprint"],"additionalProperties":false,"description":"Exact values for packageSecurityAuditRecord. Add verdict (\"pass\" or \"concerns\"), summary, and optionally auditor."},"audit_prompt":{"type":"string","description":"What to review and how to record it, as the owner would ask."}},"required":["next_step","operation","http_route","args","audit_prompt"],"additionalProperties":false},"self_published":{"description":"Present when internet_visible was turned on without owner Approve because the package declares no credential or capability. The package cannot use any credential while public this way.","type":"boolean","const":true},"self_publish_blocker":{"description":"Why internet_visible waits on owner Approve instead of self-publishing: the capability set has credentials or storage to approve, a package in the tree is unpublished, a dependency republished since this package's publish (stale_dependencies: publish this package again), the tree declares credentials, the tree declares other capabilities, the current published commit + fingerprint has no security audit (not_audited) or one with verdict concerns (audit_concerns), or the caller may not publish this package. For not_audited: audit, record verdict pass with packageSecurityAuditRecord; that re-evaluates the pending request.","type":"string","enum":["unpublished","stale_dependencies","declares_credentials","declares_capabilities","not_audited","audit_concerns","not_permitted"]},"self_publish_error":{"description":"Present when self-publish applied but its approval failed; internet_visible waits on owner Approve at approval_url instead.","type":"string"}},"required":["ok","package"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"package:write","x-kody-read-only":false},"delete":{"operationId":"packageDelete","summary":"Permanently delete a saved package the signed-in user owns.","description":"Permanently delete a saved package the signed-in user owns. This cannot be undone. It removes the package from the account and from /community if it was public, stops its jobs, clears package storage and package-scoped secrets, and best-effort deletes Artifacts repos. Existing forks keep their copies. Hiding (`packageUpdate` hidden) or making a package private is not deletion. Do not call this because a package is unused, failing, or over quota unless the owner explicitly asked to delete that specific package. Load it with packageGet or packageList, show the owner the package name and what will be destroyed, wait for them to type that name, then pass package_id and confirm_name matching the package name exactly.\n\nOrg permission: `package:delete`.","tags":["packages"],"parameters":[{"name":"package_id","in":"path","required":true,"description":"Saved package id to delete.","schema":{"type":"string","minLength":1,"description":"Saved package id to delete."}},{"name":"confirm_name","in":"query","required":false,"description":"Required. Must equal the package name (`package.json` name, for example @you/my-package). Ask the owner to type that name first. The capability refuses the delete and names the expected value when this is missing or wrong.","schema":{"description":"Required. Must equal the package name (`package.json` name, for example @you/my-package). Ask the owner to type that name first. The capability refuses the delete and names the expected value when this is missing or wrong.","type":"string","minLength":1}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"package_id":{"type":"string"}},"required":["ok","package_id"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"package:delete","x-kody-read-only":false}},"/v1/packages/{package_id}/collaborators":{"get":{"operationId":"packageCollaboratorList","summary":"List who can use one package in the organization this request is bound to: teams, org members, and outside collaborat...","description":"List who can use one package in the organization this request is bound to: teams, org members, and outside collaborators with their preset (Use, Contribute, or Manage) and grant_id. package_id takes the package id or its kody id. You need manage access on the package. Add a team or org member, or change their preset, with packageCollaboratorSet; remove one with packageCollaboratorRemove.\n\nOrg permission: none (touches no org data).","tags":["packages"],"parameters":[{"name":"package_id","in":"path","required":true,"description":"Package id or kody id.","schema":{"type":"string","minLength":1,"description":"Package id or kody id."}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"package":{"type":"object","properties":{"id":{"type":"string"},"kody_id":{"type":"string"},"name":{"type":"string"}},"required":["id","kody_id","name"],"additionalProperties":false},"collaborators":{"type":"array","items":{"type":"object","properties":{"grant_id":{"type":"string"},"subject_type":{"type":"string","enum":["user","team"]},"subject_id":{"type":"string"},"kind":{"type":"string","enum":["team","member","outside"],"description":"team: a team in this org. member: an org member. outside: holds this grant without membership (granted elsewhere)."},"username":{"type":["string","null"]},"display_name":{"type":["string","null"]},"team_slug":{"type":["string","null"]},"team_name":{"type":["string","null"]},"preset":{"anyOf":[{"type":"string","enum":["use","contribute","manage"]},{"type":"null"}],"description":"Null for an advanced grant; see permissions."},"permissions":{"type":"array","items":{"type":"string"}},"created_at":{"type":"string"}},"required":["grant_id","subject_type","subject_id","kind","username","display_name","team_slug","team_name","preset","permissions","created_at"],"additionalProperties":false}}},"required":["package","collaborators"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"none","x-kody-read-only":true},"post":{"operationId":"packageCollaboratorSet","summary":"Add a team or org member as a collaborator on one package in the organization this request is bound to, or change the...","description":"Add a team or org member as a collaborator on one package in the organization this request is bound to, or change the preset of one who already is. Pass exactly one of team_slug, team_id, username, or user_id, and a preset (use, contribute, or manage). Only teams and members of this organization are accepted; Owners already have full access. You need manage access on the package. Audited like accessGrant.\n\nOrg permission: none (touches no org data).","tags":["packages"],"parameters":[{"name":"package_id","in":"path","required":true,"description":"Package id or kody id.","schema":{"type":"string","minLength":1,"description":"Package id or kody id."}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"team_slug":{"type":"string","minLength":1},"team_id":{"type":"string","minLength":1},"username":{"description":"Username of an org member, without the leading @.","type":"string","minLength":1},"user_id":{"type":"string","minLength":1},"preset":{"type":"string","enum":["use","contribute","manage"]}},"required":["preset"]}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"package":{"type":"object","properties":{"id":{"type":"string"},"kody_id":{"type":"string"},"name":{"type":"string"}},"required":["id","kody_id","name"],"additionalProperties":false},"collaborator":{"type":"object","properties":{"grant_id":{"type":"string"},"subject_type":{"type":"string","enum":["user","team"]},"subject_id":{"type":"string"},"kind":{"type":"string","enum":["team","member","outside"],"description":"team: a team in this org. member: an org member. outside: holds this grant without membership (granted elsewhere)."},"username":{"type":["string","null"]},"display_name":{"type":["string","null"]},"team_slug":{"type":["string","null"]},"team_name":{"type":["string","null"]},"preset":{"anyOf":[{"type":"string","enum":["use","contribute","manage"]},{"type":"null"}],"description":"Null for an advanced grant; see permissions."},"permissions":{"type":"array","items":{"type":"string"}},"created_at":{"type":"string"}},"required":["grant_id","subject_type","subject_id","kind","username","display_name","team_slug","team_name","preset","permissions","created_at"],"additionalProperties":false}},"required":["package","collaborator"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"none","x-kody-read-only":false}},"/v1/packages/{package_id}/collaborators/{grant_id}":{"delete":{"operationId":"packageCollaboratorRemove","summary":"Remove one collaborator from a package in the organization this request is bound to, by the grant_id from packageColl...","description":"Remove one collaborator from a package in the organization this request is bound to, by the grant_id from packageCollaboratorList. Works for teams, org members, and outside collaborators. You need manage access on the package. Audited like accessRevoke.\n\nOrg permission: none (touches no org data).","tags":["packages"],"parameters":[{"name":"package_id","in":"path","required":true,"description":"Package id or kody id.","schema":{"type":"string","minLength":1,"description":"Package id or kody id."}},{"name":"grant_id","in":"path","required":true,"schema":{"type":"string","minLength":1}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"grant_id":{"type":"string"},"removed":{"type":"boolean","const":true}},"required":["grant_id","removed"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"none","x-kody-read-only":false}},"/v1/packages/{package_id}/git-remote":{"post":{"operationId":"packageGetGitRemote","summary":"Start or continue the git lane for saved packages: mint a short-lived Cloudflare Artifacts git remote so coding agent...","description":"Start or continue the git lane for saved packages: mint a short-lived Cloudflare Artifacts git remote so coding agents with local filesystem/git access can clone into a temporary directory. When scope is omitted, defaults to write if you have write access to the package, otherwise read. Pass scope explicitly to force read or write; requesting write without write access is denied with guidance (use scope: 'read', ask an Owner for a grant, or communityFork a public package). A read remote rejects push with: this remote is read-only; request scope: 'write'. Pass `create: true` with a new `@scope/leaf` name (or the name leaf) to register a stub saved package and mint its remote in one call, so new packages can be authored via clone-edit-push instead of packageSave file blobs. Prefer the scoped name for existing packages; use `package_id` only when the name is not known. The result includes `git_author` (signed-in Kody account email and display name) and `setup_commands` that set local `user.email` / `user.name` to that identity — never invent a git email. Write access verifies the current package source has a restorable backup snapshot before clone/edit/publish. Individual files may be at most 10 MiB (10,485,760 stored bytes; UTF-8 for text, raw for binary): publish rejects anything larger with external-hosting guidance (commit a link or pointer instead), and the Artifacts remote itself fails pushes above ~32 MiB of pack content with a raw HTTP 413.\n\nOrg permission: `package:read`.","tags":["packages"],"parameters":[{"name":"package_id","in":"path","required":true,"description":"Saved-package UUID. Use when the scoped name is not known, or for a stable ref.","schema":{"description":"Saved-package UUID. Use when the scoped name is not known, or for a stable ref.","type":"string","minLength":1}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"kody_id":{"description":"Package name (`@owner/leaf` or the name leaf). Prefer this when you know the name.","type":"string","minLength":1},"create":{"default":false,"description":"Set true with the new `@scope/leaf` name (or the name leaf) to register a new stub saved package (private, minimal scaffold) when none exists yet, then mint its remote in the same call. Existing packages are reused as-is. Prefer the scoped name for existing packages; use `package_id` only when the name is not known.","type":"boolean"},"description":{"description":"Package description used when `create: true` registers a new stub package. At most 200 characters (short public tagline). Ignored for existing packages.","type":"string","minLength":1,"maxLength":200},"scope":{"description":"Access scope for the minted Artifacts token. When omitted, defaults to write if you have write access to the package, otherwise read. Explicit scope is honored; requesting write without write access is denied. A read remote rejects push with: this remote is read-only; request scope: 'write'.","type":"string","enum":["read","write"]},"ttl_seconds":{"default":14400,"type":"integer","minimum":60,"maximum":86400}}}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"package_id":{"type":"string"},"kody_id":{"type":"string","description":"Package name leaf (same value as `slug`)."},"slug":{"type":"string","description":"Package name leaf (same value as `kody_id`)."},"created":{"type":"boolean","description":"True when this call registered a new stub saved package before minting the remote."},"remote":{"type":"string"},"authenticated_remote":{"type":"string"},"git_extra_header":{"type":"string"},"scope":{"type":"string","enum":["read","write"]},"expires_at":{"type":"string"},"git_author":{"type":"object","properties":{"name":{"type":"string","description":"Signed-in Kody account display name. Use as git user.name; do not guess a name."},"email":{"type":"string","format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$","description":"Signed-in Kody account email. Use as git user.email; never invent an email."}},"required":["name","email"],"additionalProperties":false,"description":"Git author for this clone: the signed-in Kody account. setup_commands set local user.name and user.email to these values."},"setup_commands":{"type":"array","items":{"type":"string"}}},"required":["package_id","kody_id","slug","created","remote","authenticated_remote","git_extra_header","scope","expires_at","git_author","setup_commands"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"package:read","x-kody-read-only":false}},"/v1/packages/{package_id}/security-audits":{"post":{"operationId":"packageSecurityAuditRecord","summary":"Record an informational security audit for the exact published version of a saved package: its published commit plus ...","description":"Record an informational security audit for the exact published version of a saved package: its published commit plus capability-set fingerprint (both shown in the security audit prompt on the package capability approval page, and in the security_audit next step packageUpdate returns when a package moves toward internet-visible). Review that version first: declared vs used credentials, leaked credentials, unintended public exposure, risky network hosts, and package storage use. Then record verdict pass or concerns with a plain-language summary. The audit is tied to that commit and fingerprint; a new publish or changed capability set reads as not audited again. Recording an audit approves nothing by itself. One exception: when a request to make the package internet-visible is already pending (packageUpdate internet_visible: true), recording verdict pass re-evaluates self-publish, which makes the package internet-visible without the owner click (self_published: true) when the resolved capability set is empty and nothing in its dependency tree declares a credential or another capability. Otherwise hand the owner approval_url next. Requires package:read (to review the source) as well as package:write. Token-shaped strings in the summary are redacted.\n\nOrg permission: `package:write`.","tags":["packages"],"parameters":[{"name":"package_id","in":"path","required":true,"description":"Saved package id that was audited.","schema":{"type":"string","minLength":1,"description":"Saved package id that was audited."}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"published_commit":{"type":"string","minLength":1,"description":"Published commit SHA that was reviewed. Must match the package current published commit."},"fingerprint":{"type":"string","minLength":1,"description":"Capability-set fingerprint that was reviewed. Must match the package current capability fingerprint."},"verdict":{"type":"string","enum":["pass","concerns"],"description":"`pass` when nothing concerning was found; `concerns` when the owner should look closer before approving."},"summary":{"type":"string","minLength":1,"maxLength":4000,"description":"Plain-language summary for the package owner: what was checked, what was found, and anything they should look at before approving. No secret values."},"auditor":{"description":"Optional name of the agent or person who performed the review, shown as \"Audited by …\". Defaults to the signed-in user.","type":"string","maxLength":120}},"required":["published_commit","fingerprint","verdict","summary"]}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"audit_id":{"type":"string"},"package_id":{"type":"string"},"published_commit":{"type":"string"},"fingerprint":{"type":"string"},"verdict":{"type":"string","enum":["pass","concerns"]},"recorded_at":{"type":"string"},"audit_url":{"type":"string"},"approval_url":{"type":"string","description":"The package approval page to hand the owner next."},"next_step":{"type":"string"},"self_published":{"description":"Present when this pass made the package internet-visible through self-publish for a pending internet-visible request.","type":"boolean","const":true},"self_publish_blocker":{"description":"Present when an internet-visible request is pending and self-publish still does not apply; the owner approves at approval_url. Same values as packageUpdate self_publish_blocker.","type":"string"}},"required":["ok","audit_id","package_id","published_commit","fingerprint","verdict","recorded_at","audit_url","approval_url","next_step"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"package:write","x-kody-read-only":false}},"/v1/packages/{package_id}/external-push":{"post":{"operationId":"packagePublishExternalPush","summary":"Publish the current Artifacts git HEAD for a saved package after a packageGetGitRemote clone/edit/push workflow and s...","description":"Publish the current Artifacts git HEAD for a saved package after a packageGetGitRemote clone/edit/push workflow and server-side checks pass. Non-fast-forward publishes require explicit destructive overwrite confirmation and a verified restorable backup snapshot. Full check-time esbuild is deferred to the published artifact rebuild so callable and importable targets are bundled once; unchanged targets are copied from the previous published commit when their reachable inputs match, and a rebuild failure returns checks_failed with a bundle check. Published and already_published responses include hosted_app_url when the package declares an app, plus bounded static dependent metadata so agents can decide whether stale kody:@ bundled snapshots need inspection or dependent republish; Kody does not republish dependents automatically. Those success results also include phase_timings with optional millisecond fields clone_ms, checks_typecheck_ms, checks_bundle_ms, rebuild_ms, dependents_ms, and total_ms — omitted keys did not run; checks_bundle_ms is omitted when bundle validation is deferred to rebuild; checks_bundle_ms and rebuild_ms stay separate. Common cases return the full synchronous result. If the publish exceeds the inline budget (~35s), the work is dispatched once to a durable workflow (idempotent per acting caller plus the full semantic publish input, including force/overwrite flags) and this capability returns status dispatched with a workflow_id to poll via workflowRunList instead of hanging until an opaque execute timeout. Active and succeeded durable runs still dedupe; a terminal failure (for example Durable Object reset because its code was updated) releases the idempotency key so the same commit can be published again. dispatched includes phase_timings.total_ms as time-to-dispatch.\n\nOrg permission: `package:write`.","tags":["packages"],"parameters":[{"name":"package_id","in":"path","required":true,"schema":{"type":"string","minLength":1}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"kody_id":{"type":"string","minLength":1},"allow_force":{"default":false,"type":"boolean"},"confirm_destructive_overwrite":{"default":false,"description":"Set to true only when the user explicitly approved destructive overwrite of existing package source history. Promoting publishes replace advertised history with a new root commit (and drop leftover session refs); promotePublished:false stays additive. Restorable backups retain prior content — secret scrub of backups still needs packageDelete or an explicit purge.","type":"boolean"}}}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"oneOf":[{"type":"object","properties":{"status":{"type":"string","const":"already_published"},"published_commit":{"type":["string","null"]},"hosted_app_url":{"type":["string","null"]},"test_hints":{"type":"object","properties":{"app":{"type":"string"},"subscriptions":{"type":"array","items":{"type":"object","properties":{"topic":{"type":"string"},"snippet":{"type":"string"}},"required":["topic","snippet"],"additionalProperties":false}},"enablements":{"type":"object","properties":{"message":{"type":"string","description":"Agent-directed message: ask the user whether to enable each listed trigger, with the exact enablementEnable call (or Approve for webhooks/email)."},"triggers":{"type":"array","items":{"type":"object","properties":{"kind":{"type":"string","enum":["cron","subscription","webhook"]},"name":{"type":"string"},"reason":{"type":"string","enum":["missing","paused"]},"call":{"description":"Exact enablementEnable call when applicable; null for Approve-only triggers.","type":["string","null"]}},"required":["kind","name","reason","call"],"additionalProperties":false}}},"required":["message","triggers"],"additionalProperties":false}},"additionalProperties":false},"static_dependents":{"type":"object","properties":{"total":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"Total direct static dependent packages found."},"stale":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"Count of direct static dependent packages with stale bundled snapshots."},"truncated":{"type":"boolean","description":"True when more dependent packages exist than are returned in items."},"items":{"type":"array","items":{"type":"object","properties":{"package_id":{"type":"string","description":"Saved package id of the dependent package."},"kody_id":{"type":"string","description":"Package name leaf of the dependent package."},"name":{"type":"string","description":"Scoped package.json name of the dependent package."},"source_id":{"type":"string","description":"Repo-backed source id for the dependent package."},"published_commit":{"description":"Current published commit of the dependent package.","type":["string","null"]},"stale":{"type":"boolean","description":"True when at least one dependent bundle artifact captured a dependency commit that differs from the package's current published commit."},"artifact_count":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"Number of published bundle artifacts that reference this dependency."},"entrypoints":{"type":"array","items":{"type":"string"},"description":"Bounded list of dependent bundle entrypoints referencing this dependency."},"entrypoints_truncated":{"type":"boolean","description":"True when the dependent has more matching entrypoints than returned."},"bundled_dependency_commit":{"description":"Dependency commit captured in the dependent bundle, or null when matching artifacts have mixed or missing commits.","type":["string","null"]},"current_dependency_commit":{"type":"string","description":"Current published commit for the referenced dependency package."},"recommended_action":{"type":"string","description":"Agent guidance for this dependent package."}},"required":["package_id","kody_id","name","source_id","published_commit","stale","artifact_count","entrypoints","entrypoints_truncated","bundled_dependency_commit","current_dependency_commit","recommended_action"],"additionalProperties":false,"description":"A direct static dependent package from persisted bundle metadata."},"description":"Bounded direct static dependent package summaries."},"recommended_next_action":{"type":"string","description":"Agent guidance explaining whether to inspect or republish dependents. Kody does not republish dependents automatically."}},"required":["total","stale","truncated","items","recommended_next_action"],"additionalProperties":false,"description":"Bounded summary of saved packages whose published bundles statically captured this package through kody:@ imports."},"pending_secret_package_approvals":{"anyOf":[{"type":"object","properties":{"package_id":{"type":"string","description":"Saved package id that needs approvals."},"kody_id":{"type":"string","description":"Package name leaf that needs approvals (same value as `slug`)."},"slug":{"type":"string","description":"Package name leaf that needs approvals."},"secrets":{"type":"array","items":{"type":"object","properties":{"secret_name":{"type":"string"},"approval_url":{"type":"string","description":"Per-secret package approval URL in the account UI."}},"required":["secret_name","approval_url"],"additionalProperties":false},"description":"User secrets that still need package approval."},"bulk_approval_url":{"description":"One-click bulk approval URL when two or more secrets still need package approval; prefer this over individual links.","type":["string","null"]}},"required":["package_id","kody_id","slug","secrets","bulk_approval_url"],"additionalProperties":false},{"type":"null"}],"description":"Pending user-secret package approvals detected from secretMounts and secret placeholders. Null when none are pending. Do not treat the package as ready to run until the user approves these and a static-import smoke test from execute succeeds against a read-only export or dry-run input that actually uses the approved secret."},"listing":{"type":"object","properties":{"pinnedVersion":{"type":["string","null"]},"promotedVersion":{"type":["string","null"]},"behind":{"type":"boolean","const":true},"updateHint":{"type":"string"},"updateUrl":{"type":"string"}},"required":["pinnedVersion","promotedVersion","behind","updateHint","updateUrl"],"additionalProperties":false,"description":"Present when this package has a public community listing whose pinned snapshot is still behind the published commit after promote auto-sync. Rare; a background backfill retries. No manual republish step is required."},"phase_timings":{"type":"object","properties":{"clone_ms":{"description":"Milliseconds spent cloning Artifacts HEAD into the publish workspace. Omitted when this attempt did not clone.","type":"integer","minimum":0,"maximum":9007199254740991},"checks_typecheck_ms":{"description":"Milliseconds spent in the publish typecheck phase. Omitted when typecheck did not run (for example already_published).","type":"integer","minimum":0,"maximum":9007199254740991},"checks_bundle_ms":{"description":"Milliseconds spent in the publish bundle-check phase. Distinct from rebuild_ms. Omitted when bundle check did not run, including when full esbuild validation is deferred to rebuild.","type":"integer","minimum":0,"maximum":9007199254740991},"rebuild_ms":{"description":"Milliseconds spent rebuilding published package artifacts after checks, or confirming they match this commit. Distinct from checks_bundle_ms.","type":"integer","minimum":0,"maximum":9007199254740991},"dependents_ms":{"description":"Milliseconds spent indexing static dependents, hosted app URL, test hints, and pending secret approvals.","type":"integer","minimum":0,"maximum":9007199254740991},"total_ms":{"description":"Milliseconds from the start of this publish attempt until the result was ready. On status dispatched, this is time-to-dispatch.","type":"integer","minimum":0,"maximum":9007199254740991}},"additionalProperties":false,"description":"Coarse packagePublishExternalPush phase timings in milliseconds. Field names are stable. Omitted keys mean that phase did not run in this result. checks_bundle_ms and rebuild_ms stay separate."}},"required":["status","published_commit","hosted_app_url","static_dependents","pending_secret_package_approvals","phase_timings"],"additionalProperties":false},{"type":"object","properties":{"status":{"type":"string","const":"not_fast_forward"},"previous_commit":{"type":"string"},"published_commit":{"type":"string"},"message":{"type":"string"}},"required":["status","previous_commit","published_commit","message"],"additionalProperties":false},{"type":"object","properties":{"status":{"type":"string","const":"locked"},"previous_commit":{"type":["string","null"]},"pending_commit":{"type":"string","description":"HEAD commit that passed checks. Promote it on the website approval page."},"approval_url":{"type":"string"},"message":{"type":"string"}},"required":["status","previous_commit","pending_commit","approval_url","message"],"additionalProperties":false},{"type":"object","properties":{"status":{"type":"string","const":"approval_required"},"previous_commit":{"type":["string","null"]},"pending_commit":{"type":"string","description":"HEAD commit that passed checks. The previously published commit keeps serving until the owner approves this one."},"approval_url":{"type":"string"},"approval_bundle_url":{"description":"Present when other paused publishes also wait on the owner: one page that approves them together.","type":"string"},"credential_need_changes":{"type":"array","items":{"oneOf":[{"type":"object","properties":{"key":{"type":"string"},"change":{"type":"string","const":"added"},"after":{"type":"object","properties":{"kind":{"description":"Omitted when the need accepts any fetch-capable credential for the provider.","type":"string","enum":["secret","oauth","mcp","url","login","signing"]},"provider":{"type":"string"},"multiple":{"type":"boolean"}},"required":["provider","multiple"],"additionalProperties":false},"from":{"description":"The dependency that declared an inherited need.","type":"string"}},"required":["key","change","after"],"additionalProperties":false},{"type":"object","properties":{"key":{"type":"string"},"change":{"type":"string","const":"changed"},"before":{"type":"object","properties":{"kind":{"description":"Omitted when the need accepts any fetch-capable credential for the provider.","type":"string","enum":["secret","oauth","mcp","url","login","signing"]},"provider":{"type":"string"},"multiple":{"type":"boolean"}},"required":["provider","multiple"],"additionalProperties":false},"after":{"type":"object","properties":{"kind":{"description":"Omitted when the need accepts any fetch-capable credential for the provider.","type":"string","enum":["secret","oauth","mcp","url","login","signing"]},"provider":{"type":"string"},"multiple":{"type":"boolean"}},"required":["provider","multiple"],"additionalProperties":false},"from":{"description":"The dependency that declared an inherited need.","type":"string"}},"required":["key","change","before","after"],"additionalProperties":false}]}},"message":{"type":"string"}},"required":["status","previous_commit","pending_commit","approval_url","credential_need_changes","message"],"additionalProperties":false},{"type":"object","properties":{"status":{"type":"string","const":"checks_failed"},"failed_checks":{"type":"array","items":{"type":"object","properties":{"kind":{"type":"string","enum":["manifest","docs","skills","dependencies","bundle","typecheck","lint","credentials","smoke"]},"ok":{"type":"boolean"},"message":{"type":"string"}},"required":["kind","ok","message"],"additionalProperties":false}},"manifest":{"anyOf":[{},{"type":"null"}],"description":"Parsed package.json when available; null when the manifest itself failed validation or was missing."},"run_id":{"type":"string"}},"required":["status","failed_checks","manifest","run_id"],"additionalProperties":false},{"type":"object","properties":{"status":{"type":"string","const":"published"},"previous_commit":{"type":["string","null"]},"published_commit":{"type":"string"},"manifest":{},"checks":{"type":"array","items":{"type":"object","properties":{"kind":{"type":"string","enum":["manifest","docs","skills","dependencies","bundle","typecheck","lint","credentials","smoke"]},"ok":{"type":"boolean"},"message":{"type":"string"}},"required":["kind","ok","message"],"additionalProperties":false}},"hosted_app_url":{"type":["string","null"]},"test_hints":{"type":"object","properties":{"app":{"type":"string"},"subscriptions":{"type":"array","items":{"type":"object","properties":{"topic":{"type":"string"},"snippet":{"type":"string"}},"required":["topic","snippet"],"additionalProperties":false}},"enablements":{"type":"object","properties":{"message":{"type":"string","description":"Agent-directed message: ask the user whether to enable each listed trigger, with the exact enablementEnable call (or Approve for webhooks/email)."},"triggers":{"type":"array","items":{"type":"object","properties":{"kind":{"type":"string","enum":["cron","subscription","webhook"]},"name":{"type":"string"},"reason":{"type":"string","enum":["missing","paused"]},"call":{"description":"Exact enablementEnable call when applicable; null for Approve-only triggers.","type":["string","null"]}},"required":["kind","name","reason","call"],"additionalProperties":false}}},"required":["message","triggers"],"additionalProperties":false}},"additionalProperties":false},"static_dependents":{"type":"object","properties":{"total":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"Total direct static dependent packages found."},"stale":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"Count of direct static dependent packages with stale bundled snapshots."},"truncated":{"type":"boolean","description":"True when more dependent packages exist than are returned in items."},"items":{"type":"array","items":{"type":"object","properties":{"package_id":{"type":"string","description":"Saved package id of the dependent package."},"kody_id":{"type":"string","description":"Package name leaf of the dependent package."},"name":{"type":"string","description":"Scoped package.json name of the dependent package."},"source_id":{"type":"string","description":"Repo-backed source id for the dependent package."},"published_commit":{"description":"Current published commit of the dependent package.","type":["string","null"]},"stale":{"type":"boolean","description":"True when at least one dependent bundle artifact captured a dependency commit that differs from the package's current published commit."},"artifact_count":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"Number of published bundle artifacts that reference this dependency."},"entrypoints":{"type":"array","items":{"type":"string"},"description":"Bounded list of dependent bundle entrypoints referencing this dependency."},"entrypoints_truncated":{"type":"boolean","description":"True when the dependent has more matching entrypoints than returned."},"bundled_dependency_commit":{"description":"Dependency commit captured in the dependent bundle, or null when matching artifacts have mixed or missing commits.","type":["string","null"]},"current_dependency_commit":{"type":"string","description":"Current published commit for the referenced dependency package."},"recommended_action":{"type":"string","description":"Agent guidance for this dependent package."}},"required":["package_id","kody_id","name","source_id","published_commit","stale","artifact_count","entrypoints","entrypoints_truncated","bundled_dependency_commit","current_dependency_commit","recommended_action"],"additionalProperties":false,"description":"A direct static dependent package from persisted bundle metadata."},"description":"Bounded direct static dependent package summaries."},"recommended_next_action":{"type":"string","description":"Agent guidance explaining whether to inspect or republish dependents. Kody does not republish dependents automatically."}},"required":["total","stale","truncated","items","recommended_next_action"],"additionalProperties":false,"description":"Bounded summary of saved packages whose published bundles statically captured this package through kody:@ imports."},"pending_secret_package_approvals":{"anyOf":[{"type":"object","properties":{"package_id":{"type":"string","description":"Saved package id that needs approvals."},"kody_id":{"type":"string","description":"Package name leaf that needs approvals (same value as `slug`)."},"slug":{"type":"string","description":"Package name leaf that needs approvals."},"secrets":{"type":"array","items":{"type":"object","properties":{"secret_name":{"type":"string"},"approval_url":{"type":"string","description":"Per-secret package approval URL in the account UI."}},"required":["secret_name","approval_url"],"additionalProperties":false},"description":"User secrets that still need package approval."},"bulk_approval_url":{"description":"One-click bulk approval URL when two or more secrets still need package approval; prefer this over individual links.","type":["string","null"]}},"required":["package_id","kody_id","slug","secrets","bulk_approval_url"],"additionalProperties":false},{"type":"null"}],"description":"Pending user-secret package approvals detected from secretMounts and secret placeholders. Null when none are pending. Do not treat the package as ready to run until the user approves these and a static-import smoke test from execute succeeds against a read-only export or dry-run input that actually uses the approved secret."},"listing":{"type":"object","properties":{"pinnedVersion":{"type":["string","null"]},"promotedVersion":{"type":["string","null"]},"behind":{"type":"boolean","const":true},"updateHint":{"type":"string"},"updateUrl":{"type":"string"}},"required":["pinnedVersion","promotedVersion","behind","updateHint","updateUrl"],"additionalProperties":false,"description":"Present when this package has a public community listing whose pinned snapshot is still behind the published commit after promote auto-sync. Rare; a background backfill retries. No manual republish step is required."},"phase_timings":{"type":"object","properties":{"clone_ms":{"description":"Milliseconds spent cloning Artifacts HEAD into the publish workspace. Omitted when this attempt did not clone.","type":"integer","minimum":0,"maximum":9007199254740991},"checks_typecheck_ms":{"description":"Milliseconds spent in the publish typecheck phase. Omitted when typecheck did not run (for example already_published).","type":"integer","minimum":0,"maximum":9007199254740991},"checks_bundle_ms":{"description":"Milliseconds spent in the publish bundle-check phase. Distinct from rebuild_ms. Omitted when bundle check did not run, including when full esbuild validation is deferred to rebuild.","type":"integer","minimum":0,"maximum":9007199254740991},"rebuild_ms":{"description":"Milliseconds spent rebuilding published package artifacts after checks, or confirming they match this commit. Distinct from checks_bundle_ms.","type":"integer","minimum":0,"maximum":9007199254740991},"dependents_ms":{"description":"Milliseconds spent indexing static dependents, hosted app URL, test hints, and pending secret approvals.","type":"integer","minimum":0,"maximum":9007199254740991},"total_ms":{"description":"Milliseconds from the start of this publish attempt until the result was ready. On status dispatched, this is time-to-dispatch.","type":"integer","minimum":0,"maximum":9007199254740991}},"additionalProperties":false,"description":"Coarse packagePublishExternalPush phase timings in milliseconds. Field names are stable. Omitted keys mean that phase did not run in this result. checks_bundle_ms and rebuild_ms stay separate."}},"required":["status","previous_commit","published_commit","manifest","checks","hosted_app_url","static_dependents","pending_secret_package_approvals","phase_timings"],"additionalProperties":false},{"type":"object","properties":{"status":{"type":"string","const":"dispatched"},"workflow_id":{"type":"string"},"workflow_name":{"type":"string"},"idempotency_key":{"type":"string"},"run_status":{"type":["string","null"]},"message":{"type":"string"},"phase_timings":{"type":"object","properties":{"clone_ms":{"description":"Milliseconds spent cloning Artifacts HEAD into the publish workspace. Omitted when this attempt did not clone.","type":"integer","minimum":0,"maximum":9007199254740991},"checks_typecheck_ms":{"description":"Milliseconds spent in the publish typecheck phase. Omitted when typecheck did not run (for example already_published).","type":"integer","minimum":0,"maximum":9007199254740991},"checks_bundle_ms":{"description":"Milliseconds spent in the publish bundle-check phase. Distinct from rebuild_ms. Omitted when bundle check did not run, including when full esbuild validation is deferred to rebuild.","type":"integer","minimum":0,"maximum":9007199254740991},"rebuild_ms":{"description":"Milliseconds spent rebuilding published package artifacts after checks, or confirming they match this commit. Distinct from checks_bundle_ms.","type":"integer","minimum":0,"maximum":9007199254740991},"dependents_ms":{"description":"Milliseconds spent indexing static dependents, hosted app URL, test hints, and pending secret approvals.","type":"integer","minimum":0,"maximum":9007199254740991},"total_ms":{"description":"Milliseconds from the start of this publish attempt until the result was ready. On status dispatched, this is time-to-dispatch.","type":"integer","minimum":0,"maximum":9007199254740991}},"additionalProperties":false,"description":"Coarse packagePublishExternalPush phase timings in milliseconds. Field names are stable. Omitted keys mean that phase did not run in this result. checks_bundle_ms and rebuild_ms stay separate."}},"required":["status","workflow_id","workflow_name","idempotency_key","run_status","message","phase_timings"],"additionalProperties":false}]}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"package:write","x-kody-read-only":false}},"/v1/package-subscriptions":{"get":{"operationId":"packageSubscriptionsList","summary":"List package.json#kody.subscriptions entries for the packages you can read in the org this connection is bound to, op...","description":"List package.json#kody.subscriptions entries for the packages you can read in the org this connection is bound to, optionally filtered by exact event topic. Use this to discover package event handlers such as email receipt, delivery-update, repo.pushed / repo.created / repo.deleted Artifacts lifecycle notifiers, run.error.recorded activity notifiers, integration.auth.failed / integration.auth.succeeded reconnect notifiers, mcp.server.disconnected / mcp.server.reconnected connection episodes, community.fork.upstream_updated fork notifiers, follow.published / follow.pushed follow notifiers, admin platform-feedback, admin community-activity, admin community-listing-published, admin status-incident, admin fleet.package_error_rate.elevated, admin fleet.entitlement.crossed, admin auth.denial.burst, admin email.delivery.burst, admin user.created / user.deleted, admin user.email_verification.failed, admin user.email_verification.stalled, admin user.email_outbound.paused, or admin email.system-message.sent notification subscribers before debugging dispatch or building fan-out. Admin-only topics carry only their documented payload, and declaring one does not grant delivery; dispatch checks the package owner role fresh at delivery time.\n\nOrg permission: `package:read`.","tags":["packages"],"parameters":[{"name":"topic","in":"query","required":false,"description":"Optional exact event topic filter such as \"email.message.received\", \"repo.pushed\", \"run.error.recorded\", \"integration.auth.failed\", \"integration.auth.succeeded\", \"mcp.server.disconnected\", \"community.fork.upstream_updated\", \"follow.published\", \"follow.pushed\", \"platform.feedback.submitted\", \"community.activity.recorded\", \"community.listing.published\", \"status.incident.opened\", \"fleet.package_error_rate.elevated\", \"fleet.entitlement.crossed\", \"auth.denial.burst\", \"email.delivery.burst\", \"user.created\", \"user.deleted\", \"user.email_verification.failed\", \"user.email_verification.stalled\", \"user.email_outbound.paused\", or \"email.system-message.sent\".","schema":{"description":"Optional exact event topic filter such as \"email.message.received\", \"repo.pushed\", \"run.error.recorded\", \"integration.auth.failed\", \"integration.auth.succeeded\", \"mcp.server.disconnected\", \"community.fork.upstream_updated\", \"follow.published\", \"follow.pushed\", \"platform.feedback.submitted\", \"community.activity.recorded\", \"community.listing.published\", \"status.incident.opened\", \"fleet.package_error_rate.elevated\", \"fleet.entitlement.crossed\", \"auth.denial.burst\", \"email.delivery.burst\", \"user.created\", \"user.deleted\", \"user.email_verification.failed\", \"user.email_verification.stalled\", \"user.email_outbound.paused\", or \"email.system-message.sent\".","type":"string","minLength":1}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"subscriptions":{"type":"array","items":{"type":"object","properties":{"package_id":{"type":"string"},"kody_id":{"type":"string","description":"Package name leaf (same value as `slug`)."},"slug":{"type":"string","description":"Package name leaf (same value as `kody_id`)."},"name":{"type":"string"},"topic":{"type":"string"},"handler":{"type":"string"},"description":{"type":["string","null"]},"filters":{"anyOf":[{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},{"type":"null"}]}},"required":["package_id","kody_id","slug","name","topic","handler","description","filters"],"additionalProperties":false}}},"required":["subscriptions"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"package:read","x-kody-read-only":true}},"/v1/enablements":{"get":{"operationId":"enablementList","summary":"List your enablements: the cron jobs, subscriptions, and webhooks that run as you, with paused ones and why they paused.","description":"List your enablements: the cron jobs, subscriptions, and webhooks that run as you, with paused ones and why they paused. An Owner can pass scope \"org\" to list everyone's.\n\nOrg permission: `org:read`.","tags":["packages"],"parameters":[{"name":"scope","in":"query","required":false,"description":"mine (default) or org (Owners only).","schema":{"description":"mine (default) or org (Owners only).","type":"string","enum":["mine","org"]}},{"name":"includeOff","in":"query","required":false,"description":"Include enablements that were turned off.","schema":{"description":"Include enablements that were turned off.","type":"boolean"}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"enablements":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"package_id":{"type":["string","null"]},"trigger_kind":{"type":"string","enum":["cron","subscription","webhook"],"description":"cron (a package.json#kody.jobs entry), subscription (a package.json#kody.subscriptions topic, inbound email included), or webhook (a minted package.json#kody.webhooks entry)."},"trigger_name":{"type":"string","description":"Job name, subscription topic, or webhook name."},"enabler_user_id":{"type":"string","description":"The person every run acts as, and who is billed."},"state":{"type":"string","enum":["on","paused","off"],"description":"paused: the enabler lost access; events are dropped until access is back, then it resumes by itself."},"paused_reason":{"anyOf":[{"type":"string","enum":["org_access","package_access","credential_access"]},{"type":"null"}]},"paused_permission":{"type":["string","null"]},"paused_resource":{"anyOf":[{"type":"object","properties":{"type":{"type":"string"},"id":{"type":"string"}},"required":["type","id"],"additionalProperties":false},{"type":"null"}]},"origin":{"type":"string","enum":["enabled","migrated"]},"enabled_at":{"type":"string"},"disabled_at":{"type":["string","null"]}},"required":["id","package_id","trigger_kind","trigger_name","enabler_user_id","state","paused_reason","paused_permission","paused_resource","origin","enabled_at","disabled_at"],"additionalProperties":false}}},"required":["enablements"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"org:read","x-kody-read-only":true},"post":{"operationId":"enablementEnable","summary":"Turn a package cron job or subscription topic on for yourself.","description":"Turn a package cron job or subscription topic on for yourself. A webhook is different: its first turn-on needs a person to Approve it at the approval URL (webhookUrlMint or credentialMappingPropose returns it), so this refuses a webhook that is not already on, and only returns an existing enablement. email.message.received and email.message.quarantined are refused here too: those run only for a sender, so a person Approves them from the inbox (the approval link includes sender_kind and sender_value). Every run then acts as you: your access, your credentials, billed and audited to you. Publishing never turns a trigger on, and nobody can enable one for someone else. Needs package:execute on the package. If you lose access later, the enablement pauses and resumes by itself once access is back.\n\nOrg permission: `package:execute`.","tags":["packages"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"packageId":{"description":"Saved-package UUID. Use when the scoped name is not known, or for a stable ref.","type":"string","minLength":1},"kodyId":{"description":"Package name (`@owner/leaf` or the name leaf). Prefer this when you know the name.","type":"string","minLength":1},"triggerKind":{"type":"string","enum":["cron","subscription","webhook"],"description":"cron (a package.json#kody.jobs entry), subscription (a package.json#kody.subscriptions topic, inbound email included), or webhook (a minted package.json#kody.webhooks entry)."},"triggerName":{"type":"string","minLength":1,"description":"Job name, subscription topic, or webhook name."}},"required":["triggerKind","triggerName"]}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"enablement":{"type":"object","properties":{"id":{"type":"string"},"package_id":{"type":["string","null"]},"trigger_kind":{"type":"string","enum":["cron","subscription","webhook"],"description":"cron (a package.json#kody.jobs entry), subscription (a package.json#kody.subscriptions topic, inbound email included), or webhook (a minted package.json#kody.webhooks entry)."},"trigger_name":{"type":"string","description":"Job name, subscription topic, or webhook name."},"enabler_user_id":{"type":"string","description":"The person every run acts as, and who is billed."},"state":{"type":"string","enum":["on","paused","off"],"description":"paused: the enabler lost access; events are dropped until access is back, then it resumes by itself."},"paused_reason":{"anyOf":[{"type":"string","enum":["org_access","package_access","credential_access"]},{"type":"null"}]},"paused_permission":{"type":["string","null"]},"paused_resource":{"anyOf":[{"type":"object","properties":{"type":{"type":"string"},"id":{"type":"string"}},"required":["type","id"],"additionalProperties":false},{"type":"null"}]},"origin":{"type":"string","enum":["enabled","migrated"]},"enabled_at":{"type":"string"},"disabled_at":{"type":["string","null"]}},"required":["id","package_id","trigger_kind","trigger_name","enabler_user_id","state","paused_reason","paused_permission","paused_resource","origin","enabled_at","disabled_at"],"additionalProperties":false}},"required":["enablement"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"package:execute","x-kody-read-only":false}},"/v1/enablements/{enablementId}/disable":{"post":{"operationId":"enablementDisable","summary":"Turn one enablement off for good; it stops on the next event.","description":"Turn one enablement off for good; it stops on the next event. Its enabler or an org Owner may turn it off. Turning it on again creates a new enablement with enablementEnable.\n\nOrg permission: `org:read`.","tags":["packages"],"parameters":[{"name":"enablementId","in":"path","required":true,"description":"Enablement id.","schema":{"type":"string","minLength":1,"description":"Enablement id."}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{}}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"enablement":{"type":"object","properties":{"id":{"type":"string"},"package_id":{"type":["string","null"]},"trigger_kind":{"type":"string","enum":["cron","subscription","webhook"],"description":"cron (a package.json#kody.jobs entry), subscription (a package.json#kody.subscriptions topic, inbound email included), or webhook (a minted package.json#kody.webhooks entry)."},"trigger_name":{"type":"string","description":"Job name, subscription topic, or webhook name."},"enabler_user_id":{"type":"string","description":"The person every run acts as, and who is billed."},"state":{"type":"string","enum":["on","paused","off"],"description":"paused: the enabler lost access; events are dropped until access is back, then it resumes by itself."},"paused_reason":{"anyOf":[{"type":"string","enum":["org_access","package_access","credential_access"]},{"type":"null"}]},"paused_permission":{"type":["string","null"]},"paused_resource":{"anyOf":[{"type":"object","properties":{"type":{"type":"string"},"id":{"type":"string"}},"required":["type","id"],"additionalProperties":false},{"type":"null"}]},"origin":{"type":"string","enum":["enabled","migrated"]},"enabled_at":{"type":"string"},"disabled_at":{"type":["string","null"]}},"required":["id","package_id","trigger_kind","trigger_name","enabler_user_id","state","paused_reason","paused_permission","paused_resource","origin","enabled_at","disabled_at"],"additionalProperties":false}},"required":["enablement"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"org:read","x-kody-read-only":false}},"/v1/approvals":{"get":{"operationId":"approvalPendingList","summary":"List approvals waiting on the signed-in person in this org that they can decide: paused publishes whose credential ne...","description":"List approvals waiting on the signed-in person in this org that they can decide: paused publishes whose credential needs changed or that make a package public, internet-visible packages whose credentials or storage changed, and credential picks proposed with credentialMappingPropose. Each item says in plain language what approving grants (credential, kind, provider, hosts) and what was approved before. Read-only; pass keys to approvalBundleCreate for one page the person approves in the browser.\n\nOrg permission: none (touches no org data).","tags":["packages"],"parameters":[{"name":"types","in":"query","required":false,"description":"Only these item types. Default: every type.","schema":{"description":"Only these item types. Default: every type.","type":"array","items":{"type":"string","enum":["publish","capabilities","credential-picks"]}},"style":"form","explode":true},{"name":"packages","in":"query","required":false,"description":"Only these packages, by package id or kody id.","schema":{"description":"Only these packages, by package id or kody id.","type":"array","items":{"type":"string","minLength":1}},"style":"form","explode":true}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string","description":"Pass to approvalBundleCreate items to bundle exactly this approval."},"type":{"type":"string","enum":["publish","capabilities","credential-picks"],"description":"publish: a paused publish (credential needs changed, or going public). capabilities: an internet-visible package whose credentials or storage changed since approval. credential-picks: a recorded credentialMappingPropose proposal."},"title":{"type":"string"},"summary":{"type":"string","description":"What approving does, in plain language."},"package":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"kodyId":{"type":"string"},"name":{"type":"string"}},"required":["id","kodyId","name"],"additionalProperties":false},{"type":"null"}]},"grants":{"type":"array","items":{"type":"object","properties":{"change":{"type":"string","enum":["added","changed","removed"]},"label":{"type":"string"},"where":{"type":["string","null"]},"kind":{"type":["string","null"]},"provider":{"type":["string","null"]},"hosts":{"type":"array","items":{"type":"string"}},"before":{"type":["string","null"]},"after":{"type":["string","null"]},"match":{"type":["string","null"]}},"required":["change","label","where","kind","provider","hosts","before","after","match"],"additionalProperties":false}},"canApprove":{"type":"boolean","description":"False when something must be fixed first; see statusMessage."},"statusMessage":{"type":["string","null"]},"description":{"type":"string","description":"One-line text form of this item."}},"required":["key","type","title","summary","package","grants","canApprove","statusMessage","description"],"additionalProperties":false}},"message":{"type":"string"}},"required":["items","message"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"none","x-kody-read-only":true}},"/v1/approval-bundles":{"post":{"operationId":"approvalBundleCreate","summary":"Make one approval page for the signed-in person from approvals waiting on them (see approvalPendingList): pass item k...","description":"Make one approval page for the signed-in person from approvals waiting on them (see approvalPendingList): pass item keys, or omit them to include everything pending (narrowed by types and packages). Returns a URL to send to the person. The page groups items by package, shows what each grants, and lets them approve all at once or approve or deny each one. Approving runs each item's own approval, exactly as on its package page. This never approves anything; only the person can, in the browser. Items not waiting on the person are skipped and listed. At most 100 items; the link works for 30 days.\n\nOrg permission: none (touches no org data).","tags":["packages"],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"items":{"description":"Item keys from approvalPendingList. Omit to bundle everything pending.","maxItems":100,"type":"array","items":{"type":"string","minLength":1}},"types":{"description":"When items is omitted: only these item types.","type":"array","items":{"type":"string","enum":["publish","capabilities","credential-picks"]}},"packages":{"description":"When items is omitted: only these packages, by package id or kody id.","type":"array","items":{"type":"string","minLength":1}},"note":{"description":"Shown to the person as an untrusted note from you.","type":"string","maxLength":2000}}}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"bundleId":{"type":"string"},"url":{"type":"string"},"items":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string","description":"Pass to approvalBundleCreate items to bundle exactly this approval."},"type":{"type":"string","enum":["publish","capabilities","credential-picks"],"description":"publish: a paused publish (credential needs changed, or going public). capabilities: an internet-visible package whose credentials or storage changed since approval. credential-picks: a recorded credentialMappingPropose proposal."},"title":{"type":"string"},"summary":{"type":"string","description":"What approving does, in plain language."},"package":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"kodyId":{"type":"string"},"name":{"type":"string"}},"required":["id","kodyId","name"],"additionalProperties":false},{"type":"null"}]},"grants":{"type":"array","items":{"type":"object","properties":{"change":{"type":"string","enum":["added","changed","removed"]},"label":{"type":"string"},"where":{"type":["string","null"]},"kind":{"type":["string","null"]},"provider":{"type":["string","null"]},"hosts":{"type":"array","items":{"type":"string"}},"before":{"type":["string","null"]},"after":{"type":["string","null"]},"match":{"type":["string","null"]}},"required":["change","label","where","kind","provider","hosts","before","after","match"],"additionalProperties":false}},"canApprove":{"type":"boolean","description":"False when something must be fixed first; see statusMessage."},"statusMessage":{"type":["string","null"]},"description":{"type":"string","description":"One-line text form of this item."}},"required":["key","type","title","summary","package","grants","canApprove","statusMessage","description"],"additionalProperties":false}},"skipped":{"type":"array","items":{"type":"string"},"description":"Requested keys not waiting on the person, left out."},"message":{"type":"string"}},"required":["bundleId","url","items","skipped","message"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"none","x-kody-read-only":false}},"/v1/follows":{"get":{"operationId":"followList","summary":"List follows owned by the org this connection is bound to.","description":"List follows owned by the org this connection is bound to. Each row is named by @handle/name. Status is active or paused. Paused follows stop receiving events until followAdd resumes them. This list never includes internal ids.\n\nOrg permission: `org:read`.","tags":["follows"],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"follows":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string","description":"Target @handle/name."},"kind":{"type":"string","enum":["package","repo"]},"status":{"type":"string","enum":["active","paused"]},"events":{"type":"array","items":{"type":"string","enum":["published","pushed"]},"description":"Events this follow delivers: published and/or pushed."},"created_at":{"type":"string"},"paused_at":{"type":["string","null"]},"paused_reason":{"anyOf":[{"type":"string","enum":["target_missing","access_lost"]},{"type":"null"}],"description":"Why a paused follow paused: target_missing or access_lost. Null when active."},"last_delivery_skip_reason":{"description":"Set when a delivery was skipped before the handler ran, for example zero_credits.","type":["string","null"]}},"required":["name","kind","status","events","created_at","paused_at","paused_reason","last_delivery_skip_reason"],"additionalProperties":false}}},"required":["follows"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"org:read","x-kody-read-only":true},"post":{"operationId":"followAdd","summary":"Follow a package or plain repo by @handle/name so this org receives follow.published when its live version moves and,...","description":"Follow a package or plain repo by @handle/name so this org receives follow.published when its live version moves and, when you can read it, follow.pushed when the default branch moves. Public targets are followable by any signed-in caller. Private targets require package:read (a use grant qualifies; execute-only does not) and a missing or unreadable target is reported as not found. Creating a follow that already exists returns it and, if it was paused, resumes it when you can still read the target. Pass events to choose published and/or pushed; omit them to keep the current choice (both for a new follow).\n\nOrg permission: `org:read`.","tags":["follows"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"name":{"type":"string","minLength":1,"description":"Target to follow, as @handle/name. handle is the owner org slug."},"kind":{"description":"package or repo. Omit to follow the package when both exist under that name, otherwise the plain repo.","type":"string","enum":["package","repo"]},"events":{"minItems":1,"type":"array","items":{"type":"string","enum":["published","pushed"]},"description":"Events to deliver: published (follow.published, packages only) and/or pushed (follow.pushed, needs read access)."}},"required":["name"]}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"follow":{"type":"object","properties":{"name":{"type":"string","description":"Target @handle/name."},"kind":{"type":"string","enum":["package","repo"]},"status":{"type":"string","enum":["active","paused"]},"events":{"type":"array","items":{"type":"string","enum":["published","pushed"]},"description":"Events this follow delivers: published and/or pushed."},"created_at":{"type":"string"},"paused_at":{"type":["string","null"]},"paused_reason":{"anyOf":[{"type":"string","enum":["target_missing","access_lost"]},{"type":"null"}],"description":"Why a paused follow paused: target_missing or access_lost. Null when active."},"last_delivery_skip_reason":{"description":"Set when a delivery was skipped before the handler ran, for example zero_credits.","type":["string","null"]}},"required":["name","kind","status","events","created_at","paused_at","paused_reason","last_delivery_skip_reason"],"additionalProperties":false}},"required":["follow"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"org:read","x-kody-read-only":false},"delete":{"operationId":"followRemove","summary":"Unfollow a package or plain repo by @handle/name for the org this connection is bound to.","description":"Unfollow a package or plain repo by @handle/name for the org this connection is bound to. Works for paused follows too, including ones whose target was deleted. Returns the removed follow.\n\nOrg permission: `org:read`.","tags":["follows"],"parameters":[{"name":"name","in":"query","required":true,"description":"Followed target, as @handle/name (see followList).","schema":{"type":"string","minLength":1,"description":"Followed target, as @handle/name (see followList)."}},{"name":"kind","in":"query","required":false,"description":"package or repo, when the org follows both names.","schema":{"description":"package or repo, when the org follows both names.","type":"string","enum":["package","repo"]}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"removed":{"type":"object","properties":{"name":{"type":"string","description":"Target @handle/name."},"kind":{"type":"string","enum":["package","repo"]},"status":{"type":"string","enum":["active","paused"]},"events":{"type":"array","items":{"type":"string","enum":["published","pushed"]},"description":"Events this follow delivers: published and/or pushed."},"created_at":{"type":"string"},"paused_at":{"type":["string","null"]},"paused_reason":{"anyOf":[{"type":"string","enum":["target_missing","access_lost"]},{"type":"null"}],"description":"Why a paused follow paused: target_missing or access_lost. Null when active."},"last_delivery_skip_reason":{"description":"Set when a delivery was skipped before the handler ran, for example zero_credits.","type":["string","null"]}},"required":["name","kind","status","events","created_at","paused_at","paused_reason","last_delivery_skip_reason"],"additionalProperties":false}},"required":["removed"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"org:read","x-kody-read-only":false}},"/v1/repos":{"get":{"operationId":"repoList","summary":"List plain repos owned by the org this connection is bound to, from D1 discovery metadata (no live Artifacts reads).","description":"List plain repos owned by the org this connection is bound to, from D1 discovery metadata (no live Artifacts reads). Each repo includes icon_url when an indexed or published commit is available.\n\nOrg permission: `package:read`.","tags":["repos"],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"repos":{"type":"array","items":{"type":"object","properties":{"repo_id":{"type":"string"},"name":{"type":"string"},"description":{"type":["string","null"]},"visibility":{"type":"string","enum":["public","private"]},"icon_url":{"description":"Owner-only identity mark URL for the indexed or published commit, or null when neither commit exists.","type":["string","null"]},"created_at":{"type":"string"},"updated_at":{"type":"string"}},"required":["repo_id","name","description","visibility","icon_url","created_at","updated_at"],"additionalProperties":false}}},"required":["repos"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"package:read","x-kody-read-only":true},"post":{"operationId":"repoCreate","summary":"Create a plain Artifacts-backed repo in the org this connection is bound to.","description":"Create a plain Artifacts-backed repo in the org this connection is bound to. Plain repos are live-at-HEAD (no publish step). Use repoGetGitRemote for the git lane or repoOpenSession for MCP file editing.\n\nOrg permission: `package:create`.","tags":["repos"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"name":{"type":"string","minLength":1,"description":"Repo name (lowercase letters, numbers, dashes; 1–64 characters)."},"description":{"description":"Optional short description for discovery.","type":"string","minLength":1}},"required":["name"]}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"repo_id":{"type":"string"},"name":{"type":"string"},"source_id":{"type":"string"},"repo_git_id":{"type":"string"},"session_hint":{"type":"string"},"git_lane_hint":{"type":"string"}},"required":["repo_id","name","source_id","repo_git_id","session_hint","git_lane_hint"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"package:create","x-kody-read-only":false}},"/v1/repos/{repo_id}":{"get":{"operationId":"repoGet","summary":"Load one plain repo in the org this connection is bound to, including live default-branch HEAD and progressive-disclo...","description":"Load one plain repo in the org this connection is bound to, including live default-branch HEAD and progressive-disclosure hints when the tree is package-shaped.\n\nOrg permission: `package:read`.","tags":["repos"],"parameters":[{"name":"repo_id","in":"path","required":true,"schema":{"type":"string","minLength":1}},{"name":"name","in":"query","required":false,"schema":{"type":"string","minLength":1}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"repo_id":{"type":"string"},"name":{"type":"string"},"description":{"type":["string","null"]},"visibility":{"type":"string","enum":["public","private"]},"source_id":{"type":"string"},"repo_git_id":{"type":"string"},"head_branch":{"type":"string"},"head_commit":{"type":["string","null"]},"created_at":{"type":"string"},"updated_at":{"type":"string"},"package_shaped":{"type":"boolean"},"activated":{"type":"boolean","const":false},"notice":{"type":["string","null"]}},"required":["repo_id","name","description","visibility","source_id","repo_git_id","head_branch","head_commit","created_at","updated_at","package_shaped","activated","notice"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"package:read","x-kody-read-only":true},"patch":{"operationId":"repoUpdate","summary":"Update mutable settings for a plain repo.","description":"Update mutable settings for a plain repo. Visibility is a repo setting, not package.json#private. Making a repo public makes default-branch HEAD world-readable and forkable. Making it private 404s public URLs (forks keep their copies) — pass confirm_name matching the repo slug after the owner typed that name.\n\nOrg permission: `package:write`.","tags":["repos"],"parameters":[{"name":"repo_id","in":"path","required":true,"schema":{"type":"string","minLength":1}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"name":{"type":"string","minLength":1},"changes":{"type":"object","properties":{"visibility":{"type":"string","enum":["public","private"],"description":"Repo visibility. Public means default-branch HEAD is world-readable and forkable. Private is owner-only. Changing to private 404s public URLs; existing forks keep their copies."}},"required":["visibility"],"additionalProperties":false},"confirm_name":{"description":"Required when changes.visibility is private. Must equal the repo slug (URL name). Confirm with the user first: going private 404s public URLs; existing forks keep their copies.","type":"string","minLength":1}},"required":["changes"]}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"repo_id":{"type":"string"},"name":{"type":"string"},"visibility":{"type":"string","enum":["public","private"]}},"required":["ok","repo_id","name","visibility"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"package:write","x-kody-read-only":false},"delete":{"operationId":"repoDelete","summary":"Delete a plain repo in the org this connection is bound to.","description":"Delete a plain repo in the org this connection is bound to. Removes the user_repos row, entity_sources mapping, and Artifacts repo (best-effort).\n\nOrg permission: `package:delete`.","tags":["repos"],"parameters":[{"name":"repo_id","in":"path","required":true,"schema":{"type":"string","minLength":1}},{"name":"name","in":"query","required":false,"schema":{"type":"string","minLength":1}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"repo_id":{"type":"string"},"artifacts_cleanup":{"type":"string","enum":["ok","failed"]},"warning":{"type":"string"}},"required":["ok","repo_id","artifacts_cleanup"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"package:delete","x-kody-read-only":false}},"/v1/repos/git-remote":{"post":{"operationId":"repoGetGitRemote","summary":"Mint a short-lived git remote for a plain repo (Kody smart-HTTP proxy in front of Cloudflare Artifacts).","description":"Mint a short-lived git remote for a plain repo (Kody smart-HTTP proxy in front of Cloudflare Artifacts). When scope is omitted, defaults to write if you have org-wide write access, otherwise read. Pass scope explicitly to force read or write; requesting write without write access is denied with guidance (use scope: 'read', or ask an Owner for a grant). Write pushes are live at HEAD — no package publish reconcile step runs afterward. Concurrent push lock contention is held and retried on the proxy (bounded wait) before HTTP 503 with Retry-After and \"repository busy, retry\". A read remote rejects push with: this remote is read-only; request scope: 'write'. The result includes `git_author` (signed-in Kody account email and display name) and `setup_commands` that set local `user.email` / `user.name` to that identity — never invent a git email. The Artifacts backing store fails pushes above ~32 MiB of decompressed pack content with a raw HTTP 413.\n\nOrg permission: `package:read`.","tags":["repos"],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"repo_id":{"description":"Plain repo UUID, or the repo name. OpenAPI path `/v1/repos/{repo_id}/git-remote` accepts either. Prefer `name` (or this field) on `POST /v1/repos/git-remote` when calling via CLI/OpenAPI without a path id.","type":"string","minLength":1},"name":{"description":"Plain repo name. Provide exactly one of `repo_id` or `name`. Works on MCP `api`, execute, and OpenAPI `POST /v1/repos/git-remote`.","type":"string","minLength":1},"scope":{"description":"Access scope for the minted Artifacts token. When omitted, defaults to write if you have write access, otherwise read. Explicit scope is honored; requesting write without write access is denied. A read remote rejects push with: this remote is read-only; request scope: 'write'.","type":"string","enum":["read","write"]},"ttl_seconds":{"default":14400,"type":"integer","minimum":60,"maximum":86400}}}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"repo_id":{"type":"string"},"name":{"type":"string"},"source_id":{"type":"string"},"remote":{"type":"string"},"authenticated_remote":{"type":"string"},"git_extra_header":{"type":"string"},"scope":{"type":"string","enum":["read","write"]},"expires_at":{"type":"string"},"git_author":{"type":"object","properties":{"name":{"type":"string","description":"Signed-in Kody account display name. Use as git user.name; do not guess a name."},"email":{"type":"string","format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$","description":"Signed-in Kody account email. Use as git user.email; never invent an email."}},"required":["name","email"],"additionalProperties":false,"description":"Git author for this clone: the signed-in Kody account. setup_commands set local user.name and user.email to these values."},"setup_commands":{"type":"array","items":{"type":"string"}},"live_at_head":{"type":"boolean","const":true}},"required":["repo_id","name","source_id","remote","authenticated_remote","git_extra_header","scope","expires_at","git_author","setup_commands","live_at_head"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"package:read","x-kody-read-only":false}},"/v1/repos/{repo_id}/git-remote":{"post":{"operationId":"repoGetGitRemoteByPath","summary":"Mint a short-lived git remote for a plain repo (Kody smart-HTTP proxy in front of Cloudflare Artifacts).","description":"Mint a short-lived git remote for a plain repo (Kody smart-HTTP proxy in front of Cloudflare Artifacts). When scope is omitted, defaults to write if you have org-wide write access, otherwise read. Pass scope explicitly to force read or write; requesting write without write access is denied with guidance (use scope: 'read', or ask an Owner for a grant). Write pushes are live at HEAD — no package publish reconcile step runs afterward. Concurrent push lock contention is held and retried on the proxy (bounded wait) before HTTP 503 with Retry-After and \"repository busy, retry\". A read remote rejects push with: this remote is read-only; request scope: 'write'. The result includes `git_author` (signed-in Kody account email and display name) and `setup_commands` that set local `user.email` / `user.name` to that identity — never invent a git email. The Artifacts backing store fails pushes above ~32 MiB of decompressed pack content with a raw HTTP 413.\n\nOrg permission: `package:read`.","tags":["repos"],"parameters":[{"name":"repo_id","in":"path","required":true,"description":"Plain repo UUID, or the repo name. OpenAPI path `/v1/repos/{repo_id}/git-remote` accepts either. Prefer `name` (or this field) on `POST /v1/repos/git-remote` when calling via CLI/OpenAPI without a path id.","schema":{"description":"Plain repo UUID, or the repo name. OpenAPI path `/v1/repos/{repo_id}/git-remote` accepts either. Prefer `name` (or this field) on `POST /v1/repos/git-remote` when calling via CLI/OpenAPI without a path id.","type":"string","minLength":1}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"name":{"description":"Plain repo name. Provide exactly one of `repo_id` or `name`. Works on MCP `api`, execute, and OpenAPI `POST /v1/repos/git-remote`.","type":"string","minLength":1},"scope":{"description":"Access scope for the minted Artifacts token. When omitted, defaults to write if you have write access, otherwise read. Explicit scope is honored; requesting write without write access is denied. A read remote rejects push with: this remote is read-only; request scope: 'write'.","type":"string","enum":["read","write"]},"ttl_seconds":{"default":14400,"type":"integer","minimum":60,"maximum":86400}}}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"repo_id":{"type":"string"},"name":{"type":"string"},"source_id":{"type":"string"},"remote":{"type":"string"},"authenticated_remote":{"type":"string"},"git_extra_header":{"type":"string"},"scope":{"type":"string","enum":["read","write"]},"expires_at":{"type":"string"},"git_author":{"type":"object","properties":{"name":{"type":"string","description":"Signed-in Kody account display name. Use as git user.name; do not guess a name."},"email":{"type":"string","format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$","description":"Signed-in Kody account email. Use as git user.email; never invent an email."}},"required":["name","email"],"additionalProperties":false,"description":"Git author for this clone: the signed-in Kody account. setup_commands set local user.name and user.email to these values."},"setup_commands":{"type":"array","items":{"type":"string"}},"live_at_head":{"type":"boolean","const":true}},"required":["repo_id","name","source_id","remote","authenticated_remote","git_extra_header","scope","expires_at","git_author","setup_commands","live_at_head"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"package:read","x-kody-read-only":false}},"/v1/repos/{repo_id}/promote":{"post":{"operationId":"repoPromoteToPackage","summary":"Promote a package-shaped plain repo (root package.json at HEAD) into a saved package.","description":"Promote a package-shaped plain repo (root package.json at HEAD) into a saved package. Runs the full external-push publish checks; on success creates the saved-package projection and removes the plain-repo row.\n\nOrg permission: `package:create`.","tags":["repos"],"parameters":[{"name":"repo_id","in":"path","required":true,"schema":{"type":"string","minLength":1}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"name":{"type":"string","minLength":1}}}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","const":"promoted"},"package_id":{"type":"string"},"kody_id":{"type":"string"},"name":{"type":"string"},"published_commit":{"type":"string"},"message":{"type":"string"}},"required":["status","package_id","kody_id","name","published_commit"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"package:create","x-kody-read-only":false}},"/v1/repo-publish-note":{"get":{"operationId":"repoShowPublishNote","summary":"Read the Kody publish harness git note attached to a published Artifacts commit.","description":"Read the Kody publish harness git note attached to a published Artifacts commit. Use this to inspect publish provenance, session/conversation ids, and check summaries without opening D1.\n\nOrg permission: `package:read`.","tags":["repos"],"parameters":[{"name":"source_id","in":"query","required":false,"description":"Shared entity source id for any repo-backed entity.","schema":{"description":"Shared entity source id for any repo-backed entity.","type":"string","minLength":1}},{"name":"package_id","in":"query","required":false,"schema":{"type":"string","minLength":1}},{"name":"kody_id","in":"query","required":false,"schema":{"type":"string","minLength":1}},{"name":"commit","in":"query","required":false,"description":"Commit oid to inspect. Defaults to the source published_commit.","schema":{"description":"Commit oid to inspect. Defaults to the source published_commit.","type":"string","minLength":1}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"found":{"type":"boolean"},"commit":{"type":"string"},"source_id":{"type":"string"},"repo_id":{"type":"string"},"raw_note":{"type":["string","null"]},"note":{"anyOf":[{"type":"object","properties":{"v":{"type":"number","const":1},"publishedAt":{"type":"string"},"publishedBy":{"type":"string","enum":["repo_session","source_bootstrap","external_push"]},"sourceId":{"type":"string"},"entityKind":{"type":"string","enum":["package","repo"]},"entityId":{"type":"string"},"repoId":{"type":"string"},"commit":{"type":"string"},"sessionId":{"type":["string","null"]},"conversationId":{"type":["string","null"]},"previousPublishedCommit":{"type":["string","null"]},"baseCommit":{"type":["string","null"]},"checks":{"anyOf":[{"type":"object","properties":{"runId":{"type":"string"},"treeHash":{"type":["string","null"]},"checkedAt":{"type":["string","null"]},"ok":{"type":"boolean"},"results":{"type":"array","items":{"type":"object","properties":{"kind":{"type":"string"},"ok":{"type":"boolean"},"message":{"type":"string"}},"required":["kind","ok","message"],"additionalProperties":false}}},"required":["runId","treeHash","checkedAt","ok","results"],"additionalProperties":false},{"type":"null"}]}},"required":["v","publishedAt","publishedBy","sourceId","entityKind","entityId","repoId","commit"],"additionalProperties":false},{"type":"null"}]}},"required":["found","commit","source_id","repo_id","raw_note","note"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"package:read","x-kody-read-only":true}},"/v1/repo-sessions":{"get":{"operationId":"repoListSessions","summary":"List repo editing sessions in the org this connection is bound to, defaulting to active sessions so agents can discov...","description":"List repo editing sessions in the org this connection is bound to, defaulting to active sessions so agents can discover sessions to resume, inspect, publish, or discard without already knowing session ids.\n\nOrg permission: `package:read`.","tags":["repos"],"parameters":[{"name":"status","in":"query","required":false,"description":"Which repo session lifecycle status to include. Defaults to active sessions.","schema":{"default":"active","description":"Which repo session lifecycle status to include. Defaults to active sessions.","type":"string","enum":["active","published","discarded","all"]}},{"name":"source_id","in":"query","required":false,"description":"Optional repo-backed source id to narrow the session list.","schema":{"description":"Optional repo-backed source id to narrow the session list.","type":"string","minLength":1}},{"name":"limit","in":"query","required":false,"description":"Maximum sessions to return. Capped at 100.","schema":{"default":100,"description":"Maximum sessions to return. Capped at 100.","type":"integer","minimum":1,"maximum":100}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"sessions":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"source_id":{"type":"string"},"source_root":{"type":"string"},"base_commit":{"type":"string"},"session_branch":{"type":"string"},"source_branch":{"type":"string"},"conversation_id":{"type":["string","null"]},"last_checkpoint_commit":{"type":["string","null"]},"last_check_run_id":{"type":["string","null"]},"last_check_tree_hash":{"type":["string","null"]},"expires_at":{"type":["string","null"]},"created_at":{"type":"string"},"updated_at":{"type":"string"},"published_commit":{"type":["string","null"]},"manifest_path":{"type":"string"},"entity_type":{"type":"string","enum":["package","repo"]},"status":{"type":"string","enum":["active","published","discarded"]},"resolved_target":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string","const":"source"},"source_id":{"type":"string"},"entity_kind":{"type":"string","enum":["package","repo"]},"entity_id":{"type":"string"}},"required":["kind","source_id","entity_kind","entity_id"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"package"},"source_id":{"type":"string"},"package_id":{"type":"string"},"kody_id":{"type":"string"},"name":{"type":"string"}},"required":["kind","source_id","package_id","kody_id","name"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"repo"},"source_id":{"type":"string"},"repo_id":{"type":"string"},"name":{"type":"string"}},"required":["kind","source_id","repo_id","name"],"additionalProperties":false}]}},"required":["id","source_id","source_root","base_commit","session_branch","source_branch","conversation_id","last_checkpoint_commit","last_check_run_id","last_check_tree_hash","expires_at","created_at","updated_at","published_commit","manifest_path","entity_type","status","resolved_target"],"additionalProperties":false}}},"required":["sessions"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"package:read","x-kody-read-only":true},"post":{"operationId":"repoOpenSession","summary":"Open or resume an MCP-native repo-backed editing session for a saved source artifact when editing through Kody tools ...","description":"Open or resume an MCP-native repo-backed editing session for a saved source artifact when editing through Kody tools instead of a local clone. Later repo capabilities can read, search, edit, validate, and publish against a mutable session branch. Pass conversation_id to resume that conversation's active session. Omitting conversation_id always mints a new session so concurrent callers of the same source do not share a workspace that has not checkpointed yet.\n\nOrg permission: `package:write`.","tags":["repos"],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"source_id":{"description":"Shared source id to open a session for. Prefer `target` when you know the saved package identity instead of the internal source id.","type":"string","minLength":1},"target":{"description":"User-facing repo-backed package identity. Use this instead of `source_id` when opening a saved package session.","anyOf":[{"type":"object","properties":{"kind":{"type":"string","const":"package"},"package_id":{"type":"string","minLength":1,"description":"Saved-package UUID. Use when the scoped name is not known, or for a stable ref."}},"required":["kind","package_id"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"package"},"kody_id":{"type":"string","minLength":1,"description":"Package name (`@owner/leaf` or the name leaf). Prefer this when you know the name."}},"required":["kind","kody_id"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"repo"},"repo_id":{"type":"string","minLength":1,"description":"Plain repo id to open or edit by stable identifier."}},"required":["kind","repo_id"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"repo"},"name":{"type":"string","minLength":1,"description":"Plain repo name to open or edit by user-facing identity."}},"required":["kind","name"],"additionalProperties":false}]},"conversation_id":{"description":"Optional conversation id to associate with this repo session for default resolution in later calls.","type":"string","minLength":1},"source_root":{"description":"Optional repo subdirectory to treat as the working source root.","type":"string","minLength":1},"default_branch":{"description":"Optional default branch name hint for session creation.","type":"string","minLength":1}}}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"source_id":{"type":"string"},"source_root":{"type":"string"},"base_commit":{"type":"string"},"session_branch":{"type":"string"},"source_branch":{"type":"string"},"conversation_id":{"type":["string","null"]},"last_checkpoint_commit":{"type":["string","null"]},"last_check_run_id":{"type":["string","null"]},"last_check_tree_hash":{"type":["string","null"]},"expires_at":{"type":["string","null"]},"created_at":{"type":"string"},"updated_at":{"type":"string"},"published_commit":{"type":["string","null"]},"manifest_path":{"type":"string"},"entity_type":{"type":"string","enum":["package","repo"]},"resolved_target":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string","const":"source"},"source_id":{"type":"string"},"entity_kind":{"type":"string","enum":["package","repo"]},"entity_id":{"type":"string"}},"required":["kind","source_id","entity_kind","entity_id"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"package"},"source_id":{"type":"string"},"package_id":{"type":"string"},"kody_id":{"type":"string"},"name":{"type":"string"}},"required":["kind","source_id","package_id","kody_id","name"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"repo"},"source_id":{"type":"string"},"repo_id":{"type":"string"},"name":{"type":"string"}},"required":["kind","source_id","repo_id","name"],"additionalProperties":false}]}},"required":["id","source_id","source_root","base_commit","session_branch","source_branch","conversation_id","last_checkpoint_commit","last_check_run_id","last_check_tree_hash","expires_at","created_at","updated_at","published_commit","manifest_path","entity_type","resolved_target"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"package:write","x-kody-read-only":false}},"/v1/repo-sessions/{session_id}":{"get":{"operationId":"repoGetSession","summary":"Inspect one repo editing session by id so the model can resume work without reopening it.","description":"Inspect one repo editing session by id so the model can resume work without reopening it.\n\nOrg permission: `package:read`.","tags":["repos"],"parameters":[{"name":"session_id","in":"path","required":true,"description":"Active repo session id from repoOpenSession or repoListSessions.","schema":{"type":"string","minLength":1,"description":"Active repo session id from repoOpenSession or repoListSessions."}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"source_id":{"type":"string"},"source_root":{"type":"string"},"base_commit":{"type":"string"},"session_branch":{"type":"string"},"source_branch":{"type":"string"},"conversation_id":{"type":["string","null"]},"last_checkpoint_commit":{"type":["string","null"]},"last_check_run_id":{"type":["string","null"]},"last_check_tree_hash":{"type":["string","null"]},"expires_at":{"type":["string","null"]},"created_at":{"type":"string"},"updated_at":{"type":"string"},"published_commit":{"type":["string","null"]},"manifest_path":{"type":"string"},"entity_type":{"type":"string","enum":["package","repo"]}},"required":["id","source_id","source_root","base_commit","session_branch","source_branch","conversation_id","last_checkpoint_commit","last_check_run_id","last_check_tree_hash","expires_at","created_at","updated_at","published_commit","manifest_path","entity_type"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"package:read","x-kody-read-only":true},"delete":{"operationId":"repoDiscardSession","summary":"Discard a repo editing session and delete its tracked workspace state.","description":"Discard a repo editing session and delete its tracked workspace state.\n\nOrg permission: `package:write`.","tags":["repos"],"parameters":[{"name":"session_id","in":"path","required":true,"description":"Active repo session id from repoOpenSession or repoListSessions.","schema":{"type":"string","minLength":1,"description":"Active repo session id from repoOpenSession or repoListSessions."}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"session_id":{"type":"string"},"deleted":{"type":"boolean"}},"required":["ok","session_id","deleted"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"package:write","x-kody-read-only":false}},"/v1/repo-sessions/{session_id}/status":{"get":{"operationId":"repoStatus","summary":"Return git status for the active repo session workspace.","description":"Return git status for the active repo session workspace. This is the file-level repo session API: use `repoRebaseSession` to merge from the published default branch. There is no git-command channel; branch, checkout, and remote operations are not available in sessions (use the git lane via `packageGetGitRemote` for full git).\n\nOrg permission: `package:read`.","tags":["repos"],"parameters":[{"name":"session_id","in":"path","required":true,"description":"Active repo session id from repoOpenSession or repoListSessions.","schema":{"type":"string","minLength":1,"description":"Active repo session id from repoOpenSession or repoListSessions."}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"status":{}},"required":["status"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"package:read","x-kody-read-only":true}},"/v1/repo-sessions/{session_id}/diff":{"get":{"operationId":"repoDiff","summary":"Return git diff for the active repo session workspace.","description":"Return git diff for the active repo session workspace. This is the file-level repo session API: use `repoRebaseSession` to merge from the published default branch. There is no git-command channel; branch, checkout, and remote operations are not available in sessions (use the git lane via `packageGetGitRemote` for full git).\n\nOrg permission: `package:read`.","tags":["repos"],"parameters":[{"name":"session_id","in":"path","required":true,"description":"Active repo session id from repoOpenSession or repoListSessions.","schema":{"type":"string","minLength":1,"description":"Active repo session id from repoOpenSession or repoListSessions."}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"diff":{}},"required":["diff"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"package:read","x-kody-read-only":true}},"/v1/repo-sessions/{session_id}/log":{"get":{"operationId":"repoLog","summary":"Return git commit history for the active repo session workspace.","description":"Return git commit history for the active repo session workspace. This is the file-level repo session API: use `repoRebaseSession` to merge from the published default branch. There is no git-command channel; branch, checkout, and remote operations are not available in sessions (use the git lane via `packageGetGitRemote` for full git).\n\nOrg permission: `package:read`.","tags":["repos"],"parameters":[{"name":"session_id","in":"path","required":true,"description":"Active repo session id from repoOpenSession or repoListSessions.","schema":{"type":"string","minLength":1,"description":"Active repo session id from repoOpenSession or repoListSessions."}},{"name":"depth","in":"query","required":false,"description":"Optional maximum number of commits to return.","schema":{"description":"Optional maximum number of commits to return.","type":"integer","minimum":1,"maximum":9007199254740991}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"log":{}},"required":["log"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"package:read","x-kody-read-only":true}},"/v1/repo-sessions/{session_id}/tree":{"get":{"operationId":"repoTree","summary":"Summarize a repo session subtree so the model can understand file layout before reading or editing specific files.","description":"Summarize a repo session subtree so the model can understand file layout before reading or editing specific files.\n\nOrg permission: `package:read`.","tags":["repos"],"parameters":[{"name":"session_id","in":"path","required":true,"description":"Active repo session id from repoOpenSession or repoListSessions.","schema":{"type":"string","minLength":1,"description":"Active repo session id from repoOpenSession or repoListSessions."}},{"name":"path","in":"query","required":false,"description":"Optional repo-relative subpath to summarize. Defaults to the session source root.","schema":{"description":"Optional repo-relative subpath to summarize. Defaults to the session source root.","type":"string","minLength":1}},{"name":"max_depth","in":"query","required":false,"description":"Optional maximum directory depth to include in the summary tree.","schema":{"description":"Optional maximum directory depth to include in the summary tree.","type":"integer","minimum":0,"maximum":9007199254740991}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"path":{"type":"string"},"files":{"type":"integer","minimum":0,"maximum":9007199254740991},"directories":{"type":"integer","minimum":0,"maximum":9007199254740991},"symlinks":{"type":"integer","minimum":0,"maximum":9007199254740991},"total_bytes":{"type":"integer","minimum":0,"maximum":9007199254740991},"max_depth":{"type":"integer","minimum":0,"maximum":9007199254740991}},"required":["path","files","directories","symlinks","total_bytes","max_depth"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"package:read","x-kody-read-only":true}},"/v1/repo-sessions/{session_id}/file":{"get":{"operationId":"repoReadFile","summary":"Read a file from the active repo session workspace.","description":"Read a file from the active repo session workspace. Reads the live session overlay, not just the published base commit. Append #L165, #L165-L180, or a Markdown heading slug (#export-jsdoc) to path to return that region instead of the whole file. A missing or invalid anchor fails instead of ignoring the fragment.\n\nOrg permission: `package:read`.","tags":["repos"],"parameters":[{"name":"session_id","in":"path","required":true,"description":"Active repo session id from repoOpenSession or repoListSessions.","schema":{"type":"string","minLength":1,"description":"Active repo session id from repoOpenSession or repoListSessions."}},{"name":"path","in":"query","required":true,"description":"Repo-relative file path to read. Append #L165, #L165-L180, or a Markdown heading slug (#export-jsdoc) to return that region. A missing anchor fails instead of returning the whole file.","schema":{"type":"string","minLength":1,"description":"Repo-relative file path to read. Append #L165, #L165-L180, or a Markdown heading slug (#export-jsdoc) to return that region. A missing anchor fails instead of returning the whole file."}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"path":{"type":"string"},"content":{"type":["string","null"]},"anchor":{"description":"Set when path included a # fragment. start_line/end_line are the returned window; a single #L165 line includes surrounding context.","type":"object","properties":{"kind":{"type":"string","enum":["lines","heading"]},"requested":{"type":"string"},"start_line":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"end_line":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"requested_start_line":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"requested_end_line":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"total_lines":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"heading":{"anyOf":[{"type":"object","properties":{"title":{"type":"string"},"slug":{"type":"string"},"level":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["title","slug","level"],"additionalProperties":false},{"type":"null"}]}},"required":["kind","requested","start_line","end_line","requested_start_line","requested_end_line","total_lines","heading"],"additionalProperties":false}},"required":["path","content"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"package:read","x-kody-read-only":true}},"/v1/repo-sessions/{session_id}/search":{"get":{"operationId":"repoSearch","summary":"Search within a repo session using rg-style lexical matching over the live session workspace.","description":"Search within a repo session using rg-style lexical matching over the live session workspace. This is scoped code/file search, not semantic retrieval. When mode=regex, patterns must be valid JavaScript RegExp syntax (not Python/PCRE inline flags).\n\nOrg permission: `package:read`.","tags":["repos"],"parameters":[{"name":"session_id","in":"path","required":true,"description":"Active repo session id from repoOpenSession or repoListSessions.","schema":{"type":"string","minLength":1,"description":"Active repo session id from repoOpenSession or repoListSessions."}},{"name":"pattern","in":"query","required":true,"description":"Literal text or regex to search for. In regex mode this must be valid JavaScript RegExp syntax (no Python/PCRE inline flags such as (?s) or (?i)).","schema":{"type":"string","minLength":1,"description":"Literal text or regex to search for. In regex mode this must be valid JavaScript RegExp syntax (no Python/PCRE inline flags such as (?s) or (?i))."}},{"name":"mode","in":"query","required":false,"description":"Search mode. Defaults to literal. regex uses JavaScript RegExp syntax.","schema":{"description":"Search mode. Defaults to literal. regex uses JavaScript RegExp syntax.","type":"string","enum":["literal","regex"]}},{"name":"glob","in":"query","required":false,"description":"Optional glob filter for files to search.","schema":{"description":"Optional glob filter for files to search.","type":"string","minLength":1}},{"name":"path","in":"query","required":false,"description":"Optional repo-relative subpath to scope the search to.","schema":{"description":"Optional repo-relative subpath to scope the search to.","type":"string","minLength":1}},{"name":"case_sensitive","in":"query","required":false,"description":"Whether matching should be case-sensitive.","schema":{"description":"Whether matching should be case-sensitive.","type":"boolean"}},{"name":"before","in":"query","required":false,"description":"Lines of context to include before each match.","schema":{"description":"Lines of context to include before each match.","type":"integer","minimum":0,"maximum":9007199254740991}},{"name":"after","in":"query","required":false,"description":"Lines of context to include after each match.","schema":{"description":"Lines of context to include after each match.","type":"integer","minimum":0,"maximum":9007199254740991}},{"name":"limit","in":"query","required":false,"description":"Maximum number of matches to return before truncation.","schema":{"description":"Maximum number of matches to return before truncation.","type":"integer","minimum":1,"maximum":9007199254740991}},{"name":"output_mode","in":"query","required":false,"description":"Whether to return match content or just files with matches.","schema":{"description":"Whether to return match content or just files with matches.","type":"string","enum":["content","files"]}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"files":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"matches":{"type":"array","items":{"type":"object","properties":{"line":{"type":"integer","minimum":1,"maximum":9007199254740991},"column":{"type":"integer","minimum":1,"maximum":9007199254740991},"match":{"type":"string"},"lineText":{"type":"string"},"beforeLines":{"type":"array","items":{"type":"string"}},"afterLines":{"type":"array","items":{"type":"string"}}},"required":["line","column","match","lineText","beforeLines","afterLines"],"additionalProperties":false}}},"required":["path","matches"],"additionalProperties":false}},"total_files":{"type":"integer","minimum":0,"maximum":9007199254740991},"total_matches":{"type":"integer","minimum":0,"maximum":9007199254740991},"output_mode":{"type":"string","enum":["content","files"]},"truncated":{"type":"boolean"}},"required":["files","total_files","total_matches","output_mode","truncated"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"package:read","x-kody-read-only":true}},"/v1/repo-sessions/{session_id}/edits":{"post":{"operationId":"repoEditFiles","summary":"Apply a batch of file-level edits in an active repo session: write, replace, writeJson, delete, or move.","description":"Apply a batch of file-level edits in an active repo session: write, replace, writeJson, delete, or move. Same-path write/replace/writeJson edits in one call compose in order against each prior result. Use `write` for whole-file replacements or for creating new files when a unified diff for `repoApplyPatch` would be brittle (for example, single-file job sources or generated package modules). A write replaces the file at `path` with `content` exactly, creates missing parent directories, and treats empty `content` as clearing the file. Each edit returns a per-file diff plus a `changed` flag. This is the file-level repo session API: use `repoRebaseSession` to merge from the published default branch. There is no git-command channel; branch, checkout, and remote operations are not available in sessions (use the git lane via `packageGetGitRemote` for full git). Each content-changing edit is subject to a 10 MiB per-file size limit on the planned result. Edits mutate the live session overlay only; pair with `repoCommit`, `repoRunChecks`, and `repoPublishSession` to validate and publish.\n\nOrg permission: `package:write`.","tags":["repos"],"parameters":[{"name":"session_id","in":"path","required":true,"description":"Active repo session id from repoOpenSession or repoListSessions.","schema":{"type":"string","minLength":1,"description":"Active repo session id from repoOpenSession or repoListSessions."}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"edits":{"minItems":1,"type":"array","items":{"oneOf":[{"type":"object","properties":{"kind":{"type":"string","const":"write"},"path":{"type":"string","minLength":1,"description":"Repo-relative file path to write. Existing files are overwritten; missing parent directories are created."},"content":{"type":"string","description":"Full new file content. Pass the entire file body, not a patch or diff. Empty string clears the file."}},"required":["kind","path","content"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"replace"},"path":{"type":"string","minLength":1},"search":{"type":"string"},"replacement":{"type":"string"},"options":{"type":"object","properties":{"case_sensitive":{"type":"boolean"},"regex":{"type":"boolean"},"whole_word":{"type":"boolean"},"context_before":{"type":"integer","minimum":0,"maximum":9007199254740991},"context_after":{"type":"integer","minimum":0,"maximum":9007199254740991},"max_matches":{"type":"integer","minimum":1,"maximum":9007199254740991},"spaces":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"additionalProperties":false}},"required":["kind","path","search"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"writeJson"},"path":{"type":"string","minLength":1},"value":{},"options":{"type":"object","properties":{"spaces":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"additionalProperties":false}},"required":["kind","path","value"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"delete"},"path":{"type":"string","minLength":1}},"required":["kind","path"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"move"},"path":{"type":"string","minLength":1},"to":{"type":"string","minLength":1}},"required":["kind","path","to"],"additionalProperties":false}]},"description":"Batch of file-level edits: write, replace, writeJson, delete, or move. Multiple content edits to the same path compose sequentially."},"dry_run":{"description":"Preview edits without mutating the workspace.","type":"boolean"},"rollback_on_error":{"description":"When true (default), roll back the batch if any edit fails. Set false to keep partial progress.","type":"boolean"}},"required":["edits"]}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"dry_run":{"type":"boolean"},"total_changed":{"type":"integer","minimum":0,"maximum":9007199254740991},"edits":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"changed":{"type":"boolean"},"content":{"type":"string"},"diff":{"type":"string"}},"required":["path","changed","content","diff"],"additionalProperties":false}}},"required":["dry_run","total_changed","edits"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"package:write","x-kody-read-only":false}},"/v1/repo-sessions/{session_id}/patch":{"post":{"operationId":"repoApplyPatch","summary":"Apply a unified-diff patch to the active repo session workspace.","description":"Apply a unified-diff patch to the active repo session workspace. This is the file-level repo session API: use `repoRebaseSession` to merge from the published default branch. There is no git-command channel; branch, checkout, and remote operations are not available in sessions (use the git lane via `packageGetGitRemote` for full git). Patch application is all-or-nothing across files in the patch set and subject to the 10 MiB per-file limit on patched results.\n\nOrg permission: `package:write`.","tags":["repos"],"parameters":[{"name":"session_id","in":"path","required":true,"description":"Active repo session id from repoOpenSession or repoListSessions.","schema":{"type":"string","minLength":1,"description":"Active repo session id from repoOpenSession or repoListSessions."}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"patch":{"type":"string","minLength":1,"description":"Standard unified diff to apply. Multiple file patches can be stacked in one patch string."},"dry_run":{"description":"Preview patch application without writing files.","type":"boolean"}},"required":["patch"]}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"dry_run":{"type":"boolean"},"total_changed":{"type":"integer","minimum":0,"maximum":9007199254740991},"edits":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"changed":{"type":"boolean"},"content":{"type":"string"},"diff":{"type":"string"}},"required":["path","changed","content","diff"],"additionalProperties":false}}},"required":["dry_run","total_changed","edits"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"package:write","x-kody-read-only":false}},"/v1/repo-sessions/{session_id}/restore":{"post":{"operationId":"repoRestore","summary":"Restore one or more workspace files to their content at a commit (default: the session base commit).","description":"Restore one or more workspace files to their content at a commit (default: the session base commit). This is the file-level repo session API: use `repoRebaseSession` to merge from the published default branch. There is no git-command channel; branch, checkout, and remote operations are not available in sessions (use the git lane via `packageGetGitRemote` for full git). Restoration is all-or-nothing across the requested paths.\n\nOrg permission: `package:write`.","tags":["repos"],"parameters":[{"name":"session_id","in":"path","required":true,"description":"Active repo session id from repoOpenSession or repoListSessions.","schema":{"type":"string","minLength":1,"description":"Active repo session id from repoOpenSession or repoListSessions."}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"paths":{"minItems":1,"type":"array","items":{"type":"string","minLength":1},"description":"Repo-relative workspace paths to restore."},"commit":{"description":"Commit to restore from. Defaults to the session base commit (HEAD at open).","type":"string","minLength":1}},"required":["paths"]}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"commit":{"type":"string"},"restored":{"type":"array","items":{"type":"string"}}},"required":["commit","restored"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"package:write","x-kody-read-only":false}},"/v1/repo-sessions/{session_id}/commits":{"post":{"operationId":"repoCommit","summary":"Stage all session workspace changes and create a git commit with the given message.","description":"Stage all session workspace changes and create a git commit with the given message. This is the file-level repo session API: use `repoRebaseSession` to merge from the published default branch. There is no git-command channel; branch, checkout, and remote operations are not available in sessions (use the git lane via `packageGetGitRemote` for full git). Whitespace-only commit messages are rejected.\n\nOrg permission: `package:write`.","tags":["repos"],"parameters":[{"name":"session_id","in":"path","required":true,"description":"Active repo session id from repoOpenSession or repoListSessions.","schema":{"type":"string","minLength":1,"description":"Active repo session id from repoOpenSession or repoListSessions."}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"message":{"type":"string","minLength":1,"description":"Commit message. Whitespace-only messages are rejected."}},"required":["message"]}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"oid":{"type":"string"},"message":{"type":"string"}},"required":["oid","message"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"package:write","x-kody-read-only":false}},"/v1/repo-sessions/{session_id}/checks":{"get":{"operationId":"repoGetCheckStatus","summary":"Inspect the most recent Worker-native check run metadata for an active repo session.","description":"Inspect the most recent Worker-native check run metadata for an active repo session.\n\nOrg permission: `package:read`.","tags":["repos"],"parameters":[{"name":"session_id","in":"path","required":true,"description":"Active repo session id from repoOpenSession or repoListSessions.","schema":{"type":"string","minLength":1,"description":"Active repo session id from repoOpenSession or repoListSessions."}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"run_id":{"type":["string","null"]},"tree_hash":{"type":["string","null"]},"checked_at":{"type":["string","null"]},"ok":{"type":"boolean"},"results":{"type":"array","items":{"type":"object","properties":{"kind":{"type":"string","enum":["manifest","docs","skills","dependencies","bundle","typecheck","lint","credentials","smoke"]},"ok":{"type":"boolean"},"message":{"type":"string"}},"required":["kind","ok","message"],"additionalProperties":false}}},"required":["run_id","tree_hash","checked_at","ok","results"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"package:read","x-kody-read-only":true},"post":{"operationId":"repoRunChecks","summary":"MCP/tool-only pre-publish validate for an active repo session: manifest, docs, skills, dependencies, bundle, typechec...","description":"MCP/tool-only pre-publish validate for an active repo session: manifest, docs, skills, dependencies, bundle, typecheck, lint, and credential-need checks (no local CLI required). Call after edits and before repoPublishSession. Coding agents that can run `@kodycodes/cli` may also use `kody dev` / `.kody/mocks.ts` / `execute --local` for unpublished surface tests — that is optional extra capability, not a substitute for these checks. Package publishes require non-empty root README.md (human-focused) and AGENTS.md (agent-focused).\n\nOrg permission: `package:write`.","tags":["repos"],"parameters":[{"name":"session_id","in":"path","required":true,"description":"Active repo session id from repoOpenSession or repoListSessions.","schema":{"type":"string","minLength":1,"description":"Active repo session id from repoOpenSession or repoListSessions."}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{}}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"results":{"type":"array","items":{"type":"object","properties":{"kind":{"type":"string","enum":["manifest","docs","skills","dependencies","bundle","typecheck","lint","credentials","smoke"]},"ok":{"type":"boolean"},"message":{"type":"string"}},"required":["kind","ok","message"],"additionalProperties":false}},"manifest":{"anyOf":[{"type":"object","properties":{"name":{"type":"string"},"kody_id":{"type":"string"},"description":{"type":"string"},"has_app":{"type":"boolean"}},"required":["name","kody_id","description","has_app"],"additionalProperties":false},{"type":"null"}],"description":"Parsed package.json summary when available; null when the manifest itself failed validation or was missing."}},"required":["ok","results","manifest"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"package:write","x-kody-read-only":false}},"/v1/repo-sessions/{session_id}/rebase":{"post":{"operationId":"repoRebaseSession","summary":"Rebase a repo session against the latest published source state when the base commit has moved.","description":"Rebase a repo session against the latest published source state when the base commit has moved.\n\nOrg permission: `package:write`.","tags":["repos"],"parameters":[{"name":"session_id","in":"path","required":true,"description":"Active repo session id from repoOpenSession or repoListSessions.","schema":{"type":"string","minLength":1,"description":"Active repo session id from repoOpenSession or repoListSessions."}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{}}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"session_id":{"type":"string"},"base_commit":{"type":"string"},"head_commit":{"type":["string","null"]},"merged":{"type":"boolean"}},"required":["ok","session_id","base_commit","head_commit","merged"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"package:write","x-kody-read-only":false}},"/v1/repo-sessions/{session_id}/publish":{"post":{"operationId":"repoPublishSession","summary":"Publish an active repo session back to the source repo after checks pass on the current tree and the base commit is s...","description":"Publish an active repo session back to the source repo after checks pass on the current tree and the base commit is still current. Visibility is a repo setting (`packageUpdate` / `repoUpdate`), not package.json#private. When publishing a community fork after absorbing origin updates, pass absorbed_upstream_commit.\n\nOrg permission: `package:write`.","tags":["repos"],"parameters":[{"name":"session_id","in":"path","required":true,"description":"Active repo session id from repoOpenSession or repoListSessions.","schema":{"type":"string","minLength":1,"description":"Active repo session id from repoOpenSession or repoListSessions."}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"confirm_private_visibility_change":{"default":false,"description":"Unused. Visibility is a repo setting via packageUpdate, not package.json#private.","type":"boolean"},"absorbed_upstream_commit":{"description":"When publishing a community fork after porting (or skipping) origin updates, pass origin HEAD so the behind-upstream banner clears. Does not copy files.","type":"string","minLength":1}}}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"oneOf":[{"type":"object","properties":{"status":{"type":"string","const":"ok"},"session_id":{"type":"string"},"published_commit":{"type":"string"},"message":{"type":"string"},"package_shaped":{"type":"boolean"},"notice":{"type":["string","null"]}},"required":["status","session_id","published_commit","message"],"additionalProperties":false},{"type":"object","properties":{"status":{"type":"string","const":"checks_outdated"},"session_id":{"type":"string"},"published_commit":{"type":"null"},"message":{"type":"string"}},"required":["status","session_id","published_commit","message"],"additionalProperties":false},{"type":"object","properties":{"status":{"type":"string","const":"base_moved"},"session_id":{"type":"string"},"published_commit":{"type":"null"},"message":{"type":"string"},"repair_hint":{"type":"string","const":"repoRebaseSession"},"session_base_commit":{"type":"string"},"current_published_commit":{"type":["string","null"]}},"required":["status","session_id","published_commit","message","repair_hint","session_base_commit","current_published_commit"],"additionalProperties":false},{"type":"object","properties":{"status":{"type":"string","const":"locked"},"session_id":{"type":"string"},"published_commit":{"type":"null"},"pending_commit":{"type":"string"},"current_published_commit":{"type":["string","null"]},"approval_url":{"type":"string"},"message":{"type":"string"}},"required":["status","session_id","published_commit","pending_commit","current_published_commit","approval_url","message"],"additionalProperties":false},{"type":"object","properties":{"status":{"type":"string","const":"approval_required"},"session_id":{"type":"string"},"published_commit":{"type":"null"},"pending_commit":{"type":"string"},"current_published_commit":{"type":["string","null"]},"approval_url":{"type":"string"},"approval_bundle_url":{"description":"Present when other paused publishes also wait on the owner: one page that approves them together.","type":"string"},"credential_need_changes":{"type":"array","items":{"oneOf":[{"type":"object","properties":{"key":{"type":"string"},"change":{"type":"string","const":"added"},"after":{"type":"object","properties":{"kind":{"description":"Omitted when the need accepts any fetch-capable credential for the provider.","type":"string","enum":["secret","oauth","mcp","url","login","signing"]},"provider":{"type":"string"},"multiple":{"type":"boolean"}},"required":["provider","multiple"],"additionalProperties":false},"from":{"description":"The dependency that declared an inherited need.","type":"string"}},"required":["key","change","after"],"additionalProperties":false},{"type":"object","properties":{"key":{"type":"string"},"change":{"type":"string","const":"changed"},"before":{"type":"object","properties":{"kind":{"description":"Omitted when the need accepts any fetch-capable credential for the provider.","type":"string","enum":["secret","oauth","mcp","url","login","signing"]},"provider":{"type":"string"},"multiple":{"type":"boolean"}},"required":["provider","multiple"],"additionalProperties":false},"after":{"type":"object","properties":{"kind":{"description":"Omitted when the need accepts any fetch-capable credential for the provider.","type":"string","enum":["secret","oauth","mcp","url","login","signing"]},"provider":{"type":"string"},"multiple":{"type":"boolean"}},"required":["provider","multiple"],"additionalProperties":false},"from":{"description":"The dependency that declared an inherited need.","type":"string"}},"required":["key","change","before","after"],"additionalProperties":false}]}},"message":{"type":"string"}},"required":["status","session_id","published_commit","pending_commit","current_published_commit","approval_url","credential_need_changes","message"],"additionalProperties":false}]}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"package:write","x-kody-read-only":false}},"/v1/jobs":{"get":{"operationId":"jobList","summary":"List existing scheduled jobs for the signed-in user with status, counters, and job-manager alarm state for debugging ...","description":"List existing scheduled jobs for the signed-in user with status, counters, and job-manager alarm state for debugging scheduling issues. Recurring schedules belong on a package (`kody.jobs`); deferred one-shots use `workflows.create`. recent_runs is empty here for efficiency; use jobGet for one job's recent runs or runList/runSummary for cross-job failure history.\n\nOrg permission: `job:read`.","tags":["jobs"],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"jobs":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"source_id":{"type":"string"},"published_commit":{"type":["string","null"]},"storage_id":{"type":"string"},"params":{"anyOf":[{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},{"type":"null"}]},"schedule":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","const":"once"},"run_at":{"type":"string","minLength":1,"description":"UTC timestamp for the one-off run, for example 2026-04-20T18:30:00Z."}},"required":["type","run_at"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"interval"},"every":{"type":"string","minLength":1,"description":"Recurring interval such as 15m, 1h, or 1d using ms, s, m, h, or d units."}},"required":["type","every"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"cron"},"expression":{"type":"string","minLength":1,"description":"Standard 5-field cron expression: minute hour day-of-month month day-of-week."}},"required":["type","expression"],"additionalProperties":false}]},"schedule_summary":{"type":"string"},"timezone":{"type":"string"},"enabled":{"type":"boolean"},"kill_switch_enabled":{"type":"boolean"},"expires_at":{"description":"UTC ISO expiry timestamp, or null when the job never expires.","type":["string","null"]},"expired":{"type":"boolean","description":"True when expires_at is set and now is at or past that timestamp."},"created_at":{"type":"string"},"updated_at":{"type":"string"},"next_run_at":{"type":"string"},"due_now":{"type":"boolean"},"last_run_at":{"type":["string","null"]},"last_run_status":{"anyOf":[{"type":"string","enum":["success","error"]},{"type":"null"}]},"last_run_error":{"type":["string","null"]},"last_duration_ms":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]},"run_count":{"type":"integer","minimum":0,"maximum":9007199254740991},"success_count":{"type":"integer","minimum":0,"maximum":9007199254740991},"error_count":{"type":"integer","minimum":0,"maximum":9007199254740991},"recent_runs":{"type":"array","items":{"type":"object","properties":{"id":{"description":"Run record id for drill-down with runGet when available.","type":"string"},"started_at":{"type":"string"},"finished_at":{"type":"string"},"status":{"type":"string","enum":["success","error"]},"duration_ms":{"type":"integer","minimum":0,"maximum":9007199254740991},"error":{"type":["string","null"]}},"required":["started_at","finished_at","status","duration_ms","error"],"additionalProperties":false}},"enablement_hint":{"description":"When the job is enabled but has no on enablement (or only paused ones), an agent-directed message that includes the exact enablementEnable call. Null when the job is off or already has an on enablement.","type":["string","null"]}},"required":["id","name","source_id","published_commit","storage_id","params","schedule","schedule_summary","timezone","enabled","kill_switch_enabled","expires_at","expired","created_at","updated_at","next_run_at","due_now","last_run_at","last_run_status","last_run_error","last_duration_ms","run_count","success_count","error_count","recent_runs","enablement_hint"],"additionalProperties":false}},"alarm":{"type":"object","properties":{"binding_available":{"type":"boolean"},"status":{"type":"string","enum":["missing_binding","idle","armed","out_of_sync"]},"stored_user_id":{"type":["string","null"]},"alarm_scheduled_for":{"type":["string","null"]},"next_runnable_job_id":{"type":["string","null"]},"next_runnable_run_at":{"type":["string","null"]},"alarm_in_sync":{"type":["boolean","null"]}},"required":["binding_available","status","stored_user_id","alarm_scheduled_for","next_runnable_job_id","next_runnable_run_at","alarm_in_sync"],"additionalProperties":false}},"required":["jobs","alarm"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"job:read","x-kody-read-only":true}},"/v1/jobs/{id}":{"get":{"operationId":"jobGet","summary":"Load one existing scheduled job for the signed-in user, including debugging fields such as run counters, last error, ...","description":"Load one existing scheduled job for the signed-in user, including debugging fields such as run counters, last error, recent run history from run records (with run ids for runGet log drill-down), current alarm state, and optionally the published source code. Recurring schedules belong on a package (`kody.jobs`); deferred one-shots use `workflows.create`.\n\nOrg permission: `job:read`.","tags":["jobs"],"parameters":[{"name":"id","in":"path","required":true,"description":"Job id from jobList or jobGet output.","schema":{"description":"Job id from jobList or jobGet output.","type":"string","minLength":1}},{"name":"job_id","in":"query","required":false,"description":"Alias for id, accepted for callers copying job_id outputs.","schema":{"description":"Alias for id, accepted for callers copying job_id outputs.","type":"string","minLength":1}},{"name":"includeCode","in":"query","required":false,"description":"When true, include the published job source entrypoint path and code in the response.","schema":{"description":"When true, include the published job source entrypoint path and code in the response.","type":"boolean"}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"job":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"source_id":{"type":"string"},"published_commit":{"type":["string","null"]},"storage_id":{"type":"string"},"params":{"anyOf":[{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},{"type":"null"}]},"schedule":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","const":"once"},"run_at":{"type":"string","minLength":1,"description":"UTC timestamp for the one-off run, for example 2026-04-20T18:30:00Z."}},"required":["type","run_at"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"interval"},"every":{"type":"string","minLength":1,"description":"Recurring interval such as 15m, 1h, or 1d using ms, s, m, h, or d units."}},"required":["type","every"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"cron"},"expression":{"type":"string","minLength":1,"description":"Standard 5-field cron expression: minute hour day-of-month month day-of-week."}},"required":["type","expression"],"additionalProperties":false}]},"schedule_summary":{"type":"string"},"timezone":{"type":"string"},"enabled":{"type":"boolean"},"kill_switch_enabled":{"type":"boolean"},"expires_at":{"description":"UTC ISO expiry timestamp, or null when the job never expires.","type":["string","null"]},"expired":{"type":"boolean","description":"True when expires_at is set and now is at or past that timestamp."},"created_at":{"type":"string"},"updated_at":{"type":"string"},"next_run_at":{"type":"string"},"due_now":{"type":"boolean"},"last_run_at":{"type":["string","null"]},"last_run_status":{"anyOf":[{"type":"string","enum":["success","error"]},{"type":"null"}]},"last_run_error":{"type":["string","null"]},"last_duration_ms":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]},"run_count":{"type":"integer","minimum":0,"maximum":9007199254740991},"success_count":{"type":"integer","minimum":0,"maximum":9007199254740991},"error_count":{"type":"integer","minimum":0,"maximum":9007199254740991},"recent_runs":{"type":"array","items":{"type":"object","properties":{"id":{"description":"Run record id for drill-down with runGet when available.","type":"string"},"started_at":{"type":"string"},"finished_at":{"type":"string"},"status":{"type":"string","enum":["success","error"]},"duration_ms":{"type":"integer","minimum":0,"maximum":9007199254740991},"error":{"type":["string","null"]}},"required":["started_at","finished_at","status","duration_ms","error"],"additionalProperties":false}},"enablement_hint":{"description":"When the job is enabled but has no on enablement (or only paused ones), an agent-directed message that includes the exact enablementEnable call. Null when the job is off or already has an on enablement.","type":["string","null"]}},"required":["id","name","source_id","published_commit","storage_id","params","schedule","schedule_summary","timezone","enabled","kill_switch_enabled","expires_at","expired","created_at","updated_at","next_run_at","due_now","last_run_at","last_run_status","last_run_error","last_duration_ms","run_count","success_count","error_count","recent_runs","enablement_hint"],"additionalProperties":false},"alarm":{"type":"object","properties":{"binding_available":{"type":"boolean"},"status":{"type":"string","enum":["missing_binding","idle","armed","out_of_sync"]},"stored_user_id":{"type":["string","null"]},"alarm_scheduled_for":{"type":["string","null"]},"next_runnable_job_id":{"type":["string","null"]},"next_runnable_run_at":{"type":["string","null"]},"alarm_in_sync":{"type":["boolean","null"]}},"required":["binding_available","status","stored_user_id","alarm_scheduled_for","next_runnable_job_id","next_runnable_run_at","alarm_in_sync"],"additionalProperties":false},"source":{"description":"Published job source details when includeCode is true.","type":"object","properties":{"entrypoint":{"description":"Normalized manifest-declared job entrypoint path, when resolved.","type":["string","null"]},"code":{"description":"Stored source code for the entrypoint, or null when unavailable.","type":["string","null"]},"error":{"description":"Source resolution error, or null when code was loaded.","type":["string","null"]}},"required":["entrypoint","code","error"],"additionalProperties":false}},"required":["job","alarm"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"job:read","x-kody-read-only":true},"patch":{"operationId":"jobUpdate","summary":"Update metadata on an existing scheduled job: enabled, kill switch, expires_at, params, schedule, and timezone.","description":"Update metadata on an existing scheduled job: enabled, kill switch, expires_at, params, schedule, and timezone. Package-owned jobs keep source in the package repo, so name, code, and published source cannot change here — edit the package and publish. Recurring schedules belong on a package (`kody.jobs`); deferred one-shots use `workflows.create`.\n\nOrg permission: `job:write`.","tags":["jobs"],"parameters":[{"name":"id","in":"path","required":true,"description":"Existing job id from jobList or jobGet output.","schema":{"type":"string","minLength":1,"description":"Existing job id from jobList or jobGet output."}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"name":{"description":"Rejected. A job is named by its key in package.json#kody.jobs; rename it there and publish."},"params":{"description":"Optional replacement params object passed as the first argument to the job entrypoint. Pass null to clear existing params.","anyOf":[{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},{"type":"null"}]},"schedule":{"description":"Optional replacement schedule for the job.","oneOf":[{"type":"object","properties":{"type":{"type":"string","const":"once"},"run_at":{"type":"string","minLength":1,"description":"UTC timestamp for the one-off run, for example 2026-04-20T18:30:00Z."}},"required":["type","run_at"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"interval"},"every":{"type":"string","minLength":1,"description":"Recurring interval such as 15m, 1h, or 1d using ms, s, m, h, or d units."}},"required":["type","every"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"cron"},"expression":{"type":"string","minLength":1,"description":"Standard 5-field cron expression: minute hour day-of-month month day-of-week."}},"required":["type","expression"],"additionalProperties":false}]},"timezone":{"description":"Optional timezone label for cron display and schedule calculation. Pass null to reset to UTC.","anyOf":[{"type":"string","minLength":1},{"type":"null"}]},"enabled":{"description":"Enable or disable the job without deleting it.","type":"boolean"},"kill_switch_enabled":{"description":"Force the job off regardless of schedule. This remains visible in jobList and jobGet for debugging.","type":"boolean"},"expires_at":{"description":"Optional UTC ISO timestamp after which the platform stops scheduling this job and auto-disables it (enabled=false). Pass null to clear.","anyOf":[{"type":"string","minLength":1},{"type":"null"}]},"code":{"description":"Rejected. Job source cannot be changed via jobUpdate. Edit a package job in the package repo and publish."}}}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"job_id":{"type":"string"},"name":{"type":"string"},"source_id":{"type":"string"},"published_commit":{"type":["string","null"]},"storage_id":{"type":"string"},"params":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"schedule":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","const":"once"},"run_at":{"type":"string","minLength":1,"description":"UTC timestamp for the one-off run, for example 2026-04-20T18:30:00Z."}},"required":["type","run_at"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"interval"},"every":{"type":"string","minLength":1,"description":"Recurring interval such as 15m, 1h, or 1d using ms, s, m, h, or d units."}},"required":["type","every"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"cron"},"expression":{"type":"string","minLength":1,"description":"Standard 5-field cron expression: minute hour day-of-month month day-of-week."}},"required":["type","expression"],"additionalProperties":false}]},"schedule_summary":{"type":"string"},"timezone":{"type":"string"},"enabled":{"type":"boolean"},"kill_switch_enabled":{"type":"boolean"},"expires_at":{"type":["string","null"]},"expired":{"type":"boolean"},"created_at":{"type":"string"},"updated_at":{"type":"string"},"last_run_at":{"type":"string"},"last_run_status":{"type":"string","enum":["success","error"]},"last_run_error":{"type":"string"},"last_duration_ms":{"type":"integer","minimum":0,"maximum":9007199254740991},"next_run_at":{"type":"string"},"run_count":{"type":"integer","minimum":0,"maximum":9007199254740991},"success_count":{"type":"integer","minimum":0,"maximum":9007199254740991},"error_count":{"type":"integer","minimum":0,"maximum":9007199254740991},"run_history":{"type":"array","items":{"type":"object","properties":{"id":{"description":"Run record id for drill-down with runGet when available.","type":"string"},"started_at":{"type":"string"},"finished_at":{"type":"string"},"status":{"type":"string","enum":["success","error"]},"duration_ms":{"type":"integer","minimum":0,"maximum":9007199254740991},"error":{"type":"string"}},"required":["started_at","finished_at","status","duration_ms"],"additionalProperties":false}},"enablement_hint":{"description":"When the job is enabled but has no on enablement (or only paused ones), an agent-directed message that includes the exact enablementEnable call. Null when the job is off or already has an on enablement.","type":["string","null"]}},"required":["job_id","name","source_id","published_commit","storage_id","schedule","schedule_summary","timezone","enabled","kill_switch_enabled","expires_at","expired","created_at","updated_at","next_run_at","run_count","success_count","error_count","run_history","enablement_hint"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"job:write","x-kody-read-only":false}},"/v1/jobs/{id}/run":{"post":{"operationId":"jobRunNow","summary":"Run an existing scheduled job immediately by id using the normal job runtime, then return the updated job state and e...","description":"Run an existing scheduled job immediately by id using the normal job runtime, then return the updated job state and execution result for debugging. Recurring schedules belong on a package (`kody.jobs`); deferred one-shots use `workflows.create`.\n\nOrg permission: `job:execute`.","tags":["jobs"],"parameters":[{"name":"id","in":"path","required":true,"description":"Existing job id to execute immediately.","schema":{"type":"string","minLength":1,"description":"Existing job id to execute immediately."}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{}}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"job":{"type":"object","properties":{"job_id":{"type":"string"},"name":{"type":"string"},"source_id":{"type":"string"},"published_commit":{"type":["string","null"]},"storage_id":{"type":"string"},"params":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"schedule":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","const":"once"},"run_at":{"type":"string","minLength":1,"description":"UTC timestamp for the one-off run, for example 2026-04-20T18:30:00Z."}},"required":["type","run_at"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"interval"},"every":{"type":"string","minLength":1,"description":"Recurring interval such as 15m, 1h, or 1d using ms, s, m, h, or d units."}},"required":["type","every"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"cron"},"expression":{"type":"string","minLength":1,"description":"Standard 5-field cron expression: minute hour day-of-month month day-of-week."}},"required":["type","expression"],"additionalProperties":false}]},"schedule_summary":{"type":"string"},"timezone":{"type":"string"},"enabled":{"type":"boolean"},"kill_switch_enabled":{"type":"boolean"},"expires_at":{"type":["string","null"]},"expired":{"type":"boolean"},"created_at":{"type":"string"},"updated_at":{"type":"string"},"last_run_at":{"type":"string"},"last_run_status":{"type":"string","enum":["success","error"]},"last_run_error":{"type":"string"},"last_duration_ms":{"type":"integer","minimum":0,"maximum":9007199254740991},"next_run_at":{"type":"string"},"run_count":{"type":"integer","minimum":0,"maximum":9007199254740991},"success_count":{"type":"integer","minimum":0,"maximum":9007199254740991},"error_count":{"type":"integer","minimum":0,"maximum":9007199254740991},"run_history":{"type":"array","items":{"type":"object","properties":{"id":{"description":"Run record id for drill-down with runGet when available.","type":"string"},"started_at":{"type":"string"},"finished_at":{"type":"string"},"status":{"type":"string","enum":["success","error"]},"duration_ms":{"type":"integer","minimum":0,"maximum":9007199254740991},"error":{"type":"string"}},"required":["started_at","finished_at","status","duration_ms"],"additionalProperties":false}},"enablement_hint":{"description":"When the job is enabled but has no on enablement (or only paused ones), an agent-directed message that includes the exact enablementEnable call. Null when the job is off or already has an on enablement.","type":["string","null"]}},"required":["job_id","name","source_id","published_commit","storage_id","schedule","schedule_summary","timezone","enabled","kill_switch_enabled","expires_at","expired","created_at","updated_at","next_run_at","run_count","success_count","error_count","run_history","enablement_hint"],"additionalProperties":false},"execution":{"oneOf":[{"type":"object","properties":{"ok":{"type":"boolean","const":true},"result":{},"logs":{"type":"array","items":{"type":"string"}}},"required":["ok","logs"],"additionalProperties":false},{"type":"object","properties":{"ok":{"type":"boolean","const":false},"error":{"type":"string"},"logs":{"type":"array","items":{"type":"string"}}},"required":["ok","error","logs"],"additionalProperties":false}]},"deleted_after_run":{"type":"boolean","description":"Whether the job was deleted after this run. One-off jobs stay on their package instead of being deleted after running."}},"required":["job","execution","deleted_after_run"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"job:execute","x-kody-read-only":false}},"/v1/workflow-runs":{"get":{"operationId":"workflowRunList","summary":"List recent Cloudflare Workflow runs created through kody:runtime workflows.create for durable work that may outlive ...","description":"List recent Cloudflare Workflow runs created through kody:runtime workflows.create for durable work that may outlive execute timeouts, including source, status, and completion/error metadata.\n\nOrg permission: `job:read`.","tags":["jobs"],"parameters":[{"name":"limit","in":"query","required":false,"description":"Maximum number of recent workflow runs to return. Defaults to 25.","schema":{"description":"Maximum number of recent workflow runs to return. Defaults to 25.","type":"integer","minimum":1,"maximum":100}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"workflows":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"source_type":{"type":"string","enum":["package","inline"]},"package_id":{"type":["string","null"]},"kody_id":{"type":["string","null"]},"source_id":{"type":["string","null"]},"workflow_name":{"type":"string"},"export_name":{"type":["string","null"]},"idempotency_key":{"type":"string"},"run_at":{"type":"string"},"plan_date":{"type":["string","null"]},"status":{"anyOf":[{"type":"string","enum":["queued","running","paused","waiting","waitingForPause","unknown","complete","errored","terminated","cancelled"]},{"type":"null"}]},"created_at":{"type":"string"},"updated_at":{"type":"string"},"completed_at":{"type":["string","null"]},"last_error":{"type":["string","null"]}},"required":["id","source_type","package_id","kody_id","source_id","workflow_name","export_name","idempotency_key","run_at","plan_date","status","created_at","updated_at","completed_at","last_error"],"additionalProperties":false}}},"required":["workflows"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"job:read","x-kody-read-only":true}},"/v1/workflow-runs/{id}/cancel":{"post":{"operationId":"workflowRunCancel","summary":"Cancel a Cloudflare Workflow run created through kody:runtime workflows.create by id.","description":"Cancel a Cloudflare Workflow run created through kody:runtime workflows.create by id. Terminates the underlying workflow instance and marks the run cancelled; cancelling an already-finished run is a safe no-op.\n\nOrg permission: `job:execute`.","tags":["jobs"],"parameters":[{"name":"id","in":"path","required":true,"description":"Workflow run id from workflowRunList or workflows.create output (dynwf-… inline runs or pkgwf-… package runs).","schema":{"type":"string","minLength":1,"description":"Workflow run id from workflowRunList or workflows.create output (dynwf-… inline runs or pkgwf-… package runs)."}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{}}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"cancelled":{"type":"boolean"},"already_terminal":{"type":"boolean"},"status":{"anyOf":[{"type":"string","enum":["queued","running","paused","waiting","waitingForPause","unknown","complete","errored","terminated","cancelled"]},{"type":"null"}]},"message":{"type":"string"}},"required":["id","cancelled","already_terminal","status","message"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"job:execute","x-kody-read-only":false}},"/v1/webhooks":{"get":{"operationId":"webhookList","summary":"List package.json#kody.webhooks declarations across the signed-in user's saved packages, joined with minted handle / ...","description":"List package.json#kody.webhooks declarations across the signed-in user's saved packages, joined with minted handle / enabled state. Declaring a webhook does not open ingress until webhookUrlMint is called. URL secrets and credential URLs are never returned.\n\nOrg permission: `package:read`.","tags":["webhooks"],"parameters":[{"name":"packageId","in":"query","required":false,"schema":{"type":"string","minLength":1}},{"name":"kodyId","in":"query","required":false,"schema":{"type":"string","minLength":1}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"webhooks":{"type":"array","items":{"type":"object","properties":{"package_id":{"type":"string"},"package_kody_id":{"type":"string"},"package_name":{"type":"string"},"name":{"type":"string"},"export_name":{"type":"string"},"description":{"type":["string","null"]},"response_mode":{"type":"string","enum":["ack","sync"]},"input_mode":{"type":"string","enum":["request","params"]},"rate_limit_per_minute":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"verification":{"anyOf":[{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["hmac-sha256","hmac-sha1"]},"header":{"type":"string"},"secretName":{"type":"string"},"encoding":{"type":"string","enum":["hex","base64"]},"prefix":{"type":"string"},"signedPayload":{"type":"string","enum":["body","timestamp.body"]}},"required":["type","header","encoding"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"url-secret"}},"required":["type"],"additionalProperties":false}]},{"type":"null"}]},"replay":{"anyOf":[{"type":"object","properties":{"timestampHeader":{"type":"string"},"timestampFormat":{"type":"string","enum":["unix-seconds","unix-millis","iso-8601","stripe-signature"]},"toleranceSeconds":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"deliveryIdHeader":{"type":"string"}},"additionalProperties":false},{"type":"null"}]},"challenge":{"anyOf":[{"type":"object","properties":{"type":{"type":"string","const":"subscription-challenge"},"method":{"type":"string","enum":["GET","POST"]},"challenge":{"type":"object","properties":{"in":{"type":"string","enum":["query","json"]},"key":{"type":"string","minLength":1,"maxLength":128,"pattern":"^(?!__proto__$|prototype$|constructor$)[A-Za-z0-9][A-Za-z0-9._-]*$"}},"required":["in","key"],"additionalProperties":false},"when":{"type":"object","properties":{"query":{"type":"object","propertyNames":{"type":"string","minLength":1},"additionalProperties":{"anyOf":[{"type":"string","minLength":1},{"minItems":1,"type":"array","items":{"type":"string","minLength":1}}]}},"json":{"type":"object","propertyNames":{"type":"string","minLength":1},"additionalProperties":{"type":"string","minLength":1}}},"additionalProperties":false},"prove":{"oneOf":[{"type":"object","properties":{"kind":{"type":"string","const":"none"}},"required":["kind"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"verify-token"},"in":{"type":"string","const":"query"},"key":{"type":"string","minLength":1,"maxLength":128,"pattern":"^(?!__proto__$|prototype$|constructor$)[A-Za-z0-9][A-Za-z0-9._-]*$"},"secretName":{"type":"string","minLength":1},"required":{"type":"boolean"}},"required":["kind","in","key","secretName"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"hmac"},"secretName":{"type":"string","minLength":1},"algorithm":{"type":"string","enum":["hmac-sha256"]},"encoding":{"type":"string","enum":["hex","base64"]},"prefix":{"type":"string"}},"required":["kind","secretName","algorithm","encoding"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"request-hmac"},"secretName":{"type":"string","minLength":1},"algorithm":{"type":"string","enum":["hmac-sha256"]},"encoding":{"type":"string","enum":["hex","base64"]},"prefix":{"type":"string"},"timestampHeader":{"type":"string","pattern":"^[!#$%&'*+\\-.^_`|~0-9A-Za-z]+$"},"signatureHeader":{"type":"string","pattern":"^[!#$%&'*+\\-.^_`|~0-9A-Za-z]+$"},"signedPayload":{"type":"string","const":"v0.timestamp.body"}},"required":["kind","secretName","algorithm","encoding","timestampHeader","signatureHeader","signedPayload"],"additionalProperties":false}]},"respond":{"oneOf":[{"type":"object","properties":{"as":{"type":"string","const":"text"}},"required":["as"],"additionalProperties":false},{"type":"object","properties":{"as":{"type":"string","const":"json"},"key":{"type":"string","minLength":1,"maxLength":128,"pattern":"^(?!__proto__$|prototype$|constructor$)[A-Za-z0-9][A-Za-z0-9._-]*$"}},"required":["as","key"],"additionalProperties":false},{"type":"object","properties":{"as":{"type":"string","const":"json-hmac"},"key":{"type":"string","minLength":1,"maxLength":128,"pattern":"^(?!__proto__$|prototype$|constructor$)[A-Za-z0-9][A-Za-z0-9._-]*$"}},"required":["as","key"],"additionalProperties":false}]}},"required":["type","method","challenge","respond"],"additionalProperties":false},{"type":"null"}],"description":"Platform-answered subscription challenge from package.json#kody.webhooks[].challenge (secretName is a secret-store name, never a value). Null when not declared."},"minted":{"type":"boolean","description":"True when a URL secret has been minted for this webhook."},"endpoint_id":{"description":"Webhook endpoint id when minted. Pass to rotate/enable/disable when several URLs share the name. Null when not minted.","type":["string","null"]},"instance_label":{"description":"Short label when several URLs share the declared webhook name. Null when unlabeled or not minted.","type":["string","null"]},"handle":{"description":"Opaque handle for webhookUrlApply. Null when not minted. Never a credential.","type":["string","null"]},"url_host":{"description":"Public hostname of the ingress origin. Null when not minted.","type":["string","null"]},"enabled":{"description":"Null when not minted; otherwise the mint enabled flag.","type":["boolean","null"]},"created_at":{"type":["string","null"]},"rotated_at":{"type":["string","null"]},"previous_url_active_until":{"description":"ISO timestamp while the previous URL still accepts deliveries after rotate. Null when there is no live overlap.","type":["string","null"]}},"required":["package_id","package_kody_id","package_name","name","export_name","description","response_mode","input_mode","rate_limit_per_minute","verification","replay","challenge","minted","endpoint_id","instance_label","handle","url_host","enabled","created_at","rotated_at","previous_url_active_until"],"additionalProperties":false}}},"required":["webhooks"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"package:read","x-kody-read-only":true}},"/v1/webhooks/apply":{"post":{"operationId":"webhookUrlApply","summary":"Register a minted webhook URL at an HTTPS destination without exposing the credential.","description":"Register a minted webhook URL at an HTTPS destination without exposing the credential. Pass the handle from webhookUrlMint, webhookUrlRotate, or webhookList. Destination type http performs an outbound HTTPS request and substitutes {{webhookUrl}} (and optional {{webhookSecret}} — package-owned HMAC from the webhook URL record, or a verification.secretName copied onto that record at mint or rotate) server-side into url/headers/body — interactive MCP only, and only after the owner Approves the exact destination via the same account approval flow as /connect/secrets host approval (approval_url → website Allow → durable grant → retry). Package-owned HMAC is not a user secrets-list entry and never needs a secret→host Allow; destination.secretName Bearer auth does. For GitHub repository hooks, POST https://api.github.com/repos/{owner}/{repo}/hooks with User-Agent kody, {{webhookUrl}} in config.url, {{webhookSecret}} in config.secret when HMAC is declared (omit verification.secretName so mint stores package-owned HMAC), and integration \"github\" (or a host-approved token). Returns ok, remote_id, and url_host only — never the credential URL or signing secret.\n\nOrg permission: `package:write`.","tags":["webhooks"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"handle":{"type":"string","minLength":1,"description":"Opaque handle from webhookUrlMint, webhookUrlRotate, or webhookList."},"destination":{"type":"object","properties":{"type":{"type":"string","const":"http"},"url":{"type":"string","minLength":1,"description":"HTTPS registration endpoint. May include {{webhookUrl}} and {{webhookSecret}} for server-side injection."},"method":{"description":"HTTP method. Defaults to POST.","type":"string","enum":["GET","POST","PUT","PATCH","DELETE"]},"headers":{"description":"Optional request headers. Values may include {{webhookUrl}} and {{webhookSecret}}.","type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}},"body":{"description":"Optional request body template. May include {{webhookUrl}} and {{webhookSecret}}.","type":"string","maxLength":64384},"integration":{"description":"Optional OAuth integration whose access token is sent as Authorization Bearer. Host must be allowed on the integration.","type":"string","minLength":1},"secretName":{"description":"Optional host-approved secret sent as Authorization Bearer. Host must be approved for the destination URL.","type":"string","minLength":1}},"required":["type","url"],"additionalProperties":false}},"required":["handle","destination"]}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"url_host":{"type":"string"},"http_status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"remote_id":{"type":["string","null"]},"error":{"type":["string","null"]}},"required":["ok","url_host","http_status","remote_id","error"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"package:write","x-kody-read-only":false}},"/v1/webhooks/{webhookName}/url":{"post":{"operationId":"webhookUrlMint","summary":"Mint (or remint) the URL secret for a package-declared webhook and return an opaque handle plus url_host.","description":"Mint (or remint) the URL secret for a package-declared webhook and return an opaque handle plus url_host. Pass createInstance+instanceLabel to mint another URL under the same declared name (each URL needs its own Approve). The credential URL is never returned — register it with webhookUrlApply. Minting does not turn the webhook on: deliveries fail with enablement_not_on until a person opens approval_url and clicks Approve, which runs it as them (and is where its credentials are mapped). Existing approvals are kept across remint and rotate.\n\nOrg permission: `package:write`.","tags":["webhooks"],"parameters":[{"name":"webhookName","in":"path","required":true,"description":"Webhook name from package.json#kody.webhooks[].name.","schema":{"type":"string","minLength":1,"description":"Webhook name from package.json#kody.webhooks[].name."}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"packageId":{"description":"Saved-package UUID. Use when the scoped name is not known, or for a stable ref.","type":"string","minLength":1},"kodyId":{"description":"Package name (`@owner/leaf` or the name leaf). Prefer this when you know the name.","type":"string","minLength":1},"createInstance":{"description":"When true, mint another URL under the same declared name. Requires instanceLabel.","type":"boolean"},"instanceLabel":{"description":"Short label to tell this URL apart from others under the same name.","type":"string","minLength":1,"maxLength":64}}}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"webhook":{"type":"object","properties":{"package_id":{"type":"string"},"package_kody_id":{"type":"string"},"name":{"type":"string"},"endpoint_id":{"type":"string","description":"Webhook endpoint id. The URL identity for this mint."},"instance_label":{"description":"Short label when several URLs share the declared webhook name. Null on the first mint without a label.","type":["string","null"]},"handle":{"type":"string","description":"Opaque handle for webhookUrlApply. Does not contain the URL secret."},"url_host":{"type":"string","description":"Public hostname of the ingress origin (no path or secret)."},"enabled":{"type":"boolean"},"created_at":{"type":"string"},"rotated_at":{"type":"string"},"previous_url_active_until":{"description":"ISO timestamp while the previous URL still accepts deliveries after rotate. Null on first mint.","type":["string","null"]},"approval_url":{"description":"Send this to the person: deliveries run only after they open it and click Approve. Null once the webhook is on (or paused) for someone.","type":["string","null"]}},"required":["package_id","package_kody_id","name","endpoint_id","instance_label","handle","url_host","enabled","created_at","rotated_at","previous_url_active_until","approval_url"],"additionalProperties":false}},"required":["webhook"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"package:write","x-kody-read-only":false}},"/v1/webhooks/{webhookName}/url/rotate":{"post":{"operationId":"webhookUrlRotate","summary":"Rotate the URL secret for a minted package webhook and return a new opaque handle.","description":"Rotate the URL secret for a minted package webhook and return a new opaque handle. The previous URL stays active for 24 hours, or until the first accepted delivery arrives on the new URL. Register the new URL with webhookUrlApply — the credential is never returned.\n\nOrg permission: `package:write`.","tags":["webhooks"],"parameters":[{"name":"webhookName","in":"path","required":true,"schema":{"type":"string","minLength":1}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"packageId":{"description":"Saved-package UUID. Use when the scoped name is not known, or for a stable ref.","type":"string","minLength":1},"kodyId":{"description":"Package name (`@owner/leaf` or the name leaf). Prefer this when you know the name.","type":"string","minLength":1},"endpointId":{"description":"Minted endpoint to rotate. Required when several URLs share the webhook name.","type":"string","minLength":1}}}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"webhook":{"type":"object","properties":{"package_id":{"type":"string"},"package_kody_id":{"type":"string"},"name":{"type":"string"},"endpoint_id":{"type":"string","description":"Webhook endpoint id. The URL identity for this mint."},"instance_label":{"description":"Short label when several URLs share the declared webhook name. Null on the first mint without a label.","type":["string","null"]},"handle":{"type":"string","description":"Opaque handle for webhookUrlApply. Does not contain the URL secret."},"url_host":{"type":"string","description":"Public hostname of the ingress origin (no path or secret)."},"enabled":{"type":"boolean"},"created_at":{"type":"string"},"rotated_at":{"type":"string"},"previous_url_active_until":{"description":"ISO timestamp while the previous URL still accepts deliveries after rotate. Null on first mint.","type":["string","null"]},"approval_url":{"description":"Send this to the person: deliveries run only after they open it and click Approve. Null once the webhook is on (or paused) for someone.","type":["string","null"]}},"required":["package_id","package_kody_id","name","endpoint_id","instance_label","handle","url_host","enabled","created_at","rotated_at","previous_url_active_until","approval_url"],"additionalProperties":false}},"required":["webhook"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"package:write","x-kody-read-only":false}},"/v1/webhooks/{webhookName}/enable":{"post":{"operationId":"webhookEnable","summary":"Enable a disabled package webhook so ingress accepts deliveries again.","description":"Enable a disabled package webhook so ingress accepts deliveries again.\n\nOrg permission: `package:write`.","tags":["webhooks"],"parameters":[{"name":"webhookName","in":"path","required":true,"schema":{"type":"string","minLength":1}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"packageId":{"description":"Saved-package UUID. Use when the scoped name is not known, or for a stable ref.","type":"string","minLength":1},"kodyId":{"description":"Package name (`@owner/leaf` or the name leaf). Prefer this when you know the name.","type":"string","minLength":1},"endpointId":{"description":"Minted endpoint to enable. Required when several URLs share the webhook name.","type":"string","minLength":1}}}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"package_id":{"type":"string"},"webhook_name":{"type":"string"},"endpoint_id":{"type":"string"},"enabled":{"type":"boolean","const":true}},"required":["package_id","webhook_name","endpoint_id","enabled"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"package:write","x-kody-read-only":false}},"/v1/webhooks/{webhookName}/disable":{"post":{"operationId":"webhookDisable","summary":"Disable a minted package webhook.","description":"Disable a minted package webhook. Ingress returns 404 while disabled (indistinguishable from unknown/unminted).\n\nOrg permission: `package:write`.","tags":["webhooks"],"parameters":[{"name":"webhookName","in":"path","required":true,"schema":{"type":"string","minLength":1}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"packageId":{"description":"Saved-package UUID. Use when the scoped name is not known, or for a stable ref.","type":"string","minLength":1},"kodyId":{"description":"Package name (`@owner/leaf` or the name leaf). Prefer this when you know the name.","type":"string","minLength":1},"endpointId":{"description":"Minted endpoint to disable. Required when several URLs share the webhook name.","type":"string","minLength":1}}}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"package_id":{"type":"string"},"webhook_name":{"type":"string"},"endpoint_id":{"type":"string"},"enabled":{"type":"boolean","const":false}},"required":["package_id","webhook_name","endpoint_id","enabled"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"package:write","x-kody-read-only":false}},"/v1/webhooks/{webhookName}/deliveries":{"get":{"operationId":"webhookDeliveryList","summary":"List recent inbound webhook deliveries for one minted package webhook from run records (metadata only; payload bodies...","description":"List recent inbound webhook deliveries for one minted package webhook from run records (metadata only; payload bodies are never stored).\n\nOrg permission: `package:read`.","tags":["webhooks"],"parameters":[{"name":"webhookName","in":"path","required":true,"schema":{"type":"string","minLength":1}},{"name":"packageId","in":"query","required":false,"description":"Saved-package UUID. Use when the scoped name is not known, or for a stable ref.","schema":{"description":"Saved-package UUID. Use when the scoped name is not known, or for a stable ref.","type":"string","minLength":1}},{"name":"kodyId","in":"query","required":false,"description":"Package name (`@owner/leaf` or the name leaf). Prefer this when you know the name.","schema":{"description":"Package name (`@owner/leaf` or the name leaf). Prefer this when you know the name.","type":"string","minLength":1}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":50}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"deliveries":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"package_id":{"type":"string"},"webhook_name":{"type":"string"},"received_at":{"type":"string"},"outcome":{"type":"string","enum":["delivered","rejected","failed"]},"http_status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"error":{"type":["string","null"]},"payload_bytes":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["id","package_id","webhook_name","received_at","outcome","http_status","error","payload_bytes"],"additionalProperties":false}}},"required":["deliveries"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"package:read","x-kody-read-only":true}},"/v1/email/inboxes":{"get":{"operationId":"emailInboxList","summary":"List email inboxes and automatic platform addresses owned by the signed-in user.","description":"List email inboxes and automatic platform addresses owned by the signed-in user.\n\nOrg permission: `email:read`.","tags":["email"],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"inboxes":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"description":{"type":["string","null"]},"enabled":{"type":"boolean"},"addresses":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"address":{"type":"string"},"enabled":{"type":"boolean"},"created_at":{"type":"string"}},"required":["id","address","enabled","created_at"],"additionalProperties":false}},"created_at":{"type":"string"},"updated_at":{"type":"string"}},"required":["id","name","description","enabled","addresses","created_at","updated_at"],"additionalProperties":false}}},"required":["inboxes"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"email:read","x-kody-read-only":true}},"/v1/email/messages":{"get":{"operationId":"emailMessageList","summary":"List stored inbound and outbound email messages owned by the signed-in user.","description":"List stored inbound and outbound email messages owned by the signed-in user.\n\nOrg permission: `email:read`.","tags":["email"],"parameters":[{"name":"inbox_id","in":"query","required":false,"schema":{"type":"string","minLength":1}},{"name":"direction","in":"query","required":false,"schema":{"type":"string","enum":["inbound","outbound"]}},{"name":"processing_status","in":"query","required":false,"schema":{"type":"string","enum":["stored","sent","failed"]}},{"name":"delivery_status","in":"query","required":false,"schema":{"type":"string","enum":["delivered","deferred","bounced","failed","rejected","complained"]}},{"name":"classification","in":"query","required":false,"schema":{"type":"string","enum":["accepted","quarantined"]}},{"name":"limit","in":"query","required":false,"schema":{"default":25,"type":"integer","exclusiveMinimum":0,"maximum":100}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"messages":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"direction":{"type":"string","enum":["inbound","outbound"]},"inbox_id":{"type":["string","null"]},"thread_id":{"type":["string","null"]},"from_address":{"type":["string","null"]},"envelope_from":{"type":["string","null"]},"to_addresses":{"type":"array","items":{"type":"string"}},"subject":{"type":["string","null"]},"message_id_header":{"type":["string","null"]},"processing_status":{"type":"string","enum":["stored","sent","failed"]},"classification":{"type":"string","enum":["accepted","quarantined"]},"classification_reason":{"type":["string","null"]},"provider_message_id":{"type":["string","null"]},"delivery_status":{"anyOf":[{"type":"string","enum":["delivered","deferred","bounced","failed","rejected","complained"]},{"type":"null"}]},"delivery_status_at":{"type":["string","null"]},"error":{"type":["string","null"]},"received_at":{"type":["string","null"]},"sent_at":{"type":["string","null"]},"created_at":{"type":"string"},"updated_at":{"type":"string"}},"required":["id","direction","inbox_id","thread_id","from_address","envelope_from","to_addresses","subject","message_id_header","processing_status","classification","classification_reason","provider_message_id","delivery_status","delivery_status_at","error","received_at","sent_at","created_at","updated_at"],"additionalProperties":false}}},"required":["messages"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"email:read","x-kody-read-only":true}},"/v1/email/messages/search":{"get":{"operationId":"emailMessageSearch","summary":"Search stored email messages owned by the signed-in user by case-insensitive substring match against subject, header ...","description":"Search stored email messages owned by the signed-in user by case-insensitive substring match against subject, header From, and envelope sender.\n\nOrg permission: `email:read`.","tags":["email"],"parameters":[{"name":"query","in":"query","required":true,"description":"Substring to match (case-insensitive) against subject, from address, and envelope sender.","schema":{"type":"string","minLength":1,"maxLength":256,"description":"Substring to match (case-insensitive) against subject, from address, and envelope sender."}},{"name":"inbox_id","in":"query","required":false,"schema":{"type":"string","minLength":1}},{"name":"direction","in":"query","required":false,"schema":{"type":"string","enum":["inbound","outbound"]}},{"name":"processing_status","in":"query","required":false,"schema":{"type":"string","enum":["stored","sent","failed"]}},{"name":"delivery_status","in":"query","required":false,"schema":{"type":"string","enum":["delivered","deferred","bounced","failed","rejected","complained"]}},{"name":"limit","in":"query","required":false,"schema":{"default":25,"type":"integer","exclusiveMinimum":0,"maximum":100}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"messages":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"direction":{"type":"string","enum":["inbound","outbound"]},"inbox_id":{"type":["string","null"]},"thread_id":{"type":["string","null"]},"from_address":{"type":["string","null"]},"envelope_from":{"type":["string","null"]},"to_addresses":{"type":"array","items":{"type":"string"}},"subject":{"type":["string","null"]},"message_id_header":{"type":["string","null"]},"processing_status":{"type":"string","enum":["stored","sent","failed"]},"classification":{"type":"string","enum":["accepted","quarantined"]},"classification_reason":{"type":["string","null"]},"provider_message_id":{"type":["string","null"]},"delivery_status":{"anyOf":[{"type":"string","enum":["delivered","deferred","bounced","failed","rejected","complained"]},{"type":"null"}]},"delivery_status_at":{"type":["string","null"]},"error":{"type":["string","null"]},"received_at":{"type":["string","null"]},"sent_at":{"type":["string","null"]},"created_at":{"type":"string"},"updated_at":{"type":"string"}},"required":["id","direction","inbox_id","thread_id","from_address","envelope_from","to_addresses","subject","message_id_header","processing_status","classification","classification_reason","provider_message_id","delivery_status","delivery_status_at","error","received_at","sent_at","created_at","updated_at"],"additionalProperties":false}}},"required":["messages"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"email:read","x-kody-read-only":true}},"/v1/email/messages/{message_id}":{"get":{"operationId":"emailMessageGet","summary":"Get one stored email message, including parsed bodies, headers, attachment metadata, and processing state.","description":"Get one stored email message, including parsed bodies, headers, attachment metadata, and processing state.\n\nOrg permission: `email:read`.","tags":["email"],"parameters":[{"name":"message_id","in":"path","required":true,"schema":{"type":"string","minLength":1}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"direction":{"type":"string","enum":["inbound","outbound"]},"inbox_id":{"type":["string","null"]},"thread_id":{"type":["string","null"]},"from_address":{"type":["string","null"]},"envelope_from":{"type":["string","null"]},"to_addresses":{"type":"array","items":{"type":"string"}},"subject":{"type":["string","null"]},"message_id_header":{"type":["string","null"]},"processing_status":{"type":"string","enum":["stored","sent","failed"]},"classification":{"type":"string","enum":["accepted","quarantined"]},"classification_reason":{"type":["string","null"]},"provider_message_id":{"type":["string","null"]},"delivery_status":{"anyOf":[{"type":"string","enum":["delivered","deferred","bounced","failed","rejected","complained"]},{"type":"null"}]},"delivery_status_at":{"type":["string","null"]},"error":{"type":["string","null"]},"received_at":{"type":["string","null"]},"sent_at":{"type":["string","null"]},"created_at":{"type":"string"},"updated_at":{"type":"string"},"cc_addresses":{"type":"array","items":{"type":"string"}},"bcc_addresses":{"type":"array","items":{"type":"string"}},"reply_to_addresses":{"type":"array","items":{"type":"string"}},"in_reply_to_header":{"type":["string","null"]},"references":{"type":"array","items":{"type":"string"}},"headers":{"anyOf":[{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},{"type":"null"}]},"auth_results":{"type":["string","null"]},"text_body":{"type":["string","null"]},"html_body":{"type":["string","null"]},"raw_size":{"type":["number","null"]},"attachments":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"filename":{"type":["string","null"]},"content_type":{"type":["string","null"]},"content_id":{"type":["string","null"]},"disposition":{"type":["string","null"]},"size":{"type":["number","null"]},"storage_kind":{"type":"string"},"storage_key":{"type":["string","null"]},"created_at":{"type":"string"}},"required":["id","filename","content_type","content_id","disposition","size","storage_kind","storage_key","created_at"],"additionalProperties":false}}},"required":["id","direction","inbox_id","thread_id","from_address","envelope_from","to_addresses","subject","message_id_header","processing_status","classification","classification_reason","provider_message_id","delivery_status","delivery_status_at","error","received_at","sent_at","created_at","updated_at","cc_addresses","bcc_addresses","reply_to_addresses","in_reply_to_header","references","headers","auth_results","text_body","html_body","raw_size","attachments"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"email:read","x-kody-read-only":true},"delete":{"operationId":"emailMessageDelete","summary":"Delete one stored email message owned by the signed-in user.","description":"Delete one stored email message owned by the signed-in user. Frees a stored_email_messages slot so new inbound mail can be accepted again.\n\nOrg permission: `email:delete`.","tags":["email"],"parameters":[{"name":"message_id","in":"path","required":true,"schema":{"type":"string","minLength":1}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"deleted":{"type":"boolean","const":true},"message_id":{"type":"string"}},"required":["deleted","message_id"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"email:delete","x-kody-read-only":false}},"/v1/email/messages/{message_id}/classify":{"post":{"operationId":"emailMessageClassify","summary":"Reclassify a stored inbound email message as accepted or quarantined.","description":"Reclassify a stored inbound email message as accepted or quarantined. Receive-time classification decides package subscription dispatch once; reclassifying to accepted does not retroactively fire email.message.received.\n\nOrg permission: `email:write`.","tags":["email"],"parameters":[{"name":"message_id","in":"path","required":true,"schema":{"type":"string","minLength":1}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"classification":{"type":"string","enum":["accepted","quarantined"]}},"required":["classification"]}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"message_id":{"type":"string"},"classification":{"type":"string","enum":["accepted","quarantined"]}},"required":["message_id","classification"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"email:write","x-kody-read-only":false}},"/v1/email/messages/{message_id}/reply":{"post":{"operationId":"emailReply","summary":"Reply to a stored inbound email from your platform-assigned {username}@<platform domain> address, preserving thread h...","description":"Reply to a stored inbound email from your platform-assigned {username}@<platform domain> address, preserving thread headers and optionally attaching files (base64 content). The recipient always comes from the stored message.\n\nOrg permission: `email:send`.","tags":["email"],"parameters":[{"name":"message_id","in":"path","required":true,"schema":{"type":"string","minLength":1}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"text":{"type":"string","minLength":1},"html":{"type":"string","minLength":1},"attachments":{"minItems":1,"maxItems":10,"type":"array","items":{"type":"object","properties":{"filename":{"type":"string","minLength":1,"maxLength":255},"content_type":{"type":"string","minLength":1,"maxLength":255},"content_base64":{"type":"string","minLength":1}},"required":["filename","content_type","content_base64"],"additionalProperties":false}}}}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"direction":{"type":"string","enum":["inbound","outbound"]},"inbox_id":{"type":["string","null"]},"thread_id":{"type":["string","null"]},"from_address":{"type":["string","null"]},"envelope_from":{"type":["string","null"]},"to_addresses":{"type":"array","items":{"type":"string"}},"subject":{"type":["string","null"]},"message_id_header":{"type":["string","null"]},"processing_status":{"type":"string","enum":["stored","sent","failed"]},"classification":{"type":"string","enum":["accepted","quarantined"]},"classification_reason":{"type":["string","null"]},"provider_message_id":{"type":["string","null"]},"delivery_status":{"anyOf":[{"type":"string","enum":["delivered","deferred","bounced","failed","rejected","complained"]},{"type":"null"}]},"delivery_status_at":{"type":["string","null"]},"error":{"type":["string","null"]},"received_at":{"type":["string","null"]},"sent_at":{"type":["string","null"]},"created_at":{"type":"string"},"updated_at":{"type":"string"}},"required":["id","direction","inbox_id","thread_id","from_address","envelope_from","to_addresses","subject","message_id_header","processing_status","classification","classification_reason","provider_message_id","delivery_status","delivery_status_at","error","received_at","sent_at","created_at","updated_at"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"email:send","x-kody-read-only":false}},"/v1/email/send":{"post":{"operationId":"emailSend","summary":"Send email from your platform-assigned {username}@<platform domain> to your verified email destinations, optionally a...","description":"Send email from your platform-assigned {username}@<platform domain> to your verified email destinations, optionally attaching files (base64 content). Destinations expand the allowed to set; Kody is not an open relay. Omit `to` to use the default destination. Every explicit address must be the verified identity email or a verified extra destination; if any `to` is missing or unverified the whole send fails. With attachments, the whole message must fit the plan email_message_bytes cap. Use emailReply to answer stored inbound mail.\n\nOrg permission: `email:send`.","tags":["email"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"to":{"anyOf":[{"type":"string","minLength":1},{"minItems":1,"type":"array","items":{"type":"string","minLength":1}}]},"subject":{"type":"string","minLength":1},"text":{"type":"string","minLength":1},"html":{"type":"string","minLength":1},"reply_to":{"type":"string","minLength":1},"attachments":{"minItems":1,"maxItems":10,"type":"array","items":{"type":"object","properties":{"filename":{"type":"string","minLength":1,"maxLength":255},"content_type":{"type":"string","minLength":1,"maxLength":255},"content_base64":{"type":"string","minLength":1}},"required":["filename","content_type","content_base64"],"additionalProperties":false}}},"required":["subject"]}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"object","properties":{"id":{"type":"string"},"direction":{"type":"string","enum":["inbound","outbound"]},"inbox_id":{"type":["string","null"]},"thread_id":{"type":["string","null"]},"from_address":{"type":["string","null"]},"envelope_from":{"type":["string","null"]},"to_addresses":{"type":"array","items":{"type":"string"}},"subject":{"type":["string","null"]},"message_id_header":{"type":["string","null"]},"processing_status":{"type":"string","enum":["stored","sent","failed"]},"classification":{"type":"string","enum":["accepted","quarantined"]},"classification_reason":{"type":["string","null"]},"provider_message_id":{"type":["string","null"]},"delivery_status":{"anyOf":[{"type":"string","enum":["delivered","deferred","bounced","failed","rejected","complained"]},{"type":"null"}]},"delivery_status_at":{"type":["string","null"]},"error":{"type":["string","null"]},"received_at":{"type":["string","null"]},"sent_at":{"type":["string","null"]},"created_at":{"type":"string"},"updated_at":{"type":"string"}},"required":["id","direction","inbox_id","thread_id","from_address","envelope_from","to_addresses","subject","message_id_header","processing_status","classification","classification_reason","provider_message_id","delivery_status","delivery_status_at","error","received_at","sent_at","created_at","updated_at"],"additionalProperties":false},"provider_message_id":{"type":["string","null"]},"status":{"type":"string"},"error":{"type":["string","null"]}},"required":["message","provider_message_id","status","error"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"email:send","x-kody-read-only":false}},"/v1/email/attachments/{attachment_id}":{"get":{"operationId":"emailAttachmentGet","summary":"Get one stored email attachment by id, returning metadata plus the attachment bytes as base64.","description":"Get one stored email attachment by id, returning metadata plus the attachment bytes as base64.\n\nOrg permission: `email:read`.","tags":["email"],"parameters":[{"name":"attachment_id","in":"path","required":true,"schema":{"type":"string","minLength":1}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"message_id":{"type":"string"},"filename":{"type":["string","null"]},"content_type":{"type":["string","null"]},"content_id":{"type":["string","null"]},"disposition":{"type":["string","null"]},"size":{"type":"number"},"data_base64":{"type":"string"}},"required":["id","message_id","filename","content_type","content_id","disposition","size","data_base64"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"email:read","x-kody-read-only":true}},"/v1/email/delivery-events":{"get":{"operationId":"emailDeliveryEventList","summary":"List stored email delivery events, including outbound provider lifecycle updates and SMTP details.","description":"List stored email delivery events, including outbound provider lifecycle updates and SMTP details.\n\nOrg permission: `email:read`.","tags":["email"],"parameters":[{"name":"message_id","in":"query","required":false,"schema":{"type":"string","minLength":1}},{"name":"event_type","in":"query","required":false,"schema":{"type":"string","enum":["receive_started","received","rejected","send_requested","sent","failed","delivered","deferred","bounced","complained"]}},{"name":"limit","in":"query","required":false,"schema":{"default":25,"type":"integer","exclusiveMinimum":0,"maximum":100}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"events":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"message_id":{"type":["string","null"]},"inbox_id":{"type":["string","null"]},"event_type":{"type":"string","enum":["receive_started","received","rejected","send_requested","sent","failed","delivered","deferred","bounced","complained"]},"provider":{"type":["string","null"]},"provider_message_id":{"type":["string","null"]},"provider_event_id":{"type":["string","null"]},"detail":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"created_at":{"type":"string"}},"required":["id","message_id","inbox_id","event_type","provider","provider_message_id","provider_event_id","detail","created_at"],"additionalProperties":false}}},"required":["events"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"email:read","x-kody-read-only":true}},"/v1/email/sender-rules":{"get":{"operationId":"emailSenderRuleList","summary":"List sender allow/block/quarantine rules for the signed-in user.","description":"List sender allow/block/quarantine rules for the signed-in user. Classification matches rules on RFC5322 From after Authentication-Results (SPF/DKIM/DMARC): allow only when From authenticates (DMARC pass or aligned SPF); block/quarantine still apply (address beats domain; subdomain suffix matching).\n\nOrg permission: `email:read`.","tags":["email"],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"rules":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"kind":{"type":"string","enum":["address","domain"]},"value":{"type":"string"},"effect":{"type":"string","enum":["allow","block","quarantine"]},"note":{"type":"string"},"created_at":{"type":"string"},"updated_at":{"type":"string"}},"required":["id","kind","value","effect","note","created_at","updated_at"],"additionalProperties":false}}},"required":["rules"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"email:read","x-kody-read-only":true},"post":{"operationId":"emailSenderRuleSet","summary":"Create or update a sender rule for the signed-in user.","description":"Create or update a sender rule for the signed-in user. Classification matches rules on RFC5322 From after Authentication-Results: allow/block/quarantine by address or domain (address beats domain; subdomain suffix matching). Allow only accepts when From authenticates (DMARC pass or aligned SPF); block rejects at SMTP before quota; quarantine stores mail and fires email.message.quarantined instead of email.message.received.\n\nOrg permission: `email:write`.","tags":["email"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","enum":["address","domain"]},"value":{"type":"string","minLength":1},"effect":{"type":"string","enum":["allow","block","quarantine"]},"note":{"type":"string"}},"required":["kind","value","effect"]}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"rule":{"type":"object","properties":{"id":{"type":"string"},"kind":{"type":"string","enum":["address","domain"]},"value":{"type":"string"},"effect":{"type":"string","enum":["allow","block","quarantine"]},"note":{"type":"string"},"created_at":{"type":"string"},"updated_at":{"type":"string"}},"required":["id","kind","value","effect","note","created_at","updated_at"],"additionalProperties":false}},"required":["rule"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"email:write","x-kody-read-only":false}},"/v1/email/sender-rules/{rule_id}":{"delete":{"operationId":"emailSenderRuleDelete","summary":"Delete one sender allow/block/quarantine rule owned by the signed-in user.","description":"Delete one sender allow/block/quarantine rule owned by the signed-in user.\n\nOrg permission: `email:write`.","tags":["email"],"parameters":[{"name":"rule_id","in":"path","required":true,"schema":{"type":"string","minLength":1}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"deleted":{"type":"boolean","const":true}},"required":["deleted"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"email:write","x-kody-read-only":false}},"/v1/email/destinations":{"get":{"operationId":"emailDestinationList","summary":"List email destinations emailSend may use.","description":"List email destinations emailSend may use. Mail comes from your platform address. The account identity email is always included. Extra addresses must be verified before emailSend can use them.\n\nOrg permission: `email:read`.","tags":["email"],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"destinations":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"email":{"type":"string"},"kind":{"type":"string","enum":["identity","additional"]},"verified":{"type":"boolean"},"is_default":{"type":"boolean"},"can_remove":{"type":"boolean"}},"required":["id","email","kind","verified","is_default","can_remove"],"additionalProperties":false}},"additional_limit":{"type":"number"},"additional_remaining":{"type":"number"}},"required":["destinations","additional_limit","additional_remaining"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"email:read","x-kody-read-only":true},"post":{"operationId":"emailDestinationAdd","summary":"Start verification for an additional email destination.","description":"Start verification for an additional email destination. Mail comes from your platform address; destinations expand the allowed to set. The address cannot receive mail until the owner opens the verification link. Re-adding an unverified address resends the link. Cap is 5 extras besides the account email.\n\nOrg permission: `email:write`.","tags":["email"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"email":{"type":"string","minLength":1}},"required":["email"]}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"destination":{"type":"object","properties":{"id":{"type":"string"},"email":{"type":"string"},"kind":{"type":"string","enum":["identity","additional"]},"verified":{"type":"boolean"},"is_default":{"type":"boolean"},"can_remove":{"type":"boolean"}},"required":["id","email","kind","verified","is_default","can_remove"],"additionalProperties":false},"created":{"type":"boolean"},"message":{"type":"string"}},"required":["destination","created","message"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"email:write","x-kody-read-only":false}},"/v1/email/destinations/{id}":{"delete":{"operationId":"emailDestinationRemove","summary":"Remove an additional email destination.","description":"Remove an additional email destination. The account identity email cannot be removed. If the removed address was the default, emailSend without `to` falls back to the identity email.\n\nOrg permission: `email:write`.","tags":["email"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","minLength":1}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"destinations":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"email":{"type":"string"},"kind":{"type":"string","enum":["identity","additional"]},"verified":{"type":"boolean"},"is_default":{"type":"boolean"},"can_remove":{"type":"boolean"}},"required":["id","email","kind","verified","is_default","can_remove"],"additionalProperties":false}}},"required":["destinations"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"email:write","x-kody-read-only":false}},"/v1/email/destinations/{id}/default":{"post":{"operationId":"emailDestinationSetDefault","summary":"Set the default email destination used when emailSend omits `to`.","description":"Set the default email destination used when emailSend omits `to`. Pass the identity id or a verified additional destination id from emailDestinationList.\n\nOrg permission: `email:write`.","tags":["email"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","minLength":1}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{}}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"destinations":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"email":{"type":"string"},"kind":{"type":"string","enum":["identity","additional"]},"verified":{"type":"boolean"},"is_default":{"type":"boolean"},"can_remove":{"type":"boolean"}},"required":["id","email","kind","verified","is_default","can_remove"],"additionalProperties":false}}},"required":["destinations"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"email:write","x-kody-read-only":false}},"/v1/integrations":{"get":{"operationId":"integrationList","summary":"List saved OAuth integration connections.","description":"List saved OAuth integration connections. Call createAuthenticatedFetch(name) to use one. Do not persist access or refresh tokens with secretSet.\n\nOrg permission: `integration:read`.","tags":["integrations"],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"integrations":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string","minLength":1},"tokenUrl":{"type":"string","format":"uri"},"apiBaseUrl":{"anyOf":[{"type":"string","format":"uri"},{"type":"null"}]},"flow":{"type":"string","enum":["pkce","confidential"]},"usePkce":{"type":["boolean","null"]},"clientId":{"type":"string","minLength":1},"requiredHosts":{"type":"array","items":{"type":"string"}},"tokenExchangeStyle":{"anyOf":[{"type":"string","enum":["form","basic-json","basic-form"]},{"type":"null"}]},"authorization":{"anyOf":[{"type":"object","properties":{"authorizeUrl":{"type":"string","format":"uri"},"scopes":{"type":"array","items":{"type":"string","minLength":1}},"scopeSeparator":{"anyOf":[{"type":"string","minLength":1},{"type":"null"}]},"extraAuthorizeParams":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}}},"required":["authorizeUrl","scopes"],"additionalProperties":false},{"type":"null"}]},"platform":{"type":"boolean"},"usageMode":{"type":"string","enum":["any","packages"]},"allowedPackageIds":{"type":"array","items":{"type":"string"}},"credentialId":{"type":"string"},"lastAuthFailure":{"type":"object","properties":{"reason":{"type":"string","enum":["missing_refresh_token","provider_rejected","missing_secret","host_not_approved","invalid_config","provider_unavailable"]},"occurredAt":{"type":"string","minLength":1},"reconnectable":{"type":"boolean"},"providerError":{"type":["string","null"]},"providerErrorDescription":{"type":["string","null"]},"httpStatus":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"title":{"type":"string"},"why":{"type":"string"},"who":{"type":"string","enum":["you","kody","the-service"]},"doLabel":{"type":"string"},"reconnectHref":{"type":"string"},"accountHref":{"type":"string"}},"required":["reason","occurredAt","reconnectable","providerError","providerErrorDescription","httpStatus","title","why","who","doLabel","reconnectHref","accountHref"],"additionalProperties":false}},"required":["name","tokenUrl","flow","clientId"],"additionalProperties":false}}},"required":["integrations"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"integration:read","x-kody-read-only":true}},"/v1/integrations/{name}":{"get":{"operationId":"integrationGet","summary":"Read an OAuth integration connection by name.","description":"Read an OAuth integration connection by name. Tokens live on the connection — call createAuthenticatedFetch(name) or integrationTokenRefresh. Do not persist tokens with secretSet.\n\nOrg permission: `integration:read`.","tags":["integrations"],"parameters":[{"name":"name","in":"path","required":true,"description":"Integration name to read.","schema":{"type":"string","minLength":1,"description":"Integration name to read."}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"integration":{"anyOf":[{"type":"object","properties":{"name":{"type":"string","minLength":1},"tokenUrl":{"type":"string","format":"uri"},"apiBaseUrl":{"anyOf":[{"type":"string","format":"uri"},{"type":"null"}]},"flow":{"type":"string","enum":["pkce","confidential"]},"usePkce":{"type":["boolean","null"]},"clientId":{"type":"string","minLength":1},"requiredHosts":{"type":"array","items":{"type":"string"}},"tokenExchangeStyle":{"anyOf":[{"type":"string","enum":["form","basic-json","basic-form"]},{"type":"null"}]},"authorization":{"anyOf":[{"type":"object","properties":{"authorizeUrl":{"type":"string","format":"uri"},"scopes":{"type":"array","items":{"type":"string","minLength":1}},"scopeSeparator":{"anyOf":[{"type":"string","minLength":1},{"type":"null"}]},"extraAuthorizeParams":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}}},"required":["authorizeUrl","scopes"],"additionalProperties":false},{"type":"null"}]},"platform":{"type":"boolean"},"usageMode":{"type":"string","enum":["any","packages"]},"allowedPackageIds":{"type":"array","items":{"type":"string"}},"credentialId":{"type":"string"},"lastAuthFailure":{"type":"object","properties":{"reason":{"type":"string","enum":["missing_refresh_token","provider_rejected","missing_secret","host_not_approved","invalid_config","provider_unavailable"]},"occurredAt":{"type":"string","minLength":1},"reconnectable":{"type":"boolean"},"providerError":{"type":["string","null"]},"providerErrorDescription":{"type":["string","null"]},"httpStatus":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"title":{"type":"string"},"why":{"type":"string"},"who":{"type":"string","enum":["you","kody","the-service"]},"doLabel":{"type":"string"},"reconnectHref":{"type":"string"},"accountHref":{"type":"string"}},"required":["reason","occurredAt","reconnectable","providerError","providerErrorDescription","httpStatus","title","why","who","doLabel","reconnectHref","accountHref"],"additionalProperties":false}},"required":["name","tokenUrl","flow","clientId"],"additionalProperties":false},{"type":"null"}]}},"required":["integration"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"integration:read","x-kody-read-only":true},"put":{"operationId":"integrationSave","summary":"Create or update an OAuth integration connection for the signed-in user.","description":"Create or update an OAuth integration connection for the signed-in user. Names are normalized to a canonical lowercase-kebab provider key. Partial updates merge into the existing connection; matching client credentials reuse a shared OAuth app across connections. Do not persist access or refresh tokens here or with secretSet — `/connect/oauth` and `integrationTokenRefresh` write those on the connection. authorization.scopes is reconnect metadata: the list the next /connect/oauth visit requests, not the current access token. After widening scopes, tell the user the token is unchanged until they reconnect, then ask whether to reconnect each affected account at /connect/oauth?provider=<connection-name>. Scopes are per connection; sibling accounts that share an OAuth app keep their own lists. This capability cannot change usageMode or add requiredHosts / retarget tokenUrl to an unapproved host. Platform (built-in) connections cannot be updated here — reconnect at /connect/oauth?provider=<name> to change scopes, or integrationDelete first to replace with a bring-your-own app.\n\nOrg permission: `integration:write`.","tags":["integrations"],"parameters":[{"name":"name","in":"path","required":true,"schema":{"type":"string","minLength":1}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"tokenUrl":{"type":"string","format":"uri"},"apiBaseUrl":{"anyOf":[{"type":"string","format":"uri"},{"type":"null"}]},"flow":{"type":"string","enum":["pkce","confidential"]},"usePkce":{"type":["boolean","null"]},"clientId":{"type":"string","minLength":1},"requiredHosts":{"type":"array","items":{"type":"string"}},"tokenExchangeStyle":{"anyOf":[{"type":"string","enum":["form","basic-json","basic-form"]},{"type":"null"}]},"authorization":{"anyOf":[{"type":"object","properties":{"authorizeUrl":{"type":"string","format":"uri"},"scopes":{"type":"array","items":{"type":"string","minLength":1}},"scopeSeparator":{"anyOf":[{"type":"string","minLength":1},{"type":"null"}]},"extraAuthorizeParams":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}}},"required":["authorizeUrl","scopes"],"additionalProperties":false},{"type":"null"}]},"accountLabel":{"anyOf":[{"type":"string","minLength":1},{"type":"null"}]},"logoBase64":{"description":"Base64-encoded OAuth app logo (SVG, PNG, JPEG, or WebP). Kody fits the image to 256px WebP before storage. Omit to keep the current logo, pass null to clear it and re-fetch the provider favicon.","type":["string","null"]}}}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"integration":{"type":"object","properties":{"name":{"type":"string","minLength":1},"tokenUrl":{"type":"string","format":"uri"},"apiBaseUrl":{"anyOf":[{"type":"string","format":"uri"},{"type":"null"}]},"flow":{"type":"string","enum":["pkce","confidential"]},"usePkce":{"type":["boolean","null"]},"clientId":{"type":"string","minLength":1},"requiredHosts":{"type":"array","items":{"type":"string"}},"tokenExchangeStyle":{"anyOf":[{"type":"string","enum":["form","basic-json","basic-form"]},{"type":"null"}]},"authorization":{"anyOf":[{"type":"object","properties":{"authorizeUrl":{"type":"string","format":"uri"},"scopes":{"type":"array","items":{"type":"string","minLength":1}},"scopeSeparator":{"anyOf":[{"type":"string","minLength":1},{"type":"null"}]},"extraAuthorizeParams":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}}},"required":["authorizeUrl","scopes"],"additionalProperties":false},{"type":"null"}]},"platform":{"type":"boolean"},"usageMode":{"type":"string","enum":["any","packages"]},"allowedPackageIds":{"type":"array","items":{"type":"string"}},"credentialId":{"type":"string"},"lastAuthFailure":{"type":"object","properties":{"reason":{"type":"string","enum":["missing_refresh_token","provider_rejected","missing_secret","host_not_approved","invalid_config","provider_unavailable"]},"occurredAt":{"type":"string","minLength":1},"reconnectable":{"type":"boolean"},"providerError":{"type":["string","null"]},"providerErrorDescription":{"type":["string","null"]},"httpStatus":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"title":{"type":"string"},"why":{"type":"string"},"who":{"type":"string","enum":["you","kody","the-service"]},"doLabel":{"type":"string"},"reconnectHref":{"type":"string"},"accountHref":{"type":"string"}},"required":["reason","occurredAt","reconnectable","providerError","providerErrorDescription","httpStatus","title","why","who","doLabel","reconnectHref","accountHref"],"additionalProperties":false}},"required":["name","tokenUrl","flow","clientId"],"additionalProperties":false}},"required":["integration"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"integration:write","x-kody-read-only":false},"delete":{"operationId":"integrationDelete","summary":"Delete a saved OAuth integration connection by name.","description":"Delete a saved OAuth integration connection by name. When it is the last connection on its OAuth app, the unused app is removed too.\n\nOrg permission: `integration:delete`.","tags":["integrations"],"parameters":[{"name":"name","in":"path","required":true,"description":"Integration name to delete.","schema":{"type":"string","minLength":1,"description":"Integration name to delete."}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"deleted":{"type":"boolean"}},"required":["deleted"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"integration:delete","x-kody-read-only":false}},"/v1/integrations/{name}/lock":{"post":{"operationId":"integrationLock","summary":"Lock an OAuth integration connection to a package so only that package (and any previously granted packages) can call...","description":"Lock an OAuth integration connection to a package so only that package (and any previously granted packages) can call createAuthenticatedFetch / token refresh. Execute and other packages are denied. Agents can lock; unlocking or removing a grant is website-only at /account/integrations/:name. This capability cannot loosen usage. integrationSave still cannot change usageMode.\n\nOrg permission: `integration:use`.","tags":["integrations"],"parameters":[{"name":"name","in":"path","required":true,"description":"Saved integration connection name (provider key).","schema":{"type":"string","minLength":1,"description":"Saved integration connection name (provider key)."}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"package_id":{"type":"string","minLength":1,"description":"Saved package id that may use this integration."}},"required":["package_id"]}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"usage_mode":{"type":"string","const":"packages"},"allowed_package_ids":{"type":"array","items":{"type":"string"}},"usage_url":{"type":"string"}},"required":["name","usage_mode","allowed_package_ids","usage_url"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"integration:use","x-kody-read-only":false}},"/v1/integrations/{name}/refresh":{"post":{"operationId":"integrationTokenRefresh","summary":"Refresh the OAuth access token for a saved integration host-side and persist the new tokens on the connection.","description":"Refresh the OAuth access token for a saved integration host-side and persist the new tokens on the connection. Connections whose provider issued neither a refresh token nor an access-token expiry at connect (for example GitHub OAuth Apps with token expiration off) are skipped with refreshed: false instead of failing. Returns metadata only — token values never appear in the output. createAuthenticatedFetch refreshes through this path for every integration; it is the only refresh path for platform (built-in) integrations, whose shared client secret stays server-side.\n\nOrg permission: `integration:use`.","tags":["integrations"],"parameters":[{"name":"name","in":"path","required":true,"description":"Integration (connection) name whose tokens should refresh.","schema":{"type":"string","minLength":1,"description":"Integration (connection) name whose tokens should refresh."}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{}}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"refreshed":{"type":"boolean"},"skippedReason":{"anyOf":[{"type":"string","enum":["refresh_not_applicable"]},{"type":"null"}]},"refreshedAt":{"type":["string","null"]},"refreshTokenRotated":{"type":"boolean"}},"required":["ok","refreshed","skippedReason","refreshedAt","refreshTokenRotated"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"integration:use","x-kody-read-only":false}},"/v1/oauth-apps":{"get":{"operationId":"integrationOauthAppList","summary":"List OAuth apps for the signed-in user with connection counts and the connection names that share each app.","description":"List OAuth apps for the signed-in user with connection counts and the connection names that share each app. Use this before rotating client credentials so one write updates every sibling connection.\n\nOrg permission: `integration:read`.","tags":["integrations"],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"apps":{"type":"array","items":{"type":"object","properties":{"slug":{"type":"string","minLength":1},"provider":{"type":"string","minLength":1},"label":{"type":["string","null"]},"clientId":{"type":"string","minLength":1},"hasClientSecret":{"type":"boolean"},"tokenUrl":{"type":"string","format":"uri"},"authorizeUrl":{"anyOf":[{"type":"string","format":"uri"},{"type":"null"}]},"apiBaseUrl":{"anyOf":[{"type":"string","format":"uri"},{"type":"null"}]},"flow":{"type":"string","enum":["pkce","confidential"]},"usePkce":{"type":["boolean","null"]},"tokenExchangeStyle":{"anyOf":[{"type":"string","enum":["form","basic-json","basic-form"]},{"type":"null"}]},"scopeSeparator":{"type":["string","null"]},"extraAuthorizeParams":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}},"connectionCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"connections":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string","minLength":1},"accountLabel":{"type":["string","null"]}},"required":["name","accountLabel"],"additionalProperties":false}},"logoPath":{"type":["string","null"]},"autoLogoPath":{"type":["string","null"]},"logoSource":{"anyOf":[{"type":"string","enum":["upload","favicon"]},{"type":"null"}]},"createdAt":{"type":"string","minLength":1},"updatedAt":{"type":"string","minLength":1}},"required":["slug","provider","label","clientId","hasClientSecret","tokenUrl","authorizeUrl","apiBaseUrl","flow","usePkce","tokenExchangeStyle","scopeSeparator","extraAuthorizeParams","connectionCount","connections","createdAt","updatedAt"],"additionalProperties":false}}},"required":["apps"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"integration:read","x-kody-read-only":true}},"/v1/oauth-apps/{slug}":{"delete":{"operationId":"integrationOauthAppDelete","summary":"Delete a user-registered OAuth app and every connection on it.","description":"Delete a user-registered OAuth app and every connection on it. Built-in (platform) apps cannot be deleted this way — disconnect their connections with integrationDelete instead.\n\nOrg permission: `integration:delete`.","tags":["integrations"],"parameters":[{"name":"slug","in":"path","required":true,"description":"User-lane OAuth app slug to delete, including every connection.","schema":{"type":"string","minLength":1,"description":"User-lane OAuth app slug to delete, including every connection."}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"deleted":{"type":"boolean"},"connectionNames":{"type":"array","items":{"type":"string"}}},"required":["deleted","connectionNames"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"integration:delete","x-kody-read-only":false}},"/v1/oauth-apps/{slug}/rotate-credentials":{"post":{"operationId":"integrationOauthAppRotateCredentials","summary":"Rotate the client id on a shared OAuth app.","description":"Rotate the client id on a shared OAuth app. Every connection on that app sees the new client id on the next join — one write instead of updating each connection. Rotate the client secret value from /account/integrations.\n\nOrg permission: `integration:write`.","tags":["integrations"],"parameters":[{"name":"slug","in":"path","required":true,"description":"OAuth app slug whose client credentials should be rotated.","schema":{"type":"string","minLength":1,"description":"OAuth app slug whose client credentials should be rotated."}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"clientId":{"type":"string","minLength":1,"description":"New OAuth client id (inline value)."}},"required":["clientId"]}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"app":{"type":"object","properties":{"slug":{"type":"string","minLength":1},"provider":{"type":"string","minLength":1},"label":{"type":["string","null"]},"clientId":{"type":"string","minLength":1},"hasClientSecret":{"type":"boolean"},"tokenUrl":{"type":"string","format":"uri"},"authorizeUrl":{"anyOf":[{"type":"string","format":"uri"},{"type":"null"}]},"apiBaseUrl":{"anyOf":[{"type":"string","format":"uri"},{"type":"null"}]},"flow":{"type":"string","enum":["pkce","confidential"]},"usePkce":{"type":["boolean","null"]},"tokenExchangeStyle":{"anyOf":[{"type":"string","enum":["form","basic-json","basic-form"]},{"type":"null"}]},"scopeSeparator":{"type":["string","null"]},"extraAuthorizeParams":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}},"connectionCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"connections":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string","minLength":1},"accountLabel":{"type":["string","null"]}},"required":["name","accountLabel"],"additionalProperties":false}},"logoPath":{"type":["string","null"]},"autoLogoPath":{"type":["string","null"]},"logoSource":{"anyOf":[{"type":"string","enum":["upload","favicon"]},{"type":"null"}]},"createdAt":{"type":"string","minLength":1},"updatedAt":{"type":"string","minLength":1}},"required":["slug","provider","label","clientId","hasClientSecret","tokenUrl","authorizeUrl","apiBaseUrl","flow","usePkce","tokenExchangeStyle","scopeSeparator","extraAuthorizeParams","connectionCount","connections","createdAt","updatedAt"],"additionalProperties":false}},"required":["app"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"integration:write","x-kody-read-only":false}},"/v1/platform-apps":{"get":{"operationId":"integrationPlatformAppList","summary":"List the published platform (built-in) OAuth apps this deployment offers.","description":"List the published platform (built-in) OAuth apps this deployment offers. Each connects without a bring-your-own provider app at /connect/oauth?provider=<slug>&platform=<slug>. Often empty: operators publish built-ins individually, and every other provider connects with the user’s own OAuth app at /connect/oauth.\n\nOrg permission: `integration:read`.","tags":["integrations"],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"apps":{"type":"array","items":{"type":"object","properties":{"slug":{"type":"string","minLength":1},"provider":{"type":"string","minLength":1},"label":{"type":["string","null"]},"description":{"type":["string","null"]},"clientId":{"type":"string","minLength":1},"tokenUrl":{"type":"string","format":"uri"},"authorizeUrl":{"type":"string","format":"uri"},"apiBaseUrl":{"anyOf":[{"type":"string","format":"uri"},{"type":"null"}]},"flow":{"type":"string","enum":["pkce","confidential"]},"usePkce":{"type":["boolean","null"]},"tokenExchangeStyle":{"anyOf":[{"type":"string","enum":["form","basic-json","basic-form"]},{"type":"null"}]},"scopeSeparator":{"type":["string","null"]},"extraAuthorizeParams":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}},"allowedScopes":{"type":"array","items":{"type":"string"}},"defaultScopes":{"type":"array","items":{"type":"string"}},"requiredHosts":{"type":"array","items":{"type":"string"}},"enabled":{"type":"boolean"},"visibility":{"type":"string","enum":["draft","published"]},"logoPath":{"type":["string","null"]},"createdAt":{"type":"string","minLength":1},"updatedAt":{"type":"string","minLength":1}},"required":["slug","provider","label","description","clientId","tokenUrl","authorizeUrl","apiBaseUrl","flow","usePkce","tokenExchangeStyle","scopeSeparator","extraAuthorizeParams","allowedScopes","defaultScopes","requiredHosts","enabled","visibility","logoPath","createdAt","updatedAt"],"additionalProperties":false}}},"required":["apps"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"integration:read","x-kody-read-only":true}},"/v1/mcp-servers":{"get":{"operationId":"mcpServerList","summary":"List the signed-in user's saved MCP servers with live connection status, pending OAuth authUrls (Kody consent pages t...","description":"List the signed-in user's saved MCP servers with live connection status, pending OAuth authUrls (Kody consent pages the user opens to approve access), whether stored tokens include a refresh token, discovered tool names, durable lastError when post-IdP settle or token refresh did not reach ready, and package usage (any context vs locked to listed packages).\n\nOrg permission: `integration:read`.","tags":["mcp-servers"],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"oauthClientOrigin":{"type":"string"},"oauthCallbackUrl":{"type":"string"},"oauthClientMetadataUrl":{"type":["string","null"]},"servers":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"url":{"type":"string"},"enabled":{"type":"boolean"},"state":{"type":"string"},"connected":{"type":"boolean"},"toolCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"authUrl":{"type":["string","null"]},"error":{"type":["string","null"]},"hasRefreshToken":{"type":"boolean"},"tools":{"type":"array","items":{"type":"string"}},"createdAt":{"type":"string"},"updatedAt":{"type":"string"},"usageMode":{"type":"string","enum":["any","packages"]},"allowedPackageIds":{"type":"array","items":{"type":"string"}}},"required":["id","name","url","enabled","state","connected","toolCount","authUrl","error","hasRefreshToken","tools","createdAt","updatedAt","usageMode","allowedPackageIds"],"additionalProperties":false}}},"required":["oauthClientOrigin","oauthCallbackUrl","oauthClientMetadataUrl","servers"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"integration:read","x-kody-read-only":true},"post":{"operationId":"mcpServerAdd","summary":"Add a remote MCP server for the signed-in user and connect to it.","description":"Add a remote MCP server for the signed-in user and connect to it. Servers that require OAuth return an authUrl: a signed-in Kody consent page the user opens and confirms before Kody sends them to the provider; other servers connect immediately. Pass bearerToken for servers that authenticate with a static Authorization header instead of (or in addition to) OAuth. Connected server tools become kody.mcp[\"server-name\"].tool_name(...) capabilities. When OAuth fails with origin or redirect URI errors, the remote authorization server must allow Kody's oauthClientOrigin, oauthCallbackUrl, and oauthClientMetadataUrl (CIMD client_id) when present.\n\nOrg permission: `integration:create`.","tags":["mcp-servers"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"name":{"type":"string","minLength":1,"description":"Short kebab-case name for the server (lowercase letters, numbers, dashes). Used as kody.mcp[\"name\"] in execute code."},"url":{"type":"string","minLength":1,"description":"The remote MCP server endpoint URL. Must be https (http is only allowed for localhost during development)."},"bearerToken":{"description":"Optional static credential for Authorization. Bare tokens are sent as Bearer <token>; values that already include an auth scheme (Bearer, token, etc.) are sent as-is. Stored only in the per-user MCP client hub, never returned later.","type":"string","minLength":1}},"required":["name","url"]}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"url":{"type":"string"},"state":{"type":"string"},"toolCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"authUrl":{"type":["string","null"]},"error":{"type":["string","null"]},"oauthClientOrigin":{"type":"string"},"oauthCallbackUrl":{"type":"string"},"oauthClientMetadataUrl":{"type":["string","null"]},"nextStep":{"type":"string"}},"required":["id","name","url","state","toolCount","authUrl","error","oauthClientOrigin","oauthCallbackUrl","oauthClientMetadataUrl","nextStep"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"integration:create","x-kody-read-only":false}},"/v1/mcp-servers/{server}":{"delete":{"operationId":"mcpServerRemove","summary":"Remove a saved MCP server: disconnects it, deletes stored OAuth tokens and client registrations, and removes its kody...","description":"Remove a saved MCP server: disconnects it, deletes stored OAuth tokens and client registrations, and removes its kody.mcp capabilities.\n\nOrg permission: `integration:delete`.","tags":["mcp-servers"],"parameters":[{"name":"server","in":"path","required":true,"description":"The saved MCP server id or name.","schema":{"type":"string","minLength":1,"description":"The saved MCP server id or name."}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"removed":{"type":"boolean"},"id":{"type":"string"},"name":{"type":"string"}},"required":["removed","id","name"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"integration:delete","x-kody-read-only":false}},"/v1/mcp-servers/{server}/enabled":{"put":{"operationId":"mcpServerSetEnabled","summary":"Enable or disable a saved MCP server.","description":"Enable or disable a saved MCP server. Disabled servers keep their stored connection and OAuth state but their tools are hidden from search, execute, and package code until re-enabled.\n\nOrg permission: `integration:write`.","tags":["mcp-servers"],"parameters":[{"name":"server","in":"path","required":true,"description":"The saved MCP server id or name.","schema":{"type":"string","minLength":1,"description":"The saved MCP server id or name."}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"enabled":{"type":"boolean","description":"Whether the server should be enabled."}},"required":["enabled"]}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"enabled":{"type":"boolean"}},"required":["id","name","enabled"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"integration:write","x-kody-read-only":false}},"/v1/mcp-servers/{server}/reconnect":{"post":{"operationId":"mcpServerReconnect","summary":"Retry connecting to a saved MCP server that is failed or disconnected.","description":"Retry connecting to a saved MCP server that is failed or disconnected. Tries stored OAuth refresh first; an authUrl is the Kody consent page the user opens to re-authorize. Surfaces a durable lastError when refresh failed.\n\nOrg permission: `integration:write`.","tags":["mcp-servers"],"parameters":[{"name":"server","in":"path","required":true,"description":"The saved MCP server id or name.","schema":{"type":"string","minLength":1,"description":"The saved MCP server id or name."}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{}}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"state":{"type":"string"},"toolCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"authUrl":{"type":["string","null"]},"error":{"type":["string","null"]},"oauthClientOrigin":{"type":"string"},"oauthCallbackUrl":{"type":"string"},"oauthClientMetadataUrl":{"type":["string","null"]}},"required":["id","name","state","toolCount","authUrl","error","oauthClientOrigin","oauthCallbackUrl","oauthClientMetadataUrl"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"integration:write","x-kody-read-only":false}},"/v1/mcp-servers/{server}/refresh":{"post":{"operationId":"mcpServerRefresh","summary":"Re-discover the tools exposed by a connected MCP server (for example after the server ships new tools).","description":"Re-discover the tools exposed by a connected MCP server (for example after the server ships new tools).\n\nOrg permission: `integration:write`.","tags":["mcp-servers"],"parameters":[{"name":"server","in":"path","required":true,"description":"The saved MCP server id or name.","schema":{"type":"string","minLength":1,"description":"The saved MCP server id or name."}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{}}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"state":{"type":"string"},"toolCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"error":{"type":["string","null"]}},"required":["id","name","state","toolCount","error"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"integration:write","x-kody-read-only":false}},"/v1/mcp-servers/{server}/lock":{"post":{"operationId":"mcpServerLock","summary":"Lock a saved MCP server to a package so only that package (and any previously granted packages) can call kody.mcp[\"se...","description":"Lock a saved MCP server to a package so only that package (and any previously granted packages) can call kody.mcp[\"server-name\"]. Execute and other packages are denied. Agents can lock; unlocking or removing a grant is website-only at /account/mcp-servers/:serverId.\n\nOrg permission: `integration:use`.","tags":["mcp-servers"],"parameters":[{"name":"server","in":"path","required":true,"description":"The saved MCP server id or name.","schema":{"type":"string","minLength":1,"description":"The saved MCP server id or name."}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"package_id":{"type":"string","minLength":1,"description":"Saved package id that may call this MCP server."}},"required":["package_id"]}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"usage_mode":{"type":"string","const":"packages"},"allowed_package_ids":{"type":"array","items":{"type":"string"}},"usage_url":{"type":"string"}},"required":["id","name","usage_mode","allowed_package_ids","usage_url"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"integration:use","x-kody-read-only":false}},"/v1/runs":{"get":{"operationId":"runList","summary":"List recent execution history across jobs, webhooks, package apps, workflows, ad-hoc execute, and other runtimes so y...","description":"List recent execution history across jobs, webhooks, package apps, workflows, ad-hoc execute, and other runtimes so you can debug failures or inspect what ran. Ad-hoc execute runs are included for both success and error. Terminal rows may include a bounded metadata.result snapshot. By default, ignored/resolved error runs are hidden (error_triage defaults to open); use runUpdate or runUpdateBulk to triage noise, or pass error_triage all/ignored/resolved to inspect those rows. Pass status success (or omit status with error_triage all) for a recent \"what ran\" list. Records are retained about 30 days, capped per user, and cap-pruned in this order: handled errors, successes, then open errors.\n\nOrg permission: `job:read`.","tags":["runs"],"parameters":[{"name":"surface","in":"query","required":false,"description":"Optional runtime surface filter such as job, webhook, execute, app_fetch, or workflow.","schema":{"description":"Optional runtime surface filter such as job, webhook, execute, app_fetch, or workflow.","type":"string","enum":["execute","export","subscription","app_fetch","app_realtime","job","workflow","retriever","webhook"]}},{"name":"status","in":"query","required":false,"description":"Optional status filter: running, success, or error.","schema":{"description":"Optional status filter: running, success, or error.","type":"string","enum":["running","success","error"]}},{"name":"package_id","in":"query","required":false,"description":"Optional saved package id to scope package-owned runs.","schema":{"description":"Optional saved package id to scope package-owned runs.","type":"string","minLength":1}},{"name":"job_id","in":"query","required":false,"description":"Optional job id to list runs for one scheduled job.","schema":{"description":"Optional job id to list runs for one scheduled job.","type":"string","minLength":1}},{"name":"workflow_id","in":"query","required":false,"description":"Optional workflow run id (dynwf-… or pkgwf-…) from workflows.create. Returns that workflow's run, whose metadata.result holds the return value once it succeeds.","schema":{"description":"Optional workflow run id (dynwf-… or pkgwf-…) from workflows.create. Returns that workflow's run, whose metadata.result holds the return value once it succeeds.","type":"string","minLength":1}},{"name":"since","in":"query","required":false,"description":"Optional ISO 8601 lower bound on started_at (inclusive), for example 2026-07-01T00:00:00.000Z.","schema":{"description":"Optional ISO 8601 lower bound on started_at (inclusive), for example 2026-07-01T00:00:00.000Z.","type":"string","minLength":1}},{"name":"error_triage","in":"query","required":false,"description":"Soft error-triage filter. Defaults to open (hides ignored/resolved noise). Use ignored, resolved, or all to inspect triaged runs.","schema":{"description":"Soft error-triage filter. Defaults to open (hides ignored/resolved noise). Use ignored, resolved, or all to inspect triaged runs.","type":"string","enum":["open","ignored","resolved","all"]}},{"name":"limit","in":"query","required":false,"description":"Page size (default 25, max 100).","schema":{"description":"Page size (default 25, max 100).","type":"integer","exclusiveMinimum":0,"maximum":100}},{"name":"cursor","in":"query","required":false,"description":"Opaque pagination cursor from a previous next_cursor value.","schema":{"description":"Opaque pagination cursor from a previous next_cursor value.","type":"string","minLength":1}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"runs":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"surface":{"type":"string","enum":["execute","export","subscription","app_fetch","app_realtime","job","workflow","retriever","webhook"]},"status":{"type":"string","enum":["running","success","error"]},"name":{"type":["string","null"]},"package_id":{"type":["string","null"]},"kody_id":{"type":["string","null"]},"source_id":{"type":["string","null"]},"published_commit":{"type":["string","null"]},"storage_id":{"type":["string","null"]},"job_id":{"type":["string","null"]},"workflow_id":{"type":["string","null"]},"invocation_id":{"type":["string","null"]},"session_id":{"type":["string","null"]},"idempotency_key":{"type":["string","null"]},"parent_run_id":{"type":["string","null"]},"started_at":{"type":"string"},"finished_at":{"type":["string","null"]},"duration_ms":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]},"error_name":{"type":["string","null"]},"error_message":{"type":["string","null"]},"error_triage":{"anyOf":[{"type":"string","enum":["ignored","resolved"]},{"type":"null"}],"description":"Soft triage for error runs: ignored, resolved, or null when open / not an error."},"triage_note":{"type":["string","null"]},"triaged_at":{"type":["string","null"]},"triaged_by":{"type":["string","null"]},"metadata":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"log_count":{"type":"integer","minimum":0,"maximum":9007199254740991}},"required":["id","surface","status","name","package_id","kody_id","source_id","published_commit","storage_id","job_id","workflow_id","invocation_id","session_id","idempotency_key","parent_run_id","started_at","finished_at","duration_ms","error_name","error_message","error_triage","triage_note","triaged_at","triaged_by","metadata","log_count"],"additionalProperties":false}},"next_cursor":{"description":"Opaque cursor for the next page, or null when this is the last page.","type":["string","null"]}},"required":["runs","next_cursor"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"job:read","x-kody-read-only":true}},"/v1/runs/summary":{"get":{"operationId":"runSummary","summary":"Summarize recent run totals, open error count (excluding ignored/resolved), ignored/resolved counts, still-running co...","description":"Summarize recent run totals, open error count (excluding ignored/resolved), ignored/resolved counts, still-running count, and per-surface breakdown to answer \"is anything broken?\" before drilling into runList or runGet. Use runUpdate to mark handled error noise. Counts include successful ad-hoc execute runs. Records are retained about 30 days, capped per user, and pruned failure-last.\n\nOrg permission: `job:read`.","tags":["runs"],"parameters":[{"name":"since","in":"query","required":false,"description":"Optional ISO 8601 lower bound (inclusive). Defaults to the earliest retained record when omitted.","schema":{"description":"Optional ISO 8601 lower bound (inclusive). Defaults to the earliest retained record when omitted.","type":"string","minLength":1}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"since":{"type":"string"},"total":{"type":"integer","minimum":0,"maximum":9007199254740991},"errors":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"Open (not ignored/resolved) error count."},"ignored":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"Error runs marked ignored."},"resolved":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"Error runs marked resolved."},"running":{"type":"integer","minimum":0,"maximum":9007199254740991},"by_surface":{"type":"array","items":{"type":"object","properties":{"surface":{"type":"string","enum":["execute","export","subscription","app_fetch","app_realtime","job","workflow","retriever","webhook"]},"total":{"type":"integer","minimum":0,"maximum":9007199254740991},"errors":{"type":"integer","minimum":0,"maximum":9007199254740991}},"required":["surface","total","errors"],"additionalProperties":false}}},"required":["since","total","errors","ignored","resolved","running","by_surface"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"job:read","x-kody-read-only":true}},"/v1/runs/triage":{"post":{"operationId":"runUpdateBulk","summary":"Non-destructively triage up to 100 retained error runs by explicit ids or safe exact-match filters.","description":"Non-destructively triage up to 100 retained error runs by explicit ids or safe exact-match filters. Use dry_run first for operational cleanup, then repeat filtered updates while has_more is true. Original error status, message, logs, and history remain inspectable.\n\nOrg permission: `job:write`.","tags":["runs"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"run_ids":{"description":"Explicit retained run ids to triage (max 100).","minItems":1,"maxItems":100,"type":"array","items":{"type":"string","minLength":1}},"filter":{"description":"Exact-match selector for retained error runs. At least one identity or error field is required. error_triage defaults to open when resolving/ignoring.","type":"object","properties":{"surface":{"type":"string","enum":["execute","export","subscription","app_fetch","app_realtime","job","workflow","retriever","webhook"]},"package_id":{"type":"string","minLength":1},"job_id":{"type":"string","minLength":1},"name":{"type":"string","minLength":1},"error_name":{"type":"string","minLength":1},"error_message":{"type":"string","minLength":1},"error_triage":{"type":"string","enum":["open","ignored","resolved","all"]}},"additionalProperties":false},"triage":{"type":"string","enum":["ignored","resolved","open"],"description":"Set ignored/resolved, or open to clear soft triage. Execution status and error details never change."},"note":{"description":"Optional note (at most 2000 characters). Omit to preserve the current note when setting ignored/resolved; pass an empty string to clear it. Cleared automatically when triage is set to open.","type":"string","maxLength":2000},"limit":{"description":"Maximum rows updated in one call for both run_ids and filter selectors (default/max 100).","type":"integer","exclusiveMinimum":0,"maximum":100},"dry_run":{"description":"Preview matching run ids without changing any rows.","type":"boolean"}},"required":["triage"]}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"matched_run_ids":{"type":"array","items":{"type":"string"}},"updated_count":{"type":"integer","minimum":0,"maximum":9007199254740991},"has_more":{"type":"boolean"},"dry_run":{"type":"boolean"}},"required":["matched_run_ids","updated_count","has_more","dry_run"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"job:write","x-kody-read-only":false}},"/v1/runs/{run_id}":{"get":{"operationId":"runGet","summary":"Load one retained run with its captured log lines, error details, soft triage fields (error_triage / note / who / whe...","description":"Load one retained run with its captured log lines, error details, soft triage fields (error_triage / note / who / when), and (when available) a bounded metadata.result snapshot of the handler return value — useful for webhook deliveries, package exports, execute runs, and workflow runs. Works for ignored/resolved runs too. Records are retained about 30 days, capped per user, and pruned failure-last.\n\nOrg permission: `job:read`.","tags":["runs"],"parameters":[{"name":"run_id","in":"path","required":true,"description":"Run id from runList, jobGet recent_runs, or another run reference.","schema":{"type":"string","minLength":1,"description":"Run id from runList, jobGet recent_runs, or another run reference."}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"run":{"type":"object","properties":{"id":{"type":"string"},"surface":{"type":"string","enum":["execute","export","subscription","app_fetch","app_realtime","job","workflow","retriever","webhook"]},"status":{"type":"string","enum":["running","success","error"]},"name":{"type":["string","null"]},"package_id":{"type":["string","null"]},"kody_id":{"type":["string","null"]},"source_id":{"type":["string","null"]},"published_commit":{"type":["string","null"]},"storage_id":{"type":["string","null"]},"job_id":{"type":["string","null"]},"workflow_id":{"type":["string","null"]},"invocation_id":{"type":["string","null"]},"session_id":{"type":["string","null"]},"idempotency_key":{"type":["string","null"]},"parent_run_id":{"type":["string","null"]},"started_at":{"type":"string"},"finished_at":{"type":["string","null"]},"duration_ms":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]},"error_name":{"type":["string","null"]},"error_message":{"type":["string","null"]},"error_triage":{"anyOf":[{"type":"string","enum":["ignored","resolved"]},{"type":"null"}],"description":"Soft triage for error runs: ignored, resolved, or null when open / not an error."},"triage_note":{"type":["string","null"]},"triaged_at":{"type":["string","null"]},"triaged_by":{"type":["string","null"]},"metadata":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"log_count":{"type":"integer","minimum":0,"maximum":9007199254740991}},"required":["id","surface","status","name","package_id","kody_id","source_id","published_commit","storage_id","job_id","workflow_id","invocation_id","session_id","idempotency_key","parent_run_id","started_at","finished_at","duration_ms","error_name","error_message","error_triage","triage_note","triaged_at","triaged_by","metadata","log_count"],"additionalProperties":false},"logs":{"type":"array","items":{"type":"object","properties":{"run_id":{"type":"string"},"sequence":{"type":"integer","minimum":0,"maximum":9007199254740991},"level":{"type":"string","enum":["debug","info","log","warn","error"]},"message":{"type":"string"},"fields":{"anyOf":[{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},{"type":"null"}]}},"required":["run_id","sequence","level","message","fields"],"additionalProperties":false}}},"required":["run","logs"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"job:read","x-kody-read-only":true},"patch":{"operationId":"runUpdate","summary":"Mark a retained error run as ignored or resolved (or clear triage back to open) so Activity / runList / runSummary ca...","description":"Mark a retained error run as ignored or resolved (or clear triage back to open) so Activity / runList / runSummary can hide already-handled noise without deleting history. Only error runs accept ignored/resolved; original error details stay intact. Optional note records why. Default runList and runSummary hide ignored/resolved errors — pass error_triage \"all\", \"ignored\", or \"resolved\" on runList to inspect them.\n\nOrg permission: `job:write`.","tags":["runs"],"parameters":[{"name":"run_id","in":"path","required":true,"description":"Run id from runList, runGet, jobGet recent_runs, or another run reference.","schema":{"type":"string","minLength":1,"description":"Run id from runList, runGet, jobGet recent_runs, or another run reference."}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"triage":{"type":"string","enum":["ignored","resolved","open"],"description":"Set soft triage on a retained error run: ignored (noise / soft-failure), resolved (already fixed), or open (clear triage and show it again in default listings). Does not delete the run or change error_name / error_message."},"note":{"description":"Optional note (at most 2000 characters). Omit to preserve the current note when setting ignored/resolved; pass an empty string to clear it. Cleared automatically when triage is set to open.","type":"string","maxLength":2000}},"required":["triage"]}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"run":{"type":"object","properties":{"id":{"type":"string"},"surface":{"type":"string","enum":["execute","export","subscription","app_fetch","app_realtime","job","workflow","retriever","webhook"]},"status":{"type":"string","enum":["running","success","error"]},"name":{"type":["string","null"]},"package_id":{"type":["string","null"]},"kody_id":{"type":["string","null"]},"source_id":{"type":["string","null"]},"published_commit":{"type":["string","null"]},"storage_id":{"type":["string","null"]},"job_id":{"type":["string","null"]},"workflow_id":{"type":["string","null"]},"invocation_id":{"type":["string","null"]},"session_id":{"type":["string","null"]},"idempotency_key":{"type":["string","null"]},"parent_run_id":{"type":["string","null"]},"started_at":{"type":"string"},"finished_at":{"type":["string","null"]},"duration_ms":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]},"error_name":{"type":["string","null"]},"error_message":{"type":["string","null"]},"error_triage":{"anyOf":[{"type":"string","enum":["ignored","resolved"]},{"type":"null"}],"description":"Soft triage for error runs: ignored, resolved, or null when open / not an error."},"triage_note":{"type":["string","null"]},"triaged_at":{"type":["string","null"]},"triaged_by":{"type":["string","null"]},"metadata":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"log_count":{"type":"integer","minimum":0,"maximum":9007199254740991}},"required":["id","surface","status","name","package_id","kody_id","source_id","published_commit","storage_id","job_id","workflow_id","invocation_id","session_id","idempotency_key","parent_run_id","started_at","finished_at","duration_ms","error_name","error_message","error_triage","triage_note","triaged_at","triaged_by","metadata","log_count"],"additionalProperties":false}},"required":["run"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"job:write","x-kody-read-only":false}},"/v1/storage/{storage_id}/export":{"get":{"operationId":"storageExport","summary":"Export one durable storage bucket as JSON for inspection, debugging, or comparisons.","description":"Export one durable storage bucket as JSON for inspection, debugging, or comparisons.\n\nOrg permission: `package:read`.","tags":["storage"],"parameters":[{"name":"storage_id","in":"path","required":true,"description":"Durable storage id to inspect.","schema":{"type":"string","minLength":1,"description":"Durable storage id to inspect."}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":1000}},{"name":"start_after","in":"query","required":false,"schema":{"type":"string","minLength":1}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"storage_id":{"type":"string"},"export":{"type":"object","properties":{"entries":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string"},"value":{}},"required":["key","value"],"additionalProperties":false}},"estimatedBytes":{"type":"number"},"truncated":{"type":"boolean"},"nextStartAfter":{"type":["string","null"]},"pageSize":{"type":"number"}},"required":["entries","estimatedBytes","truncated","nextStartAfter","pageSize"],"additionalProperties":false}},"required":["storage_id","export"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"package:read","x-kody-read-only":true}},"/v1/storage/{storage_id}/query":{"post":{"operationId":"storageQuery","summary":"Run SQL against one durable storage bucket.","description":"Run SQL against one durable storage bucket. Requires package:write (connection-profile write) whenever storage_id resolves to a package bucket — including writable:false SELECT/EXPLAIN/PRAGMA inspection. Defaults to read-only SQL and only allows SELECT, EXPLAIN, and schema PRAGMA queries unless writable is explicitly true. A large read is allowed and metered; warning is set once the scan crosses the oversized-read line, and the call stops only after the documented row ceiling.\n\nOrg permission: `package:write`.","tags":["storage"],"parameters":[{"name":"storage_id","in":"path","required":true,"description":"Durable storage id to inspect.","schema":{"type":"string","minLength":1,"description":"Durable storage id to inspect."}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"query":{"type":"string","minLength":1},"params":{"description":"Optional positional SQL bindings.","type":"array","items":{"type":["string","number","boolean","null"]}},"writable":{"description":"Optional write access toggle. Defaults to false for inspection workflows.","type":"boolean"}},"required":["query"]}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"storage_id":{"type":"string"},"query":{"type":"string"},"columns":{"type":"array","items":{"type":"string"}},"rows":{"type":"array","items":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":["string","number","null"]}}},"row_count":{"type":"number"},"rows_read":{"type":"number"},"rows_written":{"type":"number"},"truncated":{"type":"boolean"},"warning":{"description":"Set when this statement examined at least 1000000 rows. The read is allowed and metered on the monthly Rows read include. Null under that line. A read stops after 1000000000 rows.","type":["string","null"]},"writable":{"type":"boolean"}},"required":["ok","storage_id","query","columns","rows","row_count","rows_read","rows_written","truncated","warning","writable"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"package:write","x-kody-read-only":false}},"/v1/community/listings":{"get":{"operationId":"communitySearch","summary":"Search public package listings on this deployment.","description":"Search public package listings on this deployment. Default ranking is relevance and community ratings; pass sort=newest for last published first. Pass category to browse one closed listing category. Use `communityGet` for full detail before forking.\n\nOrg permission: `search:read`.","tags":["community"],"parameters":[{"name":"query","in":"query","required":true,"description":"Natural-language search query for public packages.","schema":{"type":"string","description":"Natural-language search query for public packages."}},{"name":"limit","in":"query","required":false,"description":"Maximum number of matches to return (default 10, max 50).","schema":{"default":10,"description":"Maximum number of matches to return (default 10, max 50).","type":"integer","minimum":1,"maximum":50}},{"name":"sort","in":"query","required":false,"description":"best (default) ranks by relevance and ratings. newest orders matching listings by last community publish, including republishes.","schema":{"default":"best","description":"best (default) ranks by relevance and ratings. newest orders matching listings by last community publish, including republishes.","type":"string","enum":["best","newest"]}},{"name":"category","in":"query","required":false,"description":"Optional browse category. integrations, examples, productivity, apps, and utilities come from package.json#kody.category (or tag inference). other is the uncategorized remainder.","schema":{"description":"Optional browse category. integrations, examples, productivity, apps, and utilities come from package.json#kody.category (or tag inference). other is the uncategorized remainder.","type":"string","enum":["integrations","examples","productivity","apps","utilities","other"]}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"outcome":{"type":"string","enum":["matches","no_matches"]},"guidance":{"type":"string"},"matches":{"type":"array","items":{"type":"object","properties":{"average_stars":{"type":["number","null"]},"rating_count":{"type":"integer","minimum":0,"maximum":9007199254740991},"average_adaptation_effort":{"type":["number","null"]},"fork_count":{"type":"integer","minimum":0,"maximum":9007199254740991},"listing_id":{"type":"string"},"name":{"type":"string"},"kody_id":{"type":"string"},"description":{"type":"string"},"tags":{"type":"array","items":{"type":"string"}},"category":{"type":"string","enum":["integrations","examples","productivity","apps","utilities","other"]},"version":{"description":"package.json#version from the pinned listing snapshot, or null when the author did not set a string version.","type":["string","null"]},"owner_anonymous":{"type":"boolean","const":true},"trusted":{"type":"boolean","description":"Always false. Catalog listings have no trusted-review mark."},"relevance":{"anyOf":[{"type":"number","minimum":0,"maximum":1},{"type":"null"}],"description":"Blended lexical and vector query relevance from 0 to 1; null when browsing with an empty query."},"published_at":{"type":"string","description":"Last community publish time for this listing. Republishing updates this timestamp."},"public_url":{"type":"string","description":"Canonical shareable user URL ({base}/@{username}/{package-name-leaf}); share this URL with humans."}},"required":["average_stars","rating_count","average_adaptation_effort","fork_count","listing_id","name","kody_id","description","tags","category","version","owner_anonymous","trusted","relevance","published_at","public_url"],"additionalProperties":false}}},"required":["outcome","guidance","matches"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"search:read","x-kody-read-only":true},"post":{"operationId":"communityPublish","summary":"Make a saved package public (first community listing), or force-refresh an already-public listing to the current publ...","description":"Make a saved package public (first community listing), or force-refresh an already-public listing to the current published_commit. Default-branch HEAD becomes world-readable and forkable, and the package appears on /community. Prefer packageUpdate with changes.visibility: \"public\" for the first publish. After that, packagePublishExternalPush / promote auto-advance the listing pin — you do not need a separate republish step. Before calling for a first publish, review the package for overly personal content (package_authoring visibility). If anything looks personal, stop, tell the user, suggest generalizing, and wait for explicit go-ahead. No license, logo, or Intent platform gates. Runtime uses published_commit. Listings owned by anyone are third-party code — review before forking.\n\nOrg permission: `package:publish`.","tags":["community"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"package_id":{"type":"string","minLength":1,"description":"Saved package id to publish as a public package."}},"required":["package_id"]}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"listing_id":{"type":"string"},"name":{"type":"string"},"kody_id":{"type":"string"},"description":{"type":"string"},"category":{"type":"string","enum":["integrations","examples","productivity","apps","utilities","other"]},"license":{"type":"string"},"version":{"description":"package.json#version from the pinned listing snapshot, or null when the author did not set a string version.","type":["string","null"]},"pinned_commit":{"type":"string"},"status":{"type":"string","enum":["active","delisted"]},"public_url":{"type":"string","description":"Canonical shareable user URL ({base}/@{username}/{package-name-leaf}); share this URL with humans."},"published_at":{"type":"string"}},"required":["listing_id","name","kody_id","description","category","license","version","pinned_commit","status","public_url","published_at"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"package:publish","x-kody-read-only":false}},"/v1/community/listings/{listing_id}":{"get":{"operationId":"communityGet","summary":"Load full detail for one public package, including untrusted README content and aggregate ratings.","description":"Load full detail for one public package, including untrusted README content and aggregate ratings.\n\nOrg permission: `search:read`.","tags":["community"],"parameters":[{"name":"listing_id","in":"path","required":true,"description":"Catalog entry id to load.","schema":{"type":"string","minLength":1,"description":"Catalog entry id to load."}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"average_stars":{"type":["number","null"]},"rating_count":{"type":"integer","minimum":0,"maximum":9007199254740991},"average_adaptation_effort":{"type":["number","null"]},"fork_count":{"type":"integer","minimum":0,"maximum":9007199254740991},"listing_id":{"type":"string"},"name":{"type":"string"},"kody_id":{"type":"string"},"description":{"type":"string"},"tags":{"type":"array","items":{"type":"string"}},"category":{"type":"string","enum":["integrations","examples","productivity","apps","utilities","other"]},"license":{"type":"string"},"version":{"description":"package.json#version from the pinned listing snapshot, or null when the author did not set a string version.","type":["string","null"]},"pinned_commit":{"type":"string"},"status":{"type":"string","enum":["active","delisted"]},"trusted":{"type":"boolean","description":"Always false. Catalog listings have no trusted-review mark."},"featured":{"type":"boolean","description":"True when an admin featured this listing as an onboarding starter package. Featured is editorial placement, not a safety review."},"owner_username":{"type":"string"},"owner_profile_url":{"type":["string","null"]},"public_url":{"type":"string","description":"Canonical shareable user URL ({base}/@{username}/{package-name-leaf}); share this URL with humans."},"published_at":{"type":"string"},"readme_untrusted":{"type":["string","null"]},"content_warning":{"type":"string"},"fork_instructions":{"type":"string"}},"required":["average_stars","rating_count","average_adaptation_effort","fork_count","listing_id","name","kody_id","description","tags","category","license","version","pinned_commit","status","trusted","featured","owner_username","owner_profile_url","public_url","published_at","readme_untrusted","content_warning","fork_instructions"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"search:read","x-kody-read-only":true},"delete":{"operationId":"communityUnpublish","summary":"Make a public package private: unlist it from /community and 404 public URLs (existing forks keep their copies).","description":"Make a public package private: unlist it from /community and 404 public URLs (existing forks keep their copies). Prefer packageUpdate with changes.visibility: \"private\" and confirm_name matching the package slug. Delisted listings cannot be unpublished by the owner.\n\nOrg permission: `package:publish`.","tags":["community"],"parameters":[{"name":"listing_id","in":"path","required":true,"description":"Catalog entry id to unpublish.","schema":{"type":"string","minLength":1,"description":"Catalog entry id to unpublish."}},{"name":"confirm_name","in":"query","required":true,"description":"Must equal the package name leaf (URL slug). Confirm with the user first: going private 404s public URLs and unlists the catalog; existing forks keep their copies.","schema":{"type":"string","minLength":1,"description":"Must equal the package name leaf (URL slug). Confirm with the user first: going private 404s public URLs and unlists the catalog; existing forks keep their copies."}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"listing_id":{"type":"string"},"unpublished":{"type":"boolean","const":true}},"required":["listing_id","unpublished"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"package:publish","x-kody-read-only":false}},"/v1/community/listings/{listing_id}/fork":{"post":{"operationId":"communityFork","summary":"Fork a public package into an inert package source in your scope.","description":"Fork a public package into an inert package source in your scope. The fork cannot run until you review the code and publish through a repo session. When the listing leaf is already taken by an unrelated package and you omit `kody_id`, Kody picks the next free leaf (for example `leaf-2`). Pass an explicit package name leaf (or `@owner/leaf`) to choose the name yourself.\n\nOrg permission: `package:create`.","tags":["community"],"parameters":[{"name":"listing_id","in":"path","required":true,"description":"Catalog entry id to fork.","schema":{"type":"string","minLength":1,"description":"Catalog entry id to fork."}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"kody_id":{"description":"Optional package name leaf (or `@owner/leaf`). Omit to use the listing leaf, or the next free alternate when that leaf is already taken by an unrelated package.","type":"string","minLength":1}}}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"fork_id":{"type":"string"},"package_id":{"type":"string"},"source_id":{"type":"string"},"target_kody_id":{"type":"string"},"target_name":{"type":"string"},"origin_commit":{"type":"string"},"files_count":{"type":"integer","minimum":0,"maximum":9007199254740991},"cross_scope_references":{"type":"array","items":{"type":"object","properties":{"file":{"type":"string"},"specifier":{"type":"string"}},"required":["file","specifier"],"additionalProperties":false}},"next_steps":{"type":"string"},"content_warning":{"type":"string"},"serverTiming":{"description":"Request-scoped phase timings. Same shape as execute serverTiming. Not stored. bootstrap-source includes Durable Object startup; subtract nested bootstrap-* phases to estimate cold start.","type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"durationMs":{"type":"number","minimum":0}},"required":["name","durationMs"],"additionalProperties":false}}},"required":["fork_id","package_id","source_id","target_kody_id","target_name","origin_commit","files_count","cross_scope_references","next_steps","content_warning"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"package:create","x-kody-read-only":false}},"/v1/community/listings/{listing_id}/rate":{"post":{"operationId":"communityRate","summary":"Rate a public package after forking it.","description":"Rate a public package after forking it. Stars measure usefulness (1–5); adaptation_effort measures how hard it was to adapt (1 = trivial, 5 = very hard). Ratings feed community search ranking.\n\nOrg permission: `org:read`.","tags":["community"],"parameters":[{"name":"listing_id","in":"path","required":true,"description":"Catalog entry id to rate.","schema":{"type":"string","minLength":1,"description":"Catalog entry id to rate."}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"stars":{"type":"integer","minimum":1,"maximum":5,"description":"Usefulness rating from 1 (low) to 5 (high)."},"adaptation_effort":{"type":"integer","minimum":1,"maximum":5,"description":"Adaptation difficulty from 1 (trivial) to 5 (very hard)."},"note":{"description":"Optional short note about the fork experience.","type":"string","maxLength":1000}},"required":["stars","adaptation_effort"]}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"listing_id":{"type":"string"},"rated":{"type":"boolean","const":true}},"required":["listing_id","rated"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"org:read","x-kody-read-only":false}},"/v1/community/listings/{listing_id}/report":{"post":{"operationId":"communityReport","summary":"Report a public package to deployment admins.","description":"Report a public package to deployment admins. Reports include the reporter identity and are not anonymous.\n\nOrg permission: `org:read`.","tags":["community"],"parameters":[{"name":"listing_id","in":"path","required":true,"description":"Catalog entry id to report.","schema":{"type":"string","minLength":1,"description":"Catalog entry id to report."}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"reason":{"type":"string","minLength":1,"maxLength":2000,"description":"Report reason (1–2000 characters)."}},"required":["reason"]}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"report_id":{"type":"string"},"listing_id":{"type":"string"},"status":{"type":"string","const":"open"}},"required":["report_id","listing_id","status"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"org:read","x-kody-read-only":false}},"/v1/community/fork-adopt":{"post":{"operationId":"communityForkAdopt","summary":"Return a website adoption URL for a community-forked package.","description":"Return a website adoption URL for a community-forked package. Adoption keeps fork provenance but grants self-authored-like read/use access to your user secrets (mutations still need an allowed_packages grant). This capability never adopts: only the account owner can adopt, signed in on the package settings page, after reviewing the source. Send the approval_url to the user and wait; never treat this call as adoption.\n\nOrg permission: `package:read`.","tags":["community"],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"package_id":{"description":"Saved-package UUID. Use when the scoped name is not known, or for a stable ref.","type":"string","minLength":1},"kody_id":{"description":"Package name (`@owner/leaf` or the name leaf). Prefer this when you know the name.","type":"string","minLength":1}}}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["approval_required","already_adopted"]},"package_id":{"type":"string"},"kody_id":{"type":"string"},"listing_id":{"type":"string"},"origin_commit":{"type":"string"},"adopted_at":{"type":["string","null"]},"approval_url":{"type":"string"},"message":{"type":"string"}},"required":["status","package_id","kody_id","listing_id","origin_commit","adopted_at","approval_url","message"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"package:read","x-kody-read-only":true}},"/v1/community/profile":{"get":{"operationId":"communityProfileGet","summary":"Load a community user profile with packages and recent activity.","description":"Load a community user profile with packages and recent activity. Omit username to load your own profile (includes a private profile and private, hidden, or unpublished packages). Other users see only public packages. Private profiles of other users return user_found false without leaking existence.\n\nOrg permission: `org:read`.","tags":["community"],"parameters":[{"name":"username","in":"query","required":false,"description":"Username to load. Omit to load the authenticated caller’s own profile.","schema":{"description":"Username to load. Omit to load the authenticated caller’s own profile.","type":"string","minLength":1}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"user_found":{"type":"boolean"},"profile":{"anyOf":[{"type":"object","properties":{"username":{"type":"string"},"display_name":{"type":"string"},"bio":{"type":["string","null"]},"avatar_url":{"type":["string","null"]},"visibility":{"type":"string","enum":["public","private"]},"joined_at":{"type":"string"},"public_package_count":{"type":"integer","minimum":0,"maximum":9007199254740991},"listing_count":{"type":"integer","minimum":0,"maximum":9007199254740991}},"required":["username","display_name","bio","avatar_url","visibility","joined_at","public_package_count","listing_count"],"additionalProperties":false},{"type":"null"}]},"packages":{"type":"array","items":{"type":"object","properties":{"package_id":{"type":"string"},"name":{"type":"string"},"kody_id":{"type":"string"},"description":{"type":"string"},"tags":{"type":"array","items":{"type":"string"}},"updated_at":{"type":"string","description":"Last time the owner edited the saved package. Independent of what is published to the community."},"community_listing_id":{"type":["string","null"]},"community_published_at":{"description":"Last time the package was published to its catalog entry, or null when it has no active listing.","type":["string","null"]},"needs_republish":{"type":"boolean","description":"True when the active catalog entry pin is behind the package published commit. False when there is no listing, or the pin matches. Do not derive this from updated_at versus published_at."},"hidden":{"description":"Present only on the caller’s own profile. Hidden packages stay off ranked search.","type":"boolean"},"is_private":{"description":"Present only on the caller’s own profile. Repo visibility (`saved_packages.is_private`), not package.json#private.","type":"boolean"}},"required":["name","kody_id","description","tags","updated_at","community_listing_id","community_published_at","needs_republish"],"additionalProperties":false}},"recent_activity":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","enum":["listing_published","listing_updated","listing_forked"]},"actor_username":{"type":"string"},"actor_display_name":{"type":"string"},"actor_avatar_url":{"type":["string","null"]},"listing_id":{"type":"string"},"listing_name":{"type":"string"},"listing_kody_id":{"type":"string"},"created_at":{"type":"string"},"public_url":{"type":"string","description":"Canonical shareable user URL ({base}/@{username}/{package-name-leaf}); share this URL with humans."}},"required":["type","actor_username","actor_display_name","actor_avatar_url","listing_id","listing_name","listing_kody_id","created_at","public_url"],"additionalProperties":false}}},"required":["user_found","profile","packages","recent_activity"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"org:read","x-kody-read-only":true},"patch":{"operationId":"communityProfileUpdate","summary":"Update your community profile display name, bio, and/or visibility.","description":"Update your community profile display name, bio, and/or visibility. At least one field is required. Visibility private hides your profile from other users.\n\nOrg permission: `org:write`.","tags":["community"],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"display_name":{"description":"Display name shown on your profile. Empty string clears it.","type":"string","maxLength":50},"bio":{"description":"Short bio text. Empty string clears it.","type":"string","maxLength":500},"visibility":{"description":"Profile visibility. Private profiles are hidden from other users.","type":"string","enum":["public","private"]}}}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"username":{"type":"string"},"display_name":{"type":"string"},"bio":{"type":["string","null"]},"avatar_url":{"type":["string","null"]},"visibility":{"type":"string","enum":["public","private"]},"joined_at":{"type":"string"},"public_package_count":{"type":"integer","minimum":0,"maximum":9007199254740991},"listing_count":{"type":"integer","minimum":0,"maximum":9007199254740991}},"required":["username","display_name","bio","avatar_url","visibility","joined_at","public_package_count","listing_count"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"org:write","x-kody-read-only":false}},"/v1/tokens":{"get":{"operationId":"tokenList","summary":"List this account's API tokens (metadata only; token values are never returned after mint).","description":"List this account's API tokens (metadata only; token values are never returned after mint). Tokens require an explicit lifetime: lifetime \"short\" (3600s idle / 86400s max) or \"long\" (1209600s idle / 7776000s max), or both idle_ttl_seconds (60-1209600) and max_lifetime_seconds (up to 7776000). Each successful request slides expires_at forward, never past max_expires_at. At most 500 active tokens per account; a new mint reclaims the active token(s) with the least remaining life (sooner of idle deadline and absolute expiry), never the caller's own token.\n\nOrg permission: `token:read`.","tags":["tokens"],"parameters":[{"name":"include_inactive","in":"query","required":false,"description":"Include expired and revoked tokens (kept for 7 days).","schema":{"description":"Include expired and revoked tokens (kept for 7 days).","type":"boolean"}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"tokens":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"org_id":{"type":"string","description":"For org-bound tokens: the fixed org id. For user-owned tokens: the personal org id (placeholder; each request picks an org via `?org=`)."},"org_binding":{"type":"string","enum":["org","user"],"description":"`org`: fixed to org_id. `user`: person-owned; pass `?org=<slug>` on each request (default personal org). Membership/grants are checked live."},"scopes":{"type":"array","items":{"type":"string","enum":["package:read","package:execute","package:write","package:delete","package:publish","package:manage_access","app:read","app:execute","app:write","app:delete","app:manage_access","job:read","job:execute","job:write","job:delete","job:manage_access","secret:use","secret:read","secret:write","secret:delete","secret:manage_access","integration:use","integration:read","integration:write","integration:delete","integration:manage_access","memory:read","memory:write","memory:delete","memory:manage_access","email:read","email:send","email:write","email:delete","email:manage_access","package:create","app:create","job:create","secret:create","integration:create","memory:create","email:create","org:read","org:write","org:delete","org:execute","search:read","member:read","member:write","member:delete","team:read","team:write","team:delete","billing:read","billing:write","audit:read","token:read","token:delete"]}},"status":{"type":"string","enum":["active","expired","revoked"]},"idle_ttl_seconds":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"expires_at":{"type":"string","description":"Sliding expiry. Each successful request pushes it forward."},"max_expires_at":{"type":"string","description":"Absolute expiry. The token never outlives it."},"created_via":{"type":"string"},"created_at":{"type":"string"},"last_used_at":{"type":["string","null"]},"rotated_at":{"type":["string","null"]},"revoked_at":{"type":["string","null"]},"profile_name":{"description":"Named connection profile this token is bound to, or null for unlimited.","type":["string","null"]}},"required":["id","name","org_id","org_binding","scopes","status","idle_ttl_seconds","expires_at","max_expires_at","created_via","created_at","last_used_at","rotated_at","revoked_at","profile_name"],"additionalProperties":false}}},"required":["tokens"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"token:read","x-kody-read-only":true},"post":{"operationId":"tokenCreate","summary":"Mint a scoped API token for this account.","description":"Mint a scoped API token for this account. The token value is returned once. Tokens require an explicit lifetime: lifetime \"short\" (3600s idle / 86400s max) or \"long\" (1209600s idle / 7776000s max), or both idle_ttl_seconds (60-1209600) and max_lifetime_seconds (up to 7776000). Each successful request slides expires_at forward, never past max_expires_at. At most 500 active tokens per account; a new mint reclaims the active token(s) with the least remaining life (sooner of idle deadline and absolute expiry), never the caller's own token. A token-authenticated caller can only grant scopes it holds and cannot outlive its own max_expires_at.\n\nOrg permission: none (touches no org data).","tags":["tokens"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"name":{"type":"string","minLength":1,"maxLength":100,"description":"Label shown in token lists, e.g. `kody-cli on laptop`."},"scopes":{"minItems":1,"type":"array","items":{"type":"string","enum":["package:read","package:execute","package:write","package:delete","package:publish","package:manage_access","app:read","app:execute","app:write","app:delete","app:manage_access","job:read","job:execute","job:write","job:delete","job:manage_access","secret:use","secret:read","secret:write","secret:delete","secret:manage_access","integration:use","integration:read","integration:write","integration:delete","integration:manage_access","memory:read","memory:write","memory:delete","memory:manage_access","email:read","email:send","email:write","email:delete","email:manage_access","package:create","app:create","job:create","secret:create","integration:create","memory:create","email:create","org:read","org:write","org:delete","org:execute","search:read","member:read","member:write","member:delete","team:read","team:write","team:delete","billing:read","billing:write","audit:read","token:read","token:delete"]},"description":"Org-permission scopes to grant. There is no write-implies-read hierarchy. A token can only mint tokens with scopes it holds.\n`package:read`: Read saved packages and package-backed resources.\n`package:execute`: Execute saved packages.\n`package:write`: Change saved packages and package-backed resources.\n`package:delete`: Delete saved packages.\n`package:publish`: Publish packages to the community catalog.\n`package:manage_access`: Manage package access grants.\n`app:read`: Read package apps.\n`app:execute`: Run package apps.\n`app:write`: Granted `app:write` in this org.\n`app:delete`: Granted `app:delete` in this org.\n`app:manage_access`: Granted `app:manage_access` in this org.\n`job:read`: Read package jobs and workflow runs.\n`job:execute`: Run package jobs.\n`job:write`: Granted `job:write` in this org.\n`job:delete`: Granted `job:delete` in this org.\n`job:manage_access`: Granted `job:manage_access` in this org.\n`secret:use`: Use secrets without reading plaintext.\n`secret:read`: Granted `secret:read` in this org.\n`secret:write`: Change existing secrets (plaintext is never returned).\n`secret:delete`: Granted `secret:delete` in this org.\n`secret:manage_access`: Granted `secret:manage_access` in this org.\n`integration:use`: Use connected integrations.\n`integration:read`: Read OAuth integrations and connected MCP servers.\n`integration:write`: Granted `integration:write` in this org.\n`integration:delete`: Granted `integration:delete` in this org.\n`integration:manage_access`: Granted `integration:manage_access` in this org.\n`memory:read`: Read memories and MCP server instructions.\n`memory:write`: Change existing memories.\n`memory:delete`: Granted `memory:delete` in this org.\n`memory:manage_access`: Granted `memory:manage_access` in this org.\n`email:read`: Read inboxes and messages.\n`email:send`: Send email.\n`email:write`: Granted `email:write` in this org.\n`email:delete`: Granted `email:delete` in this org.\n`email:manage_access`: Granted `email:manage_access` in this org.\n`package:create`: Create saved packages.\n`app:create`: Granted `app:create` in this org.\n`job:create`: Granted `job:create` in this org.\n`secret:create`: Create new secrets.\n`integration:create`: Granted `integration:create` in this org.\n`memory:create`: Create new memories.\n`email:create`: Granted `email:create` in this org.\n`org:read`: Read this org’s profile, members, and billing summary.\n`org:write`: Change this org’s profile and settings.\n`org:delete`: Delete this org.\n`org:execute`: Run execute and local CapabilityProxy hops for this org (API tokens need this scope; CLI `kody login` OAuth is a separate credential).\n`search:read`: Run unified Kody search.\n`member:read`: Read org members.\n`member:write`: Invite and change org members.\n`member:delete`: Remove org members.\n`team:read`: Read teams.\n`team:write`: Create and change teams.\n`team:delete`: Delete teams.\n`billing:read`: Read billing and plan.\n`billing:write`: Change billing and plan.\n`audit:read`: Read the org audit log.\n`token:read`: List and inspect API tokens.\n`token:delete`: Revoke API tokens."},"org_binding":{"description":"`org` (default): bind to the current request org. `user`: person-owned token; each call picks an org with `?org=<slug>` (default personal). Existing org-bound tokens stay unchanged.","type":"string","enum":["org","user"]},"profile":{"description":"Optional connection profile name. The token’s package access is limited to that profile’s grants. Experimenters only.","type":"string","minLength":1,"maxLength":64},"lifetime":{"description":"Required unless idle_ttl_seconds and max_lifetime_seconds are both set. `short` = 1h idle / 24h max. `long` = 14d idle / 3mo max. Single-task agents should use `short`.","type":"string","enum":["short","long"]},"idle_ttl_seconds":{"description":"Seconds without use before the token expires. Required with max_lifetime_seconds when lifetime is omitted.","type":"integer","minimum":60,"maximum":1209600},"max_lifetime_seconds":{"description":"Absolute lifetime cap in seconds. Required with idle_ttl_seconds when lifetime is omitted.","type":"integer","minimum":60,"maximum":7776000}},"required":["name","scopes"]}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"org_id":{"type":"string","description":"For org-bound tokens: the fixed org id. For user-owned tokens: the personal org id (placeholder; each request picks an org via `?org=`)."},"org_binding":{"type":"string","enum":["org","user"],"description":"`org`: fixed to org_id. `user`: person-owned; pass `?org=<slug>` on each request (default personal org). Membership/grants are checked live."},"scopes":{"type":"array","items":{"type":"string","enum":["package:read","package:execute","package:write","package:delete","package:publish","package:manage_access","app:read","app:execute","app:write","app:delete","app:manage_access","job:read","job:execute","job:write","job:delete","job:manage_access","secret:use","secret:read","secret:write","secret:delete","secret:manage_access","integration:use","integration:read","integration:write","integration:delete","integration:manage_access","memory:read","memory:write","memory:delete","memory:manage_access","email:read","email:send","email:write","email:delete","email:manage_access","package:create","app:create","job:create","secret:create","integration:create","memory:create","email:create","org:read","org:write","org:delete","org:execute","search:read","member:read","member:write","member:delete","team:read","team:write","team:delete","billing:read","billing:write","audit:read","token:read","token:delete"]}},"status":{"type":"string","enum":["active","expired","revoked"]},"idle_ttl_seconds":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"expires_at":{"type":"string","description":"Sliding expiry. Each successful request pushes it forward."},"max_expires_at":{"type":"string","description":"Absolute expiry. The token never outlives it."},"created_via":{"type":"string"},"created_at":{"type":"string"},"last_used_at":{"type":["string","null"]},"rotated_at":{"type":["string","null"]},"revoked_at":{"type":["string","null"]},"profile_name":{"description":"Named connection profile this token is bound to, or null for unlimited.","type":["string","null"]},"token":{"type":"string","description":"The bearer token. Shown once; Kody stores only a hash. Send it as `Authorization: Bearer <token>`."},"token_type":{"type":"string","const":"Bearer"}},"required":["id","name","org_id","org_binding","scopes","status","idle_ttl_seconds","expires_at","max_expires_at","created_via","created_at","last_used_at","rotated_at","revoked_at","profile_name","token","token_type"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"none","x-kody-read-only":false}},"/v1/tokens/bootstrap":{"post":{"operationId":"cliCredentialBootstrap","summary":"Seed CLI `--local` auth from the current Kody session without a second interactive OAuth: returns a one-shot `kody_bc...","description":"Seed CLI `--local` auth from the current Kody session without a second interactive OAuth: returns a one-shot `kody_bc_…` bootstrap code plus a CLI command that includes required lifetime flags. The CLI redeems the code over HTTPS for a scoped `kody_at_…` (never returned here). Prefer this over `tokenCreate` for interactive agents already on MCP. Do not paste API tokens into chat. Interactive desktop humans who already ran `kody login` can skip this. CI/headless may still mint `kody_at_` directly. Tokens require an explicit lifetime: lifetime \"short\" (3600s idle / 86400s max) or \"long\" (1209600s idle / 7776000s max), or both idle_ttl_seconds (60-1209600) and max_lifetime_seconds (up to 7776000). Each successful request slides expires_at forward, never past max_expires_at. At most 500 active tokens per account; a new mint reclaims the active token(s) with the least remaining life (sooner of idle deadline and absolute expiry), never the caller's own token.\n\nOrg permission: none (touches no org data).","tags":["tokens"],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"name":{"description":"Label for the eventual API token (default `kody-cli-bootstrap`).","type":"string","minLength":1,"maxLength":100},"scopes":{"description":"Org-permission scopes for the eventual `kody_at_` (default: pre-P4 local-execute parity — `org:execute` + `org:read` + package/integration/secret/email/job/app/memory use scopes — plus `package:write` and `token:delete`). There is no write-implies-read hierarchy.\n`package:read`: Read saved packages and package-backed resources.\n`package:execute`: Execute saved packages.\n`package:write`: Change saved packages and package-backed resources.\n`package:delete`: Delete saved packages.\n`package:publish`: Publish packages to the community catalog.\n`package:manage_access`: Manage package access grants.\n`app:read`: Read package apps.\n`app:execute`: Run package apps.\n`app:write`: Granted `app:write` in this org.\n`app:delete`: Granted `app:delete` in this org.\n`app:manage_access`: Granted `app:manage_access` in this org.\n`job:read`: Read package jobs and workflow runs.\n`job:execute`: Run package jobs.\n`job:write`: Granted `job:write` in this org.\n`job:delete`: Granted `job:delete` in this org.\n`job:manage_access`: Granted `job:manage_access` in this org.\n`secret:use`: Use secrets without reading plaintext.\n`secret:read`: Granted `secret:read` in this org.\n`secret:write`: Change existing secrets (plaintext is never returned).\n`secret:delete`: Granted `secret:delete` in this org.\n`secret:manage_access`: Granted `secret:manage_access` in this org.\n`integration:use`: Use connected integrations.\n`integration:read`: Read OAuth integrations and connected MCP servers.\n`integration:write`: Granted `integration:write` in this org.\n`integration:delete`: Granted `integration:delete` in this org.\n`integration:manage_access`: Granted `integration:manage_access` in this org.\n`memory:read`: Read memories and MCP server instructions.\n`memory:write`: Change existing memories.\n`memory:delete`: Granted `memory:delete` in this org.\n`memory:manage_access`: Granted `memory:manage_access` in this org.\n`email:read`: Read inboxes and messages.\n`email:send`: Send email.\n`email:write`: Granted `email:write` in this org.\n`email:delete`: Granted `email:delete` in this org.\n`email:manage_access`: Granted `email:manage_access` in this org.\n`package:create`: Create saved packages.\n`app:create`: Granted `app:create` in this org.\n`job:create`: Granted `job:create` in this org.\n`secret:create`: Create new secrets.\n`integration:create`: Granted `integration:create` in this org.\n`memory:create`: Create new memories.\n`email:create`: Granted `email:create` in this org.\n`org:read`: Read this org’s profile, members, and billing summary.\n`org:write`: Change this org’s profile and settings.\n`org:delete`: Delete this org.\n`org:execute`: Run execute and local CapabilityProxy hops for this org (API tokens need this scope; CLI `kody login` OAuth is a separate credential).\n`search:read`: Run unified Kody search.\n`member:read`: Read org members.\n`member:write`: Invite and change org members.\n`member:delete`: Remove org members.\n`team:read`: Read teams.\n`team:write`: Create and change teams.\n`team:delete`: Delete teams.\n`billing:read`: Read billing and plan.\n`billing:write`: Change billing and plan.\n`audit:read`: Read the org audit log.\n`token:read`: List and inspect API tokens.\n`token:delete`: Revoke API tokens.","minItems":1,"type":"array","items":{"type":"string","enum":["package:read","package:execute","package:write","package:delete","package:publish","package:manage_access","app:read","app:execute","app:write","app:delete","app:manage_access","job:read","job:execute","job:write","job:delete","job:manage_access","secret:use","secret:read","secret:write","secret:delete","secret:manage_access","integration:use","integration:read","integration:write","integration:delete","integration:manage_access","memory:read","memory:write","memory:delete","memory:manage_access","email:read","email:send","email:write","email:delete","email:manage_access","package:create","app:create","job:create","secret:create","integration:create","memory:create","email:create","org:read","org:write","org:delete","org:execute","search:read","member:read","member:write","member:delete","team:read","team:write","team:delete","billing:read","billing:write","audit:read","token:read","token:delete"]}},"lifetime":{"description":"Required unless idle_ttl_seconds and max_lifetime_seconds are both set. `short` = 1h idle / 24h max. `long` = 14d idle / 3mo max. Single-task agents should use `short`.","type":"string","enum":["short","long"]},"idle_ttl_seconds":{"description":"Seconds without use before the eventual token expires. Required with max_lifetime_seconds when lifetime is omitted.","type":"integer","minimum":60,"maximum":1209600},"max_lifetime_seconds":{"description":"Absolute lifetime cap for the eventual token in seconds. Required with idle_ttl_seconds when lifetime is omitted.","type":"integer","minimum":60,"maximum":7776000},"redeem_ttl_seconds":{"description":"How long the one-shot bootstrap code stays redeemable (default 600).","type":"integer","minimum":60,"maximum":900}}}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"bootstrap_code":{"type":"string","description":"One-shot code for the CLI (`kody_bc_…`). Not an API token. Pass it to `npx @kodycodes/cli auth bootstrap --code … --lifetime short` — do not paste a `kody_at_` into chat."},"expires_at":{"type":"string","description":"Absolute redeem deadline (ISO-8601)."},"cli_command":{"type":"string","description":"Ready-to-run CLI command that redeems the code into a local `KODY_API_TOKEN` store entry without a second interactive OAuth. Includes the required lifetime flags."},"name":{"type":"string"},"scopes":{"type":"array","items":{"type":"string","enum":["package:read","package:execute","package:write","package:delete","package:publish","package:manage_access","app:read","app:execute","app:write","app:delete","app:manage_access","job:read","job:execute","job:write","job:delete","job:manage_access","secret:use","secret:read","secret:write","secret:delete","secret:manage_access","integration:use","integration:read","integration:write","integration:delete","integration:manage_access","memory:read","memory:write","memory:delete","memory:manage_access","email:read","email:send","email:write","email:delete","email:manage_access","package:create","app:create","job:create","secret:create","integration:create","memory:create","email:create","org:read","org:write","org:delete","org:execute","search:read","member:read","member:write","member:delete","team:read","team:write","team:delete","billing:read","billing:write","audit:read","token:read","token:delete"]}},"idle_ttl_seconds":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"max_lifetime_seconds":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["bootstrap_code","expires_at","cli_command","name","scopes","idle_ttl_seconds","max_lifetime_seconds"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"none","x-kody-read-only":false}},"/v1/tokens/bootstrap/redeem":{"post":{"operationId":"cliCredentialBootstrapRedeem","summary":"Exchange a one-shot `kody_bc_…` bootstrap code for a scoped `kody_at_…` API token.","description":"Exchange a one-shot `kody_bc_…` bootstrap code for a scoped `kody_at_…` API token. For `@kodycodes/cli auth bootstrap` only — not the MCP `api` tool. No Authorization header; the code is the credential. The code burns on first successful redeem. Lifetime is required on redeem (CLI flags). Tokens require an explicit lifetime: lifetime \"short\" (3600s idle / 86400s max) or \"long\" (1209600s idle / 7776000s max), or both idle_ttl_seconds (60-1209600) and max_lifetime_seconds (up to 7776000). Each successful request slides expires_at forward, never past max_expires_at. At most 500 active tokens per account; a new mint reclaims the active token(s) with the least remaining life (sooner of idle deadline and absolute expiry), never the caller's own token.\n\nOrg permission: none (touches no org data).","tags":["tokens"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"code":{"type":"string","minLength":1,"description":"One-shot `kody_bc_…` bootstrap code from `cliCredentialBootstrap`."},"lifetime":{"description":"Required unless idle_ttl_seconds and max_lifetime_seconds are both set. `short` = 1h idle / 24h max. `long` = 14d idle / 3mo max. Single-task agents should use `short`.","type":"string","enum":["short","long"]},"idle_ttl_seconds":{"description":"Seconds without use before the redeemed token expires. Required with max_lifetime_seconds when lifetime is omitted.","type":"integer","minimum":60,"maximum":1209600},"max_lifetime_seconds":{"description":"Absolute lifetime cap for the redeemed token in seconds. Required with idle_ttl_seconds when lifetime is omitted.","type":"integer","minimum":60,"maximum":7776000}},"required":["code"]}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"org_id":{"type":"string","description":"For org-bound tokens: the fixed org id. For user-owned tokens: the personal org id (placeholder; each request picks an org via `?org=`)."},"org_binding":{"type":"string","enum":["org","user"],"description":"`org`: fixed to org_id. `user`: person-owned; pass `?org=<slug>` on each request (default personal org). Membership/grants are checked live."},"scopes":{"type":"array","items":{"type":"string","enum":["package:read","package:execute","package:write","package:delete","package:publish","package:manage_access","app:read","app:execute","app:write","app:delete","app:manage_access","job:read","job:execute","job:write","job:delete","job:manage_access","secret:use","secret:read","secret:write","secret:delete","secret:manage_access","integration:use","integration:read","integration:write","integration:delete","integration:manage_access","memory:read","memory:write","memory:delete","memory:manage_access","email:read","email:send","email:write","email:delete","email:manage_access","package:create","app:create","job:create","secret:create","integration:create","memory:create","email:create","org:read","org:write","org:delete","org:execute","search:read","member:read","member:write","member:delete","team:read","team:write","team:delete","billing:read","billing:write","audit:read","token:read","token:delete"]}},"status":{"type":"string","enum":["active","expired","revoked"]},"idle_ttl_seconds":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"expires_at":{"type":"string","description":"Sliding expiry. Each successful request pushes it forward."},"max_expires_at":{"type":"string","description":"Absolute expiry. The token never outlives it."},"created_via":{"type":"string"},"created_at":{"type":"string"},"last_used_at":{"type":["string","null"]},"rotated_at":{"type":["string","null"]},"revoked_at":{"type":["string","null"]},"profile_name":{"description":"Named connection profile this token is bound to, or null for unlimited.","type":["string","null"]},"token":{"type":"string","description":"The bearer token. Shown once; Kody stores only a hash. Send it as `Authorization: Bearer <token>`."},"token_type":{"type":"string","const":"Bearer"}},"required":["id","name","org_id","org_binding","scopes","status","idle_ttl_seconds","expires_at","max_expires_at","created_via","created_at","last_used_at","rotated_at","revoked_at","profile_name","token","token_type"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"none","x-kody-read-only":false}},"/v1/tokens/current":{"get":{"operationId":"tokenGetCurrent","summary":"Return the calling API token: scopes, sliding expiry, and absolute expiry.","description":"Return the calling API token: scopes, sliding expiry, and absolute expiry. Needs no scope. Use it to check how long a token has left.\n\nOrg permission: none (touches no org data).","tags":["tokens"],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"org_id":{"type":"string","description":"For org-bound tokens: the fixed org id. For user-owned tokens: the personal org id (placeholder; each request picks an org via `?org=`)."},"org_binding":{"type":"string","enum":["org","user"],"description":"`org`: fixed to org_id. `user`: person-owned; pass `?org=<slug>` on each request (default personal org). Membership/grants are checked live."},"scopes":{"type":"array","items":{"type":"string","enum":["package:read","package:execute","package:write","package:delete","package:publish","package:manage_access","app:read","app:execute","app:write","app:delete","app:manage_access","job:read","job:execute","job:write","job:delete","job:manage_access","secret:use","secret:read","secret:write","secret:delete","secret:manage_access","integration:use","integration:read","integration:write","integration:delete","integration:manage_access","memory:read","memory:write","memory:delete","memory:manage_access","email:read","email:send","email:write","email:delete","email:manage_access","package:create","app:create","job:create","secret:create","integration:create","memory:create","email:create","org:read","org:write","org:delete","org:execute","search:read","member:read","member:write","member:delete","team:read","team:write","team:delete","billing:read","billing:write","audit:read","token:read","token:delete"]}},"status":{"type":"string","enum":["active","expired","revoked"]},"idle_ttl_seconds":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"expires_at":{"type":"string","description":"Sliding expiry. Each successful request pushes it forward."},"max_expires_at":{"type":"string","description":"Absolute expiry. The token never outlives it."},"created_via":{"type":"string"},"created_at":{"type":"string"},"last_used_at":{"type":["string","null"]},"rotated_at":{"type":["string","null"]},"revoked_at":{"type":["string","null"]},"profile_name":{"description":"Named connection profile this token is bound to, or null for unlimited.","type":["string","null"]}},"required":["id","name","org_id","org_binding","scopes","status","idle_ttl_seconds","expires_at","max_expires_at","created_via","created_at","last_used_at","rotated_at","revoked_at","profile_name"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"none","x-kody-read-only":true},"delete":{"operationId":"tokenRevokeCurrent","summary":"Revoke the calling token immediately (for example when a local session ends).","description":"Revoke the calling token immediately (for example when a local session ends). Needs no scope.\n\nOrg permission: none (touches no org data).","tags":["tokens"],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"revoked":{"type":"boolean","const":true}},"required":["id","revoked"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"none","x-kody-read-only":false}},"/v1/tokens/current/rotate":{"post":{"operationId":"tokenRotateCurrent","summary":"Replace the calling token with a new value.","description":"Replace the calling token with a new value. The old value stops working immediately; scopes and max_expires_at are unchanged. Needs no scope.\n\nOrg permission: none (touches no org data).","tags":["tokens"],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{}}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"org_id":{"type":"string","description":"For org-bound tokens: the fixed org id. For user-owned tokens: the personal org id (placeholder; each request picks an org via `?org=`)."},"org_binding":{"type":"string","enum":["org","user"],"description":"`org`: fixed to org_id. `user`: person-owned; pass `?org=<slug>` on each request (default personal org). Membership/grants are checked live."},"scopes":{"type":"array","items":{"type":"string","enum":["package:read","package:execute","package:write","package:delete","package:publish","package:manage_access","app:read","app:execute","app:write","app:delete","app:manage_access","job:read","job:execute","job:write","job:delete","job:manage_access","secret:use","secret:read","secret:write","secret:delete","secret:manage_access","integration:use","integration:read","integration:write","integration:delete","integration:manage_access","memory:read","memory:write","memory:delete","memory:manage_access","email:read","email:send","email:write","email:delete","email:manage_access","package:create","app:create","job:create","secret:create","integration:create","memory:create","email:create","org:read","org:write","org:delete","org:execute","search:read","member:read","member:write","member:delete","team:read","team:write","team:delete","billing:read","billing:write","audit:read","token:read","token:delete"]}},"status":{"type":"string","enum":["active","expired","revoked"]},"idle_ttl_seconds":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"expires_at":{"type":"string","description":"Sliding expiry. Each successful request pushes it forward."},"max_expires_at":{"type":"string","description":"Absolute expiry. The token never outlives it."},"created_via":{"type":"string"},"created_at":{"type":"string"},"last_used_at":{"type":["string","null"]},"rotated_at":{"type":["string","null"]},"revoked_at":{"type":["string","null"]},"profile_name":{"description":"Named connection profile this token is bound to, or null for unlimited.","type":["string","null"]},"token":{"type":"string","description":"The bearer token. Shown once; Kody stores only a hash. Send it as `Authorization: Bearer <token>`."},"token_type":{"type":"string","const":"Bearer"}},"required":["id","name","org_id","org_binding","scopes","status","idle_ttl_seconds","expires_at","max_expires_at","created_via","created_at","last_used_at","rotated_at","revoked_at","profile_name","token","token_type"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"none","x-kody-read-only":false}},"/v1/tokens/{token_id}":{"get":{"operationId":"tokenGet","summary":"Return one API token by id (metadata only).","description":"Return one API token by id (metadata only).\n\nOrg permission: `token:read`.","tags":["tokens"],"parameters":[{"name":"token_id","in":"path","required":true,"description":"API token id (path param on `/v1/tokens/{token_id}`).","schema":{"description":"API token id (path param on `/v1/tokens/{token_id}`).","type":"string","minLength":1}},{"name":"id","in":"query","required":false,"description":"Alias for `token_id` (same value as `tokenList` / `tokenGet` output `id`).","schema":{"description":"Alias for `token_id` (same value as `tokenList` / `tokenGet` output `id`).","type":"string","minLength":1}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"org_id":{"type":"string","description":"For org-bound tokens: the fixed org id. For user-owned tokens: the personal org id (placeholder; each request picks an org via `?org=`)."},"org_binding":{"type":"string","enum":["org","user"],"description":"`org`: fixed to org_id. `user`: person-owned; pass `?org=<slug>` on each request (default personal org). Membership/grants are checked live."},"scopes":{"type":"array","items":{"type":"string","enum":["package:read","package:execute","package:write","package:delete","package:publish","package:manage_access","app:read","app:execute","app:write","app:delete","app:manage_access","job:read","job:execute","job:write","job:delete","job:manage_access","secret:use","secret:read","secret:write","secret:delete","secret:manage_access","integration:use","integration:read","integration:write","integration:delete","integration:manage_access","memory:read","memory:write","memory:delete","memory:manage_access","email:read","email:send","email:write","email:delete","email:manage_access","package:create","app:create","job:create","secret:create","integration:create","memory:create","email:create","org:read","org:write","org:delete","org:execute","search:read","member:read","member:write","member:delete","team:read","team:write","team:delete","billing:read","billing:write","audit:read","token:read","token:delete"]}},"status":{"type":"string","enum":["active","expired","revoked"]},"idle_ttl_seconds":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"expires_at":{"type":"string","description":"Sliding expiry. Each successful request pushes it forward."},"max_expires_at":{"type":"string","description":"Absolute expiry. The token never outlives it."},"created_via":{"type":"string"},"created_at":{"type":"string"},"last_used_at":{"type":["string","null"]},"rotated_at":{"type":["string","null"]},"revoked_at":{"type":["string","null"]},"profile_name":{"description":"Named connection profile this token is bound to, or null for unlimited.","type":["string","null"]}},"required":["id","name","org_id","org_binding","scopes","status","idle_ttl_seconds","expires_at","max_expires_at","created_via","created_at","last_used_at","rotated_at","revoked_at","profile_name"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"token:read","x-kody-read-only":true},"delete":{"operationId":"tokenRevoke","summary":"Revoke an API token immediately.","description":"Revoke an API token immediately. Accepts `token_id` or `id` (from tokenList).\n\nOrg permission: `token:delete`.","tags":["tokens"],"parameters":[{"name":"token_id","in":"path","required":true,"description":"API token id (path param on `/v1/tokens/{token_id}`).","schema":{"description":"API token id (path param on `/v1/tokens/{token_id}`).","type":"string","minLength":1}},{"name":"id","in":"query","required":false,"description":"Alias for `token_id` (same value as `tokenList` / `tokenGet` output `id`).","schema":{"description":"Alias for `token_id` (same value as `tokenList` / `tokenGet` output `id`).","type":"string","minLength":1}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"revoked":{"type":"boolean","const":true}},"required":["id","revoked"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"token:delete","x-kody-read-only":false}},"/v1/tokens/{token_id}/rotate":{"post":{"operationId":"tokenRotate","summary":"Replace an active token with a new value.","description":"Replace an active token with a new value. The old value stops working immediately; scopes and max_expires_at are unchanged. A token-authenticated caller can only rotate tokens whose scopes it holds and that do not outlive it.\n\nOrg permission: `token:delete`.","tags":["tokens"],"parameters":[{"name":"token_id","in":"path","required":true,"description":"API token id (path param on `/v1/tokens/{token_id}`).","schema":{"description":"API token id (path param on `/v1/tokens/{token_id}`).","type":"string","minLength":1}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"id":{"description":"Alias for `token_id` (same value as `tokenList` / `tokenGet` output `id`).","type":"string","minLength":1}}}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"org_id":{"type":"string","description":"For org-bound tokens: the fixed org id. For user-owned tokens: the personal org id (placeholder; each request picks an org via `?org=`)."},"org_binding":{"type":"string","enum":["org","user"],"description":"`org`: fixed to org_id. `user`: person-owned; pass `?org=<slug>` on each request (default personal org). Membership/grants are checked live."},"scopes":{"type":"array","items":{"type":"string","enum":["package:read","package:execute","package:write","package:delete","package:publish","package:manage_access","app:read","app:execute","app:write","app:delete","app:manage_access","job:read","job:execute","job:write","job:delete","job:manage_access","secret:use","secret:read","secret:write","secret:delete","secret:manage_access","integration:use","integration:read","integration:write","integration:delete","integration:manage_access","memory:read","memory:write","memory:delete","memory:manage_access","email:read","email:send","email:write","email:delete","email:manage_access","package:create","app:create","job:create","secret:create","integration:create","memory:create","email:create","org:read","org:write","org:delete","org:execute","search:read","member:read","member:write","member:delete","team:read","team:write","team:delete","billing:read","billing:write","audit:read","token:read","token:delete"]}},"status":{"type":"string","enum":["active","expired","revoked"]},"idle_ttl_seconds":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"expires_at":{"type":"string","description":"Sliding expiry. Each successful request pushes it forward."},"max_expires_at":{"type":"string","description":"Absolute expiry. The token never outlives it."},"created_via":{"type":"string"},"created_at":{"type":"string"},"last_used_at":{"type":["string","null"]},"rotated_at":{"type":["string","null"]},"revoked_at":{"type":["string","null"]},"profile_name":{"description":"Named connection profile this token is bound to, or null for unlimited.","type":["string","null"]},"token":{"type":"string","description":"The bearer token. Shown once; Kody stores only a hash. Send it as `Authorization: Bearer <token>`."},"token_type":{"type":"string","const":"Bearer"}},"required":["id","name","org_id","org_binding","scopes","status","idle_ttl_seconds","expires_at","max_expires_at","created_via","created_at","last_used_at","rotated_at","revoked_at","profile_name","token","token_type"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"token:delete","x-kody-read-only":false}},"/v1/capability-proxy/session":{"get":{"operationId":"capabilityProxySession","summary":"Preflight for local execute: confirms the bearer is valid (scoped `kody_at_` with `org:execute`, or CLI `kody login` ...","description":"Preflight for local execute: confirms the bearer is valid (scoped `kody_at_` with `org:execute`, or CLI `kody login` MCP OAuth). Returns scopes, expiry, and proxy limits. Call before starting user code.\n\nOrg permission: `org:execute`.","tags":["capability-proxy"],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"scopes":{"type":"array","items":{"type":"string"}},"expiresAt":{"type":"string","description":"Sliding expiry; every proxied call pushes it forward."},"maxExpiresAt":{"type":"string","description":"Absolute expiry of the token."},"idleTtlSeconds":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"user":{"type":"object","properties":{"userId":{"type":"string"},"email":{"type":"string"}},"required":["userId","email"],"additionalProperties":false},"features":{"type":"array","items":{"type":"string"},"description":"Optional host features this proxy serves, e.g. `credential-call-map` (the `credentials` call field and `kody.credentialClientCheck`)."},"limits":{"type":"object","properties":{"maxPathSegments":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"maxArgs":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"maxRequestBytes":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["maxPathSegments","maxArgs","maxRequestBytes"],"additionalProperties":false}},"required":["scopes","expiresAt","maxExpiresAt","idleTtlSeconds","user","features","limits"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"org:execute","x-kody-read-only":true}},"/v1/capability-proxy/call":{"post":{"operationId":"capabilityProxyCall","summary":"Run one `kody:runtime` call from a local execute venue: `path` is the runtime property path (`['kody','emailSend']`, ...","description":"Run one `kody:runtime` call from a local execute venue: `path` is the runtime property path (`['kody','emailSend']`, `['kody','authenticatedFetch']`, `['kody','oauthClientCredentials']`, `['kody','mcp',server,tool]`, `['kody','packageStorageGet']`, `['workflows','create']`) and `args` the positional arguments. Behaves like the same call inside cloud execute. Authenticated fetch, OAuth client-credentials grants, and stamped packageStorage / packageSecrets hop here so OAuth tokens and secret plaintext stay on origin. Accepts a scoped API token or CLI MCP OAuth. Errors use the standard envelope; capability failures return `capability_error` with the capability's message.\n\nOrg permission: `org:execute`.","tags":["capability-proxy"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"path":{"minItems":2,"maxItems":8,"type":"array","items":{"type":"string","minLength":1,"maxLength":200},"description":"`kody:runtime` property path, e.g. `['kody','emailSend']`, `['kody','mcp','home','lights_on']`, or `['workflows','create']`."},"args":{"maxItems":8,"type":"array","items":{},"description":"Positional arguments passed to the runtime function."},"conversationId":{"description":"Optional MCP conversation id to attribute the call to.","type":"string","minLength":1,"maxLength":64},"credentials":{"description":"Credential picks for this local run, by need key (CLI `--credential key=name`), read by `kody.credentialClient*` calls. Same shape as `execute` `credentials`. Picks choose only among credentials you can Use.","type":"object","propertyNames":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9._-]{0,99}$"},"additionalProperties":{"anyOf":[{"anyOf":[{"type":"string","minLength":1,"maxLength":100},{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":100,"description":"Credential name to pick for this need key (must match a credential the actor can Use)."},"scope":{"description":"When an org credential and a personal credential share the name, choose which one. Omit when the name alone is unique.","type":"string","enum":["org","personal"]}},"required":["name"],"additionalProperties":false}]},{"maxItems":16,"type":"array","items":{"anyOf":[{"type":"string","minLength":1,"maxLength":100},{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":100,"description":"Credential name to pick for this need key (must match a credential the actor can Use)."},"scope":{"description":"When an org credential and a personal credential share the name, choose which one. Omit when the name alone is unique.","type":"string","enum":["org","personal"]}},"required":["name"],"additionalProperties":false}]}}]}}},"required":["path","args"]}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"result":{"description":"Return value of the runtime call (JSON)."}},"required":["result"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"org:execute","x-kody-read-only":false}},"/v1/capability-proxy/gateway-fetch":{"post":{"operationId":"capabilityProxyGatewayFetch","summary":"Native streaming hop for local execute: the request body is the outbound fetch body (raw bytes, no JSON wrapper).","description":"Native streaming hop for local execute: the request body is the outbound fetch body (raw bytes, no JSON wrapper). Hop metadata is in `X-Kody-Gateway-Url` (required), `X-Kody-Gateway-Method`, `X-Kody-Gateway-Package-Id`, `X-Kody-Gateway-Headers`, and `x-kody-secret-resolution`. A successful response is the upstream HTTP response, streamed — not `{ status, headers, bodyBase64 }`. Requires `org:execute` and a scoped API token or CLI MCP OAuth bearer. Not available as a JSON MCP `api` invoke; use `POST /v1/capability-proxy/gateway-fetch`.\n\nOrg permission: `org:execute`.","tags":["capability-proxy"],"parameters":[{"name":"X-Kody-Gateway-Url","in":"header","required":true,"description":"Absolute outbound URL. May contain literal `{{secret:…}}` / `{{integration-token:…}}` placeholders.","schema":{"type":"string"}},{"name":"X-Kody-Gateway-Method","in":"header","required":false,"description":"Outbound HTTP method. Defaults to GET.","schema":{"type":"string"}},{"name":"X-Kody-Gateway-Package-Id","in":"header","required":false,"description":"Claimed package stamp. Origin verifies `package:execute` for that id.","schema":{"type":"string"}},{"name":"X-Kody-Gateway-Headers","in":"header","required":false,"description":"JSON object of outbound header name → string value. Invalid JSON or non-string values are `400 invalid_request`.","schema":{"type":"string"}},{"name":"x-kody-secret-resolution","in":"header","required":false,"description":"`on` (default), `headers-only`, or `off`. Origin strips this header before the request leaves.","schema":{"type":"string"}}],"requestBody":{"required":false,"description":"Raw outbound fetch body, streamed. No JSON wrapper and no base64. Set `Content-Type` to the outbound value.","content":{"*/*":{"schema":{"type":"string","format":"binary"},"description":"Raw outbound bytes (may be multipart)."}}},"responses":{"200":{"description":"Upstream HTTP response: status, headers, and body, streamed. Not a JSON envelope. Upstream 4xx/5xx (including 429) are forwarded as the stream, not the JSON Error envelope.","content":{"*/*":{"schema":{"type":"string","format":"binary"},"description":"Upstream response body, streamed."}}},"default":{"description":"Origin-side failure before the upstream stream starts (auth, validation, etc.). Upstream 4xx/5xx are not this response — they are forwarded on the 200 stream with the upstream status, headers, and body.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"apiToken":[]}],"x-kody-permission":"org:execute","x-kody-read-only":false}},"/v1/local-execute/package-graph":{"post":{"operationId":"localExecutePackageGraph","summary":"Resolve published, stamped `kody:@…` importable-module artifacts for an ad hoc execute module so `@kodycodes/cli exec...","description":"Resolve published, stamped `kody:@…` importable-module artifacts for an ad hoc execute module so `@kodycodes/cli execute --local` / `kody dev` can embed them in workerd. Uses the same static-import scanner and resolution policy as cloud execute (packages resolve only in the caller org). Pass inline `code` (up to just under the Open API JSON body limit of 5 MiB, leaving room for the JSON wrapper) and/or `imports`; when only `imports` is set, origin synthesizes a tiny entry so multi-megabyte worker bundles (TanStack / React apps) do not need to be posted. Does **not** execute the user module and does not meter `dynamic_worker_day`. CapabilityProxy remains for per-call `kody:runtime` hops during the later local run. Requires `org:execute` and a scoped API token or CLI MCP OAuth bearer.\n\nOrg permission: `org:execute`.","tags":["capability-proxy"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"anyOf":[{"type":"object","properties":{"code":{"type":"string","minLength":1,"maxLength":5177344},"imports":{"maxItems":64,"type":"array","items":{"type":"string","minLength":1,"maxLength":512}},"conversationId":{"type":"string","minLength":1,"maxLength":128}},"required":["code"],"additionalProperties":false},{"type":"object","properties":{"imports":{"maxItems":64,"type":"array","items":{"type":"string","minLength":1,"maxLength":512}},"code":{"type":"string","minLength":1,"maxLength":5177344},"conversationId":{"type":"string","minLength":1,"maxLength":128}},"required":["imports"],"additionalProperties":false}]}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"modules":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string","minLength":1},"esModule":{"type":"string"}},"required":["name","esModule"],"additionalProperties":false}},"imports":{"type":"array","items":{"type":"string"}},"warnings":{"type":"array","items":{"type":"string"}}},"required":["modules","imports","warnings"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"org:execute","x-kody-read-only":true}},"/v1/execute":{"post":{"operationId":"execute","summary":"Run one ESM module in Kody's hosted sandbox.","description":"Run one ESM module in Kody's hosted sandbox. Same inputs and result envelope as the MCP `execute` tool (`content`, `structuredContent`, `isError`). Requires `Authorization: Bearer kody_at_…` with `org:execute`. JSON bodies follow the Open API 5 MiB cap. Older CLIs keep using MCP `execute`; this route does not accept MCP OAuth.\n\nOrg permission: `org:execute`.","tags":["execute"],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"code":{"description":"Single ESM module string with a default export. Imports may be npm packages compatible with the Cloudflare Workers runtime.","type":"string"},"invoke":{"description":"Published package export to run (`kody:@owner/name/export`). Omit code when this is set.","type":"string","minLength":1},"params":{"description":"JSON object passed to the default export.","type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"responseLimit":{"type":"integer","minimum":1,"maximum":9007199254740991},"conversationId":{"description":"Optional short conversation identifier. Ties related calls together. If you already have a `conversationId` from an earlier response in the same conversation, pass it back unchanged. Otherwise omit this field to receive a server-generated ID, then reuse the returned `conversationId` on subsequent calls - this enables optimizations like reduced response size. Do not invent your own `conversationId`.","type":"string","minLength":1,"maxLength":64},"memoryContext":{"description":"Optional short, structured task context for memory retrieval. Keep it brief and factual rather than hidden reasoning. If durable memory may need to be written or deleted, agents should later run `metaMemoryVerify` before mutating memory.","type":"object","properties":{"task":{"description":"Optional task or goal summary for future memory retrieval.","type":"string","minLength":1,"maxLength":300},"query":{"description":"Optional task or goal summary for future memory retrieval.","type":"string","minLength":1,"maxLength":300},"entities":{"description":"Optional short phrases that identify important entities, constraints, or references for future memory retrieval.","maxItems":8,"type":"array","items":{"type":"string","minLength":1,"maxLength":120}},"constraints":{"description":"Optional short phrases that identify important entities, constraints, or references for future memory retrieval.","maxItems":8,"type":"array","items":{"type":"string","minLength":1,"maxLength":120}}},"additionalProperties":false},"idempotencyKey":{"type":"string","minLength":1,"maxLength":256},"credentials":{"type":"object","propertyNames":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9._-]{0,99}$"},"additionalProperties":{"anyOf":[{"anyOf":[{"type":"string","minLength":1,"maxLength":100},{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":100,"description":"Credential name to pick for this need key (must match a credential the actor can Use)."},"scope":{"description":"When an org credential and a personal credential share the name, choose which one. Omit when the name alone is unique.","type":"string","enum":["org","personal"]}},"required":["name"],"additionalProperties":false}]},{"maxItems":16,"type":"array","items":{"anyOf":[{"type":"string","minLength":1,"maxLength":100},{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":100,"description":"Credential name to pick for this need key (must match a credential the actor can Use)."},"scope":{"description":"When an org credential and a personal credential share the name, choose which one. Omit when the name alone is unique.","type":"string","enum":["org","personal"]}},"required":["name"],"additionalProperties":false}]}}]},"description":"Optional credential picks by need key, for `credential(key)` / `credentials(key)` in this run: `{ github: \"work\", google: [\"work\", \"personal\"], x: { name: \"work\", scope: \"org\" } }`. A string is a credential name; add `scope` when an org and a personal credential share the name; an array picks several for `credentials(key)`, and `[]` picks none. Picks choose only among credentials you can Use."}}}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"content":{"type":"array","items":{}},"structuredContent":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"isError":{"type":"boolean"}},"required":["content","structuredContent","isError"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"org:execute","x-kody-read-only":false}},"/v1/search/tool":{"post":{"operationId":"searchTool","summary":"Same catalog search as the MCP `search` tool, including exact `entity` refs.","description":"Same catalog search as the MCP `search` tool, including exact `entity` refs. Requires `search:read`. The result envelope matches the tool (`content`, `structuredContent`, `isError`). `GET /v1/search` remains the capability.\n\nOrg permission: `search:read`.","tags":["search"],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"query":{"description":"Natural language description, or a scoped `@owner/leaf` name, current-origin account package URL, owner-matching hosted package URL, or an exact saved-package UUID (`package_id`) when the name is not known.","type":"string","minLength":1},"entity":{"description":"Optional exact entity reference \"{type}:{id}\" (capability, guide, integration, mcp-server, package, or secret), or an array of refs to batch related detail lookups. Guide refs accept \"#{heading}\" or a line anchor \"#L165\" / \"#L165-L180\". Package refs accept \"#{subpath}\" to open one export contract (leading \"./\" is optional), or \"#{path}\" / \"#{path}#L165\" / \"#{path}#heading\" to open one file. A fragment that matches an export subpath still opens that export. Use \"mcp-server:{name}\" to list tools on a connected MCP server.","anyOf":[{"type":"string","minLength":1},{"minItems":1,"maxItems":10,"type":"array","items":{"type":"string","minLength":1}}]},"domain":{"description":"Optional capability domain id (for example \"email\" or \"mcp:linear\"). With \"query\", ranks only that domain's capabilities; without \"query\", lists the domain's capabilities.","type":"string","minLength":1},"limit":{"description":"Number of ranked results to return. Defaults to 15.","type":"integer","minimum":1,"maximum":100},"maxResponseSize":{"description":"Response size budget before trimming low-ranked results. Defaults to 4000.","type":"integer","minimum":1,"maximum":9007199254740991},"conversationId":{"description":"Optional short conversation identifier. Ties related calls together. If you already have a `conversationId` from an earlier response in the same conversation, pass it back unchanged. Otherwise omit this field to receive a server-generated ID, then reuse the returned `conversationId` on subsequent calls - this enables optimizations like reduced response size. Do not invent your own `conversationId`.","type":"string","minLength":1,"maxLength":64},"memoryContext":{"description":"Optional short, structured task context for memory retrieval. Keep it brief and factual rather than hidden reasoning. If durable memory may need to be written or deleted, agents should later run `metaMemoryVerify` before mutating memory.","type":"object","properties":{"task":{"description":"Optional task or goal summary for future memory retrieval.","type":"string","minLength":1,"maxLength":300},"query":{"description":"Optional task or goal summary for future memory retrieval.","type":"string","minLength":1,"maxLength":300},"entities":{"description":"Optional short phrases that identify important entities, constraints, or references for future memory retrieval.","maxItems":8,"type":"array","items":{"type":"string","minLength":1,"maxLength":120}},"constraints":{"description":"Optional short phrases that identify important entities, constraints, or references for future memory retrieval.","maxItems":8,"type":"array","items":{"type":"string","minLength":1,"maxLength":120}}},"additionalProperties":false},"includeHiddenPackages":{"description":"Include hidden packages in search results (hidden packages are excluded by default).","type":"boolean"}}}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"content":{"type":"array","items":{}},"structuredContent":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"isError":{"type":"boolean"}},"required":["content","structuredContent","isError"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"search:read","x-kody-read-only":true}},"/v1/tokens/device":{"post":{"operationId":"cliLoginDeviceToken","summary":"Exchange the official CLI OAuth access token from `kody login` for a user-owned `kody_at_` device token.","description":"Exchange the official CLI OAuth access token from `kody login` for a user-owned `kody_at_` device token. The OAuth bearer is accepted only on this route (and on local-execute HTTP for older CLIs). The token value is returned once. Scopes are the org-permission vocabulary; the caller role still applies. Requires `lifetime` (`short` or `long`) or both idle and max seconds.\n\nOrg permission: none (touches no org data).","tags":["tokens"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"lifetime":{"description":"Required unless idle_ttl_seconds and max_lifetime_seconds are both set. `short` = 1h idle / 24h max. `long` = 14d idle / 3mo max. Single-task agents should use `short`.","type":"string","enum":["short","long"]},"idle_ttl_seconds":{"description":"Seconds without use before the token expires. Required with max_lifetime_seconds when lifetime is omitted.","type":"integer","minimum":60,"maximum":1209600},"max_lifetime_seconds":{"description":"Absolute lifetime cap in seconds. Required with idle_ttl_seconds when lifetime is omitted.","type":"integer","minimum":60,"maximum":7776000},"name":{"type":"string","minLength":1,"maxLength":100,"description":"Label shown in token lists, e.g. `kody-cli on laptop`."}},"required":["name"]}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"org_id":{"type":"string","description":"For org-bound tokens: the fixed org id. For user-owned tokens: the personal org id (placeholder; each request picks an org via `?org=`)."},"org_binding":{"type":"string","enum":["org","user"],"description":"`org`: fixed to org_id. `user`: person-owned; pass `?org=<slug>` on each request (default personal org). Membership/grants are checked live."},"scopes":{"type":"array","items":{"type":"string","enum":["package:read","package:execute","package:write","package:delete","package:publish","package:manage_access","app:read","app:execute","app:write","app:delete","app:manage_access","job:read","job:execute","job:write","job:delete","job:manage_access","secret:use","secret:read","secret:write","secret:delete","secret:manage_access","integration:use","integration:read","integration:write","integration:delete","integration:manage_access","memory:read","memory:write","memory:delete","memory:manage_access","email:read","email:send","email:write","email:delete","email:manage_access","package:create","app:create","job:create","secret:create","integration:create","memory:create","email:create","org:read","org:write","org:delete","org:execute","search:read","member:read","member:write","member:delete","team:read","team:write","team:delete","billing:read","billing:write","audit:read","token:read","token:delete"]}},"status":{"type":"string","enum":["active","expired","revoked"]},"idle_ttl_seconds":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"expires_at":{"type":"string","description":"Sliding expiry. Each successful request pushes it forward."},"max_expires_at":{"type":"string","description":"Absolute expiry. The token never outlives it."},"created_via":{"type":"string"},"created_at":{"type":"string"},"last_used_at":{"type":["string","null"]},"rotated_at":{"type":["string","null"]},"revoked_at":{"type":["string","null"]},"profile_name":{"description":"Named connection profile this token is bound to, or null for unlimited.","type":["string","null"]},"token":{"type":"string","description":"The bearer token. Shown once; Kody stores only a hash. Send it as `Authorization: Bearer <token>`."},"token_type":{"type":"string","const":"Bearer"},"login_org":{"anyOf":[{"type":"object","properties":{"slug":{"type":"string"}},"required":["slug"],"additionalProperties":false},{"type":"null"}],"description":"Org the CLI OAuth grant was bound to. The device token is user-owned; pass this slug as ?org= on later calls."}},"required":["id","name","org_id","org_binding","scopes","status","idle_ttl_seconds","expires_at","max_expires_at","created_via","created_at","last_used_at","rotated_at","revoked_at","profile_name","token","token_type","login_org"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}},"security":[{"apiToken":[]}],"x-kody-permission":"none","x-kody-read-only":false}}},"components":{"schemas":{"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","enum":["invalid_request","unauthorized","insufficient_scope","email_verification_required","account_suspended","feature_unavailable","feature_disabled","not_found","method_not_allowed","account_deleting","payload_too_large","unsupported_media_type","rate_limited","entitlement_limit","capability_error","package_import_unresolved","package_import_unpublished","unsupported_dynamic_package_import","internal_error"]},"message":{"type":"string"},"details":{}}}}}},"responses":{"Error":{"description":"Error envelope `{ \"error\": { \"code\", \"message\", \"details\"? } }`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"RateLimited":{"description":"Too many requests (edge IP/token limit) or an entitlement / plan-cap limit. Wait at least `Retry-After` seconds before retrying.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1}},"RateLimit-Policy":{"description":"Edge-generated 429s only: advertised policies (`ip` 600/min, `token` 300/min). Remaining counts are not exposed. Entitlement 429s omit this header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"securitySchemes":{"apiToken":{"type":"http","scheme":"bearer","bearerFormat":"kody_at_<id>_<secret>","description":"Scoped Kody API token. Each operation lists its required org permission in `x-kody-permission`. Credential scopes narrow that permission."}}},"servers":[{"url":"https://api.kody.codes"}]}