{"openapi":"3.1.0","info":{"title":"oi API","version":"0.1.0","summary":"API for publishing Sites to live URLs, plus Drives, Site Data, analytics, profiles, and domains.","description":"DEPLOYMENT AVAILABILITY. This is a self-hosted oi deployment, and it implements 42 of the 90 operations below. The full contract is published here on purpose — it is the shape this deployment targets, and removing operations would hide the target — so every operation additionally declares whether this deployment answers it.\n\nRead \"x-oi-availability\" on each operation before planning a call. It is one of: \"available\" (42 operations — routed and answered here), \"planned\" (36 — defined by the contract, not implemented here yet), \"unavailable\" (12 — defined by the contract and impossible on this deployment; custom hostnames need certificates it cannot provision). \"x-oi-available\" repeats the same fact as a boolean, and \"x-oi-note\" explains it in one sentence.\n\nCalling a \"planned\" or \"unavailable\" operation returns HTTP 404 with code \"not_found\" and details.reason \"operation_not_available_on_deployment\" — distinct from a mistyped path, which returns \"API route not found\". Do not retry either. The current list is also served as prose at https://oi.mrdk.io/docs#availability.\n\n\"Available\" is not \"identical\". Where this deployment handles a FIELD differently from the contract, or requires a PRECONDITION the schema does not express, the operation additionally carries \"x-oi-divergences\": a list of {scope, target, kind, note}, with scope one of field/header/response/precondition and kind one of ignored, rejected, omitted, conditional, derived, required. The same text is prefixed to the operation description. An operation with no such list behaves as the contract describes; the declared request and response schemas are never edited to say otherwise.\n\noi lets agents publish static Sites to live URLs. The API also covers private Drive storage, Site Data, analytics, profiles, domains, and variables. This OpenAPI spec covers stable public API routes and intentionally excludes admin/internal endpoints.","contact":{"email":"hi@oi.mrdk.io","url":"https://oi.mrdk.io"}},"servers":[{"url":"https://oi.mrdk.io"}],"externalDocs":{"description":"Canonical oi docs","url":"https://oi.mrdk.io/docs"},"tags":[{"name":"Auth","description":"Agent-assisted sign-in and API key creation."},{"name":"Sites","description":"Publish, update, finalize, query, and manage hosted Sites."},{"name":"Site Data","description":"Owner-authenticated access to built-in Site Data records."},{"name":"Analytics","description":"Paid-plan Site and account analytics rollups."},{"name":"Profiles","description":"Public profile settings and profile-listed Sites."},{"name":"Drives","description":"Private cloud storage for agent files."},{"name":"Domains","description":"Custom domains, subdomain handles, and links."},{"name":"Workspaces","description":"Shared team accounts: creation, membership, invites, auto-join domain rules, and workspace Site labels. Target a workspace on other endpoints with the X-Oi-Account selector."},{"name":"Variables","description":"Account service variables for proxy routes."},{"name":"Support","description":"Authenticated support requests."}],"paths":{"/api/auth/agent/request-code":{"post":{"tags":["Auth"],"operationId":"requestAgentAuthCode","summary":"Request an email sign-in code","description":"Starts the agent-assisted API key flow by emailing a one-time code to the user.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentAuthRequestCodeRequest"}}}},"responses":{"200":{"description":"Code sent","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentAuthRequestCodeResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"available","x-oi-available":true,"x-oi-note":"Implemented and answered by this deployment."}},"/api/auth/agent/verify-code":{"post":{"tags":["Auth"],"operationId":"verifyAgentAuthCode","summary":"Verify an email code and receive an API key","description":"Completes agent-assisted sign-in. If the email is new, the account is created.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentAuthVerifyCodeRequest"}}}},"responses":{"200":{"description":"API key issued","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentAuthVerifyCodeResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"available","x-oi-available":true,"x-oi-note":"Implemented and answered by this deployment."}},"/api/v1/publish":{"post":{"tags":["Sites"],"operationId":"createSite","summary":"Create a Site","description":"[DIFFERS FROM THE CONTRACT INSIDE THIS OPERATION]\n- field `ttlSeconds` (conditional): Honored only on an authenticated create. An anonymous create ignores it and expires 24 hours after creation regardless.\n- response `expiresAt` (omitted): Absent from an authenticated create response even when ttlSeconds set an expiry; the expiry is applied. Read it back from GET /api/v1/publish/{slug}.\n- field `account` (rejected): There are no workspaces here. A selector naming any account other than the caller's personal one answers 404 account_not_found instead of publishing there.\n\nCreates a pending Site version and returns presigned upload URLs. Optional displayName and displayDescription set owner-facing Site metadata. Anonymous requests are allowed and create temporary Sites that expire after 24 hours.","security":[{},{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishCreateRequest"}}}},"responses":{"200":{"description":"Pending Site created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishCreateResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"available","x-oi-available":true,"x-oi-note":"Implemented here, with 3 documented differences inside the operation — ttlSeconds (conditional); expiresAt (omitted); account (rejected). Read \"x-oi-divergences\" before relying on those fields.","x-oi-divergences":[{"scope":"field","target":"ttlSeconds","kind":"conditional","note":"Honored only on an authenticated create. An anonymous create ignores it and expires 24 hours after creation regardless."},{"scope":"response","target":"expiresAt","kind":"omitted","note":"Absent from an authenticated create response even when ttlSeconds set an expiry; the expiry is applied. Read it back from GET /api/v1/publish/{slug}."},{"scope":"field","target":"account","kind":"rejected","note":"There are no workspaces here. A selector naming any account other than the caller's personal one answers 404 account_not_found instead of publishing there."}]}},"/api/v1/publishes":{"get":{"tags":["Sites"],"operationId":"listSites","summary":"List account Sites","description":"[DIFFERS FROM THE CONTRACT INSIDE THIS OPERATION]\n- response `ownership / sharedSource / workspace` (ignored): Present under scope=all to keep the response shape, and constant here: ownership is always \"owned\", sharedSource always null, workspace always null. There is no sharing and no workspace on this deployment, so branching on them is dead code. primaryUrl always equals siteUrl for the same reason.\n\nWithout scope, lists the selected account's Sites (personal by default; a workspace with X-Oi-Account). With scope=all, lists everything the caller can see across their personal account, accepted shared Sites, and all joined workspaces — cursor-paginated, with ownership/workspace annotations per row. scope=all cannot be combined with an account selector.","security":[{"bearerAuth":[]}],"parameters":[{"name":"scope","in":"query","required":false,"description":"Set to all to merge Sites across the caller's personal account, accepted shared Sites, and joined workspaces.","schema":{"type":"string","enum":["all"]}},{"name":"limit","in":"query","required":false,"description":"scope=all only: page size (default 20, max 100).","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"cursor","in":"query","required":false,"description":"scope=all only: opaque cursor from a previous response's nextCursor.","schema":{"type":"string"}}],"responses":{"200":{"description":"Sites","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishListResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"available","x-oi-available":true,"x-oi-note":"Implemented here, with 1 documented difference inside the operation — ownership / sharedSource / workspace (ignored). Read \"x-oi-divergences\" before relying on those fields.","x-oi-divergences":[{"scope":"response","target":"ownership / sharedSource / workspace","kind":"ignored","note":"Present under scope=all to keep the response shape, and constant here: ownership is always \"owned\", sharedSource always null, workspace always null. There is no sharing and no workspace on this deployment, so branching on them is dead code. primaryUrl always equals siteUrl for the same reason."}]}},"/api/v1/analytics":{"get":{"tags":["Analytics"],"operationId":"getAccountAnalytics","summary":"Get account analytics","description":"[NOT IMPLEMENTED ON THIS DEPLOYMENT] No request analytics are collected or served here. There is no data behind this operation to return.\n\nReturns aggregate analytics across all Sites owned by the authenticated paid account.","security":[{"bearerAuth":[]}],"parameters":[{"name":"range","in":"query","required":false,"description":"Analytics time range. Defaults to 30d when omitted or invalid.","schema":{"$ref":"#/components/schemas/AnalyticsRange"}}],"responses":{"200":{"description":"Account analytics","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountAnalyticsResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"planned","x-oi-available":false,"x-oi-note":"No request analytics are collected or served here. There is no data behind this operation to return."}},"/api/v1/publishes/search":{"get":{"tags":["Sites"],"operationId":"searchSites","summary":"Search account Sites","description":"[NOT IMPLEMENTED ON THIS DEPLOYMENT] Owner Site search is not implemented here. List Sites with GET /api/v1/publishes and filter client-side.\n\nSearches the authenticated user's active owned Sites by slug, URL/domain, viewer metadata, file path, and indexed text content. Password-protected Sites are included for the owner because search reads stored publish files, not public URLs. Set includeShared=1 to also search accepted/opened Sites shared with the authenticated account.","security":[{"bearerAuth":[]}],"parameters":[{"name":"q","in":"query","required":true,"description":"Search query. Uses Postgres websearch syntax with the simple text search configuration.","schema":{"type":"string","minLength":1}},{"name":"limit","in":"query","required":false,"description":"Maximum results to return. Defaults to 20 and is capped at 100.","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"cursor","in":"query","required":false,"description":"Opaque pagination cursor returned as nextCursor from a previous response.","schema":{"type":"string"}},{"name":"includeShared","in":"query","required":false,"description":"When set to 1, include accepted/opened Sites shared with the authenticated account.","schema":{"type":"string","enum":["1"]}}],"responses":{"200":{"description":"Search results","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SiteSearchResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"planned","x-oi-available":false,"x-oi-note":"Owner Site search is not implemented here. List Sites with GET /api/v1/publishes and filter client-side."}},"/api/v1/publishes/{slug}/analytics":{"get":{"tags":["Analytics","Sites"],"operationId":"getSiteAnalytics","summary":"Get Site analytics","description":"[NOT IMPLEMENTED ON THIS DEPLOYMENT] No request analytics are collected or served here. There is no data behind this operation to return.\n\nReturns analytics for one Site owned by the authenticated paid account.","security":[{"bearerAuth":[]}],"parameters":[{"name":"slug","in":"path","required":true,"description":"oi Site slug.","schema":{"type":"string","minLength":1}},{"name":"range","in":"query","required":false,"description":"Analytics time range. Defaults to 30d when omitted or invalid.","schema":{"$ref":"#/components/schemas/AnalyticsRange"}}],"responses":{"200":{"description":"Site analytics","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SiteAnalyticsResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"planned","x-oi-available":false,"x-oi-note":"No request analytics are collected or served here. There is no data behind this operation to return."}},"/api/v1/publishes/{slug}/data/{collection}":{"get":{"tags":["Site Data","Sites"],"operationId":"listSiteDataRecords","summary":"List Site Data records","description":"[DIFFERS FROM THE CONTRACT INSIDE THIS OPERATION]\n- precondition `collection declared in .oi/data.json` (required): The collection must be declared in the Site's published manifest: an undeclared collection is 404, and a manifest that does not compile makes every record operation 409 until it is fixed. See /docs#sitedata-manifest.\n- precondition `Site is account-owned` (required): An anonymous Site stores no records however good its manifest is, and the two tiers refuse differently: the Site's own in-page endpoints answer 403 account_required, while this owner API answers 404 for that slug, because an unclaimed Site is invisible on the account surfaces. Claim it with POST /api/v1/publish/{slug}/claim first.\n\nLists active records in one Site Data collection for a Site owned by the authenticated account. For workspace-owned Sites, pass X-Oi-Account; the original publisher or a workspace admin can manage records. This is the central owner API; browser pages usually use the Site-local /.oi/data/:collection endpoint instead.","security":[{"bearerAuth":[]}],"parameters":[{"name":"slug","in":"path","required":true,"description":"oi Site slug.","schema":{"type":"string","minLength":1}},{"name":"collection","in":"path","required":true,"description":"Site Data collection name from the Site's .oi/data.json manifest.","schema":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[a-z][a-z0-9_]*$"}},{"name":"limit","in":"query","required":false,"description":"Maximum records to return. Defaults to 50 and is capped at 100.","schema":{"type":"integer","minimum":1,"maximum":100,"default":50}},{"name":"cursor","in":"query","required":false,"description":"Opaque pagination cursor returned as nextCursor from a previous response.","schema":{"type":"string"}}],"responses":{"200":{"description":"Site Data records","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SiteDataRecordListResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"available","x-oi-available":true,"x-oi-note":"Implemented here, with 2 documented differences inside the operation — collection declared in .oi/data.json (required); Site is account-owned (required). Read \"x-oi-divergences\" before relying on those fields.","x-oi-divergences":[{"scope":"precondition","target":"collection declared in .oi/data.json","kind":"required","note":"The collection must be declared in the Site's published manifest: an undeclared collection is 404, and a manifest that does not compile makes every record operation 409 until it is fixed. See /docs#sitedata-manifest."},{"scope":"precondition","target":"Site is account-owned","kind":"required","note":"An anonymous Site stores no records however good its manifest is, and the two tiers refuse differently: the Site's own in-page endpoints answer 403 account_required, while this owner API answers 404 for that slug, because an unclaimed Site is invisible on the account surfaces. Claim it with POST /api/v1/publish/{slug}/claim first."}]},"post":{"tags":["Site Data","Sites"],"operationId":"createSiteDataRecord","summary":"Create a Site Data record","description":"[DIFFERS FROM THE CONTRACT INSIDE THIS OPERATION]\n- precondition `collection declared in .oi/data.json` (required): The collection must be declared in the Site's published manifest: an undeclared collection is 404, and a manifest that does not compile makes every record operation 409 until it is fixed. See /docs#sitedata-manifest.\n- precondition `Site is account-owned` (required): An anonymous Site stores no records however good its manifest is, and the two tiers refuse differently: the Site's own in-page endpoints answer 403 account_required, while this owner API answers 404 for that slug, because an unclaimed Site is invisible on the account surfaces. Claim it with POST /api/v1/publish/{slug}/claim first.\n\nCreates one record in a Site Data collection for a Site owned by the authenticated account. For workspace-owned Sites, pass X-Oi-Account; the original publisher or a workspace admin can manage records. The request body is validated against the collection schema.","security":[{"bearerAuth":[]}],"parameters":[{"name":"slug","in":"path","required":true,"description":"oi Site slug.","schema":{"type":"string","minLength":1}},{"name":"collection","in":"path","required":true,"description":"Site Data collection name from the Site's .oi/data.json manifest.","schema":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[a-z][a-z0-9_]*$"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Optional key for retry-safe record creation. Keys are scoped to the account, Site, and collection for a short window.","schema":{"type":"string","minLength":1,"maxLength":200}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SiteDataRecordInput"}}}},"responses":{"201":{"description":"Record created. Idempotent replays also return 201.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SiteDataRecordResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"available","x-oi-available":true,"x-oi-note":"Implemented here, with 2 documented differences inside the operation — collection declared in .oi/data.json (required); Site is account-owned (required). Read \"x-oi-divergences\" before relying on those fields.","x-oi-divergences":[{"scope":"precondition","target":"collection declared in .oi/data.json","kind":"required","note":"The collection must be declared in the Site's published manifest: an undeclared collection is 404, and a manifest that does not compile makes every record operation 409 until it is fixed. See /docs#sitedata-manifest."},{"scope":"precondition","target":"Site is account-owned","kind":"required","note":"An anonymous Site stores no records however good its manifest is, and the two tiers refuse differently: the Site's own in-page endpoints answer 403 account_required, while this owner API answers 404 for that slug, because an unclaimed Site is invisible on the account surfaces. Claim it with POST /api/v1/publish/{slug}/claim first."}]}},"/api/v1/publishes/{slug}/data/{collection}/{recordId}":{"get":{"tags":["Site Data","Sites"],"operationId":"getSiteDataRecord","summary":"Get a Site Data record","description":"[DIFFERS FROM THE CONTRACT INSIDE THIS OPERATION]\n- precondition `collection declared in .oi/data.json` (required): The collection must be declared in the Site's published manifest: an undeclared collection is 404, and a manifest that does not compile makes every record operation 409 until it is fixed. See /docs#sitedata-manifest.\n- precondition `Site is account-owned` (required): An anonymous Site stores no records however good its manifest is, and the two tiers refuse differently: the Site's own in-page endpoints answer 403 account_required, while this owner API answers 404 for that slug, because an unclaimed Site is invisible on the account surfaces. Claim it with POST /api/v1/publish/{slug}/claim first.\n\nReturns one active record from a Site Data collection for a Site owned by the authenticated account.","security":[{"bearerAuth":[]}],"parameters":[{"name":"slug","in":"path","required":true,"description":"oi Site slug.","schema":{"type":"string","minLength":1}},{"name":"collection","in":"path","required":true,"description":"Site Data collection name from the Site's .oi/data.json manifest.","schema":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[a-z][a-z0-9_]*$"}},{"name":"recordId","in":"path","required":true,"description":"Site Data record id.","schema":{"type":"string","pattern":"^rec_[0-9A-HJKMNP-TV-Z]{26}$"}}],"responses":{"200":{"description":"Site Data record","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SiteDataRecordResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"available","x-oi-available":true,"x-oi-note":"Implemented here, with 2 documented differences inside the operation — collection declared in .oi/data.json (required); Site is account-owned (required). Read \"x-oi-divergences\" before relying on those fields.","x-oi-divergences":[{"scope":"precondition","target":"collection declared in .oi/data.json","kind":"required","note":"The collection must be declared in the Site's published manifest: an undeclared collection is 404, and a manifest that does not compile makes every record operation 409 until it is fixed. See /docs#sitedata-manifest."},{"scope":"precondition","target":"Site is account-owned","kind":"required","note":"An anonymous Site stores no records however good its manifest is, and the two tiers refuse differently: the Site's own in-page endpoints answer 403 account_required, while this owner API answers 404 for that slug, because an unclaimed Site is invisible on the account surfaces. Claim it with POST /api/v1/publish/{slug}/claim first."}]},"patch":{"tags":["Site Data","Sites"],"operationId":"patchSiteDataRecord","summary":"Patch a Site Data record","description":"[DIFFERS FROM THE CONTRACT INSIDE THIS OPERATION]\n- precondition `collection declared in .oi/data.json` (required): The collection must be declared in the Site's published manifest: an undeclared collection is 404, and a manifest that does not compile makes every record operation 409 until it is fixed. See /docs#sitedata-manifest.\n- precondition `Site is account-owned` (required): An anonymous Site stores no records however good its manifest is, and the two tiers refuse differently: the Site's own in-page endpoints answer 403 account_required, while this owner API answers 404 for that slug, because an unclaimed Site is invisible on the account surfaces. Claim it with POST /api/v1/publish/{slug}/claim first.\n\nMerges submitted fields into an existing Site Data record for a Site owned by the authenticated account. The resulting record is validated against the collection schema.","security":[{"bearerAuth":[]}],"parameters":[{"name":"slug","in":"path","required":true,"description":"oi Site slug.","schema":{"type":"string","minLength":1}},{"name":"collection","in":"path","required":true,"description":"Site Data collection name from the Site's .oi/data.json manifest.","schema":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[a-z][a-z0-9_]*$"}},{"name":"recordId","in":"path","required":true,"description":"Site Data record id.","schema":{"type":"string","pattern":"^rec_[0-9A-HJKMNP-TV-Z]{26}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SiteDataRecordInput"}}}},"responses":{"200":{"description":"Record updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SiteDataRecordResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"available","x-oi-available":true,"x-oi-note":"Implemented here, with 2 documented differences inside the operation — collection declared in .oi/data.json (required); Site is account-owned (required). Read \"x-oi-divergences\" before relying on those fields.","x-oi-divergences":[{"scope":"precondition","target":"collection declared in .oi/data.json","kind":"required","note":"The collection must be declared in the Site's published manifest: an undeclared collection is 404, and a manifest that does not compile makes every record operation 409 until it is fixed. See /docs#sitedata-manifest."},{"scope":"precondition","target":"Site is account-owned","kind":"required","note":"An anonymous Site stores no records however good its manifest is, and the two tiers refuse differently: the Site's own in-page endpoints answer 403 account_required, while this owner API answers 404 for that slug, because an unclaimed Site is invisible on the account surfaces. Claim it with POST /api/v1/publish/{slug}/claim first."}]},"delete":{"tags":["Site Data","Sites"],"operationId":"deleteSiteDataRecord","summary":"Delete a Site Data record","description":"[DIFFERS FROM THE CONTRACT INSIDE THIS OPERATION]\n- precondition `collection declared in .oi/data.json` (required): The collection must be declared in the Site's published manifest: an undeclared collection is 404, and a manifest that does not compile makes every record operation 409 until it is fixed. See /docs#sitedata-manifest.\n- precondition `Site is account-owned` (required): An anonymous Site stores no records however good its manifest is, and the two tiers refuse differently: the Site's own in-page endpoints answer 403 account_required, while this owner API answers 404 for that slug, because an unclaimed Site is invisible on the account surfaces. Claim it with POST /api/v1/publish/{slug}/claim first.\n\nSoft-deletes one active record from a Site Data collection for a Site owned by the authenticated account.","security":[{"bearerAuth":[]}],"parameters":[{"name":"slug","in":"path","required":true,"description":"oi Site slug.","schema":{"type":"string","minLength":1}},{"name":"collection","in":"path","required":true,"description":"Site Data collection name from the Site's .oi/data.json manifest.","schema":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[a-z][a-z0-9_]*$"}},{"name":"recordId","in":"path","required":true,"description":"Site Data record id.","schema":{"type":"string","pattern":"^rec_[0-9A-HJKMNP-TV-Z]{26}$"}}],"responses":{"200":{"description":"Record deleted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SiteDataDeleteResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"available","x-oi-available":true,"x-oi-note":"Implemented here, with 2 documented differences inside the operation — collection declared in .oi/data.json (required); Site is account-owned (required). Read \"x-oi-divergences\" before relying on those fields.","x-oi-divergences":[{"scope":"precondition","target":"collection declared in .oi/data.json","kind":"required","note":"The collection must be declared in the Site's published manifest: an undeclared collection is 404, and a manifest that does not compile makes every record operation 409 until it is fixed. See /docs#sitedata-manifest."},{"scope":"precondition","target":"Site is account-owned","kind":"required","note":"An anonymous Site stores no records however good its manifest is, and the two tiers refuse differently: the Site's own in-page endpoints answer 403 account_required, while this owner API answers 404 for that slug, because an unclaimed Site is invisible on the account surfaces. Claim it with POST /api/v1/publish/{slug}/claim first."}]}},"/api/v1/profile":{"get":{"tags":["Profiles"],"operationId":"getProfile","summary":"Get profile settings","description":"[NOT IMPLEMENTED ON THIS DEPLOYMENT] Public profiles are not implemented here. `finalize` reports `addedToProfile: false` for the same reason.\n\nReturns the authenticated user's public profile settings and Sites shown on the profile.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Profile settings","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProfileResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"planned","x-oi-available":false,"x-oi-note":"Public profiles are not implemented here. `finalize` reports `addedToProfile: false` for the same reason."},"patch":{"tags":["Profiles"],"operationId":"patchProfile","summary":"Update profile settings","description":"[NOT IMPLEMENTED ON THIS DEPLOYMENT] Public profiles are not implemented here. `finalize` reports `addedToProfile: false` for the same reason.\n\nTurns the public profile on or off and controls whether future Sites are added to the profile automatically.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProfileSettingsPatchRequest"}}}},"responses":{"200":{"description":"Profile settings updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProfileResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"planned","x-oi-available":false,"x-oi-note":"Public profiles are not implemented here. `finalize` reports `addedToProfile: false` for the same reason."}},"/api/v1/profile/username":{"patch":{"tags":["Profiles"],"operationId":"patchProfileUsername","summary":"Change profile username","description":"[NOT IMPLEMENTED ON THIS DEPLOYMENT] Public profiles are not implemented here. `finalize` reports `addedToProfile: false` for the same reason.\n\nChanges the authenticated user's profile username and profile URL.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProfileUsernamePatchRequest"}}}},"responses":{"200":{"description":"Profile username updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProfileResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"planned","x-oi-available":false,"x-oi-note":"Public profiles are not implemented here. `finalize` reports `addedToProfile: false` for the same reason."}},"/api/v1/profile/sites":{"get":{"tags":["Profiles"],"operationId":"listProfileSites","summary":"List Sites on profile","description":"[NOT IMPLEMENTED ON THIS DEPLOYMENT] Public profiles are not implemented here. `finalize` reports `addedToProfile: false` for the same reason.\n\nLists the authenticated user's Sites currently shown on their public profile.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Profile Sites","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProfileSitesResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"planned","x-oi-available":false,"x-oi-note":"Public profiles are not implemented here. `finalize` reports `addedToProfile: false` for the same reason."},"post":{"tags":["Profiles"],"operationId":"addProfileSite","summary":"Add Site to profile","description":"[NOT IMPLEMENTED ON THIS DEPLOYMENT] Public profiles are not implemented here. `finalize` reports `addedToProfile: false` for the same reason.\n\nShows an active owned Site on the authenticated user's public profile. Gated Sites (password-protected or restricted access) cannot be shown on a profile and return 409 site_gated. Adding a Site already on the profile is idempotent.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProfileSiteAddRequest"}}}},"responses":{"200":{"description":"Site added to profile","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProfileSitesMutationResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"planned","x-oi-available":false,"x-oi-note":"Public profiles are not implemented here. `finalize` reports `addedToProfile: false` for the same reason."}},"/api/v1/profile/sites/{slug}":{"delete":{"tags":["Profiles"],"operationId":"removeProfileSite","summary":"Remove Site from profile","description":"[NOT IMPLEMENTED ON THIS DEPLOYMENT] Public profiles are not implemented here. `finalize` reports `addedToProfile: false` for the same reason.\n\nRemoves a Site from the authenticated user's public profile without deleting the Site.","security":[{"bearerAuth":[]}],"parameters":[{"name":"slug","in":"path","required":true,"description":"oi Site slug.","schema":{"type":"string","minLength":1}}],"responses":{"200":{"description":"Site removed from profile","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProfileSitesMutationResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"planned","x-oi-available":false,"x-oi-note":"Public profiles are not implemented here. `finalize` reports `addedToProfile: false` for the same reason."}},"/api/v1/publish/{slug}":{"get":{"tags":["Sites"],"operationId":"getSite","summary":"Get Site details","security":[{"bearerAuth":[]}],"parameters":[{"name":"slug","in":"path","required":true,"description":"oi Site slug.","schema":{"type":"string","minLength":1}}],"responses":{"200":{"description":"Site details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishDetailsResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"available","x-oi-available":true,"x-oi-note":"Implemented and answered by this deployment."},"put":{"tags":["Sites"],"operationId":"updateSite","summary":"Update an existing Site","description":"[DIFFERS FROM THE CONTRACT INSIDE THIS OPERATION]\n- field `claimToken` (required): The schema marks it optional, but an unclaimed anonymous Site cannot be updated without it: no Authorization and no claimToken answers 401. An account-owned Site ignores it and takes the bearer key instead.\n- field `ttlSeconds` (conditional): Same rule as create: honored on an authenticated update, ignored on an anonymous one. An update never extends an anonymous Site's expiry either way.\n- field `account` (rejected): There are no workspaces here; a selector naming any other account answers 404 account_not_found.\n- response `expiresAt / anonymous / warning` (omitted): An anonymous CREATE returns these; an anonymous UPDATE does not, so an update response is not where you learn when the Site dies. Keep the expiry from the create response — the update does not change it. claimToken and claimUrl are withheld on purpose: they are issued exactly once.\n\nCreates a pending replacement version for an existing Site. Optional displayName and displayDescription update owner-facing Site metadata. Authenticated Sites require API key ownership. Anonymous Sites require claimToken.","security":[{},{"bearerAuth":[]}],"parameters":[{"name":"slug","in":"path","required":true,"description":"oi Site slug.","schema":{"type":"string","minLength":1}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishCreateRequest"}}}},"responses":{"200":{"description":"Pending Site update created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishCreateResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"410":{"description":"Anonymous Site expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"available","x-oi-available":true,"x-oi-note":"Implemented here, with 4 documented differences inside the operation — claimToken (required); ttlSeconds (conditional); account (rejected); expiresAt / anonymous / warning (omitted). Read \"x-oi-divergences\" before relying on those fields.","x-oi-divergences":[{"scope":"field","target":"claimToken","kind":"required","note":"The schema marks it optional, but an unclaimed anonymous Site cannot be updated without it: no Authorization and no claimToken answers 401. An account-owned Site ignores it and takes the bearer key instead."},{"scope":"field","target":"ttlSeconds","kind":"conditional","note":"Same rule as create: honored on an authenticated update, ignored on an anonymous one. An update never extends an anonymous Site's expiry either way."},{"scope":"field","target":"account","kind":"rejected","note":"There are no workspaces here; a selector naming any other account answers 404 account_not_found."},{"scope":"response","target":"expiresAt / anonymous / warning","kind":"omitted","note":"An anonymous CREATE returns these; an anonymous UPDATE does not, so an update response is not where you learn when the Site dies. Keep the expiry from the create response — the update does not change it. claimToken and claimUrl are withheld on purpose: they are issued exactly once."}]},"delete":{"tags":["Sites"],"operationId":"deleteSite","summary":"Delete a Site","security":[{"bearerAuth":[]}],"parameters":[{"name":"slug","in":"path","required":true,"description":"oi Site slug.","schema":{"type":"string","minLength":1}}],"responses":{"200":{"description":"Deleted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"available","x-oi-available":true,"x-oi-note":"Implemented and answered by this deployment."}},"/api/v1/publish/{slug}/duplicate":{"post":{"tags":["Sites"],"operationId":"duplicateSite","summary":"Duplicate a Site","description":"[DIFFERS FROM THE CONTRACT INSIDE THIS OPERATION]\n- response `thumbnailJobId` (ignored): Returned as a fresh UUID to keep the response shape; no thumbnail is queued, rendered, or served here. It identifies nothing.\n- field `viewer` (ignored): Only title, description and ogImagePath are read, each falling back to the source's value when absent. The contract types viewer as a free-form object; any other key is accepted and ignored.\n- precondition `source has a live version` (required): A Site with only a pending version answers 409; finalize it before duplicating.\n- precondition `access mode of the copy` (derived): Duplicating a GATED Site does not produce an ungated copy here: the copy starts restricted to the caller's own address. Pass {\"access\":\"anyone_with_link\"} to opt out; the response's access block always states what the copy became.\n\nCreates a new Site copying the source Site's files, viewer metadata, and Site Data schema (never records). Password protection, restricted access rules, handle/custom-domain links, and TTL are not copied. For workspace-owned Sites, pass X-Oi-Account: any active member can duplicate a member-visible Site into the same workspace.","security":[{"bearerAuth":[]}],"parameters":[{"name":"slug","in":"path","required":true,"description":"oi Site slug.","schema":{"type":"string","minLength":1}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"viewer":{"type":"object","additionalProperties":true,"description":"Optional viewer metadata override for the copy."}}}}}},"responses":{"200":{"description":"Duplicated Site","content":{"application/json":{"schema":{"type":"object","properties":{"slug":{"type":"string"},"siteUrl":{"type":"string","format":"uri"},"sourceSlug":{"type":"string"},"status":{"type":"string","enum":["active"]},"currentVersionId":{"type":["string","null"]},"addedToProfile":{"type":"boolean"},"filesCount":{"type":"integer"},"thumbnailJobId":{"type":["string","null"]}},"required":["slug","siteUrl","sourceSlug","status","filesCount"]}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"available","x-oi-available":true,"x-oi-note":"Implemented here, with 4 documented differences inside the operation — thumbnailJobId (ignored); viewer (ignored); source has a live version (required); access mode of the copy (derived). Read \"x-oi-divergences\" before relying on those fields.","x-oi-divergences":[{"scope":"response","target":"thumbnailJobId","kind":"ignored","note":"Returned as a fresh UUID to keep the response shape; no thumbnail is queued, rendered, or served here. It identifies nothing."},{"scope":"field","target":"viewer","kind":"ignored","note":"Only title, description and ogImagePath are read, each falling back to the source's value when absent. The contract types viewer as a free-form object; any other key is accepted and ignored."},{"scope":"precondition","target":"source has a live version","kind":"required","note":"A Site with only a pending version answers 409; finalize it before duplicating."},{"scope":"precondition","target":"access mode of the copy","kind":"derived","note":"Duplicating a GATED Site does not produce an ungated copy here: the copy starts restricted to the caller's own address. Pass {\"access\":\"anyone_with_link\"} to opt out; the response's access block always states what the copy became."}]}},"/api/v1/publish/{slug}/finalize":{"post":{"tags":["Sites"],"operationId":"finalizeSiteVersion","summary":"Finalize a pending Site version","description":"[DIFFERS FROM THE CONTRACT INSIDE THIS OPERATION]\n- response `addedToProfile` (ignored): Always false, because public profiles are not implemented here — not a signal that this particular Site was excluded. Do not tell the user their Site was kept off a profile.\n- response `thumbnailJobId` (ignored): Returned as a fresh UUID to keep the response shape, but no thumbnail is queued, rendered, or served here (/api/thumbnails/ answers 404). It identifies nothing: do not poll it or surface it.\n- field `workspaceLabel` (ignored): Accepted and ignored: label URLs belong to workspaces, which do not exist here. The response carries no workspaceLabel and no accountUrl, and no label is reserved.\n\nMakes a pending version live after all files have been uploaded.","security":[{},{"bearerAuth":[]}],"parameters":[{"name":"slug","in":"path","required":true,"description":"oi Site slug.","schema":{"type":"string","minLength":1}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FinalizePublishRequest"}}}},"responses":{"200":{"description":"Version finalized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FinalizePublishResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"available","x-oi-available":true,"x-oi-note":"Implemented here, with 3 documented differences inside the operation — addedToProfile (ignored); thumbnailJobId (ignored); workspaceLabel (ignored). Read \"x-oi-divergences\" before relying on those fields.","x-oi-divergences":[{"scope":"response","target":"addedToProfile","kind":"ignored","note":"Always false, because public profiles are not implemented here — not a signal that this particular Site was excluded. Do not tell the user their Site was kept off a profile."},{"scope":"response","target":"thumbnailJobId","kind":"ignored","note":"Returned as a fresh UUID to keep the response shape, but no thumbnail is queued, rendered, or served here (/api/thumbnails/ answers 404). It identifies nothing: do not poll it or surface it."},{"scope":"field","target":"workspaceLabel","kind":"ignored","note":"Accepted and ignored: label URLs belong to workspaces, which do not exist here. The response carries no workspaceLabel and no accountUrl, and no label is reserved."}]}},"/api/v1/publish/{slug}/versions":{"get":{"tags":["Sites"],"operationId":"listSiteVersions","summary":"List a Site's published versions","description":"[DIFFERS FROM THE CONTRACT INSIDE THIS OPERATION]\n- response `previewUrl / thumbnailUrl` (omitted): Never present on a version row: per-version preview hosts and thumbnails are not served here. Link the Site's own URL after a restore instead of a per-version preview.\n\nReturns the Site's recorded version history, newest first. Every publish, update, console edit, and duplication records a version. Requires ownership of the Site; version history access is included for workspace Sites and requires a paid plan for personal Sites (free accounts' versions are still recorded and unlock on upgrade).","security":[{"bearerAuth":[]}],"parameters":[{"name":"slug","in":"path","required":true,"description":"oi Site slug.","schema":{"type":"string","minLength":1}}],"responses":{"200":{"description":"Version history","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SiteVersionsResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"available","x-oi-available":true,"x-oi-note":"Implemented here, with 1 documented difference inside the operation — previewUrl / thumbnailUrl (omitted). Read \"x-oi-divergences\" before relying on those fields.","x-oi-divergences":[{"scope":"response","target":"previewUrl / thumbnailUrl","kind":"omitted","note":"Never present on a version row: per-version preview hosts and thumbnails are not served here. Link the Site's own URL after a restore instead of a per-version preview."}]}},"/api/v1/publish/{slug}/versions/{versionId}":{"delete":{"tags":["Sites"],"operationId":"deleteSiteVersion","summary":"Permanently delete a recorded version","description":"Removes a historical version's files, snapshot, thumbnail, and history entry — the privacy affordance for content that should no longer be retrievable. The live version cannot be deleted, and restore events (audit history) cannot be deleted. Requires ownership; included for workspace Sites, paid plan for personal Sites.","security":[{"bearerAuth":[]}],"parameters":[{"name":"slug","in":"path","required":true,"description":"oi Site slug.","schema":{"type":"string","minLength":1}},{"name":"versionId","in":"path","required":true,"schema":{"type":"string"},"description":"A content version id from the versions list."}],"responses":{"200":{"description":"Version deleted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteSiteVersionResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"available","x-oi-available":true,"x-oi-note":"Implemented and answered by this deployment."}},"/api/v1/publish/{slug}/versions/{versionId}/restore":{"post":{"tags":["Sites"],"operationId":"restoreSiteVersion","summary":"Restore a recorded version as the live Site","description":"Instantly makes a previously recorded version the live one (a pointer flip — no re-upload). Content, rendering settings, API proxies, and Site Data schema follow the restored version; access mode, password, price, and domains stay as currently configured. The restore is recorded in the version history as a restore event. Rejected while a publish is in flight. Requires ownership; included for workspace Sites, paid plan for personal Sites.","security":[{"bearerAuth":[]}],"parameters":[{"name":"slug","in":"path","required":true,"description":"oi Site slug.","schema":{"type":"string","minLength":1}},{"name":"versionId","in":"path","required":true,"schema":{"type":"string"},"description":"A content version id from the versions list (restore events cannot be restored)."}],"responses":{"200":{"description":"Version restored","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RestoreSiteVersionResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"available","x-oi-available":true,"x-oi-note":"Implemented and answered by this deployment."}},"/api/v1/publish/{slug}/claim":{"post":{"tags":["Sites"],"operationId":"claimAnonymousSite","summary":"Claim an anonymous Site","description":"Transfers an anonymous Site to the authenticated account or browser session using a claim token.","security":[{"bearerAuth":[]}],"parameters":[{"name":"slug","in":"path","required":true,"description":"oi Site slug.","schema":{"type":"string","minLength":1}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClaimSiteRequest"}}}},"responses":{"200":{"description":"Site claimed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClaimSiteResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"410":{"description":"Site deleted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"available","x-oi-available":true,"x-oi-note":"Implemented and answered by this deployment."}},"/api/v1/publish/{slug}/uploads/refresh":{"post":{"tags":["Sites"],"operationId":"refreshSiteUploadUrls","summary":"Refresh upload URLs for a pending Site version","security":[{"bearerAuth":[]}],"parameters":[{"name":"slug","in":"path","required":true,"description":"oi Site slug.","schema":{"type":"string","minLength":1}}],"responses":{"200":{"description":"Upload URLs refreshed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishCreateResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"available","x-oi-available":true,"x-oi-note":"Implemented here, with 1 documented difference inside the operation — authorization (derived). Read \"x-oi-divergences\" before relying on those fields.","x-oi-divergences":[{"scope":"precondition","target":"authorization","kind":"derived","note":"The contract declares bearerAuth only; this deployment also accepts an unclaimed anonymous Site's claimToken (in the body or as ?claimToken=), because that flow otherwise has no way to re-mint its own upload URLs."}],"description":"[DIFFERS FROM THE CONTRACT INSIDE THIS OPERATION]\n- precondition `authorization` (derived): The contract declares bearerAuth only; this deployment also accepts an unclaimed anonymous Site's claimToken (in the body or as ?claimToken=), because that flow otherwise has no way to re-mint its own upload URLs."}},"/api/v1/publish/{slug}/metadata":{"patch":{"tags":["Sites"],"operationId":"patchSiteMetadata","summary":"Patch Site metadata and access controls","description":"Updates owner-facing displayName and displayDescription, TTL, viewer metadata, password protection, and SPA routing for an authenticated Site. Setting a password switches the Site to password access mode (a public link gated by a shared password) and clears restricted email/domain rules. Sending password null removes an existing password and returns the Site to anyone_with_link (public); on a Site without a password it is a no-op and does not change the access mode. Workspace-owned Sites support passwords (publisher-or-admin): workspace members see the Site in their dashboard but enter the password to view it, like any visitor.","security":[{"bearerAuth":[]}],"parameters":[{"name":"slug","in":"path","required":true,"description":"oi Site slug.","schema":{"type":"string","minLength":1}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishMetadataPatchRequest"}}}},"responses":{"200":{"description":"Metadata patched","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishMetadataPatchResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"available","x-oi-available":true,"x-oi-note":"Implemented and answered by this deployment."}},"/api/v1/publish/{slug}/access":{"get":{"tags":["Sites"],"operationId":"getSiteAccess","summary":"Read the Site access policy","description":"Returns the active access mode (anyone_with_link, password, restricted, or account_members), the access policy version, and the restricted email/domain allowlists. Owner only.","security":[{"bearerAuth":[]}],"parameters":[{"name":"slug","in":"path","required":true,"description":"oi Site slug.","schema":{"type":"string","minLength":1}}],"responses":{"200":{"description":"Access policy","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SiteAccessResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"available","x-oi-available":true,"x-oi-note":"Implemented and answered by this deployment."},"patch":{"tags":["Sites"],"operationId":"patchSiteAccess","summary":"Update Site access mode and allowlists","description":"[DIFFERS FROM THE CONTRACT INSIDE THIS OPERATION]\n- field `mode=account_members` (rejected): Answers 409 workspace_access_mode_unsupported: the mode applies to workspace-owned Sites and there are none here. Use anyone_with_link or restricted.\n\nSets link or restricted access for an owned Site. The request replaces the full email and domain allowlists; to add one entry, read the current policy, merge, and write the complete lists back. A successful PATCH switches the Site away from password mode and clears any existing password. Restricted access requires a claimed Site (409 otherwise). To enable password mode, use the metadata endpoint instead (mode password here returns 409). Workspace-owned Sites support anyone_with_link (public), account_members, and password (via the metadata endpoint); restricted in workspace context returns 409 workspace_access_mode_unsupported. When notify is true, invite emails are sent only to exact-email addresses newly added by this request; domain rules never send invite emails.","security":[{"bearerAuth":[]}],"parameters":[{"name":"slug","in":"path","required":true,"description":"oi Site slug.","schema":{"type":"string","minLength":1}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SiteAccessPatchRequest"}}}},"responses":{"200":{"description":"Access policy updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SiteAccessResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"available","x-oi-available":true,"x-oi-note":"Implemented here, with 1 documented difference inside the operation — mode=account_members (rejected). Read \"x-oi-divergences\" before relying on those fields.","x-oi-divergences":[{"scope":"field","target":"mode=account_members","kind":"rejected","note":"Answers 409 workspace_access_mode_unsupported: the mode applies to workspace-owned Sites and there are none here. Use anyone_with_link or restricted."}]}},"/api/v1/publish/{slug}/access/invites":{"post":{"tags":["Sites"],"operationId":"sendSiteAccessInvites","summary":"Send invite emails for an existing access policy","description":"Sends invite emails to exact-email recipients that are currently allowed on the Site. Emails not on the allowlist are reported in skipped with reason not_allowed. Domain rules do not send invite emails. Owner only.","security":[{"bearerAuth":[]}],"parameters":[{"name":"slug","in":"path","required":true,"description":"oi Site slug.","schema":{"type":"string","minLength":1}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SiteAccessInviteRequest"}}}},"responses":{"200":{"description":"Invite delivery results","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SiteAccessInviteResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"available","x-oi-available":true,"x-oi-note":"Implemented and answered by this deployment."}},"/api/v1/publish/from-drive":{"post":{"tags":["Sites","Drives"],"operationId":"publishFromDrive","summary":"Publish a Drive version as a Site","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishFromDriveRequest"}}}},"responses":{"200":{"description":"Drive published","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishFromDriveResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"available","x-oi-available":true,"x-oi-note":"Implemented here, with 2 documented differences inside the operation — slug (conditional); viewer (rejected). Read \"x-oi-divergences\" before relying on those fields.","x-oi-divergences":[{"scope":"field","target":"slug","kind":"conditional","note":"Names an EXISTING Site this account owns, to publish a new live version into. It does not reserve a name: an unknown or unowned slug answers 404 rather than creating that Site. Omit it to mint a new Site, live immediately with no finalize step."},{"scope":"field","target":"viewer","kind":"rejected","note":"Only title, description and ogImagePath are accepted; any other key answers 400. Note the asymmetry with duplicateSite, which accepts and silently ignores extra viewer keys."}],"description":"[DIFFERS FROM THE CONTRACT INSIDE THIS OPERATION]\n- field `slug` (conditional): Names an EXISTING Site this account owns, to publish a new live version into. It does not reserve a name: an unknown or unowned slug answers 404 rather than creating that Site. Omit it to mint a new Site, live immediately with no finalize step.\n- field `viewer` (rejected): Only title, description and ogImagePath are accepted; any other key answers 400. Note the asymmetry with duplicateSite, which accepts and silently ignores extra viewer keys."}},"/api/v1/drives":{"get":{"tags":["Drives"],"operationId":"listDrives","summary":"List account Drives","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Drives","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DriveListResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"available","x-oi-available":true,"x-oi-note":"Implemented and answered by this deployment."},"post":{"tags":["Drives"],"operationId":"createDrive","summary":"Create a Drive","security":[{"bearerAuth":[]}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DriveCreateRequest"}}}},"responses":{"200":{"description":"Drive created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DriveResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"available","x-oi-available":true,"x-oi-note":"Implemented and answered by this deployment."}},"/api/v1/drives/default":{"get":{"tags":["Drives"],"operationId":"getDefaultDrive","summary":"Get or create the default Drive","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Drive","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DriveResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"available","x-oi-available":true,"x-oi-note":"Implemented and answered by this deployment."}},"/api/v1/drives/{driveId}":{"get":{"tags":["Drives"],"operationId":"getDrive","summary":"Get Drive details","security":[{"bearerAuth":[]}],"parameters":[{"name":"driveId","in":"path","required":true,"description":"Drive identifier.","schema":{"type":"string","minLength":1,"example":"drv_01j..."}}],"responses":{"200":{"description":"Drive","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DriveResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"available","x-oi-available":true,"x-oi-note":"Implemented and answered by this deployment."},"patch":{"tags":["Drives"],"operationId":"patchDrive","summary":"Patch Drive metadata","security":[{"bearerAuth":[]}],"parameters":[{"name":"driveId","in":"path","required":true,"description":"Drive identifier.","schema":{"type":"string","minLength":1,"example":"drv_01j..."}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DrivePatchRequest"}}}},"responses":{"200":{"description":"Drive updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DriveResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"available","x-oi-available":true,"x-oi-note":"Implemented and answered by this deployment."},"delete":{"tags":["Drives"],"operationId":"deleteDrive","summary":"Soft-delete a Drive","security":[{"bearerAuth":[]}],"parameters":[{"name":"driveId","in":"path","required":true,"description":"Drive identifier.","schema":{"type":"string","minLength":1,"example":"drv_01j..."}}],"responses":{"200":{"description":"Drive deleted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteDriveResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"available","x-oi-available":true,"x-oi-note":"Implemented and answered by this deployment."}},"/api/v1/drives/{driveId}/files":{"get":{"tags":["Drives"],"operationId":"listDriveFiles","summary":"List Drive files","security":[{"bearerAuth":[]}],"parameters":[{"name":"driveId","in":"path","required":true,"description":"Drive identifier.","schema":{"type":"string","minLength":1,"example":"drv_01j..."}},{"name":"prefix","in":"query","required":false,"schema":{"type":"string"}},{"name":"cursor","in":"query","required":false,"schema":{"type":"string"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":200}}],"responses":{"200":{"description":"Files","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DriveFileListResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"available","x-oi-available":true,"x-oi-note":"Implemented and answered by this deployment."},"patch":{"tags":["Drives"],"operationId":"applyDriveFileBatch","summary":"Apply a batch of Drive file operations","security":[{"bearerAuth":[]}],"parameters":[{"name":"driveId","in":"path","required":true,"description":"Drive identifier.","schema":{"type":"string","minLength":1,"example":"drv_01j..."}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DriveBatchRequest"}}}},"responses":{"200":{"description":"Batch applied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DriveBatchResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"available","x-oi-available":true,"x-oi-note":"Implemented here, with 1 documented difference inside the operation — baseVersionId or per-op ETags (required). Read \"x-oi-divergences\" before relying on those fields.","x-oi-divergences":[{"scope":"precondition","target":"baseVersionId or per-op ETags","kind":"required","note":"The schema marks neither required; this deployment refuses a batch with neither (400). A multi-path rewrite has no single path whose state could be pinned for it, so the precondition has to be stated."}],"description":"[DIFFERS FROM THE CONTRACT INSIDE THIS OPERATION]\n- precondition `baseVersionId or per-op ETags` (required): The schema marks neither required; this deployment refuses a batch with neither (400). A multi-path rewrite has no single path whose state could be pinned for it, so the precondition has to be stated."}},"/api/v1/drives/{driveId}/files/{path}":{"get":{"tags":["Drives"],"operationId":"readDriveFile","summary":"Read a Drive file","security":[{"bearerAuth":[]}],"parameters":[{"name":"driveId","in":"path","required":true,"description":"Drive identifier.","schema":{"type":"string","minLength":1,"example":"drv_01j..."}},{"name":"path","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"File bytes","content":{"text/plain":{"schema":{"type":"string","format":"binary"}},"application/octet-stream":{"schema":{"type":"string","format":"binary"}},"application/json":{"schema":{"type":"string","format":"binary"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"available","x-oi-available":true,"x-oi-note":"Implemented here, with 1 documented difference inside the operation — Range (ignored). Read \"x-oi-divergences\" before relying on those fields.","x-oi-divergences":[{"scope":"header","target":"Range","kind":"ignored","note":"Drive reads are whole-object: a Range request answers 200 with the entire file and no Accept-Ranges or Content-Range, so a client that assumes 206 will silently concatenate whole copies. The Site-serving tier does honor Range; this one does not."}],"description":"[DIFFERS FROM THE CONTRACT INSIDE THIS OPERATION]\n- header `Range` (ignored): Drive reads are whole-object: a Range request answers 200 with the entire file and no Accept-Ranges or Content-Range, so a client that assumes 206 will silently concatenate whole copies. The Site-serving tier does honor Range; this one does not."},"delete":{"tags":["Drives"],"operationId":"deleteDriveFile","summary":"Delete a Drive file or prefix","security":[{"bearerAuth":[]}],"parameters":[{"name":"driveId","in":"path","required":true,"description":"Drive identifier.","schema":{"type":"string","minLength":1,"example":"drv_01j..."}},{"name":"path","in":"path","required":true,"schema":{"type":"string"}},{"name":"recursive","in":"query","required":false,"schema":{"type":"boolean"}},{"name":"baseVersionId","in":"query","required":false,"schema":{"type":"string"}},{"name":"If-Match","in":"header","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Deleted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DriveBatchResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"available","x-oi-available":true,"x-oi-note":"Implemented here, with 2 documented differences inside the operation — If-Match (single file) (derived); recursive + baseVersionId (folder) (required). Read \"x-oi-divergences\" before relying on those fields.","x-oi-divergences":[{"scope":"precondition","target":"If-Match (single file)","kind":"derived","note":"Optional, as the contract declares. A single-file delete with no If-Match and no baseVersionId pins the file as the request found it and commits against that; a path matching nothing is 404, not a silent no-op. A declared If-Match still wins and a stale one still answers 409."},{"scope":"precondition","target":"recursive + baseVersionId (folder)","kind":"required","note":"Deleting a folder needs ?recursive=true AND ?baseVersionId= (read headVersionId from GET /api/v1/drives/{driveId}). Same rule as the batch endpoint: a multi-path delete has no single path whose state could stand for it. A trailing slash on the path is rejected as a malformed Drive path."}],"description":"[DIFFERS FROM THE CONTRACT INSIDE THIS OPERATION]\n- precondition `If-Match (single file)` (derived): Optional, as the contract declares. A single-file delete with no If-Match and no baseVersionId pins the file as the request found it and commits against that; a path matching nothing is 404, not a silent no-op. A declared If-Match still wins and a stale one still answers 409.\n- precondition `recursive + baseVersionId (folder)` (required): Deleting a folder needs ?recursive=true AND ?baseVersionId= (read headVersionId from GET /api/v1/drives/{driveId}). Same rule as the batch endpoint: a multi-path delete has no single path whose state could stand for it. A trailing slash on the path is rejected as a malformed Drive path."}},"/api/v1/drives/{driveId}/files/uploads":{"post":{"tags":["Drives"],"operationId":"createDriveFileUpload","summary":"Stage a Drive file write","security":[{"bearerAuth":[]}],"parameters":[{"name":"driveId","in":"path","required":true,"description":"Drive identifier.","schema":{"type":"string","minLength":1,"example":"drv_01j..."}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DriveUploadCreateRequest"}}}},"responses":{"200":{"description":"Upload staged","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DriveUploadCreateResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"available","x-oi-available":true,"x-oi-note":"Implemented here, with 1 documented difference inside the operation — ifMatch / ifNoneMatch (derived). Read \"x-oi-divergences\" before relying on those fields.","x-oi-divergences":[{"scope":"precondition","target":"ifMatch / ifNoneMatch","kind":"derived","note":"Both stay optional as the contract declares. When neither is sent, staging records the path's current ETag (or its absence) and the response reports it as `precondition`; finalize then commits against exactly that state."}],"description":"[DIFFERS FROM THE CONTRACT INSIDE THIS OPERATION]\n- precondition `ifMatch / ifNoneMatch` (derived): Both stay optional as the contract declares. When neither is sent, staging records the path's current ETag (or its absence) and the response reports it as `precondition`; finalize then commits against exactly that state."}},"/api/v1/drives/{driveId}/files/finalize":{"post":{"tags":["Drives"],"operationId":"finalizeDriveFileUpload","summary":"Finalize a staged Drive upload","security":[{"bearerAuth":[]}],"parameters":[{"name":"driveId","in":"path","required":true,"description":"Drive identifier.","schema":{"type":"string","minLength":1,"example":"drv_01j..."}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DriveFinalizeRequest"}}}},"responses":{"200":{"description":"Upload finalized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DriveBatchResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"available","x-oi-available":true,"x-oi-note":"Implemented here, with 1 documented difference inside the operation — staged precondition (derived). Read \"x-oi-divergences\" before relying on those fields.","x-oi-divergences":[{"scope":"precondition","target":"staged precondition","kind":"derived","note":"The contract's minimal body {uploadId} is sufficient. The commit is checked against the state recorded at staging, so a concurrent writer produces 409 rather than a silent overwrite."}],"description":"[DIFFERS FROM THE CONTRACT INSIDE THIS OPERATION]\n- precondition `staged precondition` (derived): The contract's minimal body {uploadId} is sufficient. The commit is checked against the state recorded at staging, so a concurrent writer produces 409 rather than a silent overwrite."}},"/api/v1/drives/{driveId}/files/move":{"post":{"tags":["Drives"],"operationId":"moveDriveFile","summary":"Move a Drive file","security":[{"bearerAuth":[]}],"parameters":[{"name":"driveId","in":"path","required":true,"description":"Drive identifier.","schema":{"type":"string","minLength":1,"example":"drv_01j..."}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DriveMoveRequest"}}}},"responses":{"200":{"description":"File moved","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DriveBatchResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"available","x-oi-available":true,"x-oi-note":"Implemented and answered by this deployment."}},"/api/v1/drives/{driveId}/tokens":{"get":{"tags":["Drives"],"operationId":"listDriveTokens","summary":"List Drive tokens","security":[{"bearerAuth":[]}],"parameters":[{"name":"driveId","in":"path","required":true,"description":"Drive identifier.","schema":{"type":"string","minLength":1,"example":"drv_01j..."}}],"responses":{"200":{"description":"Tokens","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DriveTokenListResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"available","x-oi-available":true,"x-oi-note":"Implemented and answered by this deployment."},"post":{"tags":["Drives"],"operationId":"createDriveToken","summary":"Create a scoped Drive token","security":[{"bearerAuth":[]}],"parameters":[{"name":"driveId","in":"path","required":true,"description":"Drive identifier.","schema":{"type":"string","minLength":1,"example":"drv_01j..."}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DriveTokenCreateRequest"}}}},"responses":{"200":{"description":"Token created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DriveTokenCreateResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"available","x-oi-available":true,"x-oi-note":"Implemented here, with 1 documented difference inside the operation — perms vs permissions (rejected). Read \"x-oi-divergences\" before relying on those fields.","x-oi-divergences":[{"scope":"field","target":"perms vs permissions","kind":"rejected","note":"Both spellings are accepted, but sending both with different values answers 400 rather than picking one. Send one."}],"description":"[DIFFERS FROM THE CONTRACT INSIDE THIS OPERATION]\n- field `perms vs permissions` (rejected): Both spellings are accepted, but sending both with different values answers 400 rather than picking one. Send one."}},"/api/v1/domains":{"get":{"tags":["Domains"],"operationId":"listDomains","summary":"List custom domains","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Domains","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DomainListResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"unavailable","x-oi-available":false,"x-oi-note":"Custom hostnames need a certificate this deployment cannot provision (HTTP-01 only, no wildcard; see deploy/WILDCARD-TLS.md).","description":"[UNAVAILABLE ON THIS DEPLOYMENT] Custom hostnames need a certificate this deployment cannot provision (HTTP-01 only, no wildcard; see deploy/WILDCARD-TLS.md)."},"post":{"tags":["Domains"],"operationId":"createDomain","summary":"Add a custom domain","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDomainRequest"}}}},"responses":{"200":{"description":"Domain created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DomainResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"unavailable","x-oi-available":false,"x-oi-note":"Custom hostnames need a certificate this deployment cannot provision (HTTP-01 only, no wildcard; see deploy/WILDCARD-TLS.md).","description":"[UNAVAILABLE ON THIS DEPLOYMENT] Custom hostnames need a certificate this deployment cannot provision (HTTP-01 only, no wildcard; see deploy/WILDCARD-TLS.md)."}},"/api/v1/domains/{domain}":{"get":{"tags":["Domains"],"operationId":"getDomain","summary":"Get custom domain status","security":[{"bearerAuth":[]}],"parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Domain","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DomainResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"unavailable","x-oi-available":false,"x-oi-note":"Custom hostnames need a certificate this deployment cannot provision (HTTP-01 only, no wildcard; see deploy/WILDCARD-TLS.md).","description":"[UNAVAILABLE ON THIS DEPLOYMENT] Custom hostnames need a certificate this deployment cannot provision (HTTP-01 only, no wildcard; see deploy/WILDCARD-TLS.md)."},"delete":{"tags":["Domains"],"operationId":"deleteDomain","summary":"Remove a custom domain","security":[{"bearerAuth":[]}],"parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Domain removed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"unavailable","x-oi-available":false,"x-oi-note":"Custom hostnames need a certificate this deployment cannot provision (HTTP-01 only, no wildcard; see deploy/WILDCARD-TLS.md).","description":"[UNAVAILABLE ON THIS DEPLOYMENT] Custom hostnames need a certificate this deployment cannot provision (HTTP-01 only, no wildcard; see deploy/WILDCARD-TLS.md)."}},"/api/v1/handle":{"get":{"tags":["Domains"],"operationId":"getHandle","summary":"Get account subdomain handle","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Subdomain handle","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HandleResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"unavailable","x-oi-available":false,"x-oi-note":"Custom hostnames need a certificate this deployment cannot provision (HTTP-01 only, no wildcard; see deploy/WILDCARD-TLS.md).","description":"[UNAVAILABLE ON THIS DEPLOYMENT] Custom hostnames need a certificate this deployment cannot provision (HTTP-01 only, no wildcard; see deploy/WILDCARD-TLS.md)."},"post":{"tags":["Domains"],"operationId":"createHandle","summary":"Create account subdomain handle (discontinued)","description":"[UNAVAILABLE ON THIS DEPLOYMENT] Custom hostnames need a certificate this deployment cannot provision (HTTP-01 only, no wildcard; see deploy/WILDCARD-TLS.md).\n\nHandles are grandfathered: existing handles keep working, but new handles can no longer be registered. Always returns 410 with code handle_claims_frozen. Workspaces provide named subdomains ({workspace}.oi.mrdk.io) instead.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HandleRequest"}}}},"responses":{"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"410":{"description":"Handle registration is discontinued (handle_claims_frozen)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"unavailable","x-oi-available":false,"x-oi-note":"Custom hostnames need a certificate this deployment cannot provision (HTTP-01 only, no wildcard; see deploy/WILDCARD-TLS.md)."},"delete":{"tags":["Domains"],"operationId":"deleteHandle","summary":"Delete account subdomain handle","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Subdomain handle deleted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"unavailable","x-oi-available":false,"x-oi-note":"Custom hostnames need a certificate this deployment cannot provision (HTTP-01 only, no wildcard; see deploy/WILDCARD-TLS.md).","description":"[UNAVAILABLE ON THIS DEPLOYMENT] Custom hostnames need a certificate this deployment cannot provision (HTTP-01 only, no wildcard; see deploy/WILDCARD-TLS.md)."}},"/api/v1/links":{"get":{"tags":["Domains"],"operationId":"listLinks","summary":"List subdomain handle or domain links","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Links","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkListResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"unavailable","x-oi-available":false,"x-oi-note":"Custom hostnames need a certificate this deployment cannot provision (HTTP-01 only, no wildcard; see deploy/WILDCARD-TLS.md).","description":"[UNAVAILABLE ON THIS DEPLOYMENT] Custom hostnames need a certificate this deployment cannot provision (HTTP-01 only, no wildcard; see deploy/WILDCARD-TLS.md)."},"post":{"tags":["Domains"],"operationId":"createLink","summary":"Create a link from a subdomain handle/domain path to a Site","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkRequest"}}}},"responses":{"200":{"description":"Link created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"unavailable","x-oi-available":false,"x-oi-note":"Custom hostnames need a certificate this deployment cannot provision (HTTP-01 only, no wildcard; see deploy/WILDCARD-TLS.md).","description":"[UNAVAILABLE ON THIS DEPLOYMENT] Custom hostnames need a certificate this deployment cannot provision (HTTP-01 only, no wildcard; see deploy/WILDCARD-TLS.md)."}},"/api/v1/links/{location}":{"get":{"tags":["Domains"],"operationId":"getLink","summary":"Get a link","security":[{"bearerAuth":[]}],"parameters":[{"name":"location","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Link","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"unavailable","x-oi-available":false,"x-oi-note":"Custom hostnames need a certificate this deployment cannot provision (HTTP-01 only, no wildcard; see deploy/WILDCARD-TLS.md).","description":"[UNAVAILABLE ON THIS DEPLOYMENT] Custom hostnames need a certificate this deployment cannot provision (HTTP-01 only, no wildcard; see deploy/WILDCARD-TLS.md)."},"patch":{"tags":["Domains"],"operationId":"updateLink","summary":"Update a link","security":[{"bearerAuth":[]}],"parameters":[{"name":"location","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkPatchRequest"}}}},"responses":{"200":{"description":"Link updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"unavailable","x-oi-available":false,"x-oi-note":"Custom hostnames need a certificate this deployment cannot provision (HTTP-01 only, no wildcard; see deploy/WILDCARD-TLS.md).","description":"[UNAVAILABLE ON THIS DEPLOYMENT] Custom hostnames need a certificate this deployment cannot provision (HTTP-01 only, no wildcard; see deploy/WILDCARD-TLS.md)."},"delete":{"tags":["Domains"],"operationId":"deleteLink","summary":"Delete a link","security":[{"bearerAuth":[]}],"parameters":[{"name":"location","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Link deleted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteLinkResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"unavailable","x-oi-available":false,"x-oi-note":"Custom hostnames need a certificate this deployment cannot provision (HTTP-01 only, no wildcard; see deploy/WILDCARD-TLS.md).","description":"[UNAVAILABLE ON THIS DEPLOYMENT] Custom hostnames need a certificate this deployment cannot provision (HTTP-01 only, no wildcard; see deploy/WILDCARD-TLS.md)."}},"/api/v1/accounts":{"get":{"tags":["Workspaces"],"operationId":"listAccounts","summary":"List accounts available to the caller","description":"[NOT IMPLEMENTED ON THIS DEPLOYMENT] Workspaces are not implemented here. Every API key acts on exactly one personal account, and the `X-Oi-Account` selector is rejected rather than honored.\n\nLists the caller's personal account and joined workspaces, plus the currently selected account for the X-Oi-Account selector. With includeJoinable=1, also returns workspaces the caller could join right now via an active email-domain auto-join rule.","security":[{"bearerAuth":[]}],"parameters":[{"name":"includeJoinable","in":"query","required":false,"description":"When set to 1, include a joinable array: workspaces with an active auto-join rule matching the caller's email domain (not already a member, not suppressed). Join one with POST /api/v1/accounts/{accountId}/domain-rules/apply.","schema":{"type":"string","enum":["1","true"]}}],"responses":{"200":{"description":"Accounts","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountListResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"planned","x-oi-available":false,"x-oi-note":"Workspaces are not implemented here. Every API key acts on exactly one personal account, and the `X-Oi-Account` selector is rejected rather than honored."},"post":{"tags":["Workspaces"],"operationId":"createWorkspace","summary":"Create a workspace","description":"[NOT IMPLEMENTED ON THIS DEPLOYMENT] Workspaces are not implemented here. Every API key acts on exactly one personal account, and the `X-Oi-Account` selector is rejected rather than honored.\n\nOne-call workspace creation: creates the org account, records the caller as admin, claims the subdomain, and provisions wildcard label serving. A successful response reports provisioning readiness; degraded states include a retry endpoint. Each user can have up to 3 live created workspaces (409 workspace_creation_limit beyond that).","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkspaceCreateRequest"}}}},"responses":{"201":{"description":"Workspace created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkspaceCreateResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"planned","x-oi-available":false,"x-oi-note":"Workspaces are not implemented here. Every API key acts on exactly one personal account, and the `X-Oi-Account` selector is rejected rather than honored."}},"/api/v1/accounts/subdomain-availability":{"get":{"tags":["Workspaces"],"operationId":"checkWorkspaceSubdomainAvailability","summary":"Check workspace subdomain availability","description":"[NOT IMPLEMENTED ON THIS DEPLOYMENT] Workspaces are not implemented here. Every API key acts on exactly one personal account, and the `X-Oi-Account` selector is rejected rather than honored.\n\nAdvisory availability probe for workspace subdomains (format, reserved names, and collisions with existing hostnames, handles, and workspaces). A positive answer is not a reservation — creation still enforces uniqueness.","security":[{"bearerAuth":[]}],"parameters":[{"name":"subdomain","in":"query","required":true,"description":"Candidate workspace subdomain (the {subdomain}.oi.mrdk.io label).","schema":{"type":"string","minLength":3,"maxLength":30}}],"responses":{"200":{"description":"Availability result","content":{"application/json":{"schema":{"type":"object","properties":{"subdomain":{"type":"string"},"available":{"type":"boolean"},"message":{"type":"string","description":"Reason when unavailable."}},"required":["subdomain","available"]}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"planned","x-oi-available":false,"x-oi-note":"Workspaces are not implemented here. Every API key acts on exactly one personal account, and the `X-Oi-Account` selector is rejected rather than honored."}},"/api/v1/accounts/{accountId}/provisioning":{"post":{"tags":["Workspaces"],"operationId":"provisionWorkspaceSubdomain","summary":"Provision a workspace subdomain","description":"[NOT IMPLEMENTED ON THIS DEPLOYMENT] Workspaces are not implemented here. Every API key acts on exactly one personal account, and the `X-Oi-Account` selector is rejected rather than honored.\n\nAdmin-only endpoint that reserves the workspace root namespace, syncs namespace KV, provisions the per-workspace wildcard custom hostname, and returns wildcard DNS/SSL readiness. Use it to retry when creation reported a degraded provisioning status.","security":[{"bearerAuth":[]}],"parameters":[{"name":"accountId","in":"path","required":true,"description":"Workspace account UUID.","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Workspace provisioning result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkspaceProvisioningResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"planned","x-oi-available":false,"x-oi-note":"Workspaces are not implemented here. Every API key acts on exactly one personal account, and the `X-Oi-Account` selector is rejected rather than honored."}},"/api/v1/accounts/{accountId}/site-labels":{"get":{"tags":["Workspaces"],"operationId":"listWorkspaceSiteLabels","summary":"List workspace Site labels","description":"[NOT IMPLEMENTED ON THIS DEPLOYMENT] Workspaces are not implemented here. Every API key acts on exactly one personal account, and the `X-Oi-Account` selector is rejected rather than honored.\n\nLists non-deleted label records for an active provisioned workspace (admin only).","security":[{"bearerAuth":[]}],"parameters":[{"name":"accountId","in":"path","required":true,"description":"Workspace account UUID.","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Workspace Site labels","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkspaceSiteLabelListResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"planned","x-oi-available":false,"x-oi-note":"Workspaces are not implemented here. Every API key acts on exactly one personal account, and the `X-Oi-Account` selector is rejected rather than honored."},"post":{"tags":["Workspaces"],"operationId":"assignWorkspaceSiteLabel","summary":"Assign a workspace Site label","description":"[NOT IMPLEMENTED ON THIS DEPLOYMENT] Workspaces are not implemented here. Every API key acts on exactly one personal account, and the `X-Oi-Account` selector is rejected rather than honored.\n\nAssigns an exact DNS-safe label to an active Site already owned by the workspace and syncs label routing. Label assignment is admin-only.","security":[{"bearerAuth":[]}],"parameters":[{"name":"accountId","in":"path","required":true,"description":"Workspace account UUID.","schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkspaceSiteLabelRequest"}}}},"responses":{"201":{"description":"Workspace Site label assigned","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkspaceSiteLabelResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"planned","x-oi-available":false,"x-oi-note":"Workspaces are not implemented here. Every API key acts on exactly one personal account, and the `X-Oi-Account` selector is rejected rather than honored."}},"/api/v1/accounts/{accountId}/site-labels/{label}":{"patch":{"tags":["Workspaces"],"operationId":"renameWorkspaceSiteLabel","summary":"Rename a workspace Site label","description":"[NOT IMPLEMENTED ON THIS DEPLOYMENT] Workspaces are not implemented here. Every API key acts on exactly one personal account, and the `X-Oi-Account` selector is rejected rather than honored.\n\nRenames a workspace Site's label. The new label URL serves immediately and the old label becomes a temporary (307) redirect, so shared links keep working. The Site's canonical {slug}.oi.mrdk.io URL is unchanged. Allowed for workspace admins and the Site's original publisher.","security":[{"bearerAuth":[]}],"parameters":[{"name":"accountId","in":"path","required":true,"description":"Workspace account UUID.","schema":{"type":"string","format":"uuid"}},{"name":"label","in":"path","required":true,"description":"Current active workspace label.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkspaceSiteLabelRenameRequest"}}}},"responses":{"200":{"description":"Workspace Site label renamed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkspaceSiteLabelRenameResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"planned","x-oi-available":false,"x-oi-note":"Workspaces are not implemented here. Every API key acts on exactly one personal account, and the `X-Oi-Account` selector is rejected rather than honored."}},"/api/v1/accounts/{accountId}":{"patch":{"tags":["Workspaces"],"operationId":"updateWorkspace","summary":"Rename a workspace or set its icon","description":"[NOT IMPLEMENTED ON THIS DEPLOYMENT] Workspaces are not implemented here. Every API key acts on exactly one personal account, and the `X-Oi-Account` selector is rejected rather than honored.\n\nAdmin-only. Updates the workspace displayName and/or icon emoji. The workspace subdomain is permanent and cannot be changed.","security":[{"bearerAuth":[]}],"parameters":[{"name":"accountId","in":"path","required":true,"description":"Workspace account UUID.","schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkspaceUpdateRequest"}}}},"responses":{"200":{"description":"Workspace updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkspaceUpdateResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"planned","x-oi-available":false,"x-oi-note":"Workspaces are not implemented here. Every API key acts on exactly one personal account, and the `X-Oi-Account` selector is rejected rather than honored."},"delete":{"tags":["Workspaces"],"operationId":"deleteWorkspace","summary":"Delete a workspace","description":"[NOT IMPLEMENTED ON THIS DEPLOYMENT] Workspaces are not implemented here. Every API key acts on exactly one personal account, and the `X-Oi-Account` selector is rejected rather than honored.\n\nAdmin-only. Permanently deletes the workspace: its Sites, memberships, invites, domain rules, custom domains, and variables. This cannot be undone.","security":[{"bearerAuth":[]}],"parameters":[{"name":"accountId","in":"path","required":true,"description":"Workspace account UUID.","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Workspace deleted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkspaceDeleteResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"planned","x-oi-available":false,"x-oi-note":"Workspaces are not implemented here. Every API key acts on exactly one personal account, and the `X-Oi-Account` selector is rejected rather than honored."}},"/api/v1/accounts/{accountId}/members":{"get":{"tags":["Workspaces"],"operationId":"listWorkspaceMembers","summary":"List workspace members","description":"[NOT IMPLEMENTED ON THIS DEPLOYMENT] Workspaces are not implemented here. Every API key acts on exactly one personal account, and the `X-Oi-Account` selector is rejected rather than honored.\n\nAdmin-only. Lists the workspace's memberships, including active and removed rows.","security":[{"bearerAuth":[]}],"parameters":[{"name":"accountId","in":"path","required":true,"description":"Workspace account UUID.","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Workspace members","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkspaceMemberListResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"planned","x-oi-available":false,"x-oi-note":"Workspaces are not implemented here. Every API key acts on exactly one personal account, and the `X-Oi-Account` selector is rejected rather than honored."},"post":{"tags":["Workspaces"],"operationId":"addWorkspaceMember","summary":"Add a workspace member directly","description":"[NOT IMPLEMENTED ON THIS DEPLOYMENT] Workspaces are not implemented here. Every API key acts on exactly one personal account, and the `X-Oi-Account` selector is rejected rather than honored.\n\nAdmin-only. Adds an existing oi user to the workspace by email without an invite flow. Prefer email invites for people who may not have an account yet.","security":[{"bearerAuth":[]}],"parameters":[{"name":"accountId","in":"path","required":true,"description":"Workspace account UUID.","schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkspaceMemberAddRequest"}}}},"responses":{"201":{"description":"Member added","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkspaceMemberResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"planned","x-oi-available":false,"x-oi-note":"Workspaces are not implemented here. Every API key acts on exactly one personal account, and the `X-Oi-Account` selector is rejected rather than honored."}},"/api/v1/accounts/{accountId}/members/{userId}":{"patch":{"tags":["Workspaces"],"operationId":"updateWorkspaceMemberRole","summary":"Change a member's role","description":"[NOT IMPLEMENTED ON THIS DEPLOYMENT] Workspaces are not implemented here. Every API key acts on exactly one personal account, and the `X-Oi-Account` selector is rejected rather than honored.\n\nAdmin-only. Sets the member's role to admin or member. A workspace always keeps at least one active admin.","security":[{"bearerAuth":[]}],"parameters":[{"name":"accountId","in":"path","required":true,"description":"Workspace account UUID.","schema":{"type":"string","format":"uuid"}},{"name":"userId","in":"path","required":true,"description":"Member user UUID.","schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkspaceMemberRoleRequest"}}}},"responses":{"200":{"description":"Member role updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkspaceMemberResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"planned","x-oi-available":false,"x-oi-note":"Workspaces are not implemented here. Every API key acts on exactly one personal account, and the `X-Oi-Account` selector is rejected rather than honored."},"delete":{"tags":["Workspaces"],"operationId":"removeWorkspaceMember","summary":"Remove a member or leave the workspace","description":"[NOT IMPLEMENTED ON THIS DEPLOYMENT] Workspaces are not implemented here. Every API key acts on exactly one personal account, and the `X-Oi-Account` selector is rejected rather than honored.\n\nAdmins can remove any member; any member can remove themselves to leave. The last active admin cannot be removed.","security":[{"bearerAuth":[]}],"parameters":[{"name":"accountId","in":"path","required":true,"description":"Workspace account UUID.","schema":{"type":"string","format":"uuid"}},{"name":"userId","in":"path","required":true,"description":"Member user UUID (your own id to leave).","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Member removed","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"left":{"type":"boolean","description":"Present and true when the caller removed themselves."}},"required":["success"]}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"planned","x-oi-available":false,"x-oi-note":"Workspaces are not implemented here. Every API key acts on exactly one personal account, and the `X-Oi-Account` selector is rejected rather than honored."}},"/api/v1/accounts/{accountId}/invites":{"get":{"tags":["Workspaces"],"operationId":"listWorkspaceInvites","summary":"List pending workspace invites","description":"[NOT IMPLEMENTED ON THIS DEPLOYMENT] Workspaces are not implemented here. Every API key acts on exactly one personal account, and the `X-Oi-Account` selector is rejected rather than honored.\n\nAdmin-only. Lists the workspace's pending email invites.","security":[{"bearerAuth":[]}],"parameters":[{"name":"accountId","in":"path","required":true,"description":"Workspace account UUID.","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Pending invites","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkspaceInviteListResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"planned","x-oi-available":false,"x-oi-note":"Workspaces are not implemented here. Every API key acts on exactly one personal account, and the `X-Oi-Account` selector is rejected rather than honored."},"post":{"tags":["Workspaces"],"operationId":"createWorkspaceInvite","summary":"Send a workspace invite","description":"[NOT IMPLEMENTED ON THIS DEPLOYMENT] Workspaces are not implemented here. Every API key acts on exactly one personal account, and the `X-Oi-Account` selector is rejected rather than honored.\n\nAdmin-only. Sends an email invite with a role (default member). The recipient accepts from the email using their normal oi sign-in.","security":[{"bearerAuth":[]}],"parameters":[{"name":"accountId","in":"path","required":true,"description":"Workspace account UUID.","schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkspaceInviteCreateRequest"}}}},"responses":{"201":{"description":"Invite created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkspaceInviteCreateResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"planned","x-oi-available":false,"x-oi-note":"Workspaces are not implemented here. Every API key acts on exactly one personal account, and the `X-Oi-Account` selector is rejected rather than honored."}},"/api/v1/accounts/{accountId}/invites/{inviteId}":{"delete":{"tags":["Workspaces"],"operationId":"revokeWorkspaceInvite","summary":"Revoke a workspace invite","description":"[NOT IMPLEMENTED ON THIS DEPLOYMENT] Workspaces are not implemented here. Every API key acts on exactly one personal account, and the `X-Oi-Account` selector is rejected rather than honored.\n\nAdmin-only. Revokes a pending invite so its link stops working.","security":[{"bearerAuth":[]}],"parameters":[{"name":"accountId","in":"path","required":true,"description":"Workspace account UUID.","schema":{"type":"string","format":"uuid"}},{"name":"inviteId","in":"path","required":true,"description":"Invite UUID.","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Invite revoked","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"invite":{"$ref":"#/components/schemas/WorkspaceInvite"}},"required":["success","invite"]}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"planned","x-oi-available":false,"x-oi-note":"Workspaces are not implemented here. Every API key acts on exactly one personal account, and the `X-Oi-Account` selector is rejected rather than honored."}},"/api/v1/accounts/{accountId}/invites/{inviteId}/accept":{"post":{"tags":["Workspaces"],"operationId":"acceptWorkspaceInvite","summary":"Accept a workspace invite","description":"[NOT IMPLEMENTED ON THIS DEPLOYMENT] Workspaces are not implemented here. Every API key acts on exactly one personal account, and the `X-Oi-Account` selector is rejected rather than honored.\n\nInvitee-only: the caller's sign-in email must match the invited email. Creates the membership and returns it. Discover your pending invites with GET /api/v1/me/invites.","security":[{"bearerAuth":[]}],"parameters":[{"name":"accountId","in":"path","required":true,"description":"Workspace account UUID.","schema":{"type":"string","format":"uuid"}},{"name":"inviteId","in":"path","required":true,"description":"Invite UUID.","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Invite accepted","content":{"application/json":{"schema":{"type":"object","properties":{"invite":{"$ref":"#/components/schemas/WorkspaceInvite"},"member":{"$ref":"#/components/schemas/WorkspaceMember"}},"required":["invite","member"]}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"planned","x-oi-available":false,"x-oi-note":"Workspaces are not implemented here. Every API key acts on exactly one personal account, and the `X-Oi-Account` selector is rejected rather than honored."}},"/api/v1/accounts/{accountId}/invites/{inviteId}/decline":{"post":{"tags":["Workspaces"],"operationId":"declineWorkspaceInvite","summary":"Decline a workspace invite","description":"[NOT IMPLEMENTED ON THIS DEPLOYMENT] Workspaces are not implemented here. Every API key acts on exactly one personal account, and the `X-Oi-Account` selector is rejected rather than honored.\n\nInvitee-only: the caller's sign-in email must match the invited email. Marks the pending invite revoked.","security":[{"bearerAuth":[]}],"parameters":[{"name":"accountId","in":"path","required":true,"description":"Workspace account UUID.","schema":{"type":"string","format":"uuid"}},{"name":"inviteId","in":"path","required":true,"description":"Invite UUID.","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Invite declined","content":{"application/json":{"schema":{"type":"object","properties":{"invite":{"$ref":"#/components/schemas/WorkspaceInvite"}},"required":["invite"]}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"planned","x-oi-available":false,"x-oi-note":"Workspaces are not implemented here. Every API key acts on exactly one personal account, and the `X-Oi-Account` selector is rejected rather than honored."}},"/api/v1/me/invites":{"get":{"tags":["Workspaces"],"operationId":"listMyWorkspaceInvites","summary":"List the caller's pending workspace invites","description":"[NOT IMPLEMENTED ON THIS DEPLOYMENT] Workspaces are not implemented here. Every API key acts on exactly one personal account, and the `X-Oi-Account` selector is rejected rather than honored.\n\nPending invites addressed to the caller's sign-in email, each with workspace display context and ready-to-call accept/decline endpoints.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Pending invites for the caller","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MyInviteListResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"planned","x-oi-available":false,"x-oi-note":"Workspaces are not implemented here. Every API key acts on exactly one personal account, and the `X-Oi-Account` selector is rejected rather than honored."}},"/api/v1/accounts/{accountId}/domain-rules":{"get":{"tags":["Workspaces"],"operationId":"listWorkspaceDomainRules","summary":"List auto-join domain rules","description":"[NOT IMPLEMENTED ON THIS DEPLOYMENT] Workspaces are not implemented here. Every API key acts on exactly one personal account, and the `X-Oi-Account` selector is rejected rather than honored.\n\nAdmin-only. Lists the workspace's email-domain auto-join rules.","security":[{"bearerAuth":[]}],"parameters":[{"name":"accountId","in":"path","required":true,"description":"Workspace account UUID.","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Domain rules","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkspaceDomainRuleListResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"planned","x-oi-available":false,"x-oi-note":"Workspaces are not implemented here. Every API key acts on exactly one personal account, and the `X-Oi-Account` selector is rejected rather than honored."},"post":{"tags":["Workspaces"],"operationId":"createWorkspaceDomainRule","summary":"Create an auto-join domain rule","description":"[NOT IMPLEMENTED ON THIS DEPLOYMENT] Workspaces are not implemented here. Every API key acts on exactly one personal account, and the `X-Oi-Account` selector is rejected rather than honored.\n\nAdmin-only. Lets anyone who signs in with a matching email domain join the workspace. Consumer email domains (gmail.com and similar) are rejected.","security":[{"bearerAuth":[]}],"parameters":[{"name":"accountId","in":"path","required":true,"description":"Workspace account UUID.","schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"domain":{"type":"string","description":"Email domain (e.g. example.com)."}},"required":["domain"]}}}},"responses":{"201":{"description":"Domain rule created","content":{"application/json":{"schema":{"type":"object","properties":{"domainRule":{"$ref":"#/components/schemas/WorkspaceDomainRule"}},"required":["domainRule"]}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"planned","x-oi-available":false,"x-oi-note":"Workspaces are not implemented here. Every API key acts on exactly one personal account, and the `X-Oi-Account` selector is rejected rather than honored."}},"/api/v1/accounts/{accountId}/domain-rules/{ruleId}":{"delete":{"tags":["Workspaces"],"operationId":"disableWorkspaceDomainRule","summary":"Disable an auto-join domain rule","description":"[NOT IMPLEMENTED ON THIS DEPLOYMENT] Workspaces are not implemented here. Every API key acts on exactly one personal account, and the `X-Oi-Account` selector is rejected rather than honored.\n\nAdmin-only. Disables the rule; existing members keep their memberships.","security":[{"bearerAuth":[]}],"parameters":[{"name":"accountId","in":"path","required":true,"description":"Workspace account UUID.","schema":{"type":"string","format":"uuid"}},{"name":"ruleId","in":"path","required":true,"description":"Domain rule UUID.","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Domain rule disabled","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"domainRule":{"$ref":"#/components/schemas/WorkspaceDomainRule"}},"required":["success","domainRule"]}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"planned","x-oi-available":false,"x-oi-note":"Workspaces are not implemented here. Every API key acts on exactly one personal account, and the `X-Oi-Account` selector is rejected rather than honored."}},"/api/v1/accounts/{accountId}/domain-rules/apply":{"post":{"tags":["Workspaces"],"operationId":"applyWorkspaceDomainRule","summary":"Join a workspace via a matching domain rule","description":"[NOT IMPLEMENTED ON THIS DEPLOYMENT] Workspaces are not implemented here. Every API key acts on exactly one personal account, and the `X-Oi-Account` selector is rejected rather than honored.\n\nJoins the caller to the workspace when an active auto-join rule matches their sign-in email domain. Idempotent: joined is false when the caller was already a member.","security":[{"bearerAuth":[]}],"parameters":[{"name":"accountId","in":"path","required":true,"description":"Workspace account UUID.","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Join result","content":{"application/json":{"schema":{"type":"object","properties":{"joined":{"type":"boolean"},"domainRule":{"$ref":"#/components/schemas/WorkspaceDomainRule"},"member":{"$ref":"#/components/schemas/WorkspaceMember"}},"required":["joined","domainRule","member"]}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"planned","x-oi-available":false,"x-oi-note":"Workspaces are not implemented here. Every API key acts on exactly one personal account, and the `X-Oi-Account` selector is rejected rather than honored."}},"/api/v1/me/variables":{"get":{"tags":["Variables"],"operationId":"listVariables","summary":"List service variables","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Variables","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VariableListResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"planned","x-oi-available":false,"x-oi-note":"Account variables are not implemented here.","description":"[NOT IMPLEMENTED ON THIS DEPLOYMENT] Account variables are not implemented here."}},"/api/v1/me/variables/{name}":{"put":{"tags":["Variables"],"operationId":"setVariable","summary":"Create or update a service variable","security":[{"bearerAuth":[]}],"parameters":[{"name":"name","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VariableSetRequest"}}}},"responses":{"200":{"description":"Variable stored","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VariableResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"planned","x-oi-available":false,"x-oi-note":"Account variables are not implemented here.","description":"[NOT IMPLEMENTED ON THIS DEPLOYMENT] Account variables are not implemented here."},"delete":{"tags":["Variables"],"operationId":"deleteVariable","summary":"Delete a service variable","security":[{"bearerAuth":[]}],"parameters":[{"name":"name","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Variable deleted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"planned","x-oi-available":false,"x-oi-note":"Account variables are not implemented here.","description":"[NOT IMPLEMENTED ON THIS DEPLOYMENT] Account variables are not implemented here."}},"/api/v1/me/keys":{"get":{"tags":["Auth"],"operationId":"listApiKeys","summary":"List API keys","description":"Lists active API keys for the account, including full key values so keys can be re-read later. The original sign-up key appears with a blank name and id `legacy`. `current` marks the key used to authenticate this request.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"API keys","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyListResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"available","x-oi-available":true,"x-oi-note":"Implemented and answered by this deployment."},"post":{"tags":["Auth"],"operationId":"createApiKey","summary":"Create a named API key","description":"Creates a new named API key (`oik_` prefix). Accounts can hold up to 50 active keys.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyCreateRequest"}}}},"responses":{"201":{"description":"API key created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyCreateResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"available","x-oi-available":true,"x-oi-note":"Implemented and answered by this deployment."}},"/api/v1/me/keys/{id}":{"delete":{"tags":["Auth"],"operationId":"revokeApiKey","summary":"Revoke an API key","description":"Revokes one API key immediately; other keys are unaffected. Use the special id `legacy` to revoke the account's original default key.","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"API key revoked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyRevokeResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"available","x-oi-available":true,"x-oi-note":"Implemented and answered by this deployment."}},"/api/v1/support":{"post":{"tags":["Support"],"operationId":"createSupportRequest","summary":"Send an authenticated support request","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupportRequest"}}}},"responses":{"200":{"description":"Support request sent","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OkResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-oi-availability":"planned","x-oi-available":false,"x-oi-note":"There is no support-request endpoint here; email the support address in /docs instead.","description":"[NOT IMPLEMENTED ON THIS DEPLOYMENT] There is no support-request endpoint here; email the support address in /docs instead."}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"API key","description":"Use `Authorization: Bearer <API_KEY>`. Drive share tokens also use Bearer auth for Drive-scoped operations."}},"schemas":{"ErrorResponse":{"type":"object","description":"Structured JSON error envelope. The `error` field is retained for backwards compatibility; agents should prefer `code`, `message`, `retry_after`, and `docs_url` when present.","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["bad_request","invalid_json","invalid_request","unauthorized","forbidden","not_found","conflict","gone","rate_limit_exceeded","storage_not_configured","service_unavailable","internal_error"]},"message":{"type":"string"},"details":{"description":"Optional route-specific details. May be a string, object, or array."},"retry_after":{"type":"integer","description":"Seconds to wait before retrying. Also mirrored in the Retry-After header when present."},"docs_url":{"type":"string","format":"uri"}},"required":["error","code","message"],"additionalProperties":true},"SuccessResponse":{"type":"object","properties":{"success":{"type":"boolean","const":true}},"required":["success"],"additionalProperties":true},"OkResponse":{"type":"object","properties":{"ok":{"type":"boolean","const":true}},"required":["ok"]},"AgentAuthRequestCodeRequest":{"type":"object","properties":{"email":{"type":"string","format":"email"}},"required":["email"]},"AgentAuthRequestCodeResponse":{"type":"object","properties":{"success":{"type":"boolean"},"requiresCodeEntry":{"type":"boolean"},"expiresAt":{"type":"string","format":"date-time"}},"required":["success","requiresCodeEntry","expiresAt"]},"AgentAuthVerifyCodeRequest":{"type":"object","properties":{"email":{"type":"string","format":"email"},"code":{"type":"string","minLength":4,"maxLength":32}},"required":["email","code"]},"AgentAuthVerifyCodeResponse":{"type":"object","properties":{"success":{"type":"boolean"},"email":{"type":"string","format":"email"},"apiKey":{"type":"string"},"isNewUser":{"type":"boolean"}},"required":["success","email","apiKey","isNewUser"]},"PublishFile":{"type":"object","properties":{"path":{"type":"string","minLength":1},"size":{"type":"integer","minimum":0},"contentType":{"type":"string"},"hash":{"type":"string","pattern":"^[a-f0-9]{64}$"}},"required":["path","size"]},"ViewerMetadata":{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":200},"description":{"type":"string","minLength":1,"maxLength":2000},"ogImagePath":{"type":"string","minLength":1}}},"PublishCreateRequest":{"type":"object","properties":{"files":{"type":"array","minItems":1,"maxItems":1000,"items":{"$ref":"#/components/schemas/PublishFile"}},"ttlSeconds":{"type":["integer","null"],"minimum":1},"viewer":{"$ref":"#/components/schemas/ViewerMetadata"},"claimToken":{"type":"string","minLength":1},"account":{"type":["string","null"],"minLength":1,"description":"Optional account selector for authenticated requests (workspace subdomain or account UUID). Must match X-Oi-Account when both are provided. Selecting a workspace makes the Site workspace-owned."},"spaMode":{"type":"boolean"},"displayName":{"type":"string","minLength":1,"maxLength":80,"description":"Optional owner-facing Site title for dashboards, search, profile cards, and API responses."},"displayDescription":{"type":"string","minLength":1,"maxLength":280,"description":"Optional owner-facing Site summary for dashboards, search, and API responses."}},"required":["files"]},"UploadTarget":{"type":"object","properties":{"path":{"type":"string"},"method":{"type":"string","const":"PUT"},"url":{"type":"string","format":"uri"},"headers":{"type":"object","additionalProperties":{"type":"string"}}},"required":["path","method","url","headers"]},"PublishUpload":{"type":"object","properties":{"versionId":{"type":"string"},"uploads":{"type":"array","items":{"$ref":"#/components/schemas/UploadTarget"}},"skipped":{"type":"array","items":{"type":"string"}},"finalizeUrl":{"type":"string","format":"uri"},"expiresInSeconds":{"type":"integer"}},"required":["versionId","uploads","finalizeUrl","expiresInSeconds"]},"PublishCreateResponse":{"type":"object","properties":{"slug":{"type":"string"},"siteUrl":{"type":"string","format":"uri"},"status":{"type":"string"},"isLive":{"type":"boolean"},"requiresFinalize":{"type":"boolean"},"note":{"type":"string"},"upload":{"$ref":"#/components/schemas/PublishUpload"},"claimToken":{"type":"string"},"claimUrl":{"type":"string","format":"uri"},"expiresAt":{"type":["string","null"],"format":"date-time"},"anonymous":{"type":"boolean"},"warning":{"type":"string"},"displayName":{"type":"string","maxLength":80},"displayDescription":{"type":"string","maxLength":280}},"required":["slug","siteUrl","status","isLive","requiresFinalize","upload"],"additionalProperties":true},"FinalizePublishRequest":{"type":"object","properties":{"versionId":{"type":"string","minLength":1},"account":{"type":["string","null"],"minLength":1,"description":"Optional account selector for authenticated requests. Must match X-Oi-Account when both are provided."},"workspaceLabel":{"type":["string","null"],"minLength":1,"maxLength":63,"description":"Optional exact DNS-safe label for beta workspace-owned Sites. When omitted, finalize derives a label from generated Site metadata with a deterministic fallback. Explicit labels stay strict: conflicts return 409 instead of auto-bumping."}},"required":["versionId"]},"FinalizePublishResponse":{"type":"object","properties":{"success":{"type":"boolean"},"slug":{"type":"string"},"siteUrl":{"type":"string","format":"uri"},"accountUrl":{"type":"string","format":"uri"},"workspaceLabel":{"type":"object","description":"Workspace label allocation details when finalizing a beta workspace-owned Site.","additionalProperties":true},"currentVersionId":{"type":"string"},"previousVersionId":{"type":["string","null"]},"unchanged":{"type":"boolean","description":"True when the finalized content was identical to the already-live version, so no new version was created. currentVersionId is the existing live versionId (it will differ from the versionId minted by create/update). Settings changes carried by the update (TTL, viewer, spaMode) are still applied."}},"required":["success","slug","siteUrl","currentVersionId"],"additionalProperties":true},"SiteVersionsResponse":{"type":"object","properties":{"slug":{"type":"string"},"currentVersionId":{"type":["string","null"]},"versions":{"type":"array","items":{"type":"object","properties":{"versionId":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"source":{"type":"string","description":"Pipeline that produced the version: publish-finalize, from-drive, console-save, console-chat, duplicate-site, or backfill."},"fileCount":{"type":"integer"},"totalBytes":{"type":"integer"},"restoredFromVersionId":{"type":["string","null"],"description":"Set when this entry records a rollback to an earlier version."},"current":{"type":"boolean","description":"True for the version currently being served."},"thumbnailUrl":{"type":"string","description":"Relative URL of the version's screenshot; requires the same authentication and plan as this endpoint."},"previewUrl":{"type":"string","format":"uri","description":"Owner-only preview of this version at {versionId}--{slug}.oi.mrdk.io. Opening it in a signed-in browser authenticates automatically; the preview is never publicly accessible or indexed."}},"required":["versionId","createdAt","source","fileCount","totalBytes","current"]}}},"required":["slug","versions"]},"DeleteSiteVersionResponse":{"type":"object","properties":{"success":{"type":"boolean"},"slug":{"type":"string"},"deletedVersionId":{"type":"string"}},"required":["success","slug","deletedVersionId"]},"RestoreSiteVersionResponse":{"type":"object","properties":{"success":{"type":"boolean"},"slug":{"type":"string"},"siteUrl":{"type":"string","format":"uri"},"currentVersionId":{"type":"string","description":"The restored version, now live."},"restoredFromVersionId":{"type":"string"},"eventVersionId":{"type":"string","description":"Id of the restore event recorded in the version history."}},"required":["success","slug","siteUrl","currentVersionId"]},"PublishListResponse":{"type":"object","properties":{"publishes":{"type":"array","items":{"type":"object","properties":{"slug":{"type":"string"},"siteUrl":{"type":"string","format":"uri"},"updatedAt":{"type":"string","format":"date-time"},"expiresAt":{"type":["string","null"],"format":"date-time"},"status":{"type":"string"},"currentVersionId":{"type":["string","null"]},"pendingVersionId":{"type":["string","null"]},"primaryUrl":{"type":"string","format":"uri","description":"scope=all only: the workspace label URL where one exists, else the canonical siteUrl."},"displayName":{"type":["string","null"],"description":"scope=all only."},"displayDescription":{"type":["string","null"],"description":"scope=all only."},"ownership":{"type":"string","enum":["owned","shared","workspace"],"description":"scope=all only."},"sharedSource":{"type":["string","null"],"enum":["email","domain",null],"description":"scope=all only."},"workspace":{"type":["object","null"],"description":"scope=all only: the owning workspace for workspace rows.","properties":{"displayName":{"type":"string"},"subdomain":{"type":["string","null"]}}}},"required":["slug","siteUrl","updatedAt","expiresAt","status","currentVersionId","pendingVersionId"]}},"scope":{"type":"string","enum":["all"],"description":"Present when the request used scope=all."},"nextCursor":{"type":["string","null"],"description":"scope=all only: opaque cursor for the next page; null on the last page."}},"required":["publishes"]},"SiteSearchResult":{"type":"object","properties":{"slug":{"type":"string"},"siteUrl":{"type":"string","format":"uri"},"primaryUrl":{"type":["string","null"],"format":"uri"},"displayName":{"type":["string","null"],"maxLength":80},"displayDescription":{"type":["string","null"]},"ownership":{"type":"string","enum":["owned","shared","workspace"]},"sharedSource":{"type":["string","null"],"enum":["email","domain",null]},"workspace":{"type":["object","null"],"description":"Owning workspace, present on workspace-owned results.","properties":{"displayName":{"type":"string"},"subdomain":{"type":["string","null"]}},"required":["displayName","subdomain"]},"currentVersionId":{"type":["string","null"]},"indexedVersionId":{"type":["string","null"]},"updatedAt":{"type":"string","format":"date-time"},"matchedFields":{"type":"array","items":{"type":"string","examples":["slug","url","domain","display_name","viewer_title","viewer_description","content"]}},"matchedPaths":{"type":"array","items":{"type":"string"}},"snippet":{"type":["string","null"]}},"required":["slug","siteUrl","primaryUrl","ownership","sharedSource","workspace","currentVersionId","indexedVersionId","updatedAt","matchedFields","matchedPaths","snippet"]},"SiteSearchResponse":{"type":"object","properties":{"query":{"type":"string"},"nextCursor":{"type":["string","null"]},"results":{"type":"array","items":{"$ref":"#/components/schemas/SiteSearchResult"}}},"required":["query","nextCursor","results"]},"SiteDataRecordInput":{"type":"object","description":"Record data validated against the target collection schema from .oi/data.json. Allowed fields and value types depend on that collection.","additionalProperties":true},"SiteDataRecord":{"type":"object","properties":{"id":{"type":"string","pattern":"^rec_[0-9A-HJKMNP-TV-Z]{26}$"},"data":{"type":"object","description":"Projected record data after validation against the current collection schema.","additionalProperties":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","data","createdAt","updatedAt"]},"SiteDataRecordResponse":{"type":"object","properties":{"record":{"$ref":"#/components/schemas/SiteDataRecord"}},"required":["record"]},"SiteDataRecordListResponse":{"type":"object","properties":{"records":{"type":"array","items":{"$ref":"#/components/schemas/SiteDataRecord"}},"nextCursor":{"type":["string","null"]}},"required":["records","nextCursor"]},"SiteDataDeleteResponse":{"type":"object","properties":{"deleted":{"type":"boolean","const":true}},"required":["deleted"]},"ProfileSettings":{"type":"object","properties":{"profileFeedId":{"type":"string","pattern":"^pf_[a-z0-9]{10}$"},"username":{"type":"string","minLength":3,"maxLength":30},"enabled":{"type":"boolean"},"addNewSitesToProfile":{"type":"boolean"},"url":{"type":"string","format":"uri"},"feedUrl":{"type":"string","format":"uri"},"updatedAt":{"type":"string","format":"date-time"}},"required":["profileFeedId","username","enabled","addNewSitesToProfile","url","feedUrl","updatedAt"]},"ProfileSite":{"type":"object","properties":{"slug":{"type":"string"},"url":{"type":"string","format":"uri"},"thumbnailUrl":{"type":"string","format":"uri"},"addedAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"profileUpdatedAt":{"type":"string","format":"date-time"}},"required":["slug","url","thumbnailUrl","addedAt","updatedAt","profileUpdatedAt"],"additionalProperties":true},"ProfileResponse":{"allOf":[{"$ref":"#/components/schemas/ProfileSettings"},{"type":"object","properties":{"sites":{"type":"array","items":{"$ref":"#/components/schemas/ProfileSite"}}},"required":["sites"]}]},"ProfileSitesResponse":{"type":"object","properties":{"sites":{"type":"array","items":{"$ref":"#/components/schemas/ProfileSite"}}},"required":["sites"]},"ProfileSitesMutationResponse":{"type":"object","properties":{"success":{"type":"boolean"},"sites":{"type":"array","items":{"$ref":"#/components/schemas/ProfileSite"}}},"required":["success","sites"]},"ProfileSettingsPatchRequest":{"type":"object","properties":{"enabled":{"type":"boolean"},"addNewSitesToProfile":{"type":"boolean"}}},"ProfileUsernamePatchRequest":{"type":"object","properties":{"username":{"type":"string","minLength":1}},"required":["username"]},"ProfileSiteAddRequest":{"type":"object","properties":{"slug":{"type":"string","minLength":1}},"required":["slug"]},"PublishDetailsResponse":{"type":"object","properties":{"slug":{"type":"string"},"siteUrl":{"type":"string","format":"uri"},"status":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"expiresAt":{"type":["string","null"],"format":"date-time"},"currentVersionId":{"type":["string","null"]},"pendingVersionId":{"type":["string","null"]},"displayName":{"type":["string","null"],"maxLength":80},"displayDescription":{"type":["string","null"],"maxLength":280},"metadata":{"type":"object","properties":{"displayName":{"type":["string","null"],"maxLength":80},"displayDescription":{"type":["string","null"],"maxLength":280},"displayNameSource":{"type":["string","null"],"enum":["caller","content_generated","fallback",null]},"displayDescriptionSource":{"type":["string","null"],"enum":["caller","content_generated","fallback",null]}}},"manifest":{"type":"array","items":{"$ref":"#/components/schemas/PublishFile"}}},"required":["slug","siteUrl","status","createdAt","updatedAt","expiresAt","currentVersionId","pendingVersionId","manifest"]},"AnalyticsRange":{"type":"string","enum":["24h","7d","30d","90d","all"],"default":"30d"},"AnalyticsSeriesPoint":{"type":"object","properties":{"bucket":{"type":"string","format":"date","description":"UTC day in YYYY-MM-DD format."},"views":{"type":"integer","minimum":0},"visitors":{"type":"integer","minimum":0}},"required":["bucket","views","visitors"]},"SiteAnalyticsResponse":{"type":"object","properties":{"slug":{"type":"string"},"analyticsStartedAt":{"type":["string","null"],"format":"date-time"},"lastEventAt":{"type":["string","null"],"format":"date-time"},"range":{"$ref":"#/components/schemas/AnalyticsRange"},"totals":{"type":"object","properties":{"allTimeViews":{"type":"integer","minimum":0},"rangeViews":{"type":"integer","minimum":0},"rangeVisitors":{"type":"integer","minimum":0}},"required":["allTimeViews","rangeViews","rangeVisitors"]},"series":{"type":"array","items":{"$ref":"#/components/schemas/AnalyticsSeriesPoint"}},"topPaths":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"views":{"type":"integer","minimum":0}},"required":["path","views"]}},"topReferrers":{"type":"array","items":{"type":"object","properties":{"referrer":{"type":"string"},"views":{"type":"integer","minimum":0}},"required":["referrer","views"]}},"topCountries":{"type":"array","items":{"type":"object","properties":{"country":{"type":"string","description":"Coarse country code or Unknown."},"views":{"type":"integer","minimum":0}},"required":["country","views"]}},"topCrawlers":{"type":"array","items":{"type":"object","properties":{"crawler":{"type":"string"},"hits":{"type":"integer","minimum":0}},"required":["crawler","hits"]}},"top404Paths":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"referrer":{"type":"string"},"hits":{"type":"integer","minimum":0}},"required":["path","referrer","hits"]}}},"required":["slug","analyticsStartedAt","lastEventAt","range","totals","series","topPaths","topReferrers","topCountries","topCrawlers","top404Paths"]},"AccountAnalyticsResponse":{"type":"object","properties":{"analyticsStartedAt":{"type":["string","null"],"format":"date-time"},"lastEventAt":{"type":["string","null"],"format":"date-time"},"range":{"$ref":"#/components/schemas/AnalyticsRange"},"totals":{"type":"object","properties":{"allTimeViews":{"type":"integer","minimum":0},"rangeViews":{"type":"integer","minimum":0},"rangeVisitors":{"type":"integer","minimum":0},"assetHits":{"type":"integer","minimum":0},"notFoundHits":{"type":"integer","minimum":0},"botHits":{"type":"integer","minimum":0}},"required":["allTimeViews","rangeViews","rangeVisitors","assetHits","notFoundHits","botHits"]},"series":{"type":"array","items":{"$ref":"#/components/schemas/AnalyticsSeriesPoint"}},"topSites":{"type":"array","items":{"type":"object","properties":{"slug":{"type":"string"},"label":{"type":["string","null"],"description":"Vanity label for workspace sites served at {label}.{subdomain} hosts."},"siteUrl":{"type":"string","format":"uri"},"views":{"type":"integer","minimum":0},"visitors":{"type":"integer","minimum":0}},"required":["slug","label","siteUrl","views","visitors"]}},"topReferrers":{"type":"array","items":{"type":"object","properties":{"referrer":{"type":"string"},"views":{"type":"integer","minimum":0}},"required":["referrer","views"]}},"topPaths":{"type":"array","items":{"type":"object","properties":{"slug":{"type":"string"},"path":{"type":"string"},"views":{"type":"integer","minimum":0}},"required":["slug","path","views"]}},"topCountries":{"type":"array","items":{"type":"object","properties":{"country":{"type":"string","description":"Coarse country code or Unknown."},"views":{"type":"integer","minimum":0}},"required":["country","views"]}},"topCrawlers":{"type":"array","items":{"type":"object","properties":{"crawler":{"type":"string"},"hits":{"type":"integer","minimum":0}},"required":["crawler","hits"]}},"top404Paths":{"type":"array","items":{"type":"object","properties":{"slug":{"type":"string"},"path":{"type":"string"},"hits":{"type":"integer","minimum":0}},"required":["slug","path","hits"]}}},"required":["analyticsStartedAt","lastEventAt","range","totals","series","topSites","topReferrers","topPaths","topCountries","topCrawlers","top404Paths"]},"ClaimSiteRequest":{"type":"object","properties":{"claimToken":{"type":"string","minLength":1}},"required":["claimToken"]},"ClaimSiteResponse":{"type":"object","properties":{"success":{"type":"boolean"},"slug":{"type":"string"},"siteUrl":{"type":"string","format":"uri"},"expiresAt":{"type":"null"}},"required":["success","slug","siteUrl","expiresAt"]},"PublishMetadataPatchRequest":{"type":"object","properties":{"ttlSeconds":{"type":["integer","null"],"minimum":1},"viewer":{"$ref":"#/components/schemas/ViewerMetadata"},"password":{"type":["string","null"],"minLength":1,"maxLength":128},"spaMode":{"type":["boolean","null"]},"displayName":{"type":"string","minLength":1,"maxLength":80,"description":"Owner-facing Site title for dashboards, search, profile cards, and API responses."},"displayDescription":{"type":"string","minLength":1,"maxLength":280,"description":"Owner-facing Site summary for dashboards, search, and API responses."}}},"PublishMetadataPatchResponse":{"type":"object","properties":{"success":{"type":"boolean"},"passwordProtected":{"type":"boolean"},"spaMode":{"type":"boolean"},"note":{"type":"string"},"metadata":{"type":"object","description":"Returned when displayName or displayDescription is updated.","additionalProperties":true}},"required":["success"],"additionalProperties":true},"SiteAccessPolicy":{"type":"object","properties":{"mode":{"type":"string","enum":["anyone_with_link","password","restricted","account_members"],"description":"Active access mode for the Site."},"accessPolicyVersion":{"type":"integer","minimum":0,"description":"Increments on every access change. Changing the policy invalidates older viewer grants."},"allowedEmails":{"type":"array","items":{"type":"string","format":"email"},"description":"Exact-email allowlist. Empty unless mode is restricted."},"allowedDomains":{"type":"array","items":{"type":"string"},"description":"Email-domain allowlist. Empty unless mode is restricted."}},"required":["mode","accessPolicyVersion","allowedEmails","allowedDomains"]},"SiteAccessResponse":{"type":"object","properties":{"access":{"$ref":"#/components/schemas/SiteAccessPolicy"},"notifications":{"$ref":"#/components/schemas/SiteAccessNotifications","description":"Present on PATCH responses when notify is true and invite emails were sent or skipped."}},"required":["access"],"additionalProperties":true},"SiteAccessPatchRequest":{"type":"object","properties":{"mode":{"type":"string","enum":["anyone_with_link","restricted","account_members"],"description":"Target access mode. Use account_members only for workspace-owned Sites. Workspace-owned Sites accept anyone_with_link (public) or account_members here; restricted is personal-only. Use the metadata endpoint to enable password mode (personal and workspace Sites)."},"allowedEmails":{"type":"array","items":{"type":"string","format":"email"},"maxItems":200,"description":"Full replacement exact-email allowlist. Used only with restricted mode. Normalized to lowercase."},"allowedDomains":{"type":"array","items":{"type":"string"},"maxItems":200,"description":"Full replacement email-domain allowlist (e.g. example.com). Used only with restricted mode. Normalized to lowercase."},"notify":{"type":"boolean","description":"When true, sends invite emails to exact-email addresses newly added by this request. Confirm with the user before sending."}},"required":["mode"]},"SiteAccessInviteRequest":{"type":"object","properties":{"emails":{"type":"array","items":{"type":"string","format":"email"},"minItems":1,"maxItems":200}},"required":["emails"]},"SiteAccessNotifications":{"type":"object","properties":{"sent":{"type":"array","items":{"type":"string","format":"email"}},"failed":{"type":"array","items":{"type":"object","properties":{"email":{"type":"string","format":"email"},"error":{"type":"string"}},"required":["email","error"]}},"skipped":{"type":"array","items":{"type":"object","properties":{"email":{"type":"string","format":"email"},"reason":{"type":"string","enum":["not_allowed"]}},"required":["email","reason"]}}},"required":["sent","failed","skipped"]},"SiteAccessInviteResponse":{"type":"object","properties":{"notifications":{"$ref":"#/components/schemas/SiteAccessNotifications"}},"required":["notifications"]},"PublishFromDriveRequest":{"type":"object","properties":{"driveId":{"type":"string","minLength":1},"versionId":{"type":"string","minLength":1},"slug":{"type":"string","minLength":1},"spaMode":{"type":"boolean"},"password":{"type":"string","minLength":1,"maxLength":128},"viewer":{"$ref":"#/components/schemas/ViewerMetadata"}},"required":["driveId"]},"PublishFromDriveResponse":{"type":"object","properties":{"success":{"type":"boolean"},"slug":{"type":"string"},"siteUrl":{"type":"string","format":"uri"},"driveId":{"type":"string"},"driveVersionId":{"type":"string"},"currentVersionId":{"type":"string"},"filesCount":{"type":"integer"}},"required":["success","slug","siteUrl","driveId","driveVersionId","currentVersionId","filesCount"]},"Drive":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"description":{"type":["string","null"]},"isDefault":{"type":"boolean"},"headVersionId":{"type":["string","null"]},"dashboardUrl":{"type":"string","format":"uri"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","name","isDefault","headVersionId","dashboardUrl","createdAt","updatedAt"],"additionalProperties":true},"DriveCreateRequest":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":120},"description":{"type":["string","null"],"maxLength":2000},"isDefault":{"type":"boolean"}}},"DrivePatchRequest":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":120},"description":{"type":["string","null"],"maxLength":2000},"isDefault":{"type":"boolean"}}},"DriveResponse":{"type":"object","properties":{"drive":{"$ref":"#/components/schemas/Drive"},"headVersionId":{"type":["string","null"]},"token":{"type":"object","properties":{"id":{"type":"string"},"perms":{"type":"string","enum":["read","write"]},"manageTokens":{"type":"boolean"},"pathPrefix":{"type":["string","null"]},"expiresAt":{"type":["string","null"],"format":"date-time"}}}},"required":["drive"],"additionalProperties":true},"DriveListResponse":{"type":"object","properties":{"drives":{"type":"array","items":{"$ref":"#/components/schemas/Drive"}}},"required":["drives"]},"DeleteDriveResponse":{"type":"object","properties":{"success":{"type":"boolean"},"recoverableUntil":{"type":"string","format":"date-time"}},"required":["success","recoverableUntil"]},"DriveFile":{"type":"object","properties":{"path":{"type":"string"},"etag":{"type":"string"},"versionId":{"type":["string","null"]},"size":{"type":"integer"},"contentType":{"type":"string"},"sha256":{"type":"string"},"updatedAt":{"type":"string","format":"date-time"},"lastModifiedBy":{"type":["object","null"],"additionalProperties":true},"lastOperation":{"type":["string","null"]}},"required":["path","etag","versionId","size","contentType","sha256","updatedAt"]},"DriveFileListResponse":{"type":"object","properties":{"files":{"type":"array","items":{"$ref":"#/components/schemas/DriveFile"}},"nextCursor":{"type":["string","null"]}},"required":["files","nextCursor"]},"DriveUploadCreateRequest":{"type":"object","properties":{"path":{"type":"string","minLength":1},"size":{"type":"integer","minimum":0},"contentType":{"type":"string"},"sha256":{"type":"string","pattern":"^(sha256:)?[a-f0-9]{64}$"},"ifMatch":{"type":"string"},"ifNoneMatch":{"type":"string","const":"*"}},"required":["path","size"]},"DriveUploadCreateResponse":{"type":"object","properties":{"uploadId":{"type":"string"},"method":{"type":"string","const":"PUT"},"url":{"type":"string","format":"uri"},"headers":{"type":"object","additionalProperties":{"type":"string"}},"expiresInSeconds":{"type":"integer"}},"required":["uploadId","method","url","headers","expiresInSeconds"],"additionalProperties":true},"DriveFinalizeRequest":{"type":"object","properties":{"uploadId":{"type":"string","minLength":1},"path":{"type":"string","minLength":1}},"required":["uploadId"]},"DriveMoveRequest":{"type":"object","properties":{"from":{"type":"string","minLength":1},"to":{"type":"string","minLength":1},"ifMatch":{"type":"string","minLength":1},"overwriteIfMatch":{"type":"string","minLength":1}},"required":["from","to","ifMatch"]},"DriveBatchRequest":{"type":"object","properties":{"baseVersionId":{"type":"string"},"ops":{"type":"array","minItems":1,"maxItems":50,"items":{"type":"object","properties":{"op":{"type":"string","enum":["write","create","delete","move"]},"path":{"type":"string"},"from":{"type":"string"},"to":{"type":"string"},"uploadId":{"type":"string"},"ifMatch":{"type":"string"},"ifNoneMatch":{"type":"string","const":"*"},"overwriteIfMatch":{"type":"string"}},"required":["op"],"additionalProperties":false}}},"required":["ops"]},"DriveBatchResponse":{"type":"object","properties":{"success":{"type":"boolean"},"driveId":{"type":"string"},"versionId":{"type":"string"},"files":{"type":"array","items":{"$ref":"#/components/schemas/DriveFile"}},"deleted":{"type":"boolean"}},"additionalProperties":true},"DriveTokenCreateRequest":{"type":"object","properties":{"perms":{"type":"string","enum":["read","write"]},"permissions":{"type":"string","enum":["read","write"]},"manageTokens":{"type":"boolean","default":false},"pathPrefix":{"type":["string","null"]},"ttl":{"type":["string","null"],"example":"7d"},"label":{"type":["string","null"],"maxLength":200}}},"DriveToken":{"type":"object","properties":{"id":{"type":"string"},"perms":{"type":"string","enum":["read","write"]},"manageTokens":{"type":"boolean"},"pathPrefix":{"type":["string","null"]},"label":{"type":["string","null"]},"expiresAt":{"type":["string","null"],"format":"date-time"}},"additionalProperties":true},"DriveTokenListResponse":{"type":"object","properties":{"tokens":{"type":"array","items":{"$ref":"#/components/schemas/DriveToken"}}},"required":["tokens"]},"DriveTokenCreateResponse":{"type":"object","properties":{"token":{"type":"string","description":"Secret token value. Returned only when created."},"drive":{"$ref":"#/components/schemas/Drive"}},"additionalProperties":true},"CreateDomainRequest":{"type":"object","properties":{"domain":{"type":"string"}},"required":["domain"]},"DnsInstruction":{"type":"object","properties":{"type":{"type":"string"},"host":{"type":"string"},"value":{"type":"string"}},"required":["type","host","value"]},"DomainResponse":{"type":"object","properties":{"domain":{"type":"string"},"namespace_id":{"type":"string"},"status":{"type":"string","enum":["pending","active","error"]},"ssl_status":{"type":["string","null"]},"is_apex":{"type":"boolean"},"dns_instructions":{"type":"array","items":{"$ref":"#/components/schemas/DnsInstruction"}},"www_companion":{"type":"object","additionalProperties":true}},"additionalProperties":true},"DomainListResponse":{"type":"object","properties":{"domains":{"type":"array","items":{"$ref":"#/components/schemas/DomainResponse"}}},"required":["domains"]},"HandleRequest":{"type":"object","properties":{"handle":{"type":"string"},"username":{"type":"string"}}},"HandleResponse":{"type":"object","properties":{"handle":{"type":["string","null"]},"hostname":{"type":["string","null"]},"links":{"type":"array","items":{"$ref":"#/components/schemas/LinkResponse"}}},"additionalProperties":true},"LinkRequest":{"type":"object","properties":{"location":{"type":"string"},"mount_path":{"type":"string"},"slug":{"type":"string"},"domain":{"type":"string"},"namespace_id":{"type":"string"}},"required":["slug"]},"LinkPatchRequest":{"type":"object","properties":{"slug":{"type":"string"},"domain":{"type":"string"},"namespace_id":{"type":"string"}},"required":["slug"]},"LinkResponse":{"type":"object","properties":{"location":{"type":["string","null"]},"slug":{"type":["string","null"]},"hostname":{"type":["string","null"]},"url":{"type":["string","null"],"format":"uri"},"created_at":{"type":["string","null"],"format":"date-time"}},"additionalProperties":true},"LinkListResponse":{"type":"object","properties":{"hostname":{"type":["string","null"]},"links":{"type":"array","items":{"$ref":"#/components/schemas/LinkResponse"}}},"required":["links"]},"DeleteLinkResponse":{"type":"object","properties":{"deleted":{"type":"boolean"},"location":{"type":["string","null"]}},"required":["deleted"]},"WorkspaceProvisioningNamespace":{"type":"object","properties":{"namespaceId":{"type":"string","format":"uuid"},"hostname":{"type":"string"},"status":{"type":"string","enum":["active","pending","error"]},"sslStatus":{"type":["string","null"]},"cfCustomHostnameId":{"type":["string","null"]},"routingMode":{"type":"string","enum":["serve","redirect"]},"createdAt":{"type":"string","format":"date-time"}},"required":["namespaceId","hostname","status","sslStatus","cfCustomHostnameId","routingMode","createdAt"]},"WorkspaceDcvDelegation":{"type":"object","properties":{"cname":{"type":"string"},"cnameTarget":{"type":"string"},"recordId":{"type":"string"}},"required":["cname","cnameTarget"]},"WorkspaceWildcardDnsRecord":{"type":"object","properties":{"name":{"type":"string"},"content":{"type":"string"},"recordId":{"type":"string"}},"required":["name","content"]},"WorkspaceWildcardProvisioning":{"type":"object","properties":{"hostname":{"type":"string"},"wildcardHostname":{"type":"string"},"customHostnameId":{"type":["string","null"]},"sslStatus":{"type":["string","null"]},"active":{"type":"boolean"},"dcvDelegation":{"anyOf":[{"$ref":"#/components/schemas/WorkspaceDcvDelegation"},{"type":"null"}]},"wildcardDnsRecord":{"anyOf":[{"$ref":"#/components/schemas/WorkspaceWildcardDnsRecord"},{"type":"null"}]},"error":{"type":"string"}},"required":["hostname","wildcardHostname","customHostnameId","sslStatus","active","dcvDelegation","wildcardDnsRecord"]},"WorkspaceProvisioningResponse":{"type":"object","properties":{"accountId":{"type":"string","format":"uuid"},"subdomain":{"type":"string"},"hostname":{"type":"string"},"provisioningStatus":{"type":"string","enum":["active","degraded"]},"namespace":{"$ref":"#/components/schemas/WorkspaceProvisioningNamespace"},"kvSynced":{"type":"boolean"},"wildcard":{"$ref":"#/components/schemas/WorkspaceWildcardProvisioning"}},"required":["accountId","subdomain","hostname","provisioningStatus","namespace","kvSynced","wildcard"]},"WorkspaceSiteLabelRequest":{"type":"object","properties":{"label":{"type":"string","minLength":1,"maxLength":63,"pattern":"^[a-z0-9][a-z0-9-]*[a-z0-9]$","description":"Exact workspace URL label, e.g. `q3-board-deck` in `q3-board-deck.zora.oi.mrdk.io`."},"slug":{"type":"string","minLength":1,"description":"Active Site slug already owned by the workspace account."}},"required":["label","slug"]},"WorkspaceSiteLabelRoute":{"type":"object","properties":{"type":{"type":"string","enum":["workspace_label","workspace_label_redirect"]},"accountId":{"type":"string","format":"uuid"},"workspaceHost":{"type":"string"},"hostname":{"type":"string"},"label":{"type":"string"},"slug":{"type":"string"},"redirectToLabel":{"type":"string"},"redirectCode":{"type":"integer","enum":[302,307]}},"additionalProperties":false},"WorkspaceSiteLabel":{"type":"object","properties":{"labelId":{"type":"string","format":"uuid"},"accountId":{"type":"string","format":"uuid"},"label":{"type":"string"},"slug":{"type":["string","null"]},"status":{"type":"string","enum":["reserved","active","redirect","deleted"]},"redirectToLabel":{"type":["string","null"]},"redirectCode":{"type":["integer","null"],"enum":[302,307,null]},"workspaceHost":{"type":"string"},"hostname":{"type":"string"},"url":{"type":"string","format":"uri"},"route":{"anyOf":[{"$ref":"#/components/schemas/WorkspaceSiteLabelRoute"},{"type":"null"}]},"createdByUserId":{"type":["string","null"],"format":"uuid"},"updatedByUserId":{"type":["string","null"],"format":"uuid"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["labelId","accountId","label","slug","status","workspaceHost","hostname","url","route"]},"WorkspaceSiteLabelResponse":{"type":"object","properties":{"siteLabel":{"$ref":"#/components/schemas/WorkspaceSiteLabel"},"kvSynced":{"type":"boolean","description":"Whether label routing KV was synced immediately. A false value means the dirty namespace queue can reconcile later."}},"required":["siteLabel","kvSynced"]},"WorkspaceSiteLabelListResponse":{"type":"object","properties":{"accountId":{"type":"string","format":"uuid"},"siteLabels":{"type":"array","items":{"$ref":"#/components/schemas/WorkspaceSiteLabel"}}},"required":["accountId","siteLabels"]},"WorkspaceAccount":{"type":"object","properties":{"accountId":{"type":"string","format":"uuid"},"type":{"type":"string","enum":["personal","org"]},"displayName":{"type":"string"},"iconEmoji":{"type":["string","null"],"description":"Workspace icon: a single emoji, or null when unset."},"subdomain":{"type":["string","null"]},"status":{"type":"string","enum":["active","suspended","deleted"]},"provisioningStatus":{"type":"string","enum":["provisioning","active","degraded","failed"]},"role":{"type":"string","enum":["admin","member"]},"selector":{"type":"object","description":"Selector values for X-Oi-Account / body account. Prefer the immutable id for stored automations.","properties":{"id":{"type":"string","format":"uuid"},"subdomain":{"type":["string","null"]}}}},"additionalProperties":true,"required":["accountId","type","displayName","status","provisioningStatus","role"]},"AccountListResponse":{"type":"object","properties":{"accounts":{"type":"array","items":{"$ref":"#/components/schemas/WorkspaceAccount"}},"currentAccountId":{"type":["string","null"],"format":"uuid"},"selectorError":{"type":["object","null"],"additionalProperties":true},"joinable":{"type":"array","items":{"$ref":"#/components/schemas/JoinableWorkspace"},"description":"Only present with includeJoinable=1: workspaces the caller could join right now via an active auto-join rule matching their email domain."}},"required":["accounts","currentAccountId"]},"JoinableWorkspace":{"type":"object","properties":{"accountId":{"type":"string","format":"uuid"},"displayName":{"type":"string"},"iconEmoji":{"type":["string","null"]},"subdomain":{"type":["string","null"]},"domain":{"type":"string","description":"The email domain whose active auto-join rule makes the caller eligible."},"joinEndpoint":{"type":"string","description":"POST here to join (the domain-rules apply endpoint)."}},"required":["accountId","displayName","domain","joinEndpoint"]},"WorkspaceCreateRequest":{"type":"object","properties":{"displayName":{"type":"string","minLength":1,"maxLength":80},"subdomain":{"type":["string","null"],"description":"Workspace subdomain to claim ({subdomain}.oi.mrdk.io). Omit to create the workspace without a home; provisioning requires it."}},"required":["displayName"]},"WorkspaceCreateResponse":{"type":"object","properties":{"account":{"$ref":"#/components/schemas/WorkspaceAccount"},"provisioning":{"type":["object","null"],"description":"Provisioning readiness when a subdomain was claimed. status=active means the workspace home and label URLs are ready; degraded includes a retryEndpoint.","properties":{"status":{"type":"string","enum":["provisioning","active","degraded","failed"]},"workspaceHost":{"type":"string"},"workspaceHomeUrl":{"type":["string","null"],"format":"uri"},"kvSynced":{"type":"boolean"},"wildcard":{"type":"object","additionalProperties":true},"retryEndpoint":{"type":"string"},"error":{"type":"string"},"note":{"type":"string"}},"additionalProperties":true}},"required":["account"]},"WorkspaceSiteLabelRenameRequest":{"type":"object","properties":{"label":{"type":"string","minLength":1,"maxLength":63,"description":"New DNS-safe workspace label. The old label becomes a temporary redirect."}},"required":["label"]},"WorkspaceSiteLabelRenameResponse":{"type":"object","properties":{"siteLabel":{"$ref":"#/components/schemas/WorkspaceSiteLabel"},"previousLabel":{"type":"string"},"redirect":{"anyOf":[{"$ref":"#/components/schemas/WorkspaceSiteLabelRoute"},{"type":"null"}],"description":"Redirect tombstone route for the previous label; null when renaming to the same label."},"kvSynced":{"type":"boolean"}},"required":["siteLabel","previousLabel","kvSynced"]},"WorkspaceMember":{"type":"object","properties":{"userId":{"type":"string","format":"uuid"},"email":{"type":["string","null"]},"role":{"type":"string","enum":["admin","member"]},"status":{"type":"string"},"source":{"type":"string","description":"How the membership was created (e.g. invite, domain_rule, creator)."},"sourceEmail":{"type":["string","null"]},"joinedAt":{"type":["string","null"],"format":"date-time"},"removedAt":{"type":["string","null"],"format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"additionalProperties":true,"required":["userId","role","status"]},"WorkspaceMemberResponse":{"type":"object","properties":{"member":{"$ref":"#/components/schemas/WorkspaceMember"}},"required":["member"]},"WorkspaceMemberListResponse":{"type":"object","properties":{"accountId":{"type":"string","format":"uuid"},"members":{"type":"array","items":{"$ref":"#/components/schemas/WorkspaceMember"}}},"required":["accountId","members"]},"WorkspaceMemberAddRequest":{"type":"object","properties":{"email":{"type":"string","format":"email","description":"Email of an existing oi user."},"role":{"type":"string","enum":["admin","member"],"default":"member"}},"required":["email"]},"WorkspaceMemberRoleRequest":{"type":"object","properties":{"role":{"type":"string","enum":["admin","member"]}},"required":["role"]},"WorkspaceInvite":{"type":"object","properties":{"inviteId":{"type":"string","format":"uuid"},"accountId":{"type":"string","format":"uuid"},"email":{"type":"string"},"role":{"type":"string","enum":["admin","member"]},"status":{"type":"string"},"invitedByUserId":{"type":["string","null"],"format":"uuid"},"invitedByEmail":{"type":["string","null"]},"expiresAt":{"type":["string","null"],"format":"date-time"},"revokedAt":{"type":["string","null"],"format":"date-time"},"acceptedAt":{"type":["string","null"],"format":"date-time"},"acceptedByUserId":{"type":["string","null"],"format":"uuid"}},"additionalProperties":true,"required":["inviteId","accountId","email","role","status"]},"WorkspaceInviteListResponse":{"type":"object","properties":{"accountId":{"type":"string","format":"uuid"},"invites":{"type":"array","items":{"$ref":"#/components/schemas/WorkspaceInvite"}}},"required":["accountId","invites"]},"MyInvite":{"type":"object","properties":{"inviteId":{"type":"string","format":"uuid"},"accountId":{"type":"string","format":"uuid"},"email":{"type":"string","description":"The invited email (the caller's sign-in email)."},"role":{"type":"string","enum":["admin","member"]},"status":{"type":"string"},"invitedByEmail":{"type":["string","null"]},"expiresAt":{"type":["string","null"],"format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"workspace":{"type":"object","properties":{"displayName":{"type":"string"},"subdomain":{"type":["string","null"]},"iconEmoji":{"type":["string","null"]}},"required":["displayName"]},"acceptEndpoint":{"type":"string","description":"POST here to accept the invite."},"declineEndpoint":{"type":"string","description":"POST here to decline the invite."}},"required":["inviteId","accountId","email","role","status","workspace","acceptEndpoint","declineEndpoint"]},"MyInviteListResponse":{"type":"object","properties":{"invites":{"type":"array","items":{"$ref":"#/components/schemas/MyInvite"}}},"required":["invites"]},"WorkspaceInviteCreateRequest":{"type":"object","properties":{"email":{"type":"string","format":"email"},"role":{"type":"string","enum":["admin","member"],"default":"member"}},"required":["email"]},"WorkspaceInviteCreateResponse":{"type":"object","properties":{"invite":{"$ref":"#/components/schemas/WorkspaceInvite"},"emailSent":{"type":"boolean"}},"required":["invite","emailSent"]},"WorkspaceDomainRule":{"type":"object","properties":{"ruleId":{"type":"string","format":"uuid"},"accountId":{"type":"string","format":"uuid"},"domain":{"type":"string"},"mode":{"type":"string"},"status":{"type":"string","enum":["active","disabled"]},"disabledAt":{"type":["string","null"],"format":"date-time"},"createdByUserId":{"type":["string","null"],"format":"uuid"},"createdByEmail":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"additionalProperties":true,"required":["ruleId","accountId","domain","status"]},"WorkspaceDomainRuleListResponse":{"type":"object","properties":{"accountId":{"type":"string","format":"uuid"},"domainRules":{"type":"array","items":{"$ref":"#/components/schemas/WorkspaceDomainRule"}}},"required":["accountId","domainRules"]},"WorkspaceUpdateRequest":{"type":"object","description":"At least one property is required.","properties":{"displayName":{"type":"string","minLength":1,"maxLength":80},"iconEmoji":{"type":["string","null"],"description":"Single emoji, or null to clear the icon."}}},"WorkspaceUpdateResponse":{"type":"object","properties":{"account":{"type":"object","properties":{"accountId":{"type":"string","format":"uuid"},"displayName":{"type":"string"},"iconEmoji":{"type":["string","null"]},"subdomain":{"type":["string","null"]}},"required":["accountId","displayName"]}},"required":["account"]},"WorkspaceDeleteResponse":{"type":"object","properties":{"deleted":{"type":"boolean"},"accountId":{"type":"string","format":"uuid"},"displayName":{"type":"string"},"subdomain":{"type":["string","null"]},"sites":{"type":"integer"},"customDomains":{"type":"integer"}},"additionalProperties":true,"required":["deleted","accountId"]},"VariableListResponse":{"type":"object","properties":{"variables":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"additionalProperties":true}}},"required":["variables"]},"VariableSetRequest":{"type":"object","properties":{"value":{"type":"string"},"pinToUpstreamOrigin":{"type":"boolean"}},"required":["value"]},"VariableResponse":{"type":"object","properties":{"success":{"type":"boolean"},"name":{"type":"string"}},"additionalProperties":true},"SupportRequest":{"type":"object","properties":{"subject":{"type":"string","minLength":1,"maxLength":200},"message":{"type":"string","minLength":1,"maxLength":5000}},"required":["subject","message"]},"ApiKeyListResponse":{"type":"object","properties":{"keys":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Key UUID, or `legacy` for the original sign-up key."},"name":{"type":"string","description":"Key label; blank for the original sign-up key."},"key":{"type":"string","description":"Full API key value."},"keySuffix":{"type":"string","description":"Last 4 characters of the key, for display."},"createdAt":{"type":"string","format":"date-time"},"lastUsedAt":{"type":"string","format":"date-time","nullable":true},"current":{"type":"boolean","description":"True for the key that authenticated this request."}},"required":["id","name","key","keySuffix","createdAt"]}},"limit":{"type":"integer","description":"Maximum active named keys per account."}},"required":["keys","limit"]},"ApiKeyCreateRequest":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":64,"description":"Label for the key, e.g. the agent or tool that will use it (claude, cursor)."}},"required":["name"]},"ApiKeyCreateResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"key":{"type":"string","description":"Full API key (`oik_` prefix)."},"keySuffix":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}},"required":["id","name","key","keySuffix","createdAt"]},"ApiKeyRevokeResponse":{"type":"object","properties":{"revoked":{"type":"boolean","const":true},"id":{"type":"string"}},"required":["revoked","id"]}}}}