{"openapi":"3.1.0","info":{"title":"ORC8R API","description":"JSON API for ORC8R. Authenticate with a bearer API key (`Authorization: Bearer <token>`); browser sessions may instead rely on the `orc_session` cookie. Errors are RFC 9457 Problem Details (`application/problem+json`).","version":"0.4.0-rc73"},"paths":{"/api/auth/user":{"get":{"tags":["auth"],"summary":"Get the current user","description":"Returns the user identified by the session cookie or bearer API key. Requires authentication.","operationId":"auth_user","responses":{"200":{"description":"The signed-in user","content":{"application/json":{"schema":{}}}},"401":{"description":"Not authenticated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"security":[{"api_key":[]}]}},"/api/downloads":{"get":{"tags":["downloads"],"summary":"List downloads","description":"Returns every published download repository with its version tags, plus the title and description the publisher annotated the served artifact with when it carries them. Unauthenticated: downloads are public.","operationId":"list_downloads","responses":{"200":{"description":"Download repositories and their tags","content":{"application/json":{"schema":{}}}}}}},"/api/downloads/{name}":{"get":{"tags":["downloads"],"summary":"Get a download","description":"Returns one download repository: the publisher's title and description when annotated, its version tags and, per tag, the files with size, platform, and sha256 digest. The digest is the file's own sha256 — download bytes are stored verbatim. Unauthenticated: downloads are public.","operationId":"get_download","parameters":[{"name":"name","in":"path","description":"Download repository name","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The repository, its tags, and their files","content":{"application/json":{"schema":{}}}},"404":{"description":"No such download","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/nodes/":{"get":{"tags":["nodes"],"summary":"List visible nodes","description":"Returns every node in the pools the caller can see (via org or project membership), including liveness state, as a paginated envelope.","operationId":"list_nodes","responses":{"200":{"description":"Paginated node list","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"security":[{"api_key":[]}]}},"/api/nodes/{node}/audit":{"get":{"tags":["nodes"],"summary":"Get a node's audit history","description":"Returns the node aggregate's ordered event log as a paginated envelope; each entry carries the event type, sequence, and decoded payload. Requires the `ReadNode` permission in the node's project.","operationId":"node_audit","parameters":[{"name":"node","in":"path","description":"Node wire id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Paginated event history","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Caller may not read this node","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Node not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"security":[{"api_key":[]}]}},"/api/nodes/{node}/logs":{"get":{"tags":["nodes"],"summary":"Stream a node's logs","description":"Server-Sent Events stream of a node's durable logs. Replays retained rows then live-tails. Requires the `ReadNodeLogs` permission in the node's project. `Last-Event-ID` resumes while rows are retained.","operationId":"node_logs","parameters":[{"name":"node","in":"path","description":"Node wire id","required":true,"schema":{"type":"string"}},{"name":"debug","in":"query","description":"`true` to include debug-level records","required":false,"schema":{"type":"string"}},{"name":"mode","in":"query","description":"`head` (replay then stop) or `tail` (default, keep streaming)","required":false,"schema":{"type":"string"}},{"name":"since","in":"query","description":"Tail window duration, e.g. `30s`, `15m`, `6h`, `3d`","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"SSE stream of log records","content":{"text/event-stream":{}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Caller may not read this node's logs","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Node not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"security":[{"api_key":[]}]}},"/api/nodes/{node}/terminal/ws":{"get":{"tags":["nodes"],"summary":"Open an interactive terminal (WebSocket)","description":"Upgrades to a WebSocket carrying an interactive PTY on the node's agent. Binary frames carry stdin/stdout; JSON text frames carry control (`resize`, `close`) and lifecycle events. Requires the `TerminalAttach` permission in the node's project.","operationId":"node_terminal_ws","parameters":[{"name":"node","in":"path","description":"Node wire id","required":true,"schema":{"type":"string"}},{"name":"cols","in":"query","description":"Initial terminal columns (default 80)","required":false,"schema":{"type":"integer","format":"int32","minimum":0}},{"name":"rows","in":"query","description":"Initial terminal rows (default 24)","required":false,"schema":{"type":"integer","format":"int32","minimum":0}}],"responses":{"101":{"description":"Switching protocols to WebSocket"},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Caller may not attach a terminal","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Node not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"security":[{"api_key":[]}]}},"/api/nodes/{node}/terminate":{"post":{"tags":["nodes"],"summary":"Terminate a node","description":"Requests termination of a node. Online nodes drain through the agent; offline nodes end immediately; a node hosting provider resources cascades to its children. Requires the `TerminateNode` permission. Returns the node's post-write lifecycle state.","operationId":"terminate_node","parameters":[{"name":"node","in":"path","description":"Node wire id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Termination accepted; returns the new state","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Caller may not terminate this node","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Node not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Node already ended","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"security":[{"api_key":[]}]}},"/api/orgs/{org}":{"get":{"tags":["orgs"],"summary":"Get an organization","description":"Returns the organization's identity (id, code, name) and its effective resource limits (`-1` means unlimited). Any member who can read the org may call this.","operationId":"get_org","parameters":[{"name":"org","in":"path","description":"Organization code or wire id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Organization identity and limits","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Caller may not read this organization","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Organization not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"security":[{"api_key":[]}]}},"/api/orgs/{org}/address-plan":{"get":{"tags":["networks"],"summary":"Get an organization's address plan","description":"Returns the org's allocatable and reserved prefixes and its allocated `/24` blocks. Requires the `ReadAddressPlan` permission (system operator).","operationId":"get_address_plan","parameters":[{"name":"org","in":"path","description":"Organization code or wire id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The org's address plan","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Caller may not read address plans","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Organization not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"security":[{"api_key":[]}]}},"/api/orgs/{org}/address-plan/prefixes":{"post":{"tags":["networks"],"summary":"Add an address-plan prefix","description":"Adds an allocatable (default) or reserved IPv4 prefix to the org's address plan. Requires the `ManageAddressPlans` permission. Overlaps within this plan are rejected (422); overlaps with another org's plan are allowed and reported under `warnings`.","operationId":"add_prefix","parameters":[{"name":"org","in":"path","description":"Organization code or wire id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PrefixRequest"}}},"required":true},"responses":{"200":{"description":"Updated plan with any cross-org warnings","content":{"application/json":{"schema":{}}}},"400":{"description":"Malformed request body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Caller may not manage address plans","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Organization not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Invalid prefix, kind, or overlapping prefix","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"security":[{"api_key":[]}]}},"/api/orgs/{org}/address-plan/prefixes/remove":{"post":{"tags":["networks"],"summary":"Remove an address-plan prefix","description":"Removes an allocatable (default) or reserved IPv4 prefix from the org's address plan. Requires the `ManageAddressPlans` permission.","operationId":"remove_prefix","parameters":[{"name":"org","in":"path","description":"Organization code or wire id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PrefixRequest"}}},"required":true},"responses":{"200":{"description":"Updated plan","content":{"application/json":{"schema":{}}}},"400":{"description":"Malformed request body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Caller may not manage address plans","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Organization not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Invalid prefix or kind","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"security":[{"api_key":[]}]}},"/api/orgs/{org}/apps-configure":{"post":{"tags":["appconfigs"],"summary":"Configure an org-scoped app","description":"Saves (default), resets, or refreshes version discovery for one app's org-scoped configuration. Sensitive values are tokenized server-side. Requires the `ManageOrgApps` permission. `reset` returns 204.","operationId":"configure_org_apps","parameters":[{"name":"org","in":"path","description":"Organization code or wire id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppsConfigureRequest"}}},"required":true},"responses":{"200":{"description":"Saved config (or refresh result)","content":{"application/json":{"schema":{}}}},"204":{"description":"Config reset"},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Caller may not manage org apps","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Organization not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Version discovery is disabled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Invalid app, action, param, or locked key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"security":[{"api_key":[]}]}},"/api/orgs/{org}/billing/account":{"get":{"tags":["billing"],"summary":"Get an organization's billing account","description":"Returns the org's billing account: plan, billing interval, cycle anchor, and next billing date. Requires the `read_billing` permission. Unknown orgs or orgs without an account are 404.","operationId":"get_account","parameters":[{"name":"org","in":"path","description":"Organization wire ID or code","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The billing account","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Caller lacks read_billing","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Organization or account not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"security":[{"api_key":[]}]},"put":{"tags":["billing"],"summary":"Update an organization's plan","description":"Updates the org's plan. `billing_interval` changes are not yet supported. Requires the `manage_billing` permission. An empty update is a no-op 200.","operationId":"update_account","parameters":[{"name":"org","in":"path","description":"Organization wire ID or code","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateAccountRequest"}}},"required":true},"responses":{"200":{"description":"Plan updated (or no-op)","content":{"application/json":{"schema":{}}}},"400":{"description":"Malformed body or unsupported interval change","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Caller lacks manage_billing","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Organization or account not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Invalid plan type","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"security":[{"api_key":[]}]}},"/api/orgs/{org}/billing/invoices/":{"get":{"tags":["billing"],"summary":"List an organization's invoices","description":"Lists the org's invoices, newest first, with offset pagination. Requires the `read_billing` permission.","operationId":"list_invoices","parameters":[{"name":"org","in":"path","description":"Organization wire ID or code","required":true,"schema":{"type":"string"}},{"name":"status","in":"query","description":"Filter by invoice status (e.g. `draft`, `finalized`)","required":false,"schema":{"type":"string"}},{"name":"limit","in":"query","description":"Page size (1–100, default 30)","required":false,"schema":{"type":"integer","format":"int64"}},{"name":"after","in":"query","description":"Numeric offset cursor from a prior page","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Paginated invoice list","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Caller lacks read_billing","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Organization not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"security":[{"api_key":[]}]}},"/api/orgs/{org}/billing/invoices/{invoice_id}":{"get":{"tags":["billing"],"summary":"Get one invoice","description":"Returns a single invoice for the org. Requires the `read_billing` permission. Malformed invoice IDs are 400; unknown or foreign invoices are 404.","operationId":"get_invoice","parameters":[{"name":"org","in":"path","description":"Organization wire ID or code","required":true,"schema":{"type":"string"}},{"name":"invoice_id","in":"path","description":"Invoice wire ID","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The invoice","content":{"application/json":{"schema":{}}}},"400":{"description":"Malformed invoice_id","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Caller lacks read_billing","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Invoice not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"security":[{"api_key":[]}]}},"/api/orgs/{org}/billing/invoices/{invoice_id}/lines":{"get":{"tags":["billing"],"summary":"Get an invoice's line items","description":"Returns the per-pool line items and computed total for an invoice. Requires the `read_billing` permission.","operationId":"get_invoice_lines","parameters":[{"name":"org","in":"path","description":"Organization wire ID or code","required":true,"schema":{"type":"string"}},{"name":"invoice_id","in":"path","description":"Invoice wire ID","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Line items and total","content":{"application/json":{"schema":{}}}},"400":{"description":"Malformed invoice_id","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Caller lacks read_billing","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Invoice not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"security":[{"api_key":[]}]}},"/api/orgs/{org}/billing/upcoming-invoice":{"get":{"tags":["billing"],"summary":"Get the upcoming (draft) invoice","description":"Returns the org's latest draft invoice with its line items. Requires the `read_billing` permission; 404 when no draft exists.","operationId":"upcoming_invoice","parameters":[{"name":"org","in":"path","description":"Organization wire ID or code","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Draft invoice with items","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Caller lacks read_billing","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"No upcoming invoice","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"security":[{"api_key":[]}]}},"/api/orgs/{org}/projects/":{"get":{"tags":["projects"],"summary":"List an organization's projects","description":"Returns the projects in the organization as a paginated envelope. Requires the `ListOrgProjects` permission.","operationId":"list_projects","parameters":[{"name":"org","in":"path","description":"Organization code or wire id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Paginated project list","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Caller may not list this org's projects","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Organization not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"security":[{"api_key":[]}]},"post":{"tags":["projects"],"summary":"Create a project","description":"Creates a project (name and DNS-label code) with the caller as owner. Requires the `CreateOrgProjects` permission. A code collision returns 409; hitting the org's project limit returns 422.","operationId":"create_project","parameters":[{"name":"org","in":"path","description":"Organization code or wire id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"required":true},"responses":{"201":{"description":"Project created","content":{"application/json":{"schema":{}}}},"400":{"description":"Malformed request body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Caller may not create projects here","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Organization not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Project code already taken","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Invalid name/code or org project limit reached","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"security":[{"api_key":[]}]}},"/api/orgs/{org}/projects/{proj}":{"put":{"tags":["projects"],"summary":"Rename a project","description":"Renames a project's name and/or code. Requires the `UpdateProject` permission. A code collision returns 409; invalid name/code returns 422.","operationId":"update_project","parameters":[{"name":"org","in":"path","description":"Organization code or wire id","required":true,"schema":{"type":"string"}},{"name":"proj","in":"path","description":"Project code or wire id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateProjectRequest"}}},"required":true},"responses":{"200":{"description":"Updated name and code","content":{"application/json":{"schema":{}}}},"400":{"description":"Malformed request body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Caller may not update this project","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Organization or project not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Project code already taken","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Invalid name or code","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"security":[{"api_key":[]}]}},"/api/orgs/{org}/projects/{proj}/apps-configure":{"post":{"tags":["appconfigs"],"summary":"Configure a project-scoped app","description":"Saves (default), resets, or refreshes version discovery for one app's project-scoped configuration. Sensitive values are tokenized server-side. Requires the `ManageProjectApps` permission. `reset` returns 204.","operationId":"configure_project_apps","parameters":[{"name":"org","in":"path","description":"Organization code or wire id","required":true,"schema":{"type":"string"}},{"name":"proj","in":"path","description":"Project code or wire id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppsConfigureRequest"}}},"required":true},"responses":{"200":{"description":"Saved config (or refresh result)","content":{"application/json":{"schema":{}}}},"204":{"description":"Config reset"},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Caller may not manage project apps","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Organization or project not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Version discovery is disabled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Invalid app, action, param, or locked key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"security":[{"api_key":[]}]}},"/api/orgs/{org}/projects/{proj}/members/":{"get":{"tags":["projects"],"summary":"List project members","description":"Returns the project's members as a paginated envelope, ordered by display name. Requires the `ListProjectMembers` permission.","operationId":"list_members","parameters":[{"name":"org","in":"path","description":"Organization code or wire id","required":true,"schema":{"type":"string"}},{"name":"proj","in":"path","description":"Project code or wire id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Paginated member list","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Caller may not list members","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Organization or project not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"security":[{"api_key":[]}]},"post":{"tags":["projects"],"summary":"Add a project member","description":"Adds a member to the project by `email` or `user_id` with a role. Requires the `ManageProjectMembers` permission. 400 when neither identifier is supplied; 404 when no user matches; 422 on an invalid role.","operationId":"add_member","parameters":[{"name":"org","in":"path","description":"Organization code or wire id","required":true,"schema":{"type":"string"}},{"name":"proj","in":"path","description":"Project code or wire id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddMemberRequest"}}},"required":true},"responses":{"200":{"description":"Member added","content":{"application/json":{"schema":{}}}},"400":{"description":"Malformed body or missing identifier","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Caller may not manage members","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Org, project, or user not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Invalid role","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"security":[{"api_key":[]}]}},"/api/orgs/{org}/projects/{proj}/members/{user}":{"put":{"tags":["projects"],"summary":"Update a member's role","description":"Changes a project member's role. Requires the `ManageProjectMembers` permission. 422 on an invalid role.","operationId":"update_member","parameters":[{"name":"org","in":"path","description":"Organization code or wire id","required":true,"schema":{"type":"string"}},{"name":"proj","in":"path","description":"Project code or wire id","required":true,"schema":{"type":"string"}},{"name":"user","in":"path","description":"Member user wire id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateMemberRequest"}}},"required":true},"responses":{"200":{"description":"Role updated","content":{"application/json":{"schema":{}}}},"400":{"description":"Malformed request body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Caller may not manage members","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Org, project, or user not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Invalid role","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"security":[{"api_key":[]}]},"delete":{"tags":["projects"],"summary":"Remove a project member","description":"Removes a member from the project. Requires the `ManageProjectMembers` permission. Idempotent: succeeds whether or not the user was a member.","operationId":"remove_member","parameters":[{"name":"org","in":"path","description":"Organization code or wire id","required":true,"schema":{"type":"string"}},{"name":"proj","in":"path","description":"Project code or wire id","required":true,"schema":{"type":"string"}},{"name":"user","in":"path","description":"Member user wire id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Member removed (or already absent)"},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Caller may not manage members","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Organization or project not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"security":[{"api_key":[]}]}},"/api/orgs/{org}/projects/{proj}/networks":{"get":{"tags":["networks"],"summary":"List a project's network","description":"Returns the project's isolated network (VNI, subnets, members) as a list of zero or one entry. Requires the `ReadProject` permission.","operationId":"list_project_networks","parameters":[{"name":"org","in":"path","description":"Organization code or wire id","required":true,"schema":{"type":"string"}},{"name":"proj","in":"path","description":"Project code or wire id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The project's network (0 or 1 entry)","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Caller may not read this project","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Organization or project not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"security":[{"api_key":[]}]}},"/api/orgs/{org}/projects/{proj}/pools/":{"get":{"tags":["pools"],"summary":"List a project's pools","description":"Returns the project's live pools as a paginated envelope. Requires the `ListProjectRequests` permission.","operationId":"list_project_pools","parameters":[{"name":"org","in":"path","description":"Organization code or wire id","required":true,"schema":{"type":"string"}},{"name":"proj","in":"path","description":"Project code or wire id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Paginated pool list","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Caller may not list pools here","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Organization or project not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"security":[{"api_key":[]}]},"post":{"tags":["pools"],"summary":"Create or reconfigure a pool","description":"Creates a pool provisioning request (name, size, provider, spec, app assignments); a name that already exists is reconfigured at the next request version (201 for a fresh pool, 200 for a reconfigure). Requires the `CreateRequest` permission; core pools require system membership. Sensitive app params are tokenized server-side.","operationId":"create_pool","parameters":[{"name":"org","in":"path","description":"Organization code or wire id","required":true,"schema":{"type":"string"}},{"name":"proj","in":"path","description":"Project code or wire id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePoolRequest"}}},"required":true},"responses":{"200":{"description":"Existing pool reconfigured","content":{"application/json":{"schema":{}}}},"201":{"description":"Pool created","content":{"application/json":{"schema":{}}}},"400":{"description":"Malformed pool request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Caller may not create requests here","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Organization or project not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Pool is being removed; retry later","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Invalid name, provider, spec, or app param","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Secret replication lacked quorum; retry","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"security":[{"api_key":[]}]}},"/api/orgs/{org}/projects/{proj}/pools/{pool}":{"get":{"tags":["pools"],"summary":"Get a pool by name","description":"Returns one live pool addressed by name within the project. Requires the `ReadPool` permission.","operationId":"get_project_pool","parameters":[{"name":"org","in":"path","description":"Organization code or wire id","required":true,"schema":{"type":"string"}},{"name":"proj","in":"path","description":"Project code or wire id","required":true,"schema":{"type":"string"}},{"name":"pool","in":"path","description":"Pool name","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The pool","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Caller may not read this pool","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Org, project, or pool not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"security":[{"api_key":[]}]}},"/api/orgs/{org}/projects/{proj}/pools/{pool}/agent-tokens/":{"post":{"tags":["pools"],"summary":"Mint a pool agent-registration token","description":"Issues a short-lived registration token that agents redeem at `/api/agent/connect` to enroll into the pool, plus install-script URLs. Requires the `CreatePoolAgentToken` permission. The pool must accept agent-registered nodes.","operationId":"create_agent_token","parameters":[{"name":"org","in":"path","description":"Organization code or wire id","required":true,"schema":{"type":"string"}},{"name":"proj","in":"path","description":"Project code or wire id","required":true,"schema":{"type":"string"}},{"name":"pool","in":"path","description":"Pool name","required":true,"schema":{"type":"string"}}],"responses":{"201":{"description":"Registration token and install URLs","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Caller may not mint agent tokens","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Org, project, or pool not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Pool does not accept agent-registered nodes","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"security":[{"api_key":[]}]}},"/api/orgs/{org}/projects/{proj}/providers/":{"get":{"tags":["providers"],"summary":"List providers visible to a project","description":"Returns the providers visible from the project: its own project-scoped providers, its org's org-scoped providers, and all zone-scoped providers, with per-resource capacity. Requires the `ListProjectProviders` permission.","operationId":"list_project_providers","parameters":[{"name":"org","in":"path","description":"Organization code or wire id","required":true,"schema":{"type":"string"}},{"name":"proj","in":"path","description":"Project code or wire id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"List of visible providers","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Caller may not list providers here","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Organization or project not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"security":[{"api_key":[]}]}},"/api/pools/{pool}":{"put":{"tags":["pools"],"summary":"Update a pool","description":"Resizes, changes lifecycle state (`active`/`blocked`/`rejected`), and/or reconfigures a pool addressed by id. Supplying any of `provider`, `spec`, or `apps` commits the next request version. Requires the `UpdatePool` permission; core pools require system membership. Returns the updated pool.","operationId":"update_pool","parameters":[{"name":"pool","in":"path","description":"Pool wire id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdatePoolRequest"}}},"required":true},"responses":{"200":{"description":"Updated pool","content":{"application/json":{"schema":{}}}},"400":{"description":"Malformed pool update","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Caller may not update this pool","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Pool not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Update conflicted or state invalid; retry","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Invalid size, state, provider, spec, or app param","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Secret replication lacked quorum; retry","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"security":[{"api_key":[]}]},"delete":{"tags":["pools"],"summary":"Remove a pool","description":"Removes a pool addressed by id. Requires the `DeletePool` permission. Removal completes once all nodes end: 204 when fully removed (idempotent), 202 while removal is still staged.","operationId":"delete_pool","parameters":[{"name":"pool","in":"path","description":"Pool wire id","required":true,"schema":{"type":"string"}}],"responses":{"202":{"description":"Removal staged; completing as nodes end","content":{"application/json":{"schema":{}}}},"204":{"description":"Pool removed"},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Caller may not delete this pool","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Pool not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Removal conflicted; retry","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"security":[{"api_key":[]}]}},"/api/pools/{pool}/requests/{version}":{"get":{"tags":["pools"],"summary":"Get a pool request version","description":"Returns one historical request version of a pool (provider, spec, apps). Requires the `ReadPool` permission.","operationId":"get_pool_request","parameters":[{"name":"pool","in":"path","description":"Pool wire id","required":true,"schema":{"type":"string"}},{"name":"version","in":"path","description":"Request version number","required":true,"schema":{"type":"integer","format":"int64","minimum":0}}],"responses":{"200":{"description":"The request version","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Caller may not read this pool","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Pool or request version not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"security":[{"api_key":[]}]}},"/api/pools/{pool}/requests/{version}/nodes":{"get":{"tags":["pools"],"summary":"List nodes for a pool request version","description":"Returns the nodes provisioned under a pool's request version as a paginated envelope. Requires the `ListPoolNodes` permission.","operationId":"list_pool_request_nodes","parameters":[{"name":"pool","in":"path","description":"Pool wire id","required":true,"schema":{"type":"string"}},{"name":"version","in":"path","description":"Request version number","required":true,"schema":{"type":"integer","format":"int64","minimum":0}}],"responses":{"200":{"description":"Paginated node list","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Caller may not list this pool's nodes","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Pool or request version not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"security":[{"api_key":[]}]}},"/api/support/issues":{"post":{"tags":["support"],"summary":"File a support request","description":"Validates a support request from any authenticated user and durably queues it for asynchronous delivery as a tracked GitHub issue. Returns immediately with an acknowledgement; the issue is created later by the outbox handler. Requires a configured GitHub client (otherwise 503).","operationId":"create_issue","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupportRequest"}}},"required":true},"responses":{"200":{"description":"Request accepted and queued","content":{"application/json":{"schema":{}}}},"400":{"description":"Malformed request body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"GitHub is not configured","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"security":[{"api_key":[]}]}},"/api/users/{user}":{"get":{"tags":["users"],"summary":"Get a user","description":"Returns the target user's profile. Callable by the user themselves or a system administrator (`ReadUser`).","operationId":"get_user","parameters":[{"name":"user","in":"path","description":"User wire id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The user profile","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Caller may not read this user","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"User not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"security":[{"api_key":[]}]}},"/api/users/{user}/api-keys/":{"get":{"tags":["users"],"summary":"List a user's API keys","description":"Returns the target user's API key metadata (never the secret tokens) as a paginated envelope. Callable by the user themselves or a system administrator (`ListUserApiKeys`).","operationId":"list_api_keys","parameters":[{"name":"user","in":"path","description":"User wire id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Paginated API key metadata","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Caller may not list this user's keys","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"User not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"security":[{"api_key":[]}]},"post":{"tags":["users"],"summary":"Create an API key","description":"Mints a new API key for the target user, optionally with a purpose label and an expiry duration (`30m`, `12h`, `7d`). The plaintext token is returned once. Callable by the user themselves or a system administrator (`CreateUserApiKey`).","operationId":"create_api_key","parameters":[{"name":"user","in":"path","description":"User wire id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApiKeyRequest"}}},"required":true},"responses":{"201":{"description":"The created key, including its one-time token","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Caller may not create keys for this user","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"User not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Invalid expiry duration","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"security":[{"api_key":[]}]}},"/api/users/{user}/api-keys/{apikey}":{"delete":{"tags":["users"],"summary":"Delete an API key","description":"Revokes one of the target user's API keys by its numeric id. Callable by the user themselves or a system administrator (`DeleteUserApiKey`).","operationId":"delete_api_key","parameters":[{"name":"user","in":"path","description":"User wire id","required":true,"schema":{"type":"string"}},{"name":"apikey","in":"path","description":"Numeric API key id","required":true,"schema":{"type":"integer","format":"int32","minimum":0}}],"responses":{"200":{"description":"Key revoked","content":{"application/json":{"schema":{}}}},"400":{"description":"Malformed api key id","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Caller may not delete this user's keys","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"User not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"security":[{"api_key":[]}]}},"/api/users/{user}/nodes/":{"get":{"tags":["users"],"summary":"List a user's nodes","description":"Returns the nodes in projects the target user can access, as a paginated envelope. Callable by the user themselves or a system administrator (`ReadUser`).","operationId":"list_user_nodes","parameters":[{"name":"user","in":"path","description":"User wire id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Paginated node list","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Caller may not read this user","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"User not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"security":[{"api_key":[]}]}},"/api/users/{user}/orgs/":{"get":{"tags":["users"],"summary":"List a user's organizations","description":"Returns the organizations the target user can see, as a paginated envelope. Callable by the user themselves or a system administrator (`ReadUser`).","operationId":"list_user_orgs","parameters":[{"name":"user","in":"path","description":"User wire id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Paginated organization list","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Caller may not read this user","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"User not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"security":[{"api_key":[]}]}},"/api/users/{user}/pools/":{"get":{"tags":["users"],"summary":"List a user's pools","description":"Returns the pools the target user can see, as a paginated envelope. Callable by the user themselves or a system administrator (`ReadUser`).","operationId":"list_user_pools","parameters":[{"name":"user","in":"path","description":"User wire id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Paginated pool list","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Caller may not read this user","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"User not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"security":[{"api_key":[]}]}},"/api/users/{user}/projects/":{"get":{"tags":["users"],"summary":"List a user's projects","description":"Returns the projects across the target user's visible organizations, as a paginated envelope. Callable by the user themselves or a system administrator (`ReadUser`).","operationId":"list_user_projects","parameters":[{"name":"user","in":"path","description":"User wire id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Paginated project list","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Caller may not read this user","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"User not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"security":[{"api_key":[]}]}}},"components":{"schemas":{"AddMemberRequest":{"type":"object","properties":{"email":{"type":["string","null"],"description":"Target member by email (resolved to a user); one of `email` or `user_id`."},"role":{"type":"string","description":"Project role to grant."},"user_id":{"type":["string","null"],"description":"Target member by user wire id; one of `email` or `user_id`."}}},"AppRef":{"type":"object","required":["name"],"properties":{"name":{"type":"string","description":"App repository name (bare, or scoped like `org/app`)."},"version":{"type":["string","null"],"description":"Optional version/tag; defaults to the app's `default`."}}},"AppsConfigureRequest":{"type":"object","description":"wire-compatible body: `action` omitted means save.","required":["app"],"properties":{"action":{"type":["string","null"],"description":"`save` (default), `reset`, or `refresh_versions`."},"app":{"$ref":"#/components/schemas/AppRef","description":"The app this configuration targets."},"disabled":{"type":["boolean","null"],"description":"Whether the app is disabled at this scope."},"locked":{"type":"array","items":{"type":"string"},"description":"Parameter names locked at this scope."},"params":{"type":"object","description":"Default parameter values; sensitive values are tokenized server-side.","additionalProperties":{},"propertyNames":{"type":"string"}}}},"ChangeScopeRequest":{"type":"object","required":["scope"],"properties":{"scope":{"type":"string","description":"Target visibility scope: `project`, `org`, or `zone`.","example":"org"}}},"ConnectRequest":{"type":"object","required":["agent","public_key"],"properties":{"agent":{"description":"Opaque agent metadata: hostname, hardware facts, and the local `ip` the agent\nuses for its outbound connection to the server."},"node_id":{"type":["string","null"],"description":"Rebind to an existing node after restart; never creates a node."},"public_key":{"type":"string","description":"base64url raw 32-byte ed25519 public key; the node identity for possession proofs."}}},"CreateApiKeyRequest":{"type":"object","properties":{"expiry":{"type":["string","null"],"description":"Optional lifetime as a duration like `30m`, `12h`, or `7d`."},"purpose":{"type":["string","null"],"description":"Optional label for the key (defaults to `api`)."}}},"CreatePoolRequest":{"type":"object","required":["pool","size","provider"],"properties":{"apps":{"description":"App assignments; sensitive params are tokenized server-side."},"pool":{"type":"string","description":"DNS-label pool name (1-63 lowercase letters, digits, dashes; must not end\nin `-<digits>`, which is reserved for slot names)."},"provider":{"type":"string","description":"Provider: a built-in type, a visible provider name, or a provider pool id."},"size":{"type":"integer","format":"int64","description":"Desired node count (0 for non-scalable providers).","minimum":0},"spec":{"description":"Provider-specific spec object."}}},"CreateProjectRequest":{"type":"object","required":["name","code"],"properties":{"code":{"type":"string","description":"DNS-label code (lowercase letters, digits, dashes)."},"name":{"type":"string","description":"Display name (1-80 characters)."}}},"LoginRequest":{"type":"object","required":["email","password"],"properties":{"email":{"type":"string","description":"Account email address."},"next":{"type":["string","null"],"description":"Optional post-login redirect target (browser flow only)."},"password":{"type":"string","description":"Account password."}}},"LoginWelcomeBody":{"type":"object","required":["login_welcome_html"],"properties":{"login_welcome_html":{"type":"string","description":"Operator-supplied login welcome HTML (sanitized server-side)."}}},"PortalRequest":{"type":"object","properties":{"customer_id":{"type":["string","null"],"description":"Stripe customer ID to open the billing portal for."},"org_code":{"type":["string","null"],"description":"Organization code that scopes authorization."},"return_url":{"type":["string","null"],"description":"URL Stripe returns the user to after the portal session."}}},"PrefixRequest":{"type":"object","required":["prefix"],"properties":{"kind":{"type":"string","description":"`allocatable` (default) or `reserved`."},"prefix":{"type":"string","description":"IPv4 CIDR prefix to add or remove, e.g. `10.20.0.0/16`."}}},"Problem":{"type":"object","description":"Schema mirror of [`orc::Problem`] (RFC 9457 Problem Details). The real type lives\nin the `orc` crate, which cannot derive `ToSchema` without taking a utoipa\ndependency; this mirror registers under the component name `Problem` and is the\nbody schema every error response references. Keep the fields in sync with\n`orc::Problem`.","required":["type","title","status","detail","errors"],"properties":{"current":{"type":["integer","null"],"format":"int64","description":"Current resource usage for `urn:orc:limit` problems."},"detail":{"type":"string","description":"Human-readable explanation specific to this occurrence."},"errors":{"type":"object","description":"Field-level validation errors, keyed by field name.","additionalProperties":{"type":"string"},"propertyNames":{"type":"string"}},"instance":{"type":["string","null"],"description":"URI reference identifying this specific occurrence."},"limit":{"type":["integer","null"],"format":"int64","description":"Configured resource limit for `urn:orc:limit` problems."},"resource":{"type":["string","null"],"description":"Limited resource name for `urn:orc:limit` problems."},"status":{"type":"integer","format":"int32","description":"HTTP status code for this occurrence.","minimum":0},"title":{"type":"string","description":"Short human-readable summary of the problem type."},"type":{"type":"string","description":"URI reference identifying the problem type; `about:blank` when generic."}}},"RegistrationPolicyBody":{"type":"object","required":["user_registration_enabled"],"properties":{"user_registration_enabled":{"type":"boolean","description":"Whether public self-registration is open in this zone."}}},"SetStrategyRequest":{"type":"object","required":["provider_id","strategy_type"],"properties":{"params":{"description":"Strategy-specific parameters (shape depends on `strategy_type`)."},"provider_id":{"type":"string","description":"Provider pool ID (`p_…`) the strategy applies to."},"strategy_type":{"type":"string","description":"Strategy discriminant, e.g. `flat` or `none`."}}},"SignupRequest":{"type":"object","required":["email","password"],"properties":{"email":{"type":"string","description":"Email address to register."},"name":{"type":["string","null"],"description":"Optional display name; defaults to the email local part."},"password":{"type":"string","description":"Password (8-128 characters)."}}},"SupportRequest":{"type":"object","properties":{"description":{"type":"string","description":"Body of the request (20–5000 characters)."},"kind":{"type":"string","description":"Issue kind: `bug` or `feature`."},"org_code":{"type":"string","description":"Optional organization code for context."},"project_code":{"type":"string","description":"Project code the request relates to (required; reported as `project`)."},"title":{"type":"string","description":"Short title (5–120 characters)."}}},"UpdateAccountRequest":{"type":"object","properties":{"billing_interval":{"type":["string","null"],"description":"Billing interval; updates are not yet supported (rejected with 400)."},"plan":{"type":["string","null"],"description":"New plan to switch the account to (e.g. `demo`, `standard`)."}}},"UpdateMemberRequest":{"type":"object","required":["role"],"properties":{"role":{"type":"string","description":"New project role."}}},"UpdatePoolRequest":{"type":"object","properties":{"apps":{"description":"New app assignments (presence triggers a reconfigure)."},"provider":{"type":["string","null"],"description":"New provider (presence triggers a reconfigure)."},"reason":{"type":"string","description":"Human-readable reason for a state change."},"size":{"type":["integer","null"],"format":"int64","description":"New desired node count.","minimum":0},"spec":{"description":"New provider spec (presence triggers a reconfigure)."},"state":{"type":["string","null"],"description":"Lifecycle state: `active`, `blocked`, or `rejected`."}}},"UpdateProjectRequest":{"type":"object","required":["name","code"],"properties":{"code":{"type":"string","description":"New DNS-label code (lowercase letters, digits, dashes)."},"name":{"type":"string","description":"New display name (1-80 characters)."}}}},"securitySchemes":{"api_key":{"type":"http","scheme":"bearer","description":"Bearer API key issued from a user's API keys, or a session-derived token."}}},"tags":[{"name":"auth","description":"Sign in, sign up, and read the current user."},{"name":"nodes","description":"Node inventory, live logs, interactive terminals, and termination."},{"name":"orgs","description":"Organization identity and resource limits."},{"name":"projects","description":"Projects within an organization and their memberships."},{"name":"pools","description":"Pool provisioning requests: create, reconfigure, resize, and remove."},{"name":"providers","description":"Infrastructure providers visible to a project and their visibility scope."},{"name":"networks","description":"Per-organization address plans and per-project networks."},{"name":"users","description":"User profiles, API keys, and the resources a user can see."},{"name":"appconfigs","description":"Scoped application configuration at zone, org, and project scope."},{"name":"downloads","description":"Public catalog of files published for download by this zone."},{"name":"billing","description":"Per-organization billing accounts, invoices, and the billing cycle."},{"name":"support","description":"File support requests as tracked issues."}]}