{"openapi":"3.1.0","info":{"title":"Libot Cloud Services API","description":"REST API for managing data contracts (ODCS — Open Data Contract Standard) and data products (ODPS — Open Data Product Standard). Part of the Bitol ecosystem by jgp.ai.\n\nHandles user management, contract validation and transformation (YAML, DDL, PDF), contract comparison with semver impact analysis, maturity assessment, lifecycle tracking, reference tags, Credits (API credit) system, GitHub Actions integration, and data product generation.\n\n## Authentication\n\nThis API supports two authentication mechanisms depending on the endpoint version:\n\n### V2/V3/V4 endpoints — Bearer JWT via OAuth 2.1 (recommended)\n\nModern endpoints accept Bearer JWTs minted by the Bitol authorization server.\nFirst-party and third-party clients obtain tokens through the OAuth 2.1\nauthorization-code + PKCE flow:\n\n**Step 1 — Redirect the user to:**\n\n```\nGET /oauth2/authorize\n  ?response_type=code\n  &client_id=<your-client-id>\n  &redirect_uri=<your-redirect-uri>\n  &code_challenge=<S256(verifier)>\n  &code_challenge_method=S256\n  &scope=openid\n```\n\n**Step 2 — Exchange the returned code for tokens:**\n\n```\nPOST /oauth2/token\nContent-Type: application/x-www-form-urlencoded\n\ngrant_type=authorization_code\n&code=<code>\n&redirect_uri=<your-redirect-uri>\n&code_verifier=<verifier>\n&client_id=<your-client-id>\n```\n\n**Step 3 — Use the token in subsequent requests:**\n\n```\nAuthorization: Bearer <accessToken>\n```\n\n**Step 4 — Refresh before expiry via `POST /oauth2/token` with\n`grant_type=refresh_token`.**\n\nThe previous bespoke `/v2/auth/{login,refresh,logout,verify,register,signup-request}`\nand `/v3/auth/device-code{,/poll,/confirm}` surfaces were removed in v7. Stale\nclients hitting those URLs receive HTTP 410 with a typed\n`LEGACY_AUTH_DEACTIVATED` envelope pointing at the replacements.\n\n### V1 endpoints — API Key + Password headers\n\nLegacy V1 endpoints authenticate via two custom headers sent together:\n- `X-API-KEY` — UUID obtained during user registration or via `GET /v1/users/key`\n- `X-USER-PASSWORD` — the user's plaintext password (verified server-side via BCrypt)\n\n### Public endpoints (no authentication required)\n\n- `GET /signin` — AS-hosted credential form (entry point for /oauth2/authorize)\n- `POST /oauth2/token` — OAuth 2.1 token endpoint (authorization‐code, refresh‐token)\n- `POST /v4/users/register` — Create a new account\n- `POST /v4/users/verify` — Verify email with the activation code\n- `POST /v4/users/signup-request` — Request to join (Grand Opening queue)\n- `POST /v1/users` — Create a new user (V1)\n- `GET /v1/validate` — Activate account with email code\n- `GET /v1/health` — Health check\n- `POST /v1/diagnostics` — Submit front-end error report\n\n### Admin endpoints\n\nSome endpoints require admin privileges. The authenticated user must have the `admin` flag set in their account. Admin endpoints are only visible in the **Admin API** group.\n\n## Limitations\n\n- **Email addresses** must not contain a `+` character.\n- **Blocked email domains** (registration): gmail.com, yahoo.com, hotmail.com, outlook.com, aol.com, protonmail.com, icloud.com, mail.com, yandex.com, live.com, msn.com, gmx.com, zoho.com, tutanota.com, pm.me.\n- **Contract files** must have an `.odcs.yaml` extension.\n- **Product files** must have an `.odps.yaml` extension.\n- **Logo files** must be valid SVG (content must start with `<svg` or contain the SVG namespace URI).\n- **DDL subformat**: only `PostgreSQL` is currently supported.","contact":{"name":"Jean-Georges Perrin","url":"https://jgp.ai","email":"jgp@jgp.ai"},"license":{"name":"Proprietary"},"version":"8.28.1"},"servers":[{"url":"https://api.jgp.ai","description":"Production"},{"url":"http://localhost:8080","description":"Local development"}],"security":[{"ApiKeyAuth":[],"PasswordAuth":[]}],"tags":[{"name":"Publishing","description":"Integration defaults for publishing to external platforms"},{"name":"Administration","description":"Administrative endpoints (activity logs, user listing, user deletion)"},{"name":"Publishing","description":"Logo upload and PDF rendering settings (v4 copy of /v2 publishing — #560 AC-4)"},{"name":"Org Agent Providers","description":"Organization-registered A2A agent providers (#961)"},{"name":"Administration","description":"Admin-only endpoints — per-org feature configuration (#1025)"},{"name":"Publishing","description":"Logo upload and PDF rendering settings"},{"name":"Products","description":"Create, upload, list, and retrieve data products (ODPS)"},{"name":"External Catalogs","description":"Browse external data catalogs and import datasets as contracts"},{"name":"Lifecycle","description":"V3 artifact lifecycle tracking with org context"},{"name":"Administration","description":"Admin-only endpoints with Bearer JWT authentication"},{"name":"Membership","description":"Organization membership management (param-form org addressing — #651)"},{"name":"Administration","description":"Admin-only endpoints — onboarding funnel (#1007)"},{"name":"Administration","description":"Service health check with optional Bearer JWT authentication"},{"name":"Products","description":"Data product endpoints with Bearer JWT authentication"},{"name":"Publishing","description":"Integration defaults for publishing to external platforms (v4 copy of /v2 — #560 AC-4)"},{"name":"Contracts","description":"Upload, list, retrieve, and transform data contracts (ODCS YAML, DDL, PDF)"},{"name":"Diagnostics","description":"Front-end error reporting and admin review"},{"name":"Org Settings","description":"Organization-scoped integration management"},{"name":"Service Accounts","description":"Org-owned OAuth2 machine identities (client_credentials grant) for CI/CD — #197"},{"name":"Automation","description":"Workflow installation, secrets management, and Actions triggering"},{"name":"Products","description":"V3 data product CRUD endpoints with unified org context"},{"name":"Templates","description":"V4 catalog of pre-built ODCS contract templates"},{"name":"Products","description":"Data product creation, upload, and retrieval (ODPS)"},{"name":"Org Settings","description":"Organization settings — logo, PDF configuration, GitHub token, domain management"},{"name":"Comments","description":"Comments and task assignment on artifacts (v4, experimental)"},{"name":"Diagnostics","description":"Front-end error reporting and admin review (v4 copy of /v1/diagnostics — #560 AC-3d)"},{"name":"Users","description":"User registration, authentication, profile management, and administration"},{"name":"Contracts","description":"Data contract endpoints with enhanced GitHub publishing (v3)"},{"name":"Credits","description":"Deprecated — the Credits surface is renamed to Credits (#871); use the /credits/* twins. The Credits name is being retired."},{"name":"Diagnostics","description":"Test-run story steps (screenshots + timeline) — #712"},{"name":"Onboarding","description":"Onboarding funnel tracking (#1007)"},{"name":"Credits","description":"Organization Credits management"},{"name":"Users","description":"User profile endpoints (v4 copy of /v2 users — #560 AC-4)"},{"name":"Lifecycle","description":"Artifact lifecycle tracking with Bearer JWT authentication"},{"name":"GitHub Crawl Import","description":"Experimental deterministic derivation of contracts/products from Teradata ETL in GitHub"},{"name":"Membership","description":"Organization membership management with Bearer JWT authentication"},{"name":"Maturity History","description":"V3 maturity distribution history over time"},{"name":"Contact Sync","description":"Sync external contacts to MailerLite"},{"name":"Administration","description":"Admin-only endpoints for activity logs and system monitoring"},{"name":"Contact Sync","description":"Sync external contacts to MailerLite (v4)"},{"name":"OAuth 2.1","description":"OAuth 2.1 authorization-code + refresh-token grants at /oauth2/* (post-v7 replacement for /v2/auth)"},{"name":"Org Products","description":"Organization-scoped data product endpoints (v4 copy of /v2 — #560 AC-4)"},{"name":"Maturity History","description":"Maturity distribution history over time (v4 copy of /v3/maturity-history — #560 AC-4)"},{"name":"Lifecycle","description":"Artifact lifecycle tracking for contracts and products"},{"name":"Org Products","description":"Organization-scoped data product endpoints with Bearer JWT authentication"},{"name":"Org Contracts","description":"Organization-scoped data contract endpoints (v4 copy of /v2 — #560 AC-4)"},{"name":"AI","description":"V4 AI text-suggestion proxy for the Workbench"},{"name":"Publishing","description":"Integration credential management for external platforms"},{"name":"Contracts","description":"Data contract endpoints with Bearer JWT authentication"},{"name":"Data Sources","description":"Reusable named JDBC data-source credentials for contract test execution (#718)"},{"name":"External Catalogs","description":"Browse external data catalogs and import datasets as contracts (v4 copy of /v3/catalogs — #560 AC-4)"},{"name":"Import","description":"Bulk import of ODCS/ODPS artifacts from a ZIP archive"},{"name":"Users","description":"User lifecycle: register, verify email, request to join"},{"name":"Org Settings","description":"Organization-scoped integration defaults"},{"name":"Contracts","description":"Data contract upload, retrieval, and format conversion (ODCS)"},{"name":"Credits","description":"Admin Credits management"},{"name":"Publishing","description":"Logo upload and PDF rendering settings with Bearer JWT authentication"},{"name":"DDL","description":"SQL DDL generation from data contracts and data products"},{"name":"Tags","description":"Reference tags and tag cloud for data contracts and products"},{"name":"Notifications","description":"Per-user notification feed derived from comments and task assignments"},{"name":"Tags","description":"V4 tag cloud and counts (org-aware)"},{"name":"Products","description":"Data product endpoints with enhanced GitHub publishing (v3)"},{"name":"Artifacts","description":"V4 unified artifact listing (contracts + products)"},{"name":"Org Contracts","description":"Organization-scoped data contract endpoints with Bearer JWT authentication"},{"name":"Contracts","description":"V3 data contract CRUD endpoints with unified org context"},{"name":"Users","description":"User profile endpoints with Bearer JWT authentication"},{"name":"Automation","description":"Workflow installation, secrets management, and Actions triggering (v4)"},{"name":"Lifecycle","description":"Artifact lifecycle tracking for contracts and products (v4)"},{"name":"Credits","description":"API credit management"},{"name":"Presence","description":"Active viewers of contracts and products"},{"name":"Administration","description":"Admin-only endpoints — global feature flags (#1022)"},{"name":"Org Settings","description":"Organization-scoped integration management (param-form org addressing — #651)"},{"name":"Platform","description":"Global platform feature flags (#1022)"},{"name":"Org Settings","description":"Organization-scoped GitHub integration defaults (param-form org addressing — #651)"},{"name":"Org Settings","description":"Organization logo and PDF rendering settings (param-form org addressing — #651)"},{"name":"Users","description":"User registration, authentication, profile management, and account activation"},{"name":"Administration","description":"V4 health check with Bearer JWT authentication (#569)"},{"name":"Org Settings","description":"Organization logo and PDF rendering settings"},{"name":"Maturity Model","description":"Read-only maturity-model definitions (levels + criteria) for contracts and products"},{"name":"Organizations","description":"Organization management (param-form org addressing — #651)"},{"name":"Publishing","description":"Upload logos and configure PDF output settings for branded reports"},{"name":"Signing","description":"Signing key and certificate management (v4)"},{"name":"Credits","description":"v2 Credits routes for the iOS surface"},{"name":"Organizations","description":"Organization management — create, discover, search, update, delete"},{"name":"Administration","description":"Admin-only endpoints (v4 copy of /v2 admin — #560 AC-4)"},{"name":"Products","description":"Data product management (ODPS)"},{"name":"Verification","description":"Public signature verification (no authentication required)"},{"name":"Publishing","description":"Integration credential management for external platforms (v4 copy of /v2 — #560 AC-4)"},{"name":"Organizations","description":"Organization management with Bearer JWT authentication"},{"name":"Tags","description":"Reference tags and tag cloud (v4)"},{"name":"Credits","description":"Credits — API credit balance, transactions, usage tracking, redemption, and cost management (successor of the Credits surface, #871)"}],"paths":{"/v4/users/me/integrations/{key}":{"put":{"tags":["Publishing"],"summary":"Store integration credentials","description":"**Since v7.6.0** — Sets credentials for the specified integration (github, zeenea, or controlcenter).","operationId":"setCredentials","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","additionalProperties":{}}}},"required":true},"responses":{"200":{"description":"Credentials saved","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Unknown integration key","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"integration.update","description":"Store integration credentials"}],"x-since":"7.6.0"},"delete":{"tags":["Publishing"],"summary":"Remove integration credentials","description":"**Since v7.6.0** — Clears all fields for the specified integration. Defaults are preserved.","operationId":"removeCredentials","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"integration.delete","description":"Remove integration credentials"}],"x-since":"7.6.0"}},"/v4/users/me/integrations/github/defaults":{"get":{"tags":["Publishing"],"summary":"Get GitHub defaults","description":"**Since v7.6.0** — Returns the user's configured GitHub publishing defaults.","operationId":"getDefaults","responses":{"200":{"description":"Current defaults","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"integration.defaults.get","description":"Get GitHub publishing defaults"}],"x-since":"7.6.0"},"put":{"tags":["Publishing"],"summary":"Set GitHub defaults","description":"**Since v7.6.0** — Configures default repository, branch, commit message template, and auto-publish flag for GitHub publishing.","operationId":"setDefaults","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GitHubDefaultsRequest"}}},"required":true},"responses":{"200":{"description":"Defaults configured","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"integration.defaults.update","description":"Set GitHub publishing defaults"}],"x-since":"7.6.0"},"delete":{"tags":["Publishing"],"summary":"Reset GitHub defaults","description":"**Since v7.6.0** — Clears all GitHub publishing defaults for the authenticated user.","operationId":"resetDefaults","responses":{"200":{"description":"Defaults cleared","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"integration.defaults.delete","description":"Reset GitHub publishing defaults"}],"x-since":"7.6.0"}},"/v4/reference-tags/{tagName}":{"get":{"tags":["Tags"],"summary":"Get a reference tag (v4, born-deprecated)","description":"**Since v7.1.3** — Returns details of a specific reference tag. Verbatim copy of /v1/reference-tags/{tagName}.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"getTag","parameters":[{"name":"tagName","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"reference-tag.get","description":"Get a reference tag"}],"x-since":"7.1.3","x-sunset":"2027-01-01"},"put":{"tags":["Tags"],"summary":"Update a reference tag (v4, born-deprecated)","description":"**Since v7.1.3** — Updates the properties and/or description of an existing reference tag. Verbatim copy of PUT /v1/reference-tags/{tagName}.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"updateTag","parameters":[{"name":"tagName","in":"path","required":true,"schema":{"type":"string"}},{"name":"properties","in":"query","required":false,"schema":{"type":"string"}},{"name":"description","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"reference-tag.update","description":"Update a reference tag"}],"x-since":"7.1.3","x-sunset":"2027-01-01"},"delete":{"tags":["Tags"],"summary":"Delete a reference tag (v4, born-deprecated)","description":"**Since v7.1.3** — Deletes a reference tag. Verbatim copy of DELETE /v1/reference-tags/{tagName}.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"deleteTag","parameters":[{"name":"tagName","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"reference-tag.delete","description":"Delete a reference tag"}],"x-since":"7.1.3","x-sunset":"2027-01-01"}},"/v4/reference-tags/{tagName}/apply-changes":{"put":{"tags":["Tags"],"summary":"Apply tag changes (v4, born-deprecated)","description":"**Since v7.1.3** — Applies reference tag changes to selected artifacts with specified versions. Verbatim copy of PUT /v1/reference-tags/{tagName}/apply-changes.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"applyChanges","parameters":[{"name":"tagName","in":"path","required":true,"schema":{"type":"string"}},{"name":"properties","in":"query","required":true,"schema":{"type":"string"}},{"name":"description","in":"query","required":false,"schema":{"type":"string","default":""}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","additionalProperties":{}}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"reference-tag.changes.apply","description":"Apply reference tag changes to artifacts"}],"x-since":"7.1.3","x-sunset":"2027-01-01"}},"/v4/reference-tags/{tagName}/analyze-impact":{"put":{"tags":["Tags"],"summary":"Analyze tag impact (v4, born-deprecated)","description":"**Since v7.1.3** — Analyzes which artifacts would be affected by changing this reference tag. Verbatim copy of PUT /v1/reference-tags/{tagName}/analyze-impact.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"analyzeImpact","parameters":[{"name":"tagName","in":"path","required":true,"schema":{"type":"string"}},{"name":"properties","in":"query","required":true,"schema":{"type":"string"}},{"name":"description","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"reference-tag.impact.analyze","description":"Analyze the impact of changing a reference tag"}],"x-since":"7.1.3","x-sunset":"2027-01-01"}},"/v4/products/lifecycle/{id}":{"put":{"tags":["Lifecycle"],"summary":"Edit a product lifecycle entry (v4, born-deprecated)","description":"**Since v7.1.6** — Verbatim copy of PUT /v1/products/lifecycle/{id}.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"updateProductLifecycleEntry","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LifecycleUpdateRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"lifecycle.product.update","description":"Edit a product lifecycle entry"}],"x-since":"7.1.6","x-sunset":"2027-01-01"}},"/v4/orgs":{"get":{"tags":["Organizations"],"summary":"Get organization","description":"**Since v7.26.0** — Returns organization details including associated domains. Pass org (slug) or orgId (UUID) to select the organization.","operationId":"getOrg","parameters":[{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Organization details","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Missing org/orgId parameter","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"org.get","description":"Get an organization by slug"}],"x-since":"7.26.0"},"put":{"tags":["Organizations"],"summary":"Update organization","description":"**Since v7.26.0** — Updates organization details (name, phone, address, etc.). Slug cannot be changed. Pass org (slug) or orgId (UUID) to select the organization.","operationId":"updateOrg","parameters":[{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"name","in":"query","required":false,"schema":{"type":"string"}},{"name":"phone","in":"query","required":false,"schema":{"type":"string"}},{"name":"address","in":"query","required":false,"schema":{"type":"string"}},{"name":"city","in":"query","required":false,"schema":{"type":"string"}},{"name":"state","in":"query","required":false,"schema":{"type":"string"}},{"name":"postalCode","in":"query","required":false,"schema":{"type":"string"}},{"name":"country","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Organization updated","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Missing org/orgId parameter or invalid update","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"org.update","description":"Update organization details"}],"x-since":"7.26.0"},"post":{"tags":["Organizations"],"summary":"Create an organization","description":"**Since v7.7.0** — Creates a new organization with the given name, slug, and optional domains. The authenticated user becomes the creator.","operationId":"createOrg","parameters":[{"name":"name","in":"query","required":true,"schema":{"type":"string"}},{"name":"slug","in":"query","required":true,"schema":{"type":"string"}},{"name":"domains","in":"query","required":false,"schema":{"type":"array","items":{"type":"string"}}},{"name":"Idempotency-Key","in":"header","description":"Optional. Opaque, client-generated value (≤ 255 chars). When supplied, the server caches the response of the first successful invocation and replays it on a retry with the same key. Scoped to (user, method, path). TTL configurable via bitol.idempotency.ttl-minutes (default 60).","required":false,"schema":{"type":"string","maxLength":255}}],"responses":{"201":{"description":"Organization created","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Invalid slug, duplicate slug, or domain already claimed","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"org.create","description":"Create a new organization"}],"x-since":"7.7.0"},"delete":{"tags":["Organizations"],"summary":"Delete organization (owner or platform-admin)","description":"**Since v7.26.0** — Deletes an organization: Keycloak group (detaching all members), membership rows, domains, pending invitations/join-requests, Credit balance (forfeited), and the org row; the org's artifact storage is archived (moved aside, never destroyed) — #182/TD-2. A platform admin may delete any organization. An org OWNER may delete their own organization only when it is empty — no members other than the owner, and no contracts or products; a non-empty owner delete is refused with 409 (#854). Pass org (slug) or orgId (UUID).","operationId":"deleteOrg","parameters":[{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Organization deleted","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Missing org/orgId parameter","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Caller is neither the org owner nor a platform admin","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}},"409":{"description":"Owner delete refused — organization is not empty","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"org.delete","description":"Delete an organization (owner or platform-admin)"}],"x-since":"7.26.0"}},"/v4/orgs/{slug}":{"get":{"tags":["Organizations"],"summary":"Get organization by slug (deprecated slug path)","description":"**Since v7.7.0** — Returns organization details including associated domains. Deprecated — use GET /v4/orgs with org/orgId (#651).\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"getOrgBySlug","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Organization details","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-since":"7.7.0","x-sunset":"2027-01-01"},"put":{"tags":["Organizations"],"summary":"Update organization (deprecated slug path)","description":"**Since v7.7.0** — Updates organization details (name, phone, address, etc.). Slug cannot be changed. Deprecated — use PUT /v4/orgs with org/orgId (#651).\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"updateOrgBySlug","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"name","in":"query","required":false,"schema":{"type":"string"}},{"name":"phone","in":"query","required":false,"schema":{"type":"string"}},{"name":"address","in":"query","required":false,"schema":{"type":"string"}},{"name":"city","in":"query","required":false,"schema":{"type":"string"}},{"name":"state","in":"query","required":false,"schema":{"type":"string"}},{"name":"postalCode","in":"query","required":false,"schema":{"type":"string"}},{"name":"country","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Organization updated","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-since":"7.7.0","x-sunset":"2027-01-01"},"delete":{"tags":["Organizations"],"summary":"Delete organization (owner or platform-admin, deprecated slug path)","description":"**Since v7.7.0** — Deletes an organization: Keycloak group (detaching all members), membership rows, domains, pending invitations/join-requests, Credit balance (forfeited), and the org row; the org's artifact storage is archived (moved aside, never destroyed) — #182/TD-2. Same authorization as DELETE /v4/orgs: platform-admin (any org) or the org OWNER (empty org only, else 409). Deprecated — use DELETE /v4/orgs with org/orgId (#651).\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"deleteOrgBySlug","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Organization deleted","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Caller is neither the org owner nor a platform admin","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}},"409":{"description":"Owner delete refused — organization is not empty","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-since":"7.7.0","x-sunset":"2027-01-01"}},"/v4/orgs/{slug}/transfer-ownership":{"put":{"tags":["Membership"],"summary":"Transfer organization ownership (deprecated slug path)","description":"**Since v7.11.0** — Owner atomically transfers ownership to an existing member of the same organization. Caller is demoted to MEMBER and the target user is promoted to OWNER in a single transaction. Required before a sole owner can leave the org or delete their account. Deprecated — use PUT /v4/orgs/transfer-ownership with org/orgId (#651).\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"transferOwnershipBySlug","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransferOwnershipRequest"}}},"required":true},"responses":{"200":{"description":"Ownership transferred","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"New owner is not a member of the org, or invalid payload","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Caller is not an owner of the org","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization or target user not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-since":"7.11.0","x-sunset":"2027-01-01"}},"/v4/orgs/{slug}/messages/{messageId}/reject":{"put":{"tags":["Membership"],"summary":"Reject a join request (deprecated slug path)","description":"**Since v7.11.0** — Admin/owner rejects a pending join request. Deprecated — use PUT /v4/orgs/messages/{messageId}/reject with org/orgId (#651).\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"rejectBySlug","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"messageId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"Join request rejected","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Message not found or not pending","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Insufficient role","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-since":"7.11.0","x-sunset":"2027-01-01"}},"/v4/orgs/{slug}/messages/{messageId}/decline":{"put":{"tags":["Membership"],"summary":"Decline an invitation (deprecated slug path)","description":"**Since v7.11.0** — The invited user declines the invitation. Deprecated — use PUT /v4/orgs/messages/{messageId}/decline with org/orgId (#651).\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"declineBySlug","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"messageId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"Invitation declined","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Message not found, not pending, or wrong user","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-since":"7.11.0","x-sunset":"2027-01-01"}},"/v4/orgs/{slug}/messages/{messageId}/approve":{"put":{"tags":["Membership"],"summary":"Approve a join request (deprecated slug path)","description":"**Since v7.11.0** — Admin/owner approves a pending join request. The user becomes a MEMBER. Deprecated — use PUT /v4/orgs/messages/{messageId}/approve with org/orgId (#651).\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"approveBySlug","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"messageId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"Join request approved","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Message not found or not pending","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Insufficient role","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-since":"7.11.0","x-sunset":"2027-01-01"}},"/v4/orgs/{slug}/messages/{messageId}/accept":{"put":{"tags":["Membership"],"summary":"Accept an invitation (deprecated slug path)","description":"**Since v7.11.0** — The invited user accepts. They become a MEMBER of the organization. Deprecated — use PUT /v4/orgs/messages/{messageId}/accept with org/orgId (#651).\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"acceptBySlug","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"messageId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"Invitation accepted","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Message not found, not pending, or wrong user","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-since":"7.11.0","x-sunset":"2027-01-01"}},"/v4/orgs/{slug}/members/{userId}/role":{"put":{"tags":["Membership"],"summary":"Change a member's role (deprecated slug path)","description":"**Since v7.11.0** — Owner changes a member's role. Only owners can promote to admin. Deprecated — use PUT /v4/orgs/members/{userId}/role with org/orgId (#651).\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"changeRoleBySlug","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"userId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"role","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Role updated","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Cannot demote last owner","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Insufficient role","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-since":"7.11.0","x-sunset":"2027-01-01"}},"/v4/orgs/{slug}/integrations/{key}":{"put":{"tags":["Org Settings"],"summary":"Store org integration credentials (deprecated slug path)","description":"**Since v7.10.0** — Stores credentials for an org integration. Requires ADMIN+ role. Deprecated — use PUT /v4/orgs/integrations/{key} with org/orgId (#651).\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"setCredentialsBySlug","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"key","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","additionalProperties":{}}}},"required":true},"responses":{"200":{"description":"Credentials saved","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Unknown integration key","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Insufficient role (requires ADMIN+)","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-since":"7.10.0","x-sunset":"2027-01-01"},"delete":{"tags":["Org Settings"],"summary":"Remove org integration credentials (deprecated slug path)","description":"**Since v7.10.0** — Removes the credentials of an org integration. Requires ADMIN+ role. Deprecated — use DELETE /v4/orgs/integrations/{key} with org/orgId (#651).\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"removeCredentialsBySlug","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"key","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-since":"7.10.0","x-sunset":"2027-01-01"}},"/v4/orgs/{slug}/integrations/github/defaults":{"get":{"tags":["Org Settings"],"summary":"Get org GitHub defaults (deprecated slug path)","description":"**Since v7.10.0** — Returns the organization's configured GitHub publishing defaults. Requires org membership. Deprecated — use GET /v4/orgs/integrations/github/defaults with org/orgId (#651).\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"getDefaultsBySlug","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Current defaults","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Not a member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-since":"7.10.0","x-sunset":"2027-01-01"},"put":{"tags":["Org Settings"],"summary":"Set org GitHub defaults (deprecated slug path)","description":"**Since v7.10.0** — Configures default repository, branch, commit message template, and auto-publish flag for the organization. Requires ADMIN+ role. Deprecated — use PUT /v4/orgs/integrations/github/defaults with org/orgId (#651).\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"setDefaultsBySlug","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GitHubDefaultsRequest"}}},"required":true},"responses":{"200":{"description":"Defaults configured","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Insufficient role (requires ADMIN+)","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-since":"7.10.0","x-sunset":"2027-01-01"},"delete":{"tags":["Org Settings"],"summary":"Reset org GitHub defaults (deprecated slug path)","description":"**Since v7.10.0** — Clears all GitHub publishing defaults for the organization. Requires ADMIN+ role. Deprecated — use DELETE /v4/orgs/integrations/github/defaults with org/orgId (#651).\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"resetDefaultsBySlug","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Defaults cleared","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Insufficient role (requires ADMIN+)","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-since":"7.10.0","x-sunset":"2027-01-01"}},"/v4/orgs/{slug}/github-token":{"put":{"tags":["Organizations"],"summary":"Set organization GitHub token (deprecated slug path)","description":"**Since v7.7.0** — Encrypts and stores a GitHub token for the organization. Requires OWNER role. Deprecated — use PUT /v4/orgs/github-token with org/orgId (#651).\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"setGithubTokenBySlug","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"token","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"GitHub token set","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Insufficient role (OWNER required)","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-since":"7.7.0","x-sunset":"2027-01-01"},"delete":{"tags":["Organizations"],"summary":"Remove organization GitHub token (deprecated slug path)","description":"**Since v7.7.0** — Removes the organization's stored GitHub token. Requires OWNER role. Deprecated — use DELETE /v4/orgs/github-token with org/orgId (#651).\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"removeGithubTokenBySlug","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"GitHub token removed","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Insufficient role (OWNER required)","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-since":"7.7.0","x-sunset":"2027-01-01"}},"/v4/orgs/transfer-ownership":{"put":{"tags":["Membership"],"summary":"Transfer organization ownership","description":"**Since v7.26.0** — Owner atomically transfers ownership to an existing member of the same organization. Caller is demoted to MEMBER and the target user is promoted to OWNER in a single transaction. Required before a sole owner can leave the org or delete their account. Pass org (slug) or orgId (UUID) to select the organization.","operationId":"transferOwnership","parameters":[{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransferOwnershipRequest"}}},"required":true},"responses":{"200":{"description":"Ownership transferred","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Missing org/orgId parameter, new owner is not a member of the org, or invalid payload","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Caller is not an owner of the org","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization or target user not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"org.member.transfer","description":"Transfer organization ownership"}],"x-since":"7.26.0"}},"/v4/orgs/messages/{messageId}/reject":{"put":{"tags":["Membership"],"summary":"Reject a join request","description":"**Since v7.26.0** — Admin/owner rejects a pending join request. Pass org (slug) or orgId (UUID) to select the organization. Requires ADMIN+ role.","operationId":"reject","parameters":[{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"messageId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"Join request rejected","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Missing org/orgId parameter, message not found, or not pending","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Insufficient role","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"org.member.reject","description":"Reject a join request"}],"x-since":"7.26.0"}},"/v4/orgs/messages/{messageId}/decline":{"put":{"tags":["Membership"],"summary":"Decline an invitation","description":"**Since v7.26.0** — The invited user declines the invitation. Pass org (slug) or orgId (UUID) to select the organization.","operationId":"decline","parameters":[{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"messageId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"Invitation declined","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Missing org/orgId parameter, message not found, not pending, or wrong user","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"org.member.decline","description":"Decline an organization invitation"}],"x-since":"7.26.0"}},"/v4/orgs/messages/{messageId}/approve":{"put":{"tags":["Membership"],"summary":"Approve a join request","description":"**Since v7.26.0** — Admin/owner approves a pending join request. The user becomes a MEMBER. Pass org (slug) or orgId (UUID) to select the organization. Requires ADMIN+ role.","operationId":"approve","parameters":[{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"messageId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"Join request approved","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Missing org/orgId parameter, message not found, or not pending","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Insufficient role","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"org.member.approve","description":"Approve a join request"}],"x-since":"7.26.0"}},"/v4/orgs/messages/{messageId}/accept":{"put":{"tags":["Membership"],"summary":"Accept an invitation","description":"**Since v7.26.0** — The invited user accepts. They become a MEMBER of the organization. Pass org (slug) or orgId (UUID) to select the organization.","operationId":"accept","parameters":[{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"messageId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"Invitation accepted","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Missing org/orgId parameter, message not found, not pending, or wrong user","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"org.member.accept","description":"Accept an organization invitation"}],"x-since":"7.26.0"}},"/v4/orgs/members/{userId}/role":{"put":{"tags":["Membership"],"summary":"Change a member's role","description":"**Since v7.26.0** — Owner changes a member's role. Only owners can promote to admin. Pass org (slug) or orgId (UUID) to select the organization.","operationId":"changeRole","parameters":[{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"userId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"role","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Role updated","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Missing org/orgId parameter or cannot demote last owner","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Insufficient role","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"org.member.update","description":"Change a member's role"}],"x-since":"7.26.0"}},"/v4/orgs/integrations/{key}":{"put":{"tags":["Org Settings"],"summary":"Store org integration credentials","description":"**Since v7.26.0** — Stores credentials for an org integration. Pass org (slug) or orgId (UUID) to select the organization. Requires ADMIN+ role.","operationId":"setCredentials_1","parameters":[{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"key","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","additionalProperties":{}}}},"required":true},"responses":{"200":{"description":"Credentials saved","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Missing org/orgId parameter or unknown integration key","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Insufficient role (requires ADMIN+)","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"integration.update","description":"Store org integration credentials"}],"x-since":"7.26.0"},"delete":{"tags":["Org Settings"],"summary":"Remove org integration credentials","description":"**Since v7.26.0** — Removes the credentials of an org integration. Pass org (slug) or orgId (UUID) to select the organization. Requires ADMIN+ role.","operationId":"removeCredentials_1","parameters":[{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"key","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Integration removed","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Missing org/orgId parameter or unknown integration key","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Insufficient role (requires ADMIN+)","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"integration.delete","description":"Remove org integration credentials"}],"x-since":"7.26.0"}},"/v4/orgs/integrations/github/defaults":{"get":{"tags":["Org Settings"],"summary":"Get org GitHub defaults","description":"**Since v7.26.0** — Returns the organization's configured GitHub publishing defaults. Pass org (slug) or orgId (UUID) to select the organization. Requires org membership.","operationId":"getDefaults_1","parameters":[{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Current defaults","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Missing org/orgId parameter","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Not a member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"integration.defaults.get","description":"Get org GitHub publishing defaults"}],"x-since":"7.26.0"},"put":{"tags":["Org Settings"],"summary":"Set org GitHub defaults","description":"**Since v7.26.0** — Configures default repository, branch, commit message template, and auto-publish flag for the organization. Pass org (slug) or orgId (UUID) to select the organization. Requires ADMIN+ role.","operationId":"setDefaults_1","parameters":[{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GitHubDefaultsRequest"}}},"required":true},"responses":{"200":{"description":"Defaults configured","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Missing org/orgId parameter","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Insufficient role (requires ADMIN+)","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"integration.defaults.update","description":"Set org GitHub publishing defaults"}],"x-since":"7.26.0"},"delete":{"tags":["Org Settings"],"summary":"Reset org GitHub defaults","description":"**Since v7.26.0** — Clears all GitHub publishing defaults for the organization. Pass org (slug) or orgId (UUID) to select the organization. Requires ADMIN+ role.","operationId":"resetDefaults_1","parameters":[{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Defaults cleared","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Missing org/orgId parameter","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Insufficient role (requires ADMIN+)","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"integration.defaults.delete","description":"Reset org GitHub publishing defaults"}],"x-since":"7.26.0"}},"/v4/orgs/github-token":{"put":{"tags":["Organizations"],"summary":"Set organization GitHub token","description":"**Since v7.26.0** — Encrypts and stores a GitHub token for the organization. Requires OWNER role. Pass org (slug) or orgId (UUID) to select the organization.","operationId":"setGithubToken","parameters":[{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"token","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"GitHub token set","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Missing org/orgId parameter","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Insufficient role (OWNER required)","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"org.github-token.update","description":"Set the organization GitHub token"}],"x-since":"7.26.0"},"delete":{"tags":["Organizations"],"summary":"Remove organization GitHub token","description":"**Since v7.26.0** — Removes the organization's stored GitHub token. Requires OWNER role. Pass org (slug) or orgId (UUID) to select the organization.","operationId":"removeGithubToken","parameters":[{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"GitHub token removed","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Missing org/orgId parameter","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Insufficient role (OWNER required)","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"org.github-token.delete","description":"Remove the organization GitHub token"}],"x-since":"7.26.0"}},"/v4/notifications/read":{"put":{"tags":["Notifications"],"summary":"Mark all notifications read","description":"**Since v7.23.0** — Sets the caller's mark-all-read watermark to now; a subsequent list shows unreadCount 0 for all existing items.","operationId":"markAllRead","responses":{"200":{"description":"Watermark updated","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"notifications.read-all","description":"Mark all of the caller's notifications read"}],"x-since":"7.23.0"}},"/v4/diagnostics/{id}":{"get":{"tags":["Diagnostics"],"summary":"Get a single diagnostics report (admin only)","description":"**Since v7.1.1**\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"getById","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Full report","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid Bearer JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Admin privileges required","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"diagnostics.get","description":"Get a single diagnostics report"}],"x-since":"7.1.1","x-sunset":"2027-01-01"},"put":{"tags":["Diagnostics"],"summary":"Update a diagnostics report (additive merge)","description":"**Since v7.1.1** — Unauthenticated. Fills null fields, concatenates JSONB arrays. Sets reportType to 'user'.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"update","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-CLI-KEY","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DiagnosticsReportRequest"}}},"required":true},"responses":{"200":{"description":"Report updated","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Report not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"x-intent":[{"name":"diagnostics.update","description":"Additive merge update of a diagnostics report"}],"x-since":"7.1.1","x-sunset":"2027-01-01"},"patch":{"tags":["Diagnostics"],"summary":"Resolve or reopen a diagnostics report (admin only)","description":"**Since v7.1.1**\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"resolve","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DiagnosticsResolveRequest"}}},"required":true},"responses":{"200":{"description":"Report updated","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid Bearer JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Admin privileges required","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"diagnostics.resolve","description":"Resolve or reopen a diagnostics report"}],"x-since":"7.1.1","x-sunset":"2027-01-01"}},"/v4/data-sources/{name}":{"put":{"tags":["Data Sources"],"summary":"Create or overwrite a named data source","description":"**Since v7.35.0** — Stores the JDBC coordinates and password for a reusable data source. The password is encrypted at rest (AES-256-GCM) and never returned. Pass org or orgId for an org-shared data source.","operationId":"store","parameters":[{"name":"name","in":"path","required":true,"schema":{"type":"string"}},{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/JdbcConnectionRequest"}}},"required":true},"responses":{"200":{"description":"Data source stored (no secret material in the response)","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Missing connection parameters","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated or not an org member","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"datasource.store","description":"Create or overwrite a named data source"}],"x-since":"7.35.0"},"delete":{"tags":["Data Sources"],"summary":"Delete a named data source","description":"**Since v7.35.0** — Removes a named data source from the caller's scope. Contract-server bindings that referenced it will then fail to resolve until re-pointed.","operationId":"delete","parameters":[{"name":"name","in":"path","required":true,"schema":{"type":"string"}},{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Data source deleted","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated or not an org member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"No such data source","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"datasource.delete","description":"Delete a named data source"}],"x-since":"7.35.0"}},"/v4/credits/bonuses/{code}":{"put":{"tags":["Credits"],"summary":"Update a gamification bonus (admin)","description":"**Since v7.44.0** — Updates the user bonus, org bonus, and/or enabled flag for a gamification bonus code. Admin only.","operationId":"updateBonus","parameters":[{"name":"code","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","additionalProperties":{}}}},"required":true},"responses":{"200":{"description":"Bonus updated","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Admin privileges required","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Bonus code not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"credit.bonus.update","description":"Update a gamification bonus (admin)"}],"x-since":"7.44.0"},"delete":{"tags":["Credits"],"summary":"Delete a gamification bonus (admin)","description":"**Since v7.44.0** — Deletes the gamification bonus identified by its code. Admin only.","operationId":"deleteBonus","parameters":[{"name":"code","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Bonus deleted","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Admin privileges required","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Bonus code not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"credit.bonus.delete","description":"Delete a gamification bonus (admin)"}],"x-since":"7.44.0"}},"/v4/contracts/{contractId}/jdbc-credentials":{"put":{"tags":["Contracts"],"summary":"Store JDBC credentials for on-demand contract refresh","description":"**Since v7.33.0** — Stores (or overwrites) the JDBC connection parameters for a database-sourced contract version. The password is encrypted at rest (AES-256-GCM) and is never returned by any endpoint. Pass org or orgId for organization contracts. When version is omitted, the contract's latest version is used.","operationId":"storeCredentials","parameters":[{"name":"contractId","in":"path","required":true,"schema":{"type":"string"}},{"name":"version","in":"query","required":false,"schema":{"type":"string"}},{"name":"server","in":"query","description":"Contract servers[].server name this binding is for; omit for the default","required":false,"schema":{"type":"string"}},{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/JdbcConnectionRequest"}}},"required":true},"responses":{"200":{"description":"Credentials stored (no secret material in the response)","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Missing connection parameters","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated or not an org member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Contract or organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"contract.refresh.credentials.store","description":"Store JDBC credentials for contract refresh"}],"x-since":"7.33.0"},"delete":{"tags":["Contracts"],"summary":"Delete stored JDBC credentials for a contract","description":"**Since v7.33.0** — Removes the stored JDBC connection parameters for a contract version. Subsequent refresh calls return 404 until credentials are stored again. When version is omitted, the contract's latest version is used.","operationId":"deleteCredentials","parameters":[{"name":"contractId","in":"path","required":true,"schema":{"type":"string"}},{"name":"version","in":"query","required":false,"schema":{"type":"string"}},{"name":"server","in":"query","description":"Contract servers[].server name; omit for the default binding","required":false,"schema":{"type":"string"}},{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Credentials deleted","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated or not an org member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Contract, organization, or stored credentials not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"contract.refresh.credentials.delete","description":"Delete stored JDBC credentials"}],"x-since":"7.33.0"}},"/v4/contracts/lifecycle/{id}":{"put":{"tags":["Lifecycle"],"summary":"Edit a contract lifecycle entry (v4, born-deprecated)","description":"**Since v7.1.6** — Verbatim copy of PUT /v1/contracts/lifecycle/{id}.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"updateContractLifecycleEntry","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LifecycleUpdateRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"lifecycle.contract.update","description":"Edit a contract lifecycle entry"}],"x-since":"7.1.6","x-sunset":"2027-01-01"}},"/v4/comments/{id}":{"put":{"tags":["Comments"],"summary":"Edit a comment","description":"**Since v5.0.0** — Edit the body of a comment. Only the author can edit, and only the last message in a thread can be edited.","operationId":"editComment","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"string"}}}},"required":true},"responses":{"200":{"description":"Comment updated","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Not the author","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Feature disabled or comment not found","content":{"*/*":{"schema":{"type":"object"}}}},"409":{"description":"Not the last message in the thread","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"comment.update","description":"Edit a comment body"}],"x-since":"5.0.0"},"delete":{"tags":["Comments"],"summary":"Delete a comment","description":"**Since v5.0.0** — Soft-deletes a comment. If the comment is top-level, all replies are also soft-deleted. Deleted comments appear in since-polling responses.","operationId":"deleteComment","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"204":{"description":"Comment deleted","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Not an org member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Feature disabled or comment not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"comment.delete","description":"Delete a comment"}],"x-since":"5.0.0"}},"/v4/comments/{id}/unresolve":{"put":{"tags":["Comments"],"summary":"Unresolve a comment thread","description":"**Since v5.0.0** — Removes the resolved status from a top-level comment thread.","operationId":"unresolveThread","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Thread unresolved","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Cannot unresolve a reply","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Feature disabled or comment not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"comment.thread.unresolve","description":"Unresolve a comment thread"}],"x-since":"5.0.0"}},"/v4/comments/{id}/resolve":{"put":{"tags":["Comments"],"summary":"Resolve a comment thread","description":"**Since v5.0.0** — Marks a top-level comment thread as resolved.","operationId":"resolveThread","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Thread resolved","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Cannot resolve a reply","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Feature disabled or comment not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"comment.thread.resolve","description":"Resolve a comment thread"}],"x-since":"5.0.0"}},"/v4/comments/tasks/{mentionId}/complete":{"put":{"tags":["Comments"],"summary":"Mark a task as completed","description":"**Since v5.0.0** — Marks a task assignment as completed. Only the assignee can complete it.","operationId":"completeTask","parameters":[{"name":"mentionId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Task completed","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Not the assignee","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Feature disabled or mention not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"comment.task.update","description":"Mark a comment task as completed"}],"x-since":"5.0.0"}},"/v4/admin/users/admin":{"put":{"tags":["Administration"],"summary":"Set a user's admin flag (v4 admin)","description":"**Since v7.43.4** — Promotes or demotes a user by email: body `{\"admin\": true|false}`. Admin-only; evicts the target's auth cache so the change is immediate. An admin cannot remove their own admin flag (400). The v1 `PUT /users` profile-update path does not honor `admin`; this is the endpoint for admin promotion/demotion (#760).","operationId":"setUserAdmin","parameters":[{"name":"email","in":"query","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","additionalProperties":{}}}},"required":true},"responses":{"200":{"description":"Admin flag updated; returns the updated AdminUserResponse","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Missing `admin` field, or admin attempted self-demotion","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Admin privileges required","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"User not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"admin.user.set-admin","description":"Set or unset a user's admin flag (admin)"}],"x-since":"7.43.4"}},"/v3/products/lifecycle/{id}":{"put":{"tags":["Lifecycle"],"summary":"Edit a product lifecycle entry (v3)","description":"**Since v3.1.4** — Updates the comment on a product lifecycle entry. Pass org or orgId for org-scoped entries.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"updateProductLifecycleEntry_1","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LifecycleUpdateRequest"}}},"required":true},"responses":{"200":{"description":"Entry updated successfully","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated or not an org member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Entry not found, not owned by user, or organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"lifecycle.product.update","description":"Edit a product lifecycle entry"}],"x-since":"3.1.4","x-sunset":"2027-01-01"}},"/v3/contracts/lifecycle/{id}":{"put":{"tags":["Lifecycle"],"summary":"Edit a contract lifecycle entry (v3)","description":"**Since v3.1.4** — Updates the comment on a contract lifecycle entry. Pass org or orgId for org-scoped entries.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"updateContractLifecycleEntry_1","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LifecycleUpdateRequest"}}},"required":true},"responses":{"200":{"description":"Entry updated successfully","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated or not an org member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Entry not found, not owned by user, or organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"lifecycle.contract.update","description":"Edit a contract lifecycle entry"}],"x-since":"3.1.4","x-sunset":"2027-01-01"}},"/v2/users/me/integrations/{key}":{"put":{"tags":["Publishing"],"summary":"Store integration credentials","description":"**Since v2.12.0** — Sets credentials for the specified integration (github, zeenea, or controlcenter).\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"setCredentials_2","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","additionalProperties":{}}}},"required":true},"responses":{"200":{"description":"Credentials saved","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Unknown integration key","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"integration.update","description":"Store integration credentials"}],"x-since":"2.12.0","x-sunset":"2027-01-01"},"delete":{"tags":["Publishing"],"summary":"Remove integration credentials","description":"**Since v2.12.0** — Clears all fields for the specified integration. Defaults are preserved.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"removeCredentials_2","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"integration.delete","description":"Remove integration credentials"}],"x-since":"2.12.0","x-sunset":"2027-01-01"}},"/v2/users/me/integrations/github/defaults":{"get":{"tags":["Publishing"],"summary":"Get GitHub defaults","description":"**Since v2.10.0** — Returns the user's configured GitHub publishing defaults.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"getDefaults_2","responses":{"200":{"description":"Current defaults","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"integration.defaults.get","description":"Get GitHub publishing defaults"}],"x-since":"2.10.0","x-sunset":"2027-01-01"},"put":{"tags":["Publishing"],"summary":"Set GitHub defaults","description":"**Since v2.10.0** — Configures default repository, branch, commit message template, and auto-publish flag for GitHub publishing.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"setDefaults_2","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GitHubDefaultsRequest"}}},"required":true},"responses":{"200":{"description":"Defaults configured","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"integration.defaults.update","description":"Set GitHub publishing defaults"}],"x-since":"2.10.0","x-sunset":"2027-01-01"},"delete":{"tags":["Publishing"],"summary":"Reset GitHub defaults","description":"**Since v2.10.0** — Clears all GitHub publishing defaults for the authenticated user.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"resetDefaults_2","responses":{"200":{"description":"Defaults cleared","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"integration.defaults.delete","description":"Reset GitHub publishing defaults"}],"x-since":"2.10.0","x-sunset":"2027-01-01"}},"/v2/reference-tags/{tagName}":{"get":{"tags":["Tags"],"summary":"Get a reference tag (v2)","description":"**Since v2.4.2** — Returns details of a specific reference tag\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"getTag_1","parameters":[{"name":"tagName","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Reference tag details","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Tag not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"reference-tag.get","description":"Get a reference tag"}],"x-since":"2.4.2","x-sunset":"2027-01-01"},"put":{"tags":["Tags"],"summary":"Update a reference tag (v2)","description":"**Since v2.4.2** — Updates the properties and/or description of an existing reference tag\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"updateTag_1","parameters":[{"name":"tagName","in":"path","required":true,"schema":{"type":"string"}},{"name":"properties","in":"query","required":false,"schema":{"type":"string"}},{"name":"description","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Tag updated successfully","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Invalid request","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Tag not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"reference-tag.update","description":"Update a reference tag"}],"x-since":"2.4.2","x-sunset":"2027-01-01"},"delete":{"tags":["Tags"],"summary":"Delete a reference tag (v2)","description":"**Since v2.4.2** — Deletes a reference tag\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"deleteTag_1","parameters":[{"name":"tagName","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Tag deleted successfully","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"reference-tag.delete","description":"Delete a reference tag"}],"x-since":"2.4.2","x-sunset":"2027-01-01"}},"/v2/reference-tags/{tagName}/apply-changes":{"put":{"tags":["Tags"],"summary":"Apply tag changes (v2)","description":"**Since v2.4.2** — Applies reference tag changes to selected artifacts with specified versions\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"applyChanges_1","parameters":[{"name":"tagName","in":"path","required":true,"schema":{"type":"string"}},{"name":"properties","in":"query","required":true,"schema":{"type":"string"}},{"name":"description","in":"query","required":false,"schema":{"type":"string","default":""}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","additionalProperties":{}}}},"required":true},"responses":{"200":{"description":"Changes applied successfully","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Tag not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"reference-tag.changes.apply","description":"Apply reference tag changes to artifacts"}],"x-since":"2.4.2","x-sunset":"2027-01-01"}},"/v2/reference-tags/{tagName}/analyze-impact":{"put":{"tags":["Tags"],"summary":"Analyze tag impact (v2)","description":"**Since v2.4.2** — Analyzes which artifacts would be affected by changing this reference tag\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"analyzeImpact_1","parameters":[{"name":"tagName","in":"path","required":true,"schema":{"type":"string"}},{"name":"properties","in":"query","required":true,"schema":{"type":"string"}},{"name":"description","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Impact analysis result","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Tag not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"reference-tag.impact.analyze","description":"Analyze the impact of changing a reference tag"}],"x-since":"2.4.2","x-sunset":"2027-01-01"}},"/v2/products/lifecycle/{id}":{"put":{"tags":["Lifecycle"],"summary":"Edit a product lifecycle entry (v2)","description":"**Since v2.2.0** — Deprecated — use PUT /v3/products/lifecycle/{id} instead. Requires Bearer JWT.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"updateProductLifecycleEntry_2","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LifecycleUpdateRequest"}}},"required":true},"responses":{"200":{"description":"Entry updated successfully","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Entry not found or not owned by user","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"lifecycle.product.update","description":"Edit a product lifecycle entry"}],"x-since":"2.2.0","x-sunset":"2027-01-01"}},"/v2/orgs/{slug}":{"get":{"tags":["Organizations"],"summary":"Get organization by slug","description":"**Since v2.3.0** — Returns organization details including associated domains.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"getOrg_1","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Organization details","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"org.get","description":"Get an organization by slug"}],"x-since":"2.3.0","x-sunset":"2027-01-01"},"put":{"tags":["Organizations"],"summary":"Update organization","description":"**Since v2.3.0** — Updates organization details (name, phone, address, etc.). Slug cannot be changed.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"updateOrg_1","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"name","in":"query","required":false,"schema":{"type":"string"}},{"name":"phone","in":"query","required":false,"schema":{"type":"string"}},{"name":"address","in":"query","required":false,"schema":{"type":"string"}},{"name":"city","in":"query","required":false,"schema":{"type":"string"}},{"name":"state","in":"query","required":false,"schema":{"type":"string"}},{"name":"postalCode","in":"query","required":false,"schema":{"type":"string"}},{"name":"country","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Organization updated","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"org.update","description":"Update organization details"}],"x-since":"2.3.0","x-sunset":"2027-01-01"},"delete":{"tags":["Organizations"],"summary":"Delete organization (platform-admin only)","description":"**Since v2.3.0** — Deletes an organization and its domains, Credit balance. Platform admin required.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"deleteOrg_1","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Organization deleted","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Admin privileges required","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"org.delete","description":"Delete an organization (admin only)"}],"x-since":"2.3.0","x-sunset":"2027-01-01"}},"/v2/orgs/{slug}/transfer-ownership":{"put":{"tags":["Membership"],"summary":"Transfer organization ownership","description":"**Since v7.0.23** — Owner atomically transfers ownership to an existing member of the same organization. Caller is demoted to MEMBER and the target user is promoted to OWNER in a single transaction. Required before a sole owner can leave the org or delete their account.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"transferOwnership_1","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransferOwnershipRequest"}}},"required":true},"responses":{"200":{"description":"Ownership transferred","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"New owner is not a member of the org, or invalid payload","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Caller is not an owner of the org","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization or target user not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"org.member.transfer","description":"Transfer organization ownership"}],"x-since":"7.0.23","x-sunset":"2027-01-01"}},"/v2/orgs/{slug}/messages/{messageId}/reject":{"put":{"tags":["Membership"],"summary":"Reject a join request","description":"**Since v2.5.0** — Admin/owner rejects a pending join request.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"reject_1","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"messageId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"Join request rejected","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Message not found or not pending","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Insufficient role","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"org.member.reject","description":"Reject a join request"}],"x-since":"2.5.0","x-sunset":"2027-01-01"}},"/v2/orgs/{slug}/messages/{messageId}/decline":{"put":{"tags":["Membership"],"summary":"Decline an invitation","description":"**Since v2.5.0** — The invited user declines the invitation.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"decline_1","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"messageId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"Invitation declined","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Message not found, not pending, or wrong user","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"org.member.decline","description":"Decline an organization invitation"}],"x-since":"2.5.0","x-sunset":"2027-01-01"}},"/v2/orgs/{slug}/messages/{messageId}/approve":{"put":{"tags":["Membership"],"summary":"Approve a join request","description":"**Since v2.5.0** — Admin/owner approves a pending join request. The user becomes a MEMBER.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"approve_1","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"messageId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"Join request approved","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Message not found or not pending","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Insufficient role","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"org.member.approve","description":"Approve a join request"}],"x-since":"2.5.0","x-sunset":"2027-01-01"}},"/v2/orgs/{slug}/messages/{messageId}/accept":{"put":{"tags":["Membership"],"summary":"Accept an invitation","description":"**Since v2.5.0** — The invited user accepts. They become a MEMBER of the organization.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"accept_1","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"messageId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"Invitation accepted","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Message not found, not pending, or wrong user","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"org.member.accept","description":"Accept an organization invitation"}],"x-since":"2.5.0","x-sunset":"2027-01-01"}},"/v2/orgs/{slug}/members/{userId}/role":{"put":{"tags":["Membership"],"summary":"Change a member's role","description":"**Since v2.5.0** — Owner changes a member's role. Only owners can promote to admin.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"changeRole_1","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"userId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"role","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Role updated","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Cannot demote last owner","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Insufficient role","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"org.member.update","description":"Change a member's role"}],"x-since":"2.5.0","x-sunset":"2027-01-01"}},"/v2/orgs/{slug}/integrations/{key}":{"put":{"tags":["Org Settings"],"summary":"Store org integration credentials","description":"**Since v2.12.0**\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"setCredentials_3","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"key","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","additionalProperties":{}}}},"required":true},"responses":{"200":{"description":"Credentials saved","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Unknown integration key","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Insufficient role (requires ADMIN+)","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"integration.update","description":"Store org integration credentials"}],"x-since":"2.12.0","x-sunset":"2027-01-01"},"delete":{"tags":["Org Settings"],"summary":"Remove org integration credentials","description":"**Since v2.12.0**\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"removeCredentials_3","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"key","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"integration.delete","description":"Remove org integration credentials"}],"x-since":"2.12.0","x-sunset":"2027-01-01"}},"/v2/orgs/{slug}/integrations/github/defaults":{"get":{"tags":["Org Settings"],"summary":"Get org GitHub defaults","description":"**Since v2.10.0** — Returns the organization's configured GitHub publishing defaults.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"getDefaults_3","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Current defaults","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Not a member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"integration.defaults.get","description":"Get org GitHub publishing defaults"}],"x-since":"2.10.0","x-sunset":"2027-01-01"},"put":{"tags":["Org Settings"],"summary":"Set org GitHub defaults","description":"**Since v2.10.0** — Configures default repository, branch, commit message template, and auto-publish flag for the organization.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"setDefaults_3","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GitHubDefaultsRequest"}}},"required":true},"responses":{"200":{"description":"Defaults configured","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Insufficient role (requires ADMIN+)","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"integration.defaults.update","description":"Set org GitHub publishing defaults"}],"x-since":"2.10.0","x-sunset":"2027-01-01"},"delete":{"tags":["Org Settings"],"summary":"Reset org GitHub defaults","description":"**Since v2.10.0** — Clears all GitHub publishing defaults for the organization.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"resetDefaults_3","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Defaults cleared","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Insufficient role (requires ADMIN+)","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"integration.defaults.delete","description":"Reset org GitHub publishing defaults"}],"x-since":"2.10.0","x-sunset":"2027-01-01"}},"/v2/orgs/{slug}/github-token":{"put":{"tags":["Organizations"],"summary":"Set organization GitHub token","description":"**Since v2.7.0** — Encrypts and stores a GitHub token for the organization. Requires OWNER role.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"setGithubToken_1","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"token","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"GitHub token set","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Insufficient role (OWNER required)","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"org.github-token.update","description":"Set the organization GitHub token"}],"x-since":"2.7.0","x-sunset":"2027-01-01"},"delete":{"tags":["Organizations"],"summary":"Remove organization GitHub token","description":"**Since v2.7.0** — Removes the organization's stored GitHub token. Requires OWNER role.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"removeGithubToken_1","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"GitHub token removed","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Insufficient role (OWNER required)","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"org.github-token.delete","description":"Remove the organization GitHub token"}],"x-since":"2.7.0","x-sunset":"2027-01-01"}},"/v2/contracts/lifecycle/{id}":{"put":{"tags":["Lifecycle"],"summary":"Edit a contract lifecycle entry (v2)","description":"**Since v2.2.0** — Deprecated — use PUT /v3/contracts/lifecycle/{id} instead. Requires Bearer JWT.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"updateContractLifecycleEntry_2","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LifecycleUpdateRequest"}}},"required":true},"responses":{"200":{"description":"Entry updated successfully","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Entry not found or not owned by user","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"lifecycle.contract.update","description":"Edit a contract lifecycle entry"}],"x-since":"2.2.0","x-sunset":"2027-01-01"}},"/v1/users":{"get":{"tags":["Users"],"summary":"List all users (admin only)","description":"**Since v1.0.0** — Returns all registered users with full details (except password hash). Restricted to admin users.","operationId":"listUsers","parameters":[{"name":"X-API-KEY","in":"header","required":false,"schema":{"type":"string"}},{"name":"X-USER-PASSWORD","in":"header","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"List of AdminUserResponse objects","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Invalid API key or password","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Admin privileges required","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"ApiKeyAuth":[]},{"PasswordAuth":[]}],"x-intent":[{"name":"user.list","description":"List all users (admin only)"}],"x-since":"1.0.0"},"put":{"tags":["Users"],"summary":"Update user profile","description":"**Since v1.0.0** — Updates profile fields: first name, last name, company, date of birth, comment. Password cannot be changed. Users can update their own profile; admins can update any user.","operationId":"updateUser","parameters":[{"name":"email","in":"query","required":true,"schema":{"type":"string"}},{"name":"X-API-KEY","in":"header","required":false,"schema":{"type":"string"}},{"name":"X-USER-PASSWORD","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserUpdateRequest"}}},"required":true},"responses":{"200":{"description":"Updated UserResponse","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Invalid input (placeholder values)","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Invalid API key or password","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Access denied (not own profile and not admin)","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"User not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"ApiKeyAuth":[]},{"PasswordAuth":[]}],"x-intent":[{"name":"user.update","description":"Update a user's profile"}],"x-since":"1.0.0"},"post":{"tags":["Users"],"summary":"Create a new user","description":"**Since v1.0.0** — Registers a new user account. A validation email with a 6-character code is sent to the provided email address. No authentication required.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserCreateRequest"}}},"required":true},"responses":{"201":{"description":"User created successfully, returns UserResponse with API key","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Invalid input (bad email, placeholder values, missing fields)","content":{"*/*":{"schema":{"type":"object"}}}},"500":{"description":"Email already registered","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"ApiKeyAuth":[]},{"PasswordAuth":[]}],"x-intent":[{"name":"user.create","description":"Register a new user account"}],"x-since":"1.0.0"},"delete":{"tags":["Users"],"summary":"Delete a user (admin only)","description":"**Since v1.0.0** — Deletes a user by email. The user data is backed up to the user_backup table before deletion.","operationId":"delete_1","parameters":[{"name":"email","in":"query","required":true,"schema":{"type":"string"}},{"name":"X-API-KEY","in":"header","required":false,"schema":{"type":"string"}},{"name":"X-USER-PASSWORD","in":"header","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"User successfully deleted","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Invalid API key or password","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Admin privileges required","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"User not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"ApiKeyAuth":[]},{"PasswordAuth":[]}],"x-intent":[{"name":"user.delete","description":"Delete a user by email (admin only)"}],"x-since":"1.0.0"}},"/v1/users/password":{"put":{"tags":["Users"],"summary":"Change password","description":"**Since v2.1.4** — Changes a user's password. Regular users must provide currentPassword. Admins can change any user's password via email param without currentPassword.","operationId":"changePassword","parameters":[{"name":"X-API-KEY","in":"header","required":false,"schema":{"type":"string"}},{"name":"X-USER-PASSWORD","in":"header","required":false,"schema":{"type":"string"}},{"name":"email","in":"query","required":false,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PasswordChangeRequest"}}},"required":true},"responses":{"200":{"description":"Password changed successfully","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Invalid input (missing or too short password)","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Invalid credentials or current password mismatch","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Admin privileges required for changing another user's password","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Target user not found (admin flow)","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"ApiKeyAuth":[]},{"PasswordAuth":[]}],"x-intent":[{"name":"user.change-password","description":"Change a user's password"}],"x-since":"2.1.4"}},"/v1/reference-tags/{tagName}":{"get":{"tags":["Tags"],"summary":"Get a reference tag","description":"**Since v1.0.0** — Returns details of a specific reference tag","operationId":"getTag_2","parameters":[{"name":"tagName","in":"path","required":true,"schema":{"type":"string"}},{"name":"X-API-KEY","in":"header","required":false,"schema":{"type":"string"}},{"name":"X-USER-PASSWORD","in":"header","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Reference tag details","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Invalid API key or password","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Tag not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"ApiKeyAuth":[]},{"PasswordAuth":[]}],"x-intent":[{"name":"reference-tag.get","description":"Get a reference tag"}],"x-since":"1.0.0"},"put":{"tags":["Tags"],"summary":"Update a reference tag","description":"**Since v1.0.0** — Updates the properties and/or description of an existing reference tag","operationId":"updateTag_2","parameters":[{"name":"tagName","in":"path","required":true,"schema":{"type":"string"}},{"name":"properties","in":"query","required":false,"schema":{"type":"string"}},{"name":"description","in":"query","required":false,"schema":{"type":"string"}},{"name":"X-API-KEY","in":"header","required":false,"schema":{"type":"string"}},{"name":"X-USER-PASSWORD","in":"header","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Tag updated successfully","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Invalid request","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Invalid API key or password","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Tag not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"ApiKeyAuth":[]},{"PasswordAuth":[]}],"x-intent":[{"name":"reference-tag.update","description":"Update a reference tag"}],"x-since":"1.0.0"},"delete":{"tags":["Tags"],"summary":"Delete a reference tag","description":"**Since v1.0.0** — Deletes a reference tag","operationId":"deleteTag_2","parameters":[{"name":"tagName","in":"path","required":true,"schema":{"type":"string"}},{"name":"X-API-KEY","in":"header","required":false,"schema":{"type":"string"}},{"name":"X-USER-PASSWORD","in":"header","required":false,"schema":{"type":"string"}}],"responses":{"204":{"description":"Tag deleted successfully","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Invalid API key or password","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"ApiKeyAuth":[]},{"PasswordAuth":[]}],"x-intent":[{"name":"reference-tag.delete","description":"Delete a reference tag"}],"x-since":"1.0.0"}},"/v1/reference-tags/{tagName}/apply-changes":{"put":{"tags":["Tags"],"summary":"Apply tag changes","description":"**Since v1.0.0** — Applies reference tag changes to selected artifacts with specified versions","operationId":"applyChanges_2","parameters":[{"name":"tagName","in":"path","required":true,"schema":{"type":"string"}},{"name":"properties","in":"query","required":true,"schema":{"type":"string"}},{"name":"description","in":"query","required":false,"schema":{"type":"string","default":""}},{"name":"X-API-KEY","in":"header","required":false,"schema":{"type":"string"}},{"name":"X-USER-PASSWORD","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","additionalProperties":{}}}},"required":true},"responses":{"200":{"description":"Changes applied successfully","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Invalid API key or password","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Tag not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"ApiKeyAuth":[]},{"PasswordAuth":[]}],"x-intent":[{"name":"reference-tag.changes.apply","description":"Apply reference tag changes to artifacts"}],"x-since":"1.0.0"}},"/v1/reference-tags/{tagName}/analyze-impact":{"put":{"tags":["Tags"],"summary":"Analyze tag impact","description":"**Since v1.0.0** — Analyzes which artifacts would be affected by changing this reference tag","operationId":"analyzeImpact_2","parameters":[{"name":"tagName","in":"path","required":true,"schema":{"type":"string"}},{"name":"properties","in":"query","required":true,"schema":{"type":"string"}},{"name":"description","in":"query","required":false,"schema":{"type":"string"}},{"name":"X-API-KEY","in":"header","required":false,"schema":{"type":"string"}},{"name":"X-USER-PASSWORD","in":"header","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Impact analysis result","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Invalid API key or password","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Tag not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"ApiKeyAuth":[]},{"PasswordAuth":[]}],"x-intent":[{"name":"reference-tag.impact.analyze","description":"Analyze the impact of changing a reference tag"}],"x-since":"1.0.0"}},"/v1/products/lifecycle/{id}":{"put":{"tags":["Lifecycle"],"summary":"Edit a product lifecycle entry","description":"**Since v1.0.0** — Updates the comment on a product lifecycle entry. Tracks all edits in an append-only audit trail.","operationId":"updateProductLifecycleEntry_3","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"X-API-KEY","in":"header","required":false,"schema":{"type":"string"}},{"name":"X-USER-PASSWORD","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LifecycleUpdateRequest"}}},"required":true},"responses":{"200":{"description":"Entry updated successfully","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Invalid API key or password","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Entry not found or not owned by user","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"ApiKeyAuth":[]},{"PasswordAuth":[]}],"x-intent":[{"name":"lifecycle.product.update","description":"Edit a product lifecycle entry"}],"x-since":"1.0.0"}},"/v1/diagnostics/{id}":{"get":{"tags":["Diagnostics"],"summary":"Get a single diagnostics report (admin only)","description":"**Since v3.1.0**","operationId":"getById_1","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-API-KEY","in":"header","required":false,"schema":{"type":"string","default":""}},{"name":"X-USER-PASSWORD","in":"header","required":false,"schema":{"type":"string","default":""}},{"name":"X-CLI-KEY","in":"header","required":false,"schema":{"type":"string","default":""}}],"responses":{"200":{"description":"Full report","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Not found","content":{"*/*":{"schema":{"type":"object"}}}}},"x-intent":[{"name":"diagnostics.get","description":"Get a single diagnostics report"}],"x-since":"3.1.0"},"put":{"tags":["Diagnostics"],"summary":"Update a diagnostics report (additive merge)","description":"**Since v3.1.0** — Unauthenticated. Fills null fields, concatenates JSONB arrays. Sets reportType to 'user'.","operationId":"update_1","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DiagnosticsReportRequest"}}},"required":true},"responses":{"200":{"description":"Report updated","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Report not found","content":{"*/*":{"schema":{"type":"object"}}}}},"x-intent":[{"name":"diagnostics.update","description":"Additive merge update of a diagnostics report"}],"x-since":"3.1.0"},"patch":{"tags":["Diagnostics"],"summary":"Resolve or reopen a diagnostics report (admin only)","description":"**Since v3.1.0**","operationId":"resolve_1","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-API-KEY","in":"header","required":false,"schema":{"type":"string","default":""}},{"name":"X-USER-PASSWORD","in":"header","required":false,"schema":{"type":"string","default":""}},{"name":"X-CLI-KEY","in":"header","required":false,"schema":{"type":"string","default":""}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DiagnosticsResolveRequest"}}},"required":true},"responses":{"200":{"description":"Report updated","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Not found","content":{"*/*":{"schema":{"type":"object"}}}}},"x-intent":[{"name":"diagnostics.resolve","description":"Resolve or reopen a diagnostics report"}],"x-since":"3.1.0"}},"/v1/contracts/lifecycle/{id}":{"put":{"tags":["Lifecycle"],"summary":"Edit a contract lifecycle entry","description":"**Since v1.0.0** — Updates the comment on a contract lifecycle entry. Tracks all edits in an append-only audit trail.","operationId":"updateContractLifecycleEntry_3","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"X-API-KEY","in":"header","required":false,"schema":{"type":"string"}},{"name":"X-USER-PASSWORD","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LifecycleUpdateRequest"}}},"required":true},"responses":{"200":{"description":"Entry updated successfully","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Invalid API key or password","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Entry not found or not owned by user","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"ApiKeyAuth":[]},{"PasswordAuth":[]}],"x-intent":[{"name":"lifecycle.contract.update","description":"Edit a contract lifecycle entry"}],"x-since":"1.0.0"}},"/v4/users/verify":{"post":{"tags":["Users"],"summary":"Verify email address","description":"**Since v7.0.0** — Verifies a user's email using the 6-character code sent during registration.","operationId":"verify","parameters":[{"name":"Idempotency-Key","in":"header","description":"Optional. Opaque, client-generated value (≤ 255 chars). When supplied, the server caches the response of the first successful invocation and replays it on a retry with the same key. Scoped to (user, method, path). TTL configurable via bitol.idempotency.ttl-minutes (default 60).","required":false,"schema":{"type":"string","maxLength":255}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2VerifyRequest"}}},"required":true},"responses":{"200":{"description":"Email verified","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Invalid verification code","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"User not found","content":{"*/*":{"schema":{"type":"object"}}}}},"x-intent":[{"name":"user.validate","description":"Verify a user's email address with a code"}],"x-since":"7.0.0"}},"/v4/users/signup-request":{"post":{"tags":["Users"],"summary":"Submit a request to join Workbench","description":"**Since v7.0.0** — Public endpoint — anyone can request access. Rate-limited per IP. Optionally accepts a visitorId (the onboarding-funnel beacon key, #1007): when present, the anonymous visitor journey is stitched onto the email's journey via the request_submitted funnel event.","operationId":"signupRequest","parameters":[{"name":"Idempotency-Key","in":"header","description":"Optional. Opaque, client-generated value (≤ 255 chars). When supplied, the server caches the response of the first successful invocation and replays it on a retry with the same key. Scoped to (user, method, path). TTL configurable via bitol.idempotency.ttl-minutes (default 60).","required":false,"schema":{"type":"string","maxLength":255}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"string"}}}},"required":true},"responses":{"201":{"description":"Request submitted","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Invalid input","content":{"*/*":{"schema":{"type":"object"}}}},"409":{"description":"Email already has a full account (error=already_registered; body includes signinUrl — the trusted webapp sign-in page) or a still-pending request (error=duplicate_pending; the pending request's notify counter is bumped and admins are re-notified). A latest request that was rejected or expired does NOT 409 — a fresh pending request is created (201) and the admin notification mentions the prior outcome (#1003).","content":{"*/*":{"schema":{"type":"object"}}}},"429":{"description":"Rate limit exceeded","content":{"*/*":{"schema":{"type":"object"}}}}},"x-intent":[{"name":"user.signup-request.create","description":"Submit a request to join Workbench"}],"x-since":"7.0.0"}},"/v4/users/resend-verification":{"post":{"tags":["Users"],"summary":"Resend verification email (fresh code)","description":"**Since v8.16.5** — Public endpoint. Regenerates the account's email-verification code and emails it (bypassing the marketing/integrity ban gate, like password reset). Anti-enumeration: always returns 200 with a generic message — including for unknown emails and for already-verified accounts (which get no email). Throttled to 3 resends per rolling 24 hours per account.","operationId":"resendVerification","parameters":[{"name":"Idempotency-Key","in":"header","description":"Optional. Opaque, client-generated value (≤ 255 chars). When supplied, the server caches the response of the first successful invocation and replays it on a retry with the same key. Scoped to (user, method, path). TTL configurable via bitol.idempotency.ttl-minutes (default 60).","required":false,"schema":{"type":"string","maxLength":255}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"string"}}}},"required":true},"responses":{"200":{"description":"Generic acknowledgement — sent regardless of account existence or verification state (anti-enumeration)","content":{"*/*":{"schema":{"type":"object"}}}},"429":{"description":"Too many resend requests for this account (max 3 per 24 hours)","content":{"*/*":{"schema":{"type":"object"}}}}},"x-intent":[{"name":"user.resend-verification","description":"Request a fresh email-verification code"}],"x-since":"8.16.5"}},"/v4/users/register":{"post":{"tags":["Users"],"summary":"Register a new user","description":"**Since v7.0.0** — Creates a new user account backed by Keycloak. A verification email is sent, except when the invitation code is an emailed approval code (request-to-join, #1005) and the registering email matches the approved request: mailbox ownership is already proven by delivery of the approval email, so the account is created verified (response field `validated: true`) and no verification email is sent.","operationId":"register","parameters":[{"name":"Idempotency-Key","in":"header","description":"Optional. Opaque, client-generated value (≤ 255 chars). When supplied, the server caches the response of the first successful invocation and replays it on a retry with the same key. Scoped to (user, method, path). TTL configurable via bitol.idempotency.ttl-minutes (default 60).","required":false,"schema":{"type":"string","maxLength":255}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserCreateRequest"}}},"required":true},"responses":{"201":{"description":"User registered. `validated: true` when the email-bound approval code skipped verification; otherwise a verification code was emailed.","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Invalid input","content":{"*/*":{"schema":{"type":"object"}}}},"409":{"description":"Email already registered. A Keycloak account with no matching app user is an orphan and is reclaimed automatically (deleted and recreated, #1066), so this 409 means a real app account exists — or the orphan was too privileged / still linked to reclaim.","content":{"*/*":{"schema":{"type":"object"}}}},"503":{"description":"Registration temporarily unavailable — `{ error, message }` where `error` is `auth_unavailable` (the authentication service did not answer its availability probe), `auth_error` (it answered but rejected the create), or `mail_unavailable` (the account was created but the verification email could not be sent, so the registration was rolled back).","content":{"*/*":{"schema":{"type":"object"}}}}},"x-intent":[{"name":"user.create","description":"Register a new user account"}],"x-since":"7.0.0"}},"/v4/users/me/integrations/{key}/test":{"post":{"tags":["Publishing"],"summary":"Test integration credentials","description":"**Since v7.6.0** — Tests the stored credentials for the specified integration. Always returns 200; check 'success' field.","operationId":"testCredentials","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","description":"Optional. Opaque, client-generated value (≤ 255 chars). When supplied, the server caches the response of the first successful invocation and replays it on a retry with the same key. Scoped to (user, method, path). TTL configurable via bitol.idempotency.ttl-minutes (default 60).","required":false,"schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"integration.github.test","description":"Test GitHub integration credentials"},{"name":"integration.zeenea.test","description":"Test Zeenea integration credentials"},{"name":"integration.kafka.test","description":"Test Control Center integration credentials"}],"x-since":"7.6.0"}},"/v4/users/me/integrations/{key}/test/field/{fieldName}":{"post":{"tags":["Publishing"],"summary":"Test a single integration field","description":"**Since v7.6.0** — Tests a specific field value without saving. Returns success/message/warning. Uses context or stored credentials for fields that require companion values.","operationId":"testField","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string"}},{"name":"fieldName","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","description":"Optional. Opaque, client-generated value (≤ 255 chars). When supplied, the server caches the response of the first successful invocation and replays it on a retry with the same key. Scoped to (user, method, path). TTL configurable via bitol.idempotency.ttl-minutes (default 60).","required":false,"schema":{"type":"string","maxLength":255}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","additionalProperties":{}}}},"required":true},"responses":{"200":{"description":"Test result (check 'success' field)","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Unknown integration or field name","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"integration.github.test","description":"Test a single GitHub integration field"},{"name":"integration.zeenea.test","description":"Test a single Zeenea integration field"},{"name":"integration.kafka.test","description":"Test a single Control Center integration field"}],"x-since":"7.6.0"}},"/v4/signing/keys":{"get":{"tags":["Signing"],"summary":"Get signing certificate metadata","description":"**Since v4.4.32** — Returns certificate metadata (fingerprint, subject, expiry). Never returns the private key.","operationId":"getKeys","parameters":[{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Certificate metadata","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"No signing credentials configured","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"signing-key.get","description":"Get signing certificate metadata"}],"x-since":"4.4.32"},"post":{"tags":["Signing"],"summary":"Upload signing key pair","description":"**Since v4.4.32** — Uploads a PKCS#8 PEM private key and X.509 PEM certificate chain. The private key is encrypted at rest (AES-256-GCM). Replaces any existing credentials. The certificate field accepts a concatenated PEM chain (leaf + intermediates).","operationId":"uploadKeys","parameters":[{"name":"privateKey","in":"query","required":true,"schema":{"type":"string"}},{"name":"certificate","in":"query","required":true,"schema":{"type":"string"}},{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","description":"Optional. Opaque, client-generated value (≤ 255 chars). When supplied, the server caches the response of the first successful invocation and replays it on a retry with the same key. Scoped to (user, method, path). TTL configurable via bitol.idempotency.ttl-minutes (default 60).","required":false,"schema":{"type":"string","maxLength":255}}],"responses":{"201":{"description":"Credentials stored","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Invalid key or certificate format","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"signing-key.upload","description":"Upload a signing key pair"}],"x-since":"4.4.32"},"delete":{"tags":["Signing"],"summary":"Delete signing credentials","description":"**Since v4.4.32** — Removes the signing key pair and certificate. This cannot be undone.","operationId":"deleteKeys","parameters":[{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"204":{"description":"Credentials deleted","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"signing-key.delete","description":"Delete signing credentials"}],"x-since":"4.4.32"}},"/v4/signing/keys/test":{"post":{"tags":["Signing"],"summary":"Test a signing key pair (pre-flight, no persistence)","description":"**Since v7.39.0** — Verifies that a PKCS#8 PEM private key cryptographically matches an X.509 PEM certificate's public key, without storing anything. Returns the match verdict, the detected algorithm, and the leaf certificate's validity window. A malformed PEM or a mismatch is returned with matches=false and an error message (HTTP 200), not a 4xx/5xx.","operationId":"testKeys","parameters":[{"name":"privateKey","in":"query","required":true,"schema":{"type":"string"}},{"name":"certificate","in":"query","required":true,"schema":{"type":"string"}},{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","description":"Optional. Opaque, client-generated value (≤ 255 chars). When supplied, the server caches the response of the first successful invocation and replays it on a retry with the same key. Scoped to (user, method, path). TTL configurable via bitol.idempotency.ttl-minutes (default 60).","required":false,"schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Test result (matches true/false)","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"signing-key.test","description":"Test a signing key pair without storing it"}],"x-since":"7.39.0"}},"/v4/signing/keys/generate":{"post":{"tags":["Signing"],"summary":"Generate signing key pair","description":"**Since v4.4.32** — Generates a new RSA-2048 or ECDSA P-256 key pair with a self-signed X.509 certificate (1 year validity). Returns the private key PEM as a ONE-TIME DOWNLOAD — it cannot be retrieved again. The encrypted key and certificate are stored for signing operations. Costs 50 Credits.","operationId":"generateKeys","parameters":[{"name":"algorithm","in":"query","required":false,"schema":{"type":"string","default":"RSA"}},{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","description":"Optional. Opaque, client-generated value (≤ 255 chars). When supplied, the server caches the response of the first successful invocation and replays it on a retry with the same key. Scoped to (user, method, path). TTL configurable via bitol.idempotency.ttl-minutes (default 60).","required":false,"schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Key pair generated — private key in response body","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Invalid algorithm (use RSA or ECDSA)","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"signing-key.mint","description":"Generate a signing key pair"}],"x-since":"4.4.32"}},"/v4/self-report":{"post":{"tags":["v-4-self-report-controller"],"summary":"Submit an in-app help/feedback report","description":"**Since v7.0.55** — Creates a GitHub issue from the report. Error responses carry a JSON `{message, reason}` body where `reason` is a stable machine-readable code the client maps to user copy (#753/#757):\n- `invalid_request` (400) — local validation failed (blank/oversize/bad-type).\n- `rate_limited` (429) — caller exceeded the per-IP/per-email hourly cap.\n- `github_unreachable` (502) — GitHub was unreachable (network/5xx/429) after bounded retries; the report is persisted server-side for recovery.\n- `github_rejected` (502) — GitHub was reachable but rejected the request (non-auth 4xx, e.g. 404/422); the report is persisted server-side for recovery.\n- `github_auth` (503) — the server's GitHub token was rejected (misconfigured).\n- `not_configured` (503) — self-report is not configured on this server.\nNote: a payload larger than the gateway body cap is rejected upstream by nginx with a 413 before it reaches this endpoint.","operationId":"submit","parameters":[{"name":"description","in":"query","required":true,"schema":{"type":"string"}},{"name":"context","in":"query","required":false,"schema":{"type":"string"}},{"name":"attachment","in":"query","required":false,"schema":{"type":"array","items":{"type":"string","format":"binary"}}},{"name":"Idempotency-Key","in":"header","description":"Optional. Opaque, client-generated value (≤ 255 chars). When supplied, the server caches the response of the first successful invocation and replays it on a retry with the same key. Scoped to (user, method, path). TTL configurable via bitol.idempotency.ttl-minutes (default 60).","required":false,"schema":{"type":"string","maxLength":255}}],"responses":{"201":{"description":"Report accepted; issue created.","content":{"*/*":{"schema":{"type":"object","additionalProperties":{}}}}},"400":{"description":"Validation failed — reason `invalid_request`.","content":{"*/*":{"schema":{"type":"object","additionalProperties":{}}}}},"429":{"description":"Rate-limited — reason `rate_limited`.","content":{"*/*":{"schema":{"type":"object","additionalProperties":{}}}}},"502":{"description":"GitHub-origin failure — reason `github_unreachable` or `github_rejected`.","content":{"*/*":{"schema":{"type":"object","additionalProperties":{}}}}},"503":{"description":"Server-side GitHub config error — reason `github_auth` or `not_configured`.","content":{"*/*":{"schema":{"type":"object","additionalProperties":{}}}}}},"x-intent":[{"name":"self-report.create","description":"Submit an in-app help/feedback report"}],"x-since":"7.0.55"}},"/v4/reference-tags":{"get":{"tags":["Tags"],"summary":"List all reference tags (v4, born-deprecated)","description":"**Since v7.1.3** — Returns all reference tags created by the authenticated user. Verbatim copy of /v1/reference-tags.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"listTags","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"reference-tag.list","description":"List all reference tags"}],"x-since":"7.1.3","x-sunset":"2027-01-01"},"post":{"tags":["Tags"],"summary":"Create a reference tag (v4, born-deprecated)","description":"**Since v7.1.3** — Creates a new reference tag with the specified properties. Verbatim copy of POST /v1/reference-tags.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"createTag","parameters":[{"name":"tagName","in":"query","required":true,"schema":{"type":"string"}},{"name":"properties","in":"query","required":true,"schema":{"type":"string"}},{"name":"description","in":"query","required":false,"schema":{"type":"string","default":""}},{"name":"Idempotency-Key","in":"header","description":"Optional. Opaque, client-generated value (≤ 255 chars). When supplied, the server caches the response of the first successful invocation and replays it on a retry with the same key. Scoped to (user, method, path). TTL configurable via bitol.idempotency.ttl-minutes (default 60).","required":false,"schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"reference-tag.create","description":"Create a reference tag"}],"x-since":"7.1.3","x-sunset":"2027-01-01"}},"/v4/products":{"get":{"tags":["Products"],"summary":"List product headers","description":"**Since v7.13.3** — Returns header fields for all products. Pass org or orgId to list organization products.","operationId":"readHeaders","parameters":[{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"JSON array of product header objects","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated or not an org member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"product.list","description":"List data product headers"}],"x-since":"7.13.3"},"post":{"tags":["Products"],"summary":"Upload a data product","description":"**Since v7.13.3** — Uploads an ODPS YAML data product file directly. Pass org or orgId to upload to an organization's storage.","operationId":"create","parameters":[{"name":"contractId","in":"query","required":true,"schema":{"type":"string"}},{"name":"contractVersion","in":"query","required":true,"schema":{"type":"string"}},{"name":"version","in":"query","required":false,"schema":{"type":"string"}},{"name":"name","in":"query","required":false,"schema":{"type":"string"}},{"name":"domain","in":"query","required":false,"schema":{"type":"string"}},{"name":"tenant","in":"query","required":false,"schema":{"type":"string"}},{"name":"force","in":"query","required":false,"schema":{"type":"string"}},{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","description":"Optional. Opaque, client-generated value (≤ 255 chars). When supplied, the server caches the response of the first successful invocation and replays it on a retry with the same key. Scoped to (user, method, path). TTL configurable via bitol.idempotency.ttl-minutes (default 60).","required":false,"schema":{"type":"string","maxLength":255}}],"requestBody":{"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary"}},"required":["file"]}}}},"responses":{"200":{"description":"Product uploaded successfully","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated or not an org member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}},"500":{"description":"File upload error","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Invalid file type","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"product.upload","description":"Upload an ODPS YAML data product file"}],"x-since":"7.13.3"},"delete":{"tags":["Products"],"summary":"Delete a data product","description":"**Since v7.13.3** — Soft-deletes a specific product version. Pass org or orgId for organization products.","operationId":"delete_2","parameters":[{"name":"productId","in":"query","required":true,"schema":{"type":"string"}},{"name":"version","in":"query","required":true,"schema":{"type":"string"}},{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Product deleted successfully","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated or not an org member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Product or organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"product.delete","description":"Delete a data product version"}],"x-since":"7.13.3"}},"/v4/products/{productId}/sign":{"post":{"tags":["Products"],"summary":"Sign a data product","description":"**Since v4.4.32** — Digitally signs the specified product using the caller's signing key (or the workspace key when org is specified). The signature is embedded in customProperties as an enveloped signature using JCS (RFC 8785) canonicalization.","operationId":"signProduct","parameters":[{"name":"productId","in":"path","required":true,"schema":{"type":"string"}},{"name":"version","in":"query","required":false,"schema":{"type":"string"}},{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","description":"Optional. Opaque, client-generated value (≤ 255 chars). When supplied, the server caches the response of the first successful invocation and replays it on a retry with the same key. Scoped to (user, method, path). TTL configurable via bitol.idempotency.ttl-minutes (default 60).","required":false,"schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Product signed successfully","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Product or signing credentials not found","content":{"*/*":{"schema":{"type":"object"}}}},"500":{"description":"Signing failed","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"product.sign","description":"Digitally sign a data product"}],"x-since":"4.4.32"},"delete":{"tags":["Products"],"summary":"Unsign a data product","description":"**Since v7.43.52** — Removes the enveloped signature from the specified product and records the per-artifact auto-sign opt-out (customProperties autosign=false) so no automatic path re-signs it. A subsequent manual sign clears the opt-out.","operationId":"unsignProduct","parameters":[{"name":"productId","in":"path","required":true,"schema":{"type":"string"}},{"name":"version","in":"query","required":false,"schema":{"type":"string"}},{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Signature removed","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated or not an org member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Product not found, or product has no signature","content":{"*/*":{"schema":{"type":"object"}}}},"500":{"description":"Unsign failed","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"product.unsign","description":"Remove the digital signature from a data product"}],"x-since":"7.43.52"}},"/v4/products/publish-github":{"post":{"tags":["Products"],"summary":"Publish product to GitHub","description":"**Since v7.26.0** — Enhanced publish with pre-publish version check, Git tagging, and auto-publish of referenced contracts. Compares local content against the last published version (via scoped Git tags). Returns SKIP if identical, CONFLICT (409) if version not bumped, or publishes and tags on success. Referenced contracts from outputPorts/inputPorts are automatically checked and published. Pass org or orgId to publish from an organization's storage using the org's GitHub token.","operationId":"publishToGitHub","parameters":[{"name":"productId","in":"query","description":"UUID of the data product to publish","required":true,"schema":{"type":"string"}},{"name":"version","in":"query","description":"Semantic version of the product to publish (e.g. 1.2.3). Defaults to the product's current version when omitted.","required":false,"schema":{"type":"string"}},{"name":"branch","in":"query","description":"GitHub branch to publish to. Defaults to the branch encoded in the product's canonicalUrl, falling back to the repo's default branch.","required":false,"schema":{"type":"string"}},{"name":"force","in":"query","description":"Force publish — skip pre-publish version conflict check","required":false,"schema":{"type":"string"}},{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","description":"Optional. Opaque, client-generated value (≤ 255 chars). When supplied, the server caches the response of the first successful invocation and replays it on a retry with the same key. Scoped to (user, method, path). TTL configurable via bitol.idempotency.ttl-minutes (default 60).","required":false,"schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Product published (or skipped if identical). Includes tag, skipped flag, and per-contract results","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Missing GitHub token, missing canonicalUrl, or invalid GitHub URL","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated or not an org member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Product or organization not found","content":{"*/*":{"schema":{"type":"object"}}}},"409":{"description":"Version conflict — product or referenced contract version not bumped. Returns per-contract details when contracts conflict","content":{"*/*":{"schema":{"type":"object"}}}},"502":{"description":"GitHub API error","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"product.publish","description":"Publish a data product to GitHub"}],"x-since":"7.26.0"}},"/v4/pdf-settings":{"get":{"tags":["Publishing"],"summary":"Read PDF settings (v4)","description":"**Since v8.10.0** — Returns the page size and footer this workspace renders its branded PDFs with (#977). `footer` is the footer the workspace explicitly set, or null when it has never set one — a client should render null as an empty field meaning \"use the automatic workspace copyright\". `effectiveFooter` is what actually prints today.","operationId":"getPdfSettings","responses":{"200":{"description":"The saved report format","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PdfSettingsResponse"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"pdf-settings.read","description":"Read the saved PDF rendering settings"}],"x-since":"8.10.0"},"post":{"tags":["Publishing"],"summary":"Update PDF settings (v4)","description":"**Since v7.4.0** — Updates PDF rendering settings (page size and footer message).","operationId":"updatePdfSettings","parameters":[{"name":"size","in":"query","required":true,"schema":{"type":"string"}},{"name":"footer","in":"query","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","description":"Optional. Opaque, client-generated value (≤ 255 chars). When supplied, the server caches the response of the first successful invocation and replays it on a retry with the same key. Scoped to (user, method, path). TTL configurable via bitol.idempotency.ttl-minutes (default 60).","required":false,"schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"PDF settings updated successfully","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated","content":{"*/*":{"schema":{"type":"object"}}}},"500":{"description":"Failed to update settings file","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"pdf-settings.update","description":"Update PDF rendering settings"}],"x-since":"7.4.0"}},"/v4/orgs/{slug}/settings/pdf-settings":{"post":{"tags":["Org Settings"],"summary":"Update organization PDF settings (deprecated slug path)","description":"**Since v7.5.0** — Updates PDF rendering settings (page size, footer) for the organization. Requires ADMIN+ role. Deprecated — use POST /v4/orgs/settings/pdf-settings with org/orgId (#651).\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"updatePdfSettingsBySlug","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"size","in":"query","required":true,"schema":{"type":"string"}},{"name":"footer","in":"query","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","description":"Optional. Opaque, client-generated value (≤ 255 chars). When supplied, the server caches the response of the first successful invocation and replays it on a retry with the same key. Scoped to (user, method, path). TTL configurable via bitol.idempotency.ttl-minutes (default 60).","required":false,"schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"PDF settings updated","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Insufficient role","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}},"500":{"description":"Failed to update settings","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-since":"7.5.0","x-sunset":"2027-01-01"}},"/v4/orgs/{slug}/settings/logo":{"get":{"tags":["Org Settings"],"summary":"Get organization logo (deprecated slug path)","description":"**Since v7.5.0** — Returns the organization's current SVG logo. Requires org membership. Deprecated — use GET /v4/orgs/settings/logo with org/orgId (#651).\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"getLogoBySlug","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"SVG logo content","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Not a member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found or no logo","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-since":"7.5.0","x-sunset":"2027-01-01"},"post":{"tags":["Org Settings"],"summary":"Upload organization logo (deprecated slug path)","description":"**Since v7.5.0** — Uploads an SVG logo for the organization's PDF contract renderings. Requires ADMIN+ role. Deprecated — use POST /v4/orgs/settings/logo with org/orgId (#651).\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"uploadLogoBySlug","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"force","in":"query","required":false,"schema":{"type":"boolean","default":false}},{"name":"Idempotency-Key","in":"header","description":"Optional. Opaque, client-generated value (≤ 255 chars). When supplied, the server caches the response of the first successful invocation and replays it on a retry with the same key. Scoped to (user, method, path). TTL configurable via bitol.idempotency.ttl-minutes (default 60).","required":false,"schema":{"type":"string","maxLength":255}}],"requestBody":{"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary"}},"required":["file"]}}}},"responses":{"200":{"description":"Logo uploaded successfully","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Uploaded file is not a valid SVG","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Insufficient role","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}},"409":{"description":"Logo already exists (use force=true)","content":{"*/*":{"schema":{"type":"object"}}}},"500":{"description":"File I/O error","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-since":"7.5.0","x-sunset":"2027-01-01"}},"/v4/orgs/{slug}/products":{"get":{"tags":["Org Products"],"summary":"List organization product headers","description":"**Since v7.9.0** — Returns header fields for all products in the organization.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"readHeaders_1","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"JSON array of product headers","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Not a member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"product.list","description":"List data product headers"}],"x-since":"7.9.0","x-sunset":"2027-01-01"},"post":{"tags":["Org Products"],"summary":"Upload a product to the organization","description":"**Since v7.9.0** — Uploads an ODPS YAML file directly to the organization's storage.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"create_1","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"contractId","in":"query","required":true,"schema":{"type":"string"}},{"name":"contractVersion","in":"query","required":true,"schema":{"type":"string"}},{"name":"version","in":"query","required":false,"schema":{"type":"string"}},{"name":"name","in":"query","required":false,"schema":{"type":"string"}},{"name":"domain","in":"query","required":false,"schema":{"type":"string"}},{"name":"tenant","in":"query","required":false,"schema":{"type":"string"}},{"name":"force","in":"query","required":false,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","description":"Optional. Opaque, client-generated value (≤ 255 chars). When supplied, the server caches the response of the first successful invocation and replays it on a retry with the same key. Scoped to (user, method, path). TTL configurable via bitol.idempotency.ttl-minutes (default 60).","required":false,"schema":{"type":"string","maxLength":255}}],"requestBody":{"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary"}},"required":["file"]}}}},"responses":{"200":{"description":"Product uploaded","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Not a member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}},"500":{"description":"Product creation error","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Invalid file type","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"product.upload","description":"Upload an ODPS YAML data product file"}],"x-since":"7.9.0","x-sunset":"2027-01-01"},"delete":{"tags":["Org Products"],"summary":"Delete an organization product","description":"**Since v7.9.0** — Soft-deletes a specific product version from the organization.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"delete_3","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"productId","in":"query","required":true,"schema":{"type":"string"}},{"name":"version","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Product deleted","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Not a member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization or product not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"product.delete","description":"Delete a data product version"}],"x-since":"7.9.0","x-sunset":"2027-01-01"}},"/v4/orgs/{slug}/products/publish-github":{"post":{"tags":["Org Products"],"summary":"Publish organization product to GitHub","description":"**Since v7.9.0** — Pushes the product YAML to GitHub.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"publishToGitHub_1","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"productId","in":"query","required":true,"schema":{"type":"string"}},{"name":"version","in":"query","required":false,"schema":{"type":"string"}},{"name":"branch","in":"query","required":false,"schema":{"type":"string"}},{"name":"force","in":"query","required":false,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","description":"Optional. Opaque, client-generated value (≤ 255 chars). When supplied, the server caches the response of the first successful invocation and replays it on a retry with the same key. Scoped to (user, method, path). TTL configurable via bitol.idempotency.ttl-minutes (default 60).","required":false,"schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Product published","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Missing GitHub token or canonicalUrl","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Not a member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization or product not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"product.publish","description":"Publish a data product to GitHub"}],"x-since":"7.9.0","x-sunset":"2027-01-01"}},"/v4/orgs/{slug}/messages/{messageId}/resend":{"post":{"tags":["Membership"],"summary":"Resend a pending invitation (deprecated slug path)","description":"**Since v7.43.15** — Owner/admin re-sends the invitation email for a PENDING invitation. Deprecated — use POST /v4/orgs/messages/{messageId}/resend with org/orgId (#651).\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"resendInvitationBySlug","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"messageId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"Idempotency-Key","in":"header","description":"Optional. Opaque, client-generated value (≤ 255 chars). When supplied, the server caches the response of the first successful invocation and replays it on a retry with the same key. Scoped to (user, method, path). TTL configurable via bitol.idempotency.ttl-minutes (default 60).","required":false,"schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Invitation email re-sent","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Message not found, not pending, or not an invitation","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Insufficient role","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-since":"7.43.15","x-sunset":"2027-01-01"}},"/v4/orgs/{slug}/join":{"post":{"tags":["Membership"],"summary":"Request to join an organization (deprecated slug path)","description":"**Since v7.11.0** — Submits a join request that must be approved by an org admin or owner. Deprecated — use POST /v4/orgs/join with org/orgId (#651).\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"joinRequestBySlug","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"message","in":"query","required":false,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","description":"Optional. Opaque, client-generated value (≤ 255 chars). When supplied, the server caches the response of the first successful invocation and replays it on a retry with the same key. Scoped to (user, method, path). TTL configurable via bitol.idempotency.ttl-minutes (default 60).","required":false,"schema":{"type":"string","maxLength":255}}],"responses":{"201":{"description":"Join request created","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Already a member or pending request exists","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-since":"7.11.0","x-sunset":"2027-01-01"}},"/v4/orgs/{slug}/invite":{"post":{"tags":["Membership"],"summary":"Invite a user to the organization (deprecated slug path)","description":"**Since v7.11.0** — Admin/owner invites a user by email. The user must accept the invitation. Deprecated — use POST /v4/orgs/invite with org/orgId (#651).\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"inviteBySlug","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"email","in":"query","required":true,"schema":{"type":"string"}},{"name":"message","in":"query","required":false,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","description":"Optional. Opaque, client-generated value (≤ 255 chars). When supplied, the server caches the response of the first successful invocation and replays it on a retry with the same key. Scoped to (user, method, path). TTL configurable via bitol.idempotency.ttl-minutes (default 60).","required":false,"schema":{"type":"string","maxLength":255}}],"responses":{"201":{"description":"Invitation created","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Already a member or pending invitation","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Insufficient role","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-since":"7.11.0","x-sunset":"2027-01-01"}},"/v4/orgs/{slug}/integrations/{key}/test":{"post":{"tags":["Org Settings"],"summary":"Test org integration credentials (deprecated slug path)","description":"**Since v7.10.0** — Tests the stored credentials of an org integration. Requires ADMIN+ role. Deprecated — use POST /v4/orgs/integrations/{key}/test with org/orgId (#651).\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"testCredentialsBySlug","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"key","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","description":"Optional. Opaque, client-generated value (≤ 255 chars). When supplied, the server caches the response of the first successful invocation and replays it on a retry with the same key. Scoped to (user, method, path). TTL configurable via bitol.idempotency.ttl-minutes (default 60).","required":false,"schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-since":"7.10.0","x-sunset":"2027-01-01"}},"/v4/orgs/{slug}/integrations/{key}/test/field/{fieldName}":{"post":{"tags":["Org Settings"],"summary":"Test a single org integration field (deprecated slug path)","description":"**Since v7.10.0** — Tests a specific field value without saving. Returns success/message/warning. Uses context or stored credentials for fields that require companion values. Deprecated — use POST /v4/orgs/integrations/{key}/test/field/{fieldName} with org/orgId (#651).\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"testFieldBySlug","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"key","in":"path","required":true,"schema":{"type":"string"}},{"name":"fieldName","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","description":"Optional. Opaque, client-generated value (≤ 255 chars). When supplied, the server caches the response of the first successful invocation and replays it on a retry with the same key. Scoped to (user, method, path). TTL configurable via bitol.idempotency.ttl-minutes (default 60).","required":false,"schema":{"type":"string","maxLength":255}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","additionalProperties":{}}}},"required":true},"responses":{"200":{"description":"Test result (check 'success' field)","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Unknown integration or field name","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Insufficient role (requires ADMIN+)","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-since":"7.10.0","x-sunset":"2027-01-01"}},"/v4/orgs/{slug}/domains":{"post":{"tags":["Organizations"],"summary":"Add domain to organization (deprecated slug path)","description":"**Since v7.7.0** — Adds an email domain to the organization for discovery. Requires ADMIN+ role. Deprecated — use POST /v4/orgs/domains with org/orgId (#651).\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"addDomainBySlug","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"domain","in":"query","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","description":"Optional. Opaque, client-generated value (≤ 255 chars). When supplied, the server caches the response of the first successful invocation and replays it on a retry with the same key. Scoped to (user, method, path). TTL configurable via bitol.idempotency.ttl-minutes (default 60).","required":false,"schema":{"type":"string","maxLength":255}}],"responses":{"201":{"description":"Domain added","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Domain blocked or already claimed","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Insufficient role","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-since":"7.7.0","x-sunset":"2027-01-01"},"delete":{"tags":["Organizations"],"summary":"Remove domain from organization (deprecated slug path)","description":"**Since v7.7.0** — Removes an email domain from the organization. Requires ADMIN+ role. Deprecated — use DELETE /v4/orgs/domains with org/orgId (#651).\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"removeDomainBySlug","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"domain","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Domain removed","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Domain not found or doesn't belong to this org","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Insufficient role","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-since":"7.7.0","x-sunset":"2027-01-01"}},"/v4/orgs/{slug}/credits/transfer":{"post":{"tags":["Credits"],"summary":"Transfer Credits from org to user","description":"**Since v7.44.0** — Transfers Credits from the organization's balance to a user's personal balance. Requires ADMIN or OWNER role in the organization.","operationId":"transferOrgCreditsBySlug","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"email","in":"query","required":true,"schema":{"type":"string"}},{"name":"amount","in":"query","required":true,"schema":{"type":"integer","format":"int32"}},{"name":"Idempotency-Key","in":"header","description":"Optional. Opaque, client-generated value (≤ 255 chars). When supplied, the server caches the response of the first successful invocation and replays it on a retry with the same key. Scoped to (user, method, path). TTL configurable via bitol.idempotency.ttl-minutes (default 60).","required":false,"schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Credits transferred","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Invalid amount or insufficient org balance","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Not an admin/owner of the organization","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization or target user not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"credit.org.transfer","description":"Transfer Credits from org to user"}],"x-since":"7.44.0"}},"/v4/orgs/{slug}/credits/grant":{"post":{"tags":["Credits"],"summary":"Grant Credits to an organization (admin)","description":"**Since v7.44.0** — Admin grants Credits to an organization by slug.","operationId":"grantOrgCreditsBySlug","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"amount","in":"query","required":true,"schema":{"type":"integer","format":"int32"}},{"name":"comment","in":"query","required":false,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","description":"Optional. Opaque, client-generated value (≤ 255 chars). When supplied, the server caches the response of the first successful invocation and replays it on a retry with the same key. Scoped to (user, method, path). TTL configurable via bitol.idempotency.ttl-minutes (default 60).","required":false,"schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Credits granted to organization","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Admin privileges required","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"credit.org.grant","description":"Grant Credits to an organization (admin)"}],"x-since":"7.44.0"}},"/v4/orgs/{slug}/contracts":{"get":{"tags":["Org Contracts"],"summary":"List organization contract headers","description":"**Since v7.8.0** — Returns header fields for all contracts in the organization.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"readHeaders_2","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"storage","in":"query","required":false,"schema":{"type":"string","default":"permanent"}}],"responses":{"200":{"description":"JSON array of contract headers","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Not a member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"contract.list","description":"List organization contract headers"}],"x-since":"7.8.0","x-sunset":"2027-01-01"},"post":{"tags":["Org Contracts"],"summary":"Upload a contract to the organization","description":"**Since v7.8.0** — Uploads an ODCS YAML or DDL file to the organization's storage. Requires org membership.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"create_2","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"contractId","in":"query","required":false,"schema":{"type":"string"}},{"name":"sourceFormat","in":"query","required":false,"schema":{"type":"string"}},{"name":"version","in":"query","required":false,"schema":{"type":"string"}},{"name":"name","in":"query","required":false,"schema":{"type":"string"}},{"name":"domain","in":"query","required":false,"schema":{"type":"string"}},{"name":"tenant","in":"query","required":false,"schema":{"type":"string"}},{"name":"force","in":"query","required":false,"schema":{"type":"string"}},{"name":"storage","in":"query","required":false,"schema":{"type":"string","default":"permanent"}},{"name":"ddlUrl","in":"query","required":false,"schema":{"type":"string"}},{"name":"dbmlUrl","in":"query","required":false,"schema":{"type":"string"}},{"name":"includeViews","in":"query","description":"When sourceFormat=jdbc, also introspect database views (#185 TD-5). Views are added as SchemaObjects tagged 'view'. Default false.","required":false,"schema":{"type":"boolean","default":false}},{"name":"includeRoutines","in":"query","description":"When sourceFormat=jdbc, also discover stored procedures and functions (#186 TD-6). Attached as JSON customProperties 'storedProcedures' and 'storedFunctions'. Default false.","required":false,"schema":{"type":"boolean","default":false}},{"name":"Idempotency-Key","in":"header","description":"Optional. Opaque, client-generated value (≤ 255 chars). When supplied, the server caches the response of the first successful invocation and replays it on a retry with the same key. Scoped to (user, method, path). TTL configurable via bitol.idempotency.ttl-minutes (default 60).","required":false,"schema":{"type":"string","maxLength":255}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary"},"jdbcConnection":{"$ref":"#/components/schemas/JdbcConnectionRequest"}}}}}},"responses":{"200":{"description":"Contract uploaded","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Invalid input","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Not a member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"contract.create","description":"Upload a contract to the organization"}],"x-since":"7.8.0","x-sunset":"2027-01-01"},"delete":{"tags":["Org Contracts"],"summary":"Delete an organization contract","description":"**Since v7.8.0** — Soft-deletes a specific contract version from the organization.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"delete_4","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"contractId","in":"query","required":true,"schema":{"type":"string"}},{"name":"version","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Contract deleted","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Not a member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization or contract not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"contract.delete","description":"Delete an organization contract"}],"x-since":"7.8.0","x-sunset":"2027-01-01"}},"/v4/orgs/{slug}/contracts/transfer":{"post":{"tags":["Org Contracts"],"summary":"Transfer artifacts from personal to org storage","description":"**Since v7.8.0** — Moves contracts and/or products from the authenticated user's personal storage into the organization. Transfer is all-or-nothing: if any item fails validation, nothing is transferred. The request body is a JSON array of TransferItem objects.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"transferArtifacts","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","description":"Optional. Opaque, client-generated value (≤ 255 chars). When supplied, the server caches the response of the first successful invocation and replays it on a retry with the same key. Scoped to (user, method, path). TTL configurable via bitol.idempotency.ttl-minutes (default 60).","required":false,"schema":{"type":"string","maxLength":255}}],"requestBody":{"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TransferItem"}}}},"required":true},"responses":{"200":{"description":"Artifacts transferred successfully","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Validation failed (missing artifacts, invalid types)","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Not a member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}},"500":{"description":"File transfer error","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"contract.transfer","description":"Transfer artifacts to org storage"}],"x-since":"7.8.0","x-sunset":"2027-01-01"}},"/v4/orgs/{slug}/contracts/publish-github":{"post":{"tags":["Org Contracts"],"summary":"Publish organization contract to GitHub","description":"**Since v7.8.0** — Pushes the contract YAML to GitHub. Uses the organization's GitHub token if configured.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"publishToGitHub_2","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"contractId","in":"query","required":true,"schema":{"type":"string"}},{"name":"version","in":"query","required":false,"schema":{"type":"string"}},{"name":"branch","in":"query","required":false,"schema":{"type":"string"}},{"name":"storage","in":"query","required":false,"schema":{"type":"string","default":"permanent"}},{"name":"force","in":"query","required":false,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","description":"Optional. Opaque, client-generated value (≤ 255 chars). When supplied, the server caches the response of the first successful invocation and replays it on a retry with the same key. Scoped to (user, method, path). TTL configurable via bitol.idempotency.ttl-minutes (default 60).","required":false,"schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Contract published","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Missing GitHub token or canonicalUrl","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Not a member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization or contract not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"contract.publish","description":"Publish organization contract to GitHub"}],"x-since":"7.8.0","x-sunset":"2027-01-01"}},"/v4/orgs/settings/pdf-settings":{"get":{"tags":["Org Settings"],"summary":"Read organization PDF settings","description":"**Since v8.10.0** — Returns the page size and footer the organization renders its branded PDFs with (#977). Pass org (slug) or orgId (UUID) to select the organization. Readable by any MEMBER, like the logo. `footer` is null when the organization has never set one; `effectiveFooter` is what actually prints.","operationId":"getPdfSettings_1","parameters":[{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"The saved report format","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PdfSettingsResponse"}}}},"400":{"description":"Missing org/orgId parameter","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Not a member of the organization","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"org.settings.pdf.read","description":"Read the organization's PDF rendering settings"}],"x-since":"8.10.0"},"post":{"tags":["Org Settings"],"summary":"Update organization PDF settings","description":"**Since v7.26.0** — Updates PDF rendering settings (page size, footer) for the organization. Pass org (slug) or orgId (UUID) to select the organization. Requires ADMIN+ role.","operationId":"updatePdfSettings_1","parameters":[{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"size","in":"query","required":true,"schema":{"type":"string"}},{"name":"footer","in":"query","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","description":"Optional. Opaque, client-generated value (≤ 255 chars). When supplied, the server caches the response of the first successful invocation and replays it on a retry with the same key. Scoped to (user, method, path). TTL configurable via bitol.idempotency.ttl-minutes (default 60).","required":false,"schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"PDF settings updated","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Missing org/orgId parameter","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Insufficient role","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}},"500":{"description":"Failed to update settings","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"org.settings.pdf.update","description":"Update organization PDF rendering settings"}],"x-since":"7.26.0"}},"/v4/orgs/settings/logo":{"get":{"tags":["Org Settings"],"summary":"Get organization logo","description":"**Since v7.26.0** — Returns the organization's current SVG logo. Pass org (slug) or orgId (UUID) to select the organization. Requires org membership.","operationId":"getLogo","parameters":[{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"SVG logo content","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Missing org/orgId parameter","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Not a member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found or no logo","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"org.settings.logo.get","description":"Get the organization logo"}],"x-since":"7.26.0"},"post":{"tags":["Org Settings"],"summary":"Upload organization logo","description":"**Since v7.26.0** — Uploads an SVG logo for the organization's PDF contract renderings. Pass org (slug) or orgId (UUID) to select the organization. Requires ADMIN+ role.","operationId":"uploadLogo","parameters":[{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"force","in":"query","required":false,"schema":{"type":"boolean","default":false}},{"name":"Idempotency-Key","in":"header","description":"Optional. Opaque, client-generated value (≤ 255 chars). When supplied, the server caches the response of the first successful invocation and replays it on a retry with the same key. Scoped to (user, method, path). TTL configurable via bitol.idempotency.ttl-minutes (default 60).","required":false,"schema":{"type":"string","maxLength":255}}],"requestBody":{"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary"}},"required":["file"]}}}},"responses":{"200":{"description":"Logo uploaded successfully","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Missing org/orgId parameter or not a valid SVG","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Insufficient role","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}},"409":{"description":"Logo already exists (use force=true)","content":{"*/*":{"schema":{"type":"object"}}}},"500":{"description":"File I/O error","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"org.settings.logo.upload","description":"Upload the organization logo"}],"x-since":"7.26.0"}},"/v4/orgs/service-accounts":{"get":{"tags":["Service Accounts"],"summary":"List the org's service accounts (org-ADMIN only)","description":"**Since v7.34.0** — No secret material in the response.","operationId":"list","parameters":[{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Array of service accounts (no secrets)","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Caller is not an ADMIN of the org","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"serviceaccount.list","description":"List org service accounts"}],"x-since":"7.34.0"},"post":{"tags":["Service Accounts"],"summary":"Create a service account (org-ADMIN only)","description":"**Since v7.34.0** — Creates an OAuth2 service account owned by the organization. The response carries the client_id and the plaintext client_secret EXACTLY ONCE — only the BCrypt hash is persisted; record the secret immediately. Scopes are limited to contracts:read and contracts:publish (v1). Tokens come from POST /oauth2/token with grant_type=client_credentials (1 hour, ES256, no refresh token).","operationId":"create_3","parameters":[{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","description":"Optional. Opaque, client-generated value (≤ 255 chars). When supplied, the server caches the response of the first successful invocation and replays it on a retry with the same key. Scoped to (user, method, path). TTL configurable via bitol.idempotency.ttl-minutes (default 60).","required":false,"schema":{"type":"string","maxLength":255}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRequest"}}},"required":true},"responses":{"200":{"description":"Service account created; client_secret shown once","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Missing name or unsupported scope","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Caller is not an ADMIN of the org","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"serviceaccount.create","description":"Create an org service account"}],"x-since":"7.34.0"}},"/v4/orgs/service-accounts/{id}/rotate":{"post":{"tags":["Service Accounts"],"summary":"Rotate a service-account secret (org-ADMIN only)","description":"**Since v7.34.0** — Replaces the client_secret; the new plaintext is returned EXACTLY ONCE. The previous secret stops working immediately. A revoked account stays revoked.","operationId":"rotate","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","description":"Optional. Opaque, client-generated value (≤ 255 chars). When supplied, the server caches the response of the first successful invocation and replays it on a retry with the same key. Scoped to (user, method, path). TTL configurable via bitol.idempotency.ttl-minutes (default 60).","required":false,"schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Secret rotated; new client_secret shown once","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Caller is not an ADMIN of the org","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization or service account not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"serviceaccount.rotate","description":"Rotate a service-account secret"}],"x-since":"7.34.0"}},"/v4/orgs/messages/{messageId}/resend":{"post":{"tags":["Membership"],"summary":"Resend a pending invitation","description":"**Since v7.43.15** — Owner/admin re-sends the invitation email for a PENDING invitation. Does NOT create a new message row. Pass org (slug) or orgId (UUID) to select the organization. Requires ADMIN+ role.","operationId":"resendInvitation","parameters":[{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"messageId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"Idempotency-Key","in":"header","description":"Optional. Opaque, client-generated value (≤ 255 chars). When supplied, the server caches the response of the first successful invocation and replays it on a retry with the same key. Scoped to (user, method, path). TTL configurable via bitol.idempotency.ttl-minutes (default 60).","required":false,"schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Invitation email re-sent","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Missing org/orgId, message not found, not pending, or not an invitation","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Insufficient role","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"org.invitation.resend","description":"Resend a pending organization invitation"}],"x-since":"7.43.15"}},"/v4/orgs/join":{"post":{"tags":["Membership"],"summary":"Request to join an organization","description":"**Since v7.26.0** — Submits a join request that must be approved by an org admin or owner. Pass org (slug) or orgId (UUID) to select the organization.","operationId":"joinRequest","parameters":[{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"message","in":"query","required":false,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","description":"Optional. Opaque, client-generated value (≤ 255 chars). When supplied, the server caches the response of the first successful invocation and replays it on a retry with the same key. Scoped to (user, method, path). TTL configurable via bitol.idempotency.ttl-minutes (default 60).","required":false,"schema":{"type":"string","maxLength":255}}],"responses":{"201":{"description":"Join request created","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Missing org/orgId parameter, already a member, or pending request exists","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"org.member.join","description":"Request to join an organization"}],"x-since":"7.26.0"}},"/v4/orgs/invite":{"post":{"tags":["Membership"],"summary":"Invite a user to the organization","description":"**Since v7.26.0** — Admin/owner invites a user by email. The user must accept the invitation. Pass org (slug) or orgId (UUID) to select the organization. Requires ADMIN+ role.","operationId":"invite","parameters":[{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"email","in":"query","required":true,"schema":{"type":"string"}},{"name":"message","in":"query","required":false,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","description":"Optional. Opaque, client-generated value (≤ 255 chars). When supplied, the server caches the response of the first successful invocation and replays it on a retry with the same key. Scoped to (user, method, path). TTL configurable via bitol.idempotency.ttl-minutes (default 60).","required":false,"schema":{"type":"string","maxLength":255}}],"responses":{"201":{"description":"Invitation created","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Missing org/orgId parameter, already a member, or pending invitation","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Insufficient role","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"org.member.invite","description":"Invite a user to the organization"}],"x-since":"7.26.0"}},"/v4/orgs/integrations/{key}/test":{"post":{"tags":["Org Settings"],"summary":"Test org integration credentials","description":"**Since v7.26.0** — Tests the stored credentials of an org integration. Pass org (slug) or orgId (UUID) to select the organization. Requires ADMIN+ role.","operationId":"testCredentials_1","parameters":[{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"key","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","description":"Optional. Opaque, client-generated value (≤ 255 chars). When supplied, the server caches the response of the first successful invocation and replays it on a retry with the same key. Scoped to (user, method, path). TTL configurable via bitol.idempotency.ttl-minutes (default 60).","required":false,"schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Test result (check 'success' field)","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Missing org/orgId parameter or unknown integration key","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Insufficient role (requires ADMIN+)","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"integration.github.test","description":"Test org GitHub integration credentials"},{"name":"integration.zeenea.test","description":"Test org Zeenea integration credentials"},{"name":"integration.kafka.test","description":"Test org Control Center integration credentials"}],"x-since":"7.26.0"}},"/v4/orgs/integrations/{key}/test/field/{fieldName}":{"post":{"tags":["Org Settings"],"summary":"Test a single org integration field","description":"**Since v7.26.0** — Tests a specific field value without saving. Returns success/message/warning. Uses context or stored credentials for fields that require companion values. Pass org (slug) or orgId (UUID) to select the organization. Requires ADMIN+ role.","operationId":"testField_1","parameters":[{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"key","in":"path","required":true,"schema":{"type":"string"}},{"name":"fieldName","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","description":"Optional. Opaque, client-generated value (≤ 255 chars). When supplied, the server caches the response of the first successful invocation and replays it on a retry with the same key. Scoped to (user, method, path). TTL configurable via bitol.idempotency.ttl-minutes (default 60).","required":false,"schema":{"type":"string","maxLength":255}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","additionalProperties":{}}}},"required":true},"responses":{"200":{"description":"Test result (check 'success' field)","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Missing org/orgId parameter or unknown integration/field name","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Insufficient role (requires ADMIN+)","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"integration.github.test","description":"Test a single org GitHub integration field"},{"name":"integration.zeenea.test","description":"Test a single org Zeenea integration field"},{"name":"integration.kafka.test","description":"Test a single org Control Center integration field"}],"x-since":"7.26.0"}},"/v4/orgs/domains":{"post":{"tags":["Organizations"],"summary":"Add domain to organization","description":"**Since v7.26.0** — Adds an email domain to the organization for discovery. Requires ADMIN+ role. Pass org (slug) or orgId (UUID) to select the organization.","operationId":"addDomain","parameters":[{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"domain","in":"query","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","description":"Optional. Opaque, client-generated value (≤ 255 chars). When supplied, the server caches the response of the first successful invocation and replays it on a retry with the same key. Scoped to (user, method, path). TTL configurable via bitol.idempotency.ttl-minutes (default 60).","required":false,"schema":{"type":"string","maxLength":255}}],"responses":{"201":{"description":"Domain added","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Missing org/orgId parameter, domain blocked, or already claimed","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Insufficient role","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"org.domain.create","description":"Add an email domain to the organization"}],"x-since":"7.26.0"},"delete":{"tags":["Organizations"],"summary":"Remove domain from organization","description":"**Since v7.26.0** — Removes an email domain from the organization. Requires ADMIN+ role. Pass org (slug) or orgId (UUID) to select the organization.","operationId":"removeDomain","parameters":[{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"domain","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Domain removed","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Missing org/orgId parameter, domain not found, or doesn't belong to this org","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Insufficient role","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"org.domain.delete","description":"Remove an email domain from the organization"}],"x-since":"7.26.0"}},"/v4/orgs/agents/invoke":{"post":{"tags":["Org Agent Providers"],"summary":"Invoke an agent","description":"**Since v8.9.0** — Proxies an A2A message/send to the chosen imported agent's endpoint. Invocation runs server-side (SSRF-guarded, redirects off) so the browser never calls third-party URLs. Pass org (slug) or orgId (UUID) and the agent's cardUrl (from GET /v4/orgs/agents). Requires org membership; the org must have agent support enabled.","operationId":"invoke","parameters":[{"name":"org","in":"query","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","description":"Optional. Opaque, client-generated value (≤ 255 chars). When supplied, the server caches the response of the first successful invocation and replays it on a retry with the same key. Scoped to (user, method, path). TTL configurable via bitol.idempotency.ttl-minutes (default 60).","required":false,"schema":{"type":"string","maxLength":255}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentInvokeRequest"}}},"required":true},"responses":{"200":{"description":"The agent's reply","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Missing org/orgId or message, or a blocked URL","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Not a member, or agent support disabled","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found, or agent not imported","content":{"*/*":{"schema":{"type":"object"}}}},"502":{"description":"The agent failed, timed out, or returned no reply","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"org.agents.invoke","description":"Send a message to an imported agent via the A2A proxy"}],"x-since":"8.9.0"}},"/v4/orgs/agent-providers":{"get":{"tags":["Org Agent Providers"],"summary":"List agent providers","description":"**Since v8.6.0** — Lists the A2A agent providers registered for the organization, each with its last sync status. Pass org (slug) or orgId (UUID). Requires org membership.","operationId":"list_1","parameters":[{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Array of agent providers","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Missing org/orgId parameter","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Not a member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"org.agents.providers.list","description":"List the organization's agent providers"}],"x-since":"8.6.0"},"post":{"tags":["Org Agent Providers"],"summary":"Register an agent provider","description":"**Since v8.6.0** — Registers an A2A agent-registry URL for the organization and imports its agents. Pass org (slug) or orgId (UUID). Requires ADMIN+ role.","operationId":"add","parameters":[{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","description":"Optional. Opaque, client-generated value (≤ 255 chars). When supplied, the server caches the response of the first successful invocation and replays it on a retry with the same key. Scoped to (user, method, path). TTL configurable via bitol.idempotency.ttl-minutes (default 60).","required":false,"schema":{"type":"string","maxLength":255}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentProviderRequest"}}},"required":true},"responses":{"201":{"description":"Provider registered","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Missing org/orgId, or a malformed/blocked URL","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Insufficient role","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}},"409":{"description":"Provider URL already registered","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"org.agents.providers.add","description":"Register an agent provider"}],"x-since":"8.6.0"}},"/v4/orgs/agent-providers/{id}/sync":{"post":{"tags":["Org Agent Providers"],"summary":"Re-sync an agent provider","description":"**Since v8.6.0** — Forces an immediate re-fetch of the provider's agents. Pass org (slug) or orgId (UUID). Requires ADMIN+ role. Sync failures are reported in the provider's lastError.","operationId":"sync","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"org","in":"query","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","description":"Optional. Opaque, client-generated value (≤ 255 chars). When supplied, the server caches the response of the first successful invocation and replays it on a retry with the same key. Scoped to (user, method, path). TTL configurable via bitol.idempotency.ttl-minutes (default 60).","required":false,"schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Provider after re-sync","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Insufficient role","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization or provider not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"org.agents.providers.sync","description":"Re-sync an agent provider"}],"x-since":"8.6.0"}},"/v4/onboarding/events":{"post":{"tags":["Onboarding"],"summary":"Record a visitor-side onboarding event","description":"**Since v8.16.7** — Public, anonymous beacon. Accepts ONLY the visitor-side stages (landing_view, register_view, path_code, path_request) keyed by a client-generated visitorId — server-side stages are stamped by the backend at their authoritative transitions and are rejected here. No PII is accepted (email fields are ignored). Rate-limited per IP (60/hour).","operationId":"recordEvent","parameters":[{"name":"Idempotency-Key","in":"header","description":"Optional. Opaque, client-generated value (≤ 255 chars). When supplied, the server caches the response of the first successful invocation and replays it on a retry with the same key. Scoped to (user, method, path). TTL configurable via bitol.idempotency.ttl-minutes (default 60).","required":false,"schema":{"type":"string","maxLength":255}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"string"}}}},"required":true},"responses":{"201":{"description":"Event recorded","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Missing visitorId, or a stage outside the visitor set","content":{"*/*":{"schema":{"type":"object"}}}},"429":{"description":"Rate limit exceeded","content":{"*/*":{"schema":{"type":"object"}}}}},"x-intent":[{"name":"onboarding.event.create","description":"Record a visitor-side onboarding funnel event"}],"x-since":"8.16.7"}},"/v4/maturity-history/capture":{"post":{"tags":["Maturity History"],"summary":"Trigger maturity snapshot capture (admin)","description":"**Since v7.2.0** — Admin-only. Immediately captures a maturity snapshot for today by scanning all contract and product files across all users and organizations. Requires Bearer JWT with admin privileges.","operationId":"captureSnapshot","parameters":[{"name":"Idempotency-Key","in":"header","description":"Optional. Opaque, client-generated value (≤ 255 chars). When supplied, the server caches the response of the first successful invocation and replays it on a retry with the same key. Scoped to (user, method, path). TTL configurable via bitol.idempotency.ttl-minutes (default 60).","required":false,"schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Snapshot captured","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Admin privileges required","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"maturity.history.capture","description":"Trigger maturity snapshot capture"}],"x-since":"7.2.0"}},"/v4/logo":{"get":{"tags":["Publishing"],"summary":"Get logo (v4)","description":"**Since v7.4.0** — Returns the user's current SVG logo. User identified from JWT.","operationId":"getLogo_1","responses":{"200":{"description":"SVG logo content","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"No logo found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"logo.get","description":"Get the user's SVG logo"}],"x-since":"7.4.0"},"post":{"tags":["Publishing"],"summary":"Upload a logo (v4)","description":"**Since v7.4.0** — Uploads an SVG logo for PDF contract renderings. Use force=true to overwrite an existing logo.","operationId":"uploadLogo_1","parameters":[{"name":"force","in":"query","required":false,"schema":{"type":"boolean","default":false}},{"name":"Idempotency-Key","in":"header","description":"Optional. Opaque, client-generated value (≤ 255 chars). When supplied, the server caches the response of the first successful invocation and replays it on a retry with the same key. Scoped to (user, method, path). TTL configurable via bitol.idempotency.ttl-minutes (default 60).","required":false,"schema":{"type":"string","maxLength":255}}],"requestBody":{"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary"}},"required":["file"]}}}},"responses":{"200":{"description":"Logo uploaded successfully","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Uploaded file is not a valid SVG","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated","content":{"*/*":{"schema":{"type":"object"}}}},"409":{"description":"Logo already exists (use force=true to overwrite)","content":{"*/*":{"schema":{"type":"object"}}}},"500":{"description":"File I/O error","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"logo.upload","description":"Upload an SVG logo"}],"x-since":"7.4.0"}},"/v4/interactions":{"post":{"tags":["v-4-interactions-controller"],"summary":"Record one pseudonymous Governance Coach interaction","description":"**Since v7.51.0** — Write-side telemetry for the Governance Coach (WB2 #893): the client posts the question, answer, RAG grounding, and maturity gaps under a client-generated random pseudonym. Requires a Bearer token, but the caller's identity is never stored or logged joinably with the record. The interaction day is derived server-side at date precision (UTC); any client-supplied timestamp is ignored. Error responses carry the JSON `{message, reason}` body with reason `invalid_request` (400) when validation fails.","operationId":"record","parameters":[{"name":"Idempotency-Key","in":"header","description":"Optional. Opaque, client-generated value (≤ 255 chars). When supplied, the server caches the response of the first successful invocation and replays it on a retry with the same key. Scoped to (user, method, path). TTL configurable via bitol.idempotency.ttl-minutes (default 60).","required":false,"schema":{"type":"string","maxLength":255}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CoachInteractionRequest"}}},"required":true},"responses":{"202":{"description":"Record accepted; empty body.","content":{"*/*":{"schema":{"type":"object","additionalProperties":{}}}}},"400":{"description":"Validation failed — reason `invalid_request`.","content":{"*/*":{"schema":{"type":"object","additionalProperties":{}}}}},"401":{"description":"Missing or invalid Bearer token.","content":{"*/*":{"schema":{"type":"object","additionalProperties":{}}}}}},"x-intent":[{"name":"coach.interaction.record","description":"Record one pseudonymous Governance Coach interaction"}],"x-since":"7.51.0"}},"/v4/import":{"post":{"tags":["Import"],"summary":"Import a ZIP of ODCS/ODPS files","description":"**Since v7.50.0** — Unpacks the uploaded ZIP archive and creates every ODCS contract and ODPS product it contains (create-only: entries whose id+version already exist are skipped, never overwritten). Contracts are processed before products so products can reference contracts shipped in the same archive. Returns a per-file report; a partially failed import is a normal 200 outcome. Pass org or orgId to import into an organization's storage.","operationId":"importZip","parameters":[{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","description":"Optional. Opaque, client-generated value (≤ 255 chars). When supplied, the server caches the response of the first successful invocation and replays it on a retry with the same key. Scoped to (user, method, path). TTL configurable via bitol.idempotency.ttl-minutes (default 60).","required":false,"schema":{"type":"string","maxLength":255}}],"requestBody":{"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary"}},"required":["file"]}}}},"responses":{"200":{"description":"Per-file import report","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Missing, empty, or non-ZIP upload","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated or not an org member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"artifact.import","description":"Bulk import ODCS/ODPS files from a ZIP archive"}],"x-since":"7.50.0"}},"/v4/github/workflow":{"post":{"tags":["Automation"],"summary":"Install GitHub Actions workflow (v4, born-deprecated)","description":"**Since v7.1.2** — Installs the upload-data-products workflow file in the specified repository. Org context, credit deduction, and integration-default resolution; v3-aligned (#640).\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"installWorkflow","parameters":[{"name":"repoUrl","in":"query","required":false,"schema":{"type":"string"}},{"name":"branch","in":"query","required":false,"schema":{"type":"string","default":"main"}},{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","description":"Optional. Opaque, client-generated value (≤ 255 chars). When supplied, the server caches the response of the first successful invocation and replays it on a retry with the same key. Scoped to (user, method, path). TTL configurable via bitol.idempotency.ttl-minutes (default 60).","required":false,"schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Workflow installed","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"No GitHub token or invalid repo URL","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Not a member of the organization","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}},"502":{"description":"GitHub API error","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"github-action.workflow.install","description":"Install GitHub Actions workflow"}],"x-since":"7.1.2","x-sunset":"2027-01-01"}},"/v4/github/secrets":{"post":{"tags":["Automation"],"summary":"Set repository secrets (v4, born-deprecated)","description":"**Since v7.1.2** — Sets encrypted repository secrets for Zeenea integration. Org context, credit deduction; v3-aligned (#640).\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"setSecrets","parameters":[{"name":"repoUrl","in":"query","required":false,"schema":{"type":"string"}},{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","description":"Optional. Opaque, client-generated value (≤ 255 chars). When supplied, the server caches the response of the first successful invocation and replays it on a retry with the same key. Scoped to (user, method, path). TTL configurable via bitol.idempotency.ttl-minutes (default 60).","required":false,"schema":{"type":"string","maxLength":255}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","additionalProperties":{}}}},"required":true},"responses":{"200":{"description":"Secrets set","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"No GitHub token, invalid repo URL, or no secrets provided","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Not a member of the organization","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}},"502":{"description":"GitHub API error","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"github-action.secrets.update","description":"Set repository secrets"}],"x-since":"7.1.2","x-sunset":"2027-01-01"}},"/v4/github/provision-dispatcher-secrets":{"post":{"tags":["Automation"],"summary":"Provision dispatcher secrets (v4, born-deprecated)","description":"**Since v7.43.55** — Writes the dispatcher workflow's GitHub Actions secrets (ZEENEA_*, KAFKA_*, X_ORG_ID) to the product repo, sealed-box encrypted. Values come exclusively from server-side configuration (dispatcher.secrets.*) and the resolved org context — the request carries no secret material and cannot spoof another org's X_ORG_ID. Idempotent: re-running upserts (rotation = re-run). Requires an org context (#867).\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"provisionDispatcherSecrets","parameters":[{"name":"repoUrl","in":"query","required":false,"schema":{"type":"string"}},{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","description":"Optional. Opaque, client-generated value (≤ 255 chars). When supplied, the server caches the response of the first successful invocation and replays it on a retry with the same key. Scoped to (user, method, path). TTL configurable via bitol.idempotency.ttl-minutes (default 60).","required":false,"schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Secrets provisioned","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"No GitHub token, invalid repo URL, or no org context","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Not a member of the organization","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}},"502":{"description":"GitHub API error","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"github-action.secrets.provision-dispatcher","description":"Provision the dispatcher's GHA secrets from server-side configuration"}],"x-since":"7.43.55","x-sunset":"2027-01-01"}},"/v4/github/crawl-import":{"post":{"tags":["GitHub Crawl Import"],"summary":"Crawl a GitHub repo and import derived Teradata artifacts","description":"**Since v8.16.14** — Experimental, organization-gated. Crawls the requested folders of the given repository branch, detects Teradata SQL/BTEQ deterministically (no AI), derives one input contract per source table and one output contract per produced table (with ODCS transform* lineage and a mapped/unknown field inventory), assembles one ODPS product wiring the input and output ports, and uploads each source script under a deterministic content UUID (re-importing unchanged scripts is idempotent). Returns a per-artifact report.","operationId":"crawlImport","parameters":[{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","description":"Optional. Opaque, client-generated value (≤ 255 chars). When supplied, the server caches the response of the first successful invocation and replays it on a retry with the same key. Scoped to (user, method, path). TTL configurable via bitol.idempotency.ttl-minutes (default 60).","required":false,"schema":{"type":"string","maxLength":255}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrawlImportRequest"}}},"required":true},"responses":{"200":{"description":"Per-artifact import report","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Missing repoUrl or no crawlable files found","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Not an org member, or the GitHub crawl-import feature is not enabled for this org","content":{"*/*":{"schema":{"type":"string"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"github.crawl.import","description":"Crawl GitHub folders and derive Teradata contracts + a product (org-gated)"}],"x-since":"8.16.14"}},"/v4/github/crawl-import/stream":{"post":{"tags":["GitHub Crawl Import"],"summary":"Crawl a GitHub repo and import derived Teradata artifacts (streaming)","description":"**Since v8.18.0** — Server-Sent Events sibling of POST /v4/github/crawl-import (svc#1028). Same request body, org gating and auth. Emits `progress` events ({phase, message, done, total}) as each phase/artifact completes, then a terminal `done` event carrying the same ImportResultResponse as the non-streaming endpoint. On a runtime failure it emits an `error` event and completes. Sets `X-Accel-Buffering: no` so proxies do not buffer.","operationId":"crawlImportStream","parameters":[{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","description":"Optional. Opaque, client-generated value (≤ 255 chars). When supplied, the server caches the response of the first successful invocation and replays it on a retry with the same key. Scoped to (user, method, path). TTL configurable via bitol.idempotency.ttl-minutes (default 60).","required":false,"schema":{"type":"string","maxLength":255}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrawlImportRequest"}}},"required":true},"responses":{"200":{"description":"SSE stream of progress + a terminal done event","content":{"text/event-stream":{"schema":{"$ref":"#/components/schemas/SseEmitter"}}}},"400":{"description":"Missing repoUrl","content":{"text/event-stream":{"schema":{"$ref":"#/components/schemas/SseEmitter"}}}},"401":{"description":"Missing or invalid JWT","content":{"text/event-stream":{"schema":{"$ref":"#/components/schemas/SseEmitter"}}}},"403":{"description":"Not an org member, or the feature is not enabled for this org","content":{"text/event-stream":{"schema":{"$ref":"#/components/schemas/SseEmitter"}}}},"404":{"description":"Organization not found","content":{"text/event-stream":{"schema":{"$ref":"#/components/schemas/SseEmitter"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"github.crawl.import.stream","description":"Streaming crawl+derive with live per-phase progress (org-gated)"}],"x-since":"8.18.0"}},"/v4/github/actions/trigger":{"post":{"tags":["Automation"],"summary":"Trigger workflow dispatch (v4, born-deprecated)","description":"**Since v7.1.2** — Triggers a workflow_dispatch event for the upload workflow. Org context, credit deduction, integration-default resolution; v3-aligned (#640).\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"triggerWorkflow","parameters":[{"name":"repoUrl","in":"query","required":false,"schema":{"type":"string"}},{"name":"branch","in":"query","required":false,"schema":{"type":"string","default":"main"}},{"name":"workflowFile","in":"query","required":false,"schema":{"type":"string","default":"upload-data-products.yml"}},{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","description":"Optional. Opaque, client-generated value (≤ 255 chars). When supplied, the server caches the response of the first successful invocation and replays it on a retry with the same key. Scoped to (user, method, path). TTL configurable via bitol.idempotency.ttl-minutes (default 60).","required":false,"schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Workflow triggered","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"No GitHub token or invalid repo URL","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Not a member of the organization","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}},"502":{"description":"GitHub API error","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"github-action.workflow.trigger","description":"Trigger a workflow dispatch"}],"x-since":"7.1.2","x-sunset":"2027-01-01"}},"/v4/diagnostics":{"get":{"tags":["Diagnostics"],"summary":"List diagnostics reports (admin only)","description":"**Since v7.1.1** — Paginated. Filters: type, email, since, until, resolved, appVersion, search, provenance, app.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"list_2","parameters":[{"name":"type","in":"query","required":false,"schema":{"type":"string"}},{"name":"email","in":"query","required":false,"schema":{"type":"string"}},{"name":"since","in":"query","required":false,"schema":{"type":"string"}},{"name":"until","in":"query","required":false,"schema":{"type":"string"}},{"name":"resolved","in":"query","required":false,"schema":{"type":"boolean"}},{"name":"appVersion","in":"query","required":false,"schema":{"type":"string"}},{"name":"search","in":"query","required":false,"schema":{"type":"string"}},{"name":"provenance","in":"query","required":false,"schema":{"type":"string"}},{"name":"app","in":"query","required":false,"schema":{"type":"string"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":0}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":50}}],"responses":{"200":{"description":"Paginated list","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid Bearer JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Admin privileges required","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"diagnostics.list","description":"List diagnostics reports"}],"x-since":"7.1.1","x-sunset":"2027-01-01"},"post":{"tags":["Diagnostics"],"summary":"Submit a diagnostics report","description":"**Since v7.1.1** — Unauthenticated. Accepts a single front-end error report.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"submit_1","parameters":[{"name":"X-CLI-KEY","in":"header","required":false,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","description":"Optional. Opaque, client-generated value (≤ 255 chars). When supplied, the server caches the response of the first successful invocation and replays it on a retry with the same key. Scoped to (user, method, path). TTL configurable via bitol.idempotency.ttl-minutes (default 60).","required":false,"schema":{"type":"string","maxLength":255}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DiagnosticsReportRequest"}}},"required":true},"responses":{"201":{"description":"Report accepted","content":{"*/*":{"schema":{"type":"object"}}}},"500":{"description":"Internal error","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"x-intent":[{"name":"diagnostics.create","description":"Submit a front-end diagnostics report"}],"x-since":"7.1.1","x-sunset":"2027-01-01"}},"/v4/diagnostics/{id}/steps":{"get":{"tags":["Diagnostics"],"summary":"List a test-run's story steps (admin only)","description":"**Since v7.34.10** — Returns the ordered steps with descriptions, timestamps, payloads, and image URLs.","operationId":"listSteps","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Ordered steps","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid Bearer JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Admin privileges required","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"diagnostics.step.list","description":"List a test-run's story steps"}],"x-since":"7.34.10"},"post":{"tags":["Diagnostics"],"summary":"Append a story step to a test-run","description":"**Since v7.34.10** — multipart/form-data: a `step` JSON part + an optional `screenshot` file part. Anonymous is allowed only for small text-only steps; any screenshot or an oversized step body requires a known caller (authenticated user or X-CLI-KEY).","operationId":"appendStep","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-CLI-KEY","in":"header","required":false,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","description":"Optional. Opaque, client-generated value (≤ 255 chars). When supplied, the server caches the response of the first successful invocation and replays it on a retry with the same key. Scoped to (user, method, path). TTL configurable via bitol.idempotency.ttl-minutes (default 60).","required":false,"schema":{"type":"string","maxLength":255}}],"requestBody":{"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"step":{"type":"string"},"screenshot":{"type":"string","format":"binary"}},"required":["step"]}}}},"responses":{"201":{"description":"Step appended","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Malformed `step` JSON","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Anonymous caller attaching a file or oversized body","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Unknown or non-test-run parent","content":{"*/*":{"schema":{"type":"object"}}}}},"x-intent":[{"name":"diagnostics.step.append","description":"Append a step (with optional screenshot) to a test-run"}],"x-since":"7.34.10"}},"/v4/data-sources/{name}/test":{"post":{"tags":["Data Sources"],"summary":"Test a named data source's connection","description":"**Since v7.35.0** — Opens a real JDBC connection using the stored coordinates and password. Returns ok=true on success, or ok=false with a message on an expected failure (bad credentials, unreachable host, unsupported vendor) — never a 5xx.","operationId":"test","parameters":[{"name":"name","in":"path","required":true,"schema":{"type":"string"}},{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","description":"Optional. Opaque, client-generated value (≤ 255 chars). When supplied, the server caches the response of the first successful invocation and replays it on a retry with the same key. Scoped to (user, method, path). TTL configurable via bitol.idempotency.ttl-minutes (default 60).","required":false,"schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Connection test result (ok true/false)","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated or not an org member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"No such data source","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"datasource.test","description":"Test a named data source connection"}],"x-since":"7.35.0"}},"/v4/credits/redeem":{"post":{"tags":["Credits"],"summary":"Redeem a Credits code","description":"**Since v7.44.0** — Redeems a code to add Credits to the user's balance.","operationId":"redeemCode","parameters":[{"name":"code","in":"query","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","description":"Optional. Opaque, client-generated value (≤ 255 chars). When supplied, the server caches the response of the first successful invocation and replays it on a retry with the same key. Scoped to (user, method, path). TTL configurable via bitol.idempotency.ttl-minutes (default 60).","required":false,"schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Code redeemed successfully","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Invalid or already-used code","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"credit.code.redeem","description":"Redeem a code for Credits"}],"x-since":"7.44.0"}},"/v4/credits/grant":{"post":{"tags":["Credits"],"summary":"Grant Credits to a user (admin)","description":"**Since v7.44.0** — Admin grants Credits to a user by email.","operationId":"grantCredits","parameters":[{"name":"email","in":"query","required":true,"schema":{"type":"string"}},{"name":"amount","in":"query","required":true,"schema":{"type":"integer","format":"int32"}},{"name":"comment","in":"query","required":false,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","description":"Optional. Opaque, client-generated value (≤ 255 chars). When supplied, the server caches the response of the first successful invocation and replays it on a retry with the same key. Scoped to (user, method, path). TTL configurable via bitol.idempotency.ttl-minutes (default 60).","required":false,"schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Credits granted","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Admin privileges required","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Target user not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"credit.grant","description":"Grant Credits to a user (admin)"}],"x-since":"7.44.0"}},"/v4/credits/costs":{"get":{"tags":["Credits"],"summary":"List endpoint costs","description":"**Since v7.44.0** — Returns all configured Credits costs per endpoint.","operationId":"getCosts","responses":{"200":{"description":"Cost list returned","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"credit.cost.list","description":"List configured Credits endpoint costs"}],"x-since":"7.44.0"},"post":{"tags":["Credits"],"summary":"Create/update an endpoint cost (admin)","description":"**Since v7.44.0** — Admin sets the Credits cost for a specific API endpoint.","operationId":"saveCost","parameters":[{"name":"endpoint","in":"query","required":true,"schema":{"type":"string"}},{"name":"cost","in":"query","required":true,"schema":{"type":"integer","format":"int32"}},{"name":"method","in":"query","required":false,"schema":{"type":"string"}},{"name":"description","in":"query","required":false,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","description":"Optional. Opaque, client-generated value (≤ 255 chars). When supplied, the server caches the response of the first successful invocation and replays it on a retry with the same key. Scoped to (user, method, path). TTL configurable via bitol.idempotency.ttl-minutes (default 60).","required":false,"schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Cost saved","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Admin privileges required","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"credit.cost.update","description":"Create or update a Credits endpoint cost (admin)"}],"x-since":"7.44.0"},"delete":{"tags":["Credits"],"summary":"Delete an endpoint cost (admin)","description":"**Since v7.44.0** — Admin removes the Credits cost configuration for an endpoint.","operationId":"deleteCost","parameters":[{"name":"endpoint","in":"query","required":true,"schema":{"type":"string"}},{"name":"method","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Cost deleted","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Admin privileges required","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Cost not found for endpoint","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"credit.cost.delete","description":"Delete a Credits endpoint cost (admin)"}],"x-since":"7.44.0"}},"/v4/credits/codes":{"get":{"tags":["Credits"],"summary":"List all redeemable Credits codes (admin)","description":"**Since v7.44.0** — Admin view of all configured redemption codes.","operationId":"getAllCodes","responses":{"200":{"description":"Code list returned","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Admin privileges required","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"credit.code.list","description":"List all redeemable Credits codes (admin)"}],"x-since":"7.44.0"},"post":{"tags":["Credits"],"summary":"Create a redeemable Credits code (admin)","description":"**Since v7.44.0** — Admin creates a redeemable code that users can apply to their balance.","operationId":"createCode","parameters":[{"name":"code","in":"query","required":true,"schema":{"type":"string"}},{"name":"amount","in":"query","required":true,"schema":{"type":"integer","format":"int32"}},{"name":"globalOnce","in":"query","required":false,"schema":{"type":"boolean","default":false}},{"name":"perUserOnce","in":"query","required":false,"schema":{"type":"boolean","default":true}},{"name":"comment","in":"query","required":false,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","description":"Optional. Opaque, client-generated value (≤ 255 chars). When supplied, the server caches the response of the first successful invocation and replays it on a retry with the same key. Scoped to (user, method, path). TTL configurable via bitol.idempotency.ttl-minutes (default 60).","required":false,"schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Code created","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Admin privileges required","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"credit.code.create","description":"Create a redeemable Credits code (admin)"}],"x-since":"7.44.0"}},"/v4/credits/bonuses":{"get":{"tags":["Credits"],"summary":"List all gamification bonus definitions (admin)","description":"**Since v7.44.0** — Returns all configured gamification bonus codes with their current amounts and enabled state. Admin only.","operationId":"listBonuses","responses":{"200":{"description":"Bonus list returned","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Admin privileges required","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"credit.bonus.list","description":"List all gamification bonus definitions (admin)"}],"x-since":"7.44.0"},"post":{"tags":["Credits"],"summary":"Create a gamification bonus (admin)","description":"**Since v7.44.0** — Creates a new gamification bonus code with its description, user/org amounts, and enabled state. Admin only.","operationId":"createBonus","parameters":[{"name":"Idempotency-Key","in":"header","description":"Optional. Opaque, client-generated value (≤ 255 chars). When supplied, the server caches the response of the first successful invocation and replays it on a retry with the same key. Scoped to (user, method, path). TTL configurable via bitol.idempotency.ttl-minutes (default 60).","required":false,"schema":{"type":"string","maxLength":255}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","additionalProperties":{}}}},"required":true},"responses":{"200":{"description":"Bonus created","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Missing bonus code","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Admin privileges required","content":{"*/*":{"schema":{"type":"object"}}}},"409":{"description":"Bonus code already exists","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"credit.bonus.create","description":"Create a gamification bonus (admin)"}],"x-since":"7.44.0"}},"/v4/contracts":{"get":{"tags":["Contracts"],"summary":"List contract headers","description":"**Since v7.13.4** — Returns header fields for all contracts. Pass org or orgId to list organization contracts.","operationId":"readHeaders_3","parameters":[{"name":"storage","in":"query","required":false,"schema":{"type":"string","default":"permanent"}},{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"JSON array of contract header objects","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated or not an org member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"contract.list","description":"List contract headers"}],"x-since":"7.13.4"},"post":{"tags":["Contracts"],"summary":"Upload a data contract","description":"**Since v7.13.4** — Uploads an ODCS YAML file, a SQL DDL file, or creates a contract from a live JDBC database. Pass org or orgId to store in an organization's storage.","operationId":"create_4","parameters":[{"name":"contractId","in":"query","required":false,"schema":{"type":"string"}},{"name":"sourceFormat","in":"query","required":false,"schema":{"type":"string"}},{"name":"version","in":"query","required":false,"schema":{"type":"string"}},{"name":"name","in":"query","required":false,"schema":{"type":"string"}},{"name":"domain","in":"query","required":false,"schema":{"type":"string"}},{"name":"tenant","in":"query","required":false,"schema":{"type":"string"}},{"name":"force","in":"query","required":false,"schema":{"type":"string"}},{"name":"storage","in":"query","required":false,"schema":{"type":"string","default":"permanent"}},{"name":"ddlUrl","in":"query","required":false,"schema":{"type":"string"}},{"name":"dbmlUrl","in":"query","required":false,"schema":{"type":"string"}},{"name":"includeViews","in":"query","description":"When sourceFormat=jdbc, also introspect database views (#185 TD-5). Views are added as SchemaObjects tagged 'view'. Default false.","required":false,"schema":{"type":"boolean","default":false}},{"name":"includeRoutines","in":"query","description":"When sourceFormat=jdbc, also discover stored procedures and functions (#186 TD-6). Attached as JSON customProperties 'storedProcedures' and 'storedFunctions'. Default false.","required":false,"schema":{"type":"boolean","default":false}},{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","description":"Optional. Opaque, client-generated value (≤ 255 chars). When supplied, the server caches the response of the first successful invocation and replays it on a retry with the same key. Scoped to (user, method, path). TTL configurable via bitol.idempotency.ttl-minutes (default 60).","required":false,"schema":{"type":"string","maxLength":255}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary"},"jdbcConnection":{"$ref":"#/components/schemas/JdbcConnectionRequest"}}}}}},"responses":{"200":{"description":"Contract uploaded successfully","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Unsupported source format or invalid input","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated or not an org member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}},"422":{"description":"Invalid or malformed contract file (not YAML, unreadable, missing id/version, schema-invalid)","content":{"*/*":{"schema":{"type":"object"}}}},"500":{"description":"File upload or processing error","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"contract.create","description":"Upload a data contract"}],"x-since":"7.13.4"},"delete":{"tags":["Contracts"],"summary":"Delete a data contract","description":"**Since v7.13.4** — Soft-deletes a specific contract version. Pass org or orgId for organization contracts.","operationId":"delete_5","parameters":[{"name":"contractId","in":"query","required":true,"schema":{"type":"string"}},{"name":"version","in":"query","required":true,"schema":{"type":"string"}},{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Contract deleted successfully","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated or not an org member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Contract or organization not found","content":{"*/*":{"schema":{"type":"object"}}}},"409":{"description":"Contract is referenced by data products","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"contract.delete","description":"Delete a data contract"}],"x-since":"7.13.4"}},"/v4/contracts/{contractId}/test":{"post":{"tags":["Contracts"],"summary":"Run data-contract schema-conformance tests against a server","description":"**Since v7.36.0** — Synchronously connects to the named server declared in the contract, reads the live table metadata via JDBC, and compares it against the contract schema. Returns {status, server, checks[], log}. Connection credentials come from the stored per-server credential store (#718). Expected runtime failures (unknown server, missing credentials, unreachable host, unsupported vendor) return 200 with status:error, never a 5xx. Schema-conformance only; data-quality rule evaluation is deferred.","operationId":"testContract","parameters":[{"name":"contractId","in":"path","required":true,"schema":{"type":"string"}},{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","description":"Optional. Opaque, client-generated value (≤ 255 chars). When supplied, the server caches the response of the first successful invocation and replays it on a retry with the same key. Scoped to (user, method, path). TTL configurable via bitol.idempotency.ttl-minutes (default 60).","required":false,"schema":{"type":"string","maxLength":255}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractTestRequest"}}},"required":true},"responses":{"200":{"description":"Test run result (status pass/fail/error)","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Missing server name","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated or not an org member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Contract or organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"contract.test","description":"Run a contract's schema-conformance tests against a server"}],"x-since":"7.36.0"}},"/v4/contracts/{contractId}/sign":{"post":{"tags":["Contracts"],"summary":"Sign a data contract","description":"**Since v4.4.32** — Digitally signs the specified contract using the caller's signing key (or the workspace key when org is specified). The signature is embedded in customProperties as an enveloped signature using JCS (RFC 8785) canonicalization. Supports RS256 (RSA) and ES256 (ECDSA), auto-detected from the key type.","operationId":"signContract","parameters":[{"name":"contractId","in":"path","required":true,"schema":{"type":"string"}},{"name":"version","in":"query","required":false,"schema":{"type":"string"}},{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","description":"Optional. Opaque, client-generated value (≤ 255 chars). When supplied, the server caches the response of the first successful invocation and replays it on a retry with the same key. Scoped to (user, method, path). TTL configurable via bitol.idempotency.ttl-minutes (default 60).","required":false,"schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Contract signed successfully","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Contract or signing credentials not found","content":{"*/*":{"schema":{"type":"object"}}}},"500":{"description":"Signing failed","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"contract.sign","description":"Digitally sign a data contract"}],"x-since":"4.4.32"},"delete":{"tags":["Contracts"],"summary":"Unsign a data contract","description":"**Since v7.43.52** — Removes the enveloped signature from the specified contract and records the per-artifact auto-sign opt-out (customProperties autosign=false) so no automatic path re-signs it. A subsequent manual sign clears the opt-out.","operationId":"unsignContract","parameters":[{"name":"contractId","in":"path","required":true,"schema":{"type":"string"}},{"name":"version","in":"query","required":false,"schema":{"type":"string"}},{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Signature removed","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated or not an org member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Contract not found, or contract has no signature","content":{"*/*":{"schema":{"type":"object"}}}},"500":{"description":"Unsign failed","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"contract.unsign","description":"Remove the digital signature from a data contract"}],"x-since":"7.43.52"}},"/v4/contracts/{contractId}/refresh":{"post":{"tags":["Contracts"],"summary":"Refresh a database-sourced contract (diff only, no write)","description":"**Since v7.33.0** — Re-introspects the contract's source database using the stored JDBC credentials and returns a diff against the live contract. No new contract version is written — drift is notify-only (activity entry + email to the caller). When version is omitted, the contract's latest version is used.","operationId":"refresh","parameters":[{"name":"contractId","in":"path","required":true,"schema":{"type":"string"}},{"name":"version","in":"query","required":false,"schema":{"type":"string"}},{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","description":"Optional. Opaque, client-generated value (≤ 255 chars). When supplied, the server caches the response of the first successful invocation and replays it on a retry with the same key. Scoped to (user, method, path). TTL configurable via bitol.idempotency.ttl-minutes (default 60).","required":false,"schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Diff report between the live contract and the fresh introspection","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated or not an org member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Contract, organization, or stored credentials not found","content":{"*/*":{"schema":{"type":"object"}}}},"502":{"description":"Stored credentials invalid or introspection failed (diagnostics event recorded)","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"contract.refresh","description":"Refresh a database-sourced contract"}],"x-since":"7.33.0"}},"/v4/contracts/transfer":{"post":{"tags":["Contracts"],"summary":"Transfer artifacts from personal or org storage into an organization","description":"**Since v7.13.4** — Moves contracts and/or products into the destination organization. Requires org or orgId parameter. Default source is personal storage; pass fromOrg/fromOrgId to transfer org-to-org (#183) — the caller must hold the ADMIN role in BOTH organizations. Transfer is all-or-nothing.","operationId":"transferArtifacts_1","parameters":[{"name":"org","in":"query","description":"Destination organization slug (required)","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Destination organization UUID (required)","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"fromOrg","in":"query","description":"Source organization slug (org-to-org transfer, #183)","required":false,"schema":{"type":"string"}},{"name":"fromOrgId","in":"query","description":"Source organization UUID (org-to-org transfer, #183)","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","description":"Optional. Opaque, client-generated value (≤ 255 chars). When supplied, the server caches the response of the first successful invocation and replays it on a retry with the same key. Scoped to (user, method, path). TTL configurable via bitol.idempotency.ttl-minutes (default 60).","required":false,"schema":{"type":"string","maxLength":255}}],"requestBody":{"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TransferItem"}}}},"required":true},"responses":{"200":{"description":"Artifacts transferred successfully","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Validation failed or no org specified","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Not a member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}},"500":{"description":"File transfer error","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"contract.transfer","description":"Transfer artifacts to org storage"}],"x-since":"7.13.4"}},"/v4/contracts/test-connection":{"post":{"tags":["Contracts"],"summary":"Test JDBC database connection","description":"**Since v7.13.4** — Tests connectivity to a database without introspecting the schema.","operationId":"testConnection","parameters":[{"name":"Idempotency-Key","in":"header","description":"Optional. Opaque, client-generated value (≤ 255 chars). When supplied, the server caches the response of the first successful invocation and replays it on a retry with the same key. Scoped to (user, method, path). TTL configurable via bitol.idempotency.ttl-minutes (default 60).","required":false,"schema":{"type":"string","maxLength":255}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/JdbcConnectionRequest"}}},"required":true},"responses":{"200":{"description":"Connection test result (status: ok or error)","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Missing required parameters","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"contract.database.test","description":"Test JDBC database connection"}],"x-since":"7.13.4"}},"/v4/contracts/publish-github":{"post":{"tags":["Contracts"],"summary":"Publish contract to GitHub","description":"**Since v7.26.0** — Enhanced publish with pre-publish version check and Git tagging. Compares local content against the last published version (via scoped Git tags). Returns SKIP if identical, CONFLICT (409) if version not bumped, or publishes and tags on success. Pass org or orgId to publish from an organization's storage using the org's GitHub token.","operationId":"publishToGitHub_3","parameters":[{"name":"contractId","in":"query","description":"UUID of the data contract to publish","required":true,"schema":{"type":"string"}},{"name":"version","in":"query","description":"Semantic version of the contract to publish (e.g. 1.2.3). Defaults to the contract's current version when omitted.","required":false,"schema":{"type":"string"}},{"name":"branch","in":"query","description":"GitHub branch to publish to. Defaults to the branch encoded in the contract's canonicalUrl, falling back to the repo's default branch.","required":false,"schema":{"type":"string"}},{"name":"storage","in":"query","description":"Storage mode for the source file (\"permanent\" or \"draft\"). Defaults to permanent.","required":false,"schema":{"type":"string","default":"permanent"}},{"name":"force","in":"query","description":"Force publish — skip pre-publish version conflict check","required":false,"schema":{"type":"string"}},{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","description":"Optional. Opaque, client-generated value (≤ 255 chars). When supplied, the server caches the response of the first successful invocation and replays it on a retry with the same key. Scoped to (user, method, path). TTL configurable via bitol.idempotency.ttl-minutes (default 60).","required":false,"schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Contract published (or skipped if identical). Includes tag and skipped flag","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Missing GitHub token, missing canonicalUrl, or invalid GitHub URL","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated or not an org member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Contract or organization not found","content":{"*/*":{"schema":{"type":"object"}}}},"409":{"description":"Version conflict — content changed but version not bumped. Returns localVersion, githubVersion, suggestedVersion, and diffs","content":{"*/*":{"schema":{"type":"object"}}}},"502":{"description":"GitHub API error","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"contract.publish","description":"Publish contract to GitHub"}],"x-since":"7.26.0"}},"/v4/contact":{"post":{"tags":["Contact Sync"],"summary":"Sync a contact to MailerLite (v4, born-deprecated)","description":"**Since v7.1.4** — Accepts contact data and syncs to MailerLite. Verbatim behaviour of POST /v1/contact; v4 requires Bearer JWT (v1 used the legacy machine-identity filter).\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"syncContact","parameters":[{"name":"Idempotency-Key","in":"header","description":"Optional. Opaque, client-generated value (≤ 255 chars). When supplied, the server caches the response of the first successful invocation and replays it on a retry with the same key. Scoped to (user, method, path). TTL configurable via bitol.idempotency.ttl-minutes (default 60).","required":false,"schema":{"type":"string","maxLength":255}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContactSyncRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{}}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"contact.transfer","description":"Sync a contact to MailerLite"}],"x-since":"7.1.4","x-sunset":"2027-01-01"}},"/v4/comments":{"get":{"tags":["Comments"],"summary":"List comments for an artifact","description":"**Since v5.0.0** — Returns all comments for the given artifact. Use the 'since' parameter for polling — returns only comments created, updated, or deleted after that time.","operationId":"listComments","parameters":[{"name":"orgId","in":"query","description":"Organization UUID","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"artifactKind","in":"query","description":"Artifact kind: DataContract or DataProduct","required":true,"schema":{"type":"string"}},{"name":"artifactId","in":"query","description":"Artifact UUID","required":true,"schema":{"type":"string"}},{"name":"since","in":"query","description":"ISO 8601 timestamp for polling (optional)","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Comment list","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Not authenticated","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Not an org member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Feature disabled","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"comment.list","description":"List comments for an artifact"}],"x-since":"5.0.0"},"post":{"tags":["Comments"],"summary":"Create a comment or reply","description":"**Since v5.0.0** — Creates a new comment anchored at artifact, section, or element level. Set parentId to reply to an existing comment (flat threading — no reply-to-reply).","operationId":"createComment","parameters":[{"name":"Idempotency-Key","in":"header","description":"Optional. Opaque, client-generated value (≤ 255 chars). When supplied, the server caches the response of the first successful invocation and replays it on a retry with the same key. Scoped to (user, method, path). TTL configurable via bitol.idempotency.ttl-minutes (default 60).","required":false,"schema":{"type":"string","maxLength":255}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommentRequest"}}},"required":true},"responses":{"201":{"description":"Comment created","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Invalid request (e.g., reply-to-reply)","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Not an org member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Feature disabled","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"comment.create","description":"Create a comment or reply"}],"x-since":"5.0.0"}},"/v4/catalogs/datasets/{datasetId}/import":{"post":{"tags":["External Catalogs"],"summary":"Import a dataset from an external catalog as a data contract","description":"**Since v7.2.0** — Fetches full dataset metadata from the catalog and generates an ODCS data contract. The contract is saved to disk and can be edited in the Workbench editor.","operationId":"importDataset","parameters":[{"name":"datasetId","in":"path","description":"Dataset ID in the external catalog","required":true,"schema":{"type":"string"}},{"name":"vendor","in":"query","description":"Catalog vendor (e.g., zeenea)","required":true,"schema":{"type":"string"}},{"name":"name","in":"query","description":"Override contract name","required":false,"schema":{"type":"string"}},{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","description":"Optional. Opaque, client-generated value (≤ 255 chars). When supplied, the server caches the response of the first successful invocation and replays it on a retry with the same key. Scoped to (user, method, path). TTL configurable via bitol.idempotency.ttl-minutes (default 60).","required":false,"schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Contract created successfully","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Unknown vendor","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Catalog credentials not configured","content":{"*/*":{"schema":{"type":"object"}}}},"409":{"description":"Contract already exists for this dataset","content":{"*/*":{"schema":{"type":"object"}}}},"502":{"description":"Upstream catalog API error","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"catalog.dataset.import","description":"Import a catalog dataset as a data contract"}],"x-since":"7.2.0"}},"/v4/artifacts/validate":{"post":{"tags":["Artifacts"],"summary":"Validate an ODCS contract or ODPS product against its JSON schema","description":"**Since v7.0.12** — Validates exactly the YAML posted in the body. The JSON Schema pass is stateless and returns one ValidationFinding per schema violation (severity = error). For kind=product, a second semantic pass runs when the YAML parses: it reads the caller's contract store to check ODPS port referential integrity — an input/output port contractId that resolves to no workspace contract yields a `warn`, and a contractId shared across output ports yields an `info` (semantic findings append to the schema findings, they never replace them). Malformed YAML is reported as a single parse-error finding, not a 5xx.","operationId":"validateArtifact","parameters":[{"name":"Idempotency-Key","in":"header","description":"Optional. Opaque, client-generated value (≤ 255 chars). When supplied, the server caches the response of the first successful invocation and replays it on a retry with the same key. Scoped to (user, method, path). TTL configurable via bitol.idempotency.ttl-minutes (default 60).","required":false,"schema":{"type":"string","maxLength":255}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","additionalProperties":{}}}},"required":true},"responses":{"200":{"description":"[ValidationFinding] — empty array on a valid document","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Missing or invalid `kind` / `yaml` in the request body","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"artifact.validate","description":"Validate an artifact against its JSON schema"}],"x-since":"7.0.12"}},"/v4/artifacts/bundle":{"post":{"tags":["Artifacts"],"summary":"Apply an artifact bundle atomically","description":"**Since v8.19.0** — Creates every member of a bundle — typically a Data Product plus the contracts its output ports reference — as one all-or-nothing operation. Backs the assistant's `save_bundle` apply-bridge verb (svc#1006).\n\nContracts are always written before products, because a product whose `outputPorts[].contractId` does not yet resolve on disk is rejected. If any member fails, every artifact already written by this call is deleted and nothing is left persisted; the error names the failing member by its `role` or `suggestedName`.\n\nArtifacts live on disk rather than in rows, so atomicity here is compensating (write, then roll back on failure) rather than transactional. The observable guarantee is the same: either every member exists afterwards, or none does.\n\nRequest body: `{ \"members\": [ { \"content\": \"<full YAML>\", \"kind\": \"contract|product\", \"suggestedName\": \"...\", \"role\": \"...\" } ] }`. `kind` is optional and inferred from the document's own `kind:` field when omitted. `content` must be a FULL document, never a fragment.","operationId":"applyBundle","parameters":[{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","description":"Optional. Opaque, client-generated value (≤ 255 chars). When supplied, the server caches the response of the first successful invocation and replays it on a retry with the same key. Scoped to (user, method, path). TTL configurable via bitol.idempotency.ttl-minutes (default 60).","required":false,"schema":{"type":"string","maxLength":255}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","additionalProperties":{}}}},"required":true},"responses":{"200":{"description":"Every member was created","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Empty bundle, malformed body, or a member was rejected (nothing persisted)","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated or not an org member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"artifact.bundle","description":"Create several related artifacts atomically"}],"x-since":"8.19.0"}},"/v4/ai/suggest":{"post":{"tags":["AI"],"summary":"Suggest text for a free-text artifact field","description":"**Since v7.28.0** — Server-side proxy to the configured AI model: generates a short suggestion for a free-text field (currently description) from the supplied artifact context. A non-empty currentValue is treated as \"improve this\". The model API key never reaches the client; failures return a non-500 { error } envelope.","operationId":"suggest","parameters":[{"name":"Idempotency-Key","in":"header","description":"Optional. Opaque, client-generated value (≤ 255 chars). When supplied, the server caches the response of the first successful invocation and replays it on a retry with the same key. Scoped to (user, method, path). TTL configurable via bitol.idempotency.ttl-minutes (default 60).","required":false,"schema":{"type":"string","maxLength":255}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AiSuggestRequest"}}},"required":true},"responses":{"200":{"description":"{ suggestion: string }","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT bearer token","content":{"*/*":{"schema":{"type":"object"}}}},"502":{"description":"Upstream/model failure — { error: string }","content":{"*/*":{"schema":{"type":"object"}}}},"503":{"description":"AI disabled or not configured — { error: string }","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"ai.suggest","description":"Suggest text for a free-text artifact field"}],"x-since":"7.28.0"}},"/v4/admin/signup-requests/{id}/resend":{"post":{"tags":["Administration"],"summary":"Re-send a signup-request approval email","description":"**Since v8.13.0** — Re-sends the approval email for an approved request. A still-valid invitation code is re-sent as-is (codeStatus=reused); an expired or exhausted code is re-minted first — fresh single-use 14-day code, old one revoked — and the new code is sent (codeStatus=re-minted, #1000). Throttled to at most one send per minute. Returns 409 if the request is not approved, 404 if unknown, 429 if within the throttle window.","operationId":"resend","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"Idempotency-Key","in":"header","description":"Optional. Opaque, client-generated value (≤ 255 chars). When supplied, the server caches the response of the first successful invocation and replays it on a retry with the same key. Scoped to (user, method, path). TTL configurable via bitol.idempotency.ttl-minutes (default 60).","required":false,"schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Resend attempted; body carries the request plus codeStatus=reused|re-minted","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Admin privileges required","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Not found","content":{"*/*":{"schema":{"type":"object"}}}},"409":{"description":"Request is not in the approved state","content":{"*/*":{"schema":{"type":"object"}}}},"429":{"description":"Within the resend throttle window","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"signup-request.resend","description":"Re-send the approval email for an approved signup request"}],"x-since":"8.13.0"}},"/v4/admin/signup-requests/{id}/reject":{"post":{"tags":["Administration"],"summary":"Reject a signup request","description":"**Since v7.13.0** — Marks the request rejected. Pass {\"sendEmail\": true} to email the requester a polite decline.","operationId":"reject_2","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"Idempotency-Key","in":"header","description":"Optional. Opaque, client-generated value (≤ 255 chars). When supplied, the server caches the response of the first successful invocation and replays it on a retry with the same key. Scoped to (user, method, path). TTL configurable via bitol.idempotency.ttl-minutes (default 60).","required":false,"schema":{"type":"string","maxLength":255}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","additionalProperties":{}}}}},"responses":{"200":{"description":"Rejected","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Admin privileges required","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Not found","content":{"*/*":{"schema":{"type":"object"}}}},"409":{"description":"Already reviewed","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"signup-request.reject","description":"Reject a signup request"}],"x-since":"7.13.0"}},"/v4/admin/signup-requests/{id}/approve":{"post":{"tags":["Administration"],"summary":"Approve a signup request","description":"**Since v7.13.0** — Marks the request approved and emails the requester a sign-up link. Idempotent — approving an already-reviewed request returns 409.","operationId":"approve_2","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"Idempotency-Key","in":"header","description":"Optional. Opaque, client-generated value (≤ 255 chars). When supplied, the server caches the response of the first successful invocation and replays it on a retry with the same key. Scoped to (user, method, path). TTL configurable via bitol.idempotency.ttl-minutes (default 60).","required":false,"schema":{"type":"string","maxLength":255}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"string"}}}}},"responses":{"200":{"description":"Approved","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Admin privileges required","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Not found","content":{"*/*":{"schema":{"type":"object"}}}},"409":{"description":"Already reviewed","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"signup-request.approve","description":"Approve a signup request"}],"x-since":"7.13.0"}},"/v4/admin/signing/backfill":{"post":{"tags":["Administration"],"summary":"Backfill auto-sign for an organization (v4 admin)","description":"**Since v8.2.0** — Re-signs an organization's pre-existing artifacts that should be signed but are not — closing the #904 gap where artifacts created before the org enabled auto-sign (or before #855 shipped) were never signed, since auto-sign only fires on the next save. Reuses the exact auto-sign-on-save gate + credential resolution + per-artifact opt-out, so nothing signs that a normal save would not. Idempotent: already-signed rows are skipped (never re-signed) and customProperties autosign=false rows are respected. Operates on the latest version of each contract and product; prior versions are not touched. Pass org or orgId, and dryRun=true to only classify without signing (the #904 AC-1 enumeration).","operationId":"backfillSigning","parameters":[{"name":"org","in":"query","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"dryRun","in":"query","required":false,"schema":{"type":"boolean","default":false}},{"name":"Idempotency-Key","in":"header","description":"Optional. Opaque, client-generated value (≤ 255 chars). When supplied, the server caches the response of the first successful invocation and replays it on a retry with the same key. Scoped to (user, method, path). TTL configurable via bitol.idempotency.ttl-minutes (default 60).","required":false,"schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Backfill report (SigningBackfillResult)","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Neither org nor orgId supplied","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Admin privileges required","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"admin.signing.backfill","description":"Backfill-sign an org's unsigned artifacts"}],"x-since":"8.2.0"}},"/v4/admin/invitation-codes":{"get":{"tags":["Administration"],"summary":"List all admin invitation codes","description":"**Since v7.13.0** — Returns all admin-minted invitation codes with computed isExpired and isExhausted flags.","operationId":"list_3","responses":{"200":{"description":"List of codes","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Admin privileges required","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"invitation-code.list","description":"List all admin invitation codes"}],"x-since":"7.13.0"},"post":{"tags":["Administration"],"summary":"Mint a new admin invitation code","description":"**Since v7.13.0** — Admin-minted code for events, partners, etc. Server validates uniqueness across personal and admin tables. If 'code' is omitted, the server auto-generates one.","operationId":"mint","parameters":[{"name":"Idempotency-Key","in":"header","description":"Optional. Opaque, client-generated value (≤ 255 chars). When supplied, the server caches the response of the first successful invocation and replays it on a retry with the same key. Scoped to (user, method, path). TTL configurable via bitol.idempotency.ttl-minutes (default 60).","required":false,"schema":{"type":"string","maxLength":255}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","additionalProperties":{}}}},"required":true},"responses":{"200":{"description":"Created code","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Bad request","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Admin privileges required","content":{"*/*":{"schema":{"type":"object"}}}},"409":{"description":"Duplicate code","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"invitation-code.mint","description":"Mint a new admin invitation code"}],"x-since":"7.13.0"}},"/v4/admin/emails/{id}/resend":{"post":{"tags":["Administration"],"summary":"Re-send a logged email (v4 admin)","description":"**Since v7.27.0** — Re-sends a logged email's stored recipient/subject/body (#653). The new attempt is recorded as a fresh email-log row by the send pipeline. Rows logged before the body column existed cannot be resent (409).","operationId":"resendEmail","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"Idempotency-Key","in":"header","description":"Optional. Opaque, client-generated value (≤ 255 chars). When supplied, the server caches the response of the first successful invocation and replays it on a retry with the same key. Scoped to (user, method, path). TTL configurable via bitol.idempotency.ttl-minutes (default 60).","required":false,"schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Resend attempted; `sent` reports the outcome","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Admin privileges required","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"No email log entry with this id","content":{"*/*":{"schema":{"type":"object"}}}},"409":{"description":"Original body not retained; cannot resend","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"admin.email-log.resend","description":"Re-send a logged email (admin)"}],"x-since":"7.27.0"}},"/v4/admin/blocked-domains":{"get":{"tags":["Administration"],"summary":"List blocked domains","description":"**Since v7.13.0** — Returns all blocked email domains.","operationId":"listBlockedDomains","responses":{"200":{"description":"List of blocked domains","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Admin privileges required","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"blocked-domain.list","description":"List blocked email domains"}],"x-since":"7.13.0"},"post":{"tags":["Administration"],"summary":"Block a domain","description":"**Since v7.13.0** — Adds an email domain to the blocklist.","operationId":"blockDomain","parameters":[{"name":"Idempotency-Key","in":"header","description":"Optional. Opaque, client-generated value (≤ 255 chars). When supplied, the server caches the response of the first successful invocation and replays it on a retry with the same key. Scoped to (user, method, path). TTL configurable via bitol.idempotency.ttl-minutes (default 60).","required":false,"schema":{"type":"string","maxLength":255}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"string"}}}},"required":true},"responses":{"200":{"description":"Domain blocked successfully","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Domain already blocked or invalid input","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Admin privileges required","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"blocked-domain.create","description":"Add an email domain to the blocklist"}],"x-since":"7.13.0"}},"/v3/products":{"get":{"tags":["Products"],"summary":"List product headers (v3)","description":"**Since v3.0.0** — Returns header fields for all products. Pass org or orgId to list organization products.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"readHeaders_4","parameters":[{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"JSON array of product header objects","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated or not an org member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"product.list","description":"List data product headers"}],"x-since":"3.0.0","x-sunset":"2027-01-01"},"post":{"tags":["Products"],"summary":"Upload a data product (v3)","description":"**Since v3.0.0** — Uploads an ODPS YAML data product file directly. Pass org or orgId to upload to an organization's storage.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"create_5","parameters":[{"name":"contractId","in":"query","required":true,"schema":{"type":"string"}},{"name":"contractVersion","in":"query","required":true,"schema":{"type":"string"}},{"name":"version","in":"query","required":false,"schema":{"type":"string"}},{"name":"name","in":"query","required":false,"schema":{"type":"string"}},{"name":"domain","in":"query","required":false,"schema":{"type":"string"}},{"name":"tenant","in":"query","required":false,"schema":{"type":"string"}},{"name":"force","in":"query","required":false,"schema":{"type":"string"}},{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary"}},"required":["file"]}}}},"responses":{"200":{"description":"Product uploaded successfully","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated or not an org member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}},"500":{"description":"File upload error","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Invalid file type","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"product.upload","description":"Upload an ODPS YAML data product file"}],"x-since":"3.0.0","x-sunset":"2027-01-01"},"delete":{"tags":["Products"],"summary":"Delete a data product (v3)","description":"**Since v3.0.0** — Soft-deletes a specific product version. Pass org or orgId for organization products.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"delete_6","parameters":[{"name":"productId","in":"query","required":true,"schema":{"type":"string"}},{"name":"version","in":"query","required":true,"schema":{"type":"string"}},{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Product deleted successfully","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated or not an org member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Product or organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"product.delete","description":"Delete a data product version"}],"x-since":"3.0.0","x-sunset":"2027-01-01"}},"/v3/products/publish-github":{"post":{"tags":["Products"],"summary":"Publish product to GitHub (v3 — enhanced)","description":"**Since v2.6.1** — Enhanced publish with pre-publish version check, Git tagging, and auto-publish of referenced contracts. Compares local content against the last published version (via scoped Git tags). Returns SKIP if identical, CONFLICT (409) if version not bumped, or publishes and tags on success. Referenced contracts from outputPorts/inputPorts are automatically checked and published. Pass org, orgId, or orgSlug to publish from an organization's storage using the org's GitHub token.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"publishToGitHub_4","parameters":[{"name":"productId","in":"query","description":"UUID of the data product to publish","required":true,"schema":{"type":"string"}},{"name":"version","in":"query","description":"Semantic version of the product to publish (e.g. 1.2.3). Defaults to the product's current version when omitted.","required":false,"schema":{"type":"string"}},{"name":"branch","in":"query","description":"GitHub branch to publish to. Defaults to the branch encoded in the product's canonicalUrl, falling back to the repo's default branch.","required":false,"schema":{"type":"string"}},{"name":"force","in":"query","description":"Force publish — skip pre-publish version conflict check","required":false,"schema":{"type":"string"}},{"name":"orgSlug","in":"query","description":"Deprecated — use 'org' instead. Organization slug (legacy parameter, kept for backward compatibility).","required":false,"deprecated":true,"schema":{"type":"string"}},{"name":"org","in":"query","description":"Organization slug (canonical). Takes precedence over 'orgSlug' when both are present.","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org and orgSlug)","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Product published (or skipped if identical). Includes tag, skipped flag, and per-contract results","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Missing GitHub token, missing canonicalUrl, or invalid GitHub URL","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated or not a member of the organization","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Product or organization not found","content":{"*/*":{"schema":{"type":"object"}}}},"409":{"description":"Version conflict — product or referenced contract version not bumped. Returns per-contract details when contracts conflict","content":{"*/*":{"schema":{"type":"object"}}}},"502":{"description":"GitHub API error","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"product.publish","description":"Publish a data product to GitHub"}],"x-since":"2.6.1","x-sunset":"2027-01-01"}},"/v3/maturity-history/capture":{"post":{"tags":["Maturity History"],"summary":"Trigger maturity snapshot capture (admin)","description":"**Since v4.4.28** — Admin-only. Immediately captures a maturity snapshot for today by scanning all contract and product files across all users and organizations. Requires Bearer JWT with admin privileges.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"captureSnapshot_1","responses":{"200":{"description":"Snapshot captured","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Admin privileges required","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"maturity.history.capture","description":"Trigger maturity snapshot capture"}],"x-since":"4.4.28","x-sunset":"2027-01-01"}},"/v3/github/workflow":{"post":{"tags":["Automation"],"summary":"Install GitHub Actions workflow","description":"**Since v3.2.3** — Installs the upload-data-products workflow file in the specified repository.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"installWorkflow_1","parameters":[{"name":"repoUrl","in":"query","required":false,"schema":{"type":"string"}},{"name":"branch","in":"query","required":false,"schema":{"type":"string","default":"main"}},{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Workflow installed","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"No GitHub token or invalid repo URL","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Not a member of the organization","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}},"502":{"description":"GitHub API error","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"github-action.workflow.install","description":"Install GitHub Actions workflow"}],"x-since":"3.2.3","x-sunset":"2027-01-01"}},"/v3/github/secrets":{"post":{"tags":["Automation"],"summary":"Set repository secrets","description":"**Since v3.2.3** — Sets encrypted repository secrets for Zeenea integration.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"setSecrets_1","parameters":[{"name":"repoUrl","in":"query","required":false,"schema":{"type":"string"}},{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","additionalProperties":{}}}},"required":true},"responses":{"200":{"description":"Secrets set","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"No GitHub token, invalid repo URL, or no secrets provided","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Not a member of the organization","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}},"502":{"description":"GitHub API error","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"github-action.secrets.update","description":"Set repository secrets"}],"x-since":"3.2.3","x-sunset":"2027-01-01"}},"/v3/github/actions/trigger":{"post":{"tags":["Automation"],"summary":"Trigger workflow dispatch","description":"**Since v3.2.3** — Triggers a workflow_dispatch event for the upload workflow.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"triggerWorkflow_1","parameters":[{"name":"repoUrl","in":"query","required":false,"schema":{"type":"string"}},{"name":"branch","in":"query","required":false,"schema":{"type":"string","default":"main"}},{"name":"workflowFile","in":"query","required":false,"schema":{"type":"string","default":"upload-data-products.yml"}},{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Workflow triggered","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"No GitHub token or invalid repo URL","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Not a member of the organization","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}},"502":{"description":"GitHub API error","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"github-action.workflow.trigger","description":"Trigger a workflow dispatch"}],"x-since":"3.2.3","x-sunset":"2027-01-01"}},"/v3/contracts":{"get":{"tags":["Contracts"],"summary":"List contract headers (v3)","description":"**Since v3.0.0** — Returns header fields for all contracts. Pass org or orgId to list organization contracts.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"readHeaders_5","parameters":[{"name":"storage","in":"query","required":false,"schema":{"type":"string","default":"permanent"}},{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"JSON array of contract header objects","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated or not an org member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"contract.list","description":"List contract headers"}],"x-since":"3.0.0","x-sunset":"2027-01-01"},"post":{"tags":["Contracts"],"summary":"Upload a data contract (v3)","description":"**Since v3.0.0** — Uploads an ODCS YAML file, a SQL DDL file, or creates a contract from a live JDBC database. Pass org or orgId to store in an organization's storage.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"create_6","parameters":[{"name":"contractId","in":"query","required":false,"schema":{"type":"string"}},{"name":"sourceFormat","in":"query","required":false,"schema":{"type":"string"}},{"name":"version","in":"query","required":false,"schema":{"type":"string"}},{"name":"name","in":"query","required":false,"schema":{"type":"string"}},{"name":"domain","in":"query","required":false,"schema":{"type":"string"}},{"name":"tenant","in":"query","required":false,"schema":{"type":"string"}},{"name":"force","in":"query","required":false,"schema":{"type":"string"}},{"name":"storage","in":"query","required":false,"schema":{"type":"string","default":"permanent"}},{"name":"ddlUrl","in":"query","required":false,"schema":{"type":"string"}},{"name":"dbmlUrl","in":"query","required":false,"schema":{"type":"string"}},{"name":"includeViews","in":"query","description":"When sourceFormat=jdbc, also introspect database views (#185 TD-5). Views are added as SchemaObjects tagged 'view'. Default false.","required":false,"schema":{"type":"boolean","default":false}},{"name":"includeRoutines","in":"query","description":"When sourceFormat=jdbc, also discover stored procedures and functions (#186 TD-6). Attached as JSON customProperties 'storedProcedures' and 'storedFunctions'. Default false.","required":false,"schema":{"type":"boolean","default":false}},{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary"},"jdbcConnection":{"$ref":"#/components/schemas/JdbcConnectionRequest"}}}}}},"responses":{"200":{"description":"Contract uploaded successfully","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Unsupported source format or invalid input","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated or not an org member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}},"500":{"description":"File upload or processing error","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"contract.create","description":"Upload a data contract"}],"x-since":"3.0.0","x-sunset":"2027-01-01"},"delete":{"tags":["Contracts"],"summary":"Delete a data contract (v3)","description":"**Since v3.0.0** — Soft-deletes a specific contract version. Pass org or orgId for organization contracts.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"delete_7","parameters":[{"name":"contractId","in":"query","required":true,"schema":{"type":"string"}},{"name":"version","in":"query","required":true,"schema":{"type":"string"}},{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Contract deleted successfully","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated or not an org member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Contract or organization not found","content":{"*/*":{"schema":{"type":"object"}}}},"409":{"description":"Contract is referenced by data products","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"contract.delete","description":"Delete a data contract"}],"x-since":"3.0.0","x-sunset":"2027-01-01"}},"/v3/contracts/transfer":{"post":{"tags":["Contracts"],"summary":"Transfer artifacts from personal to org storage (v3)","description":"**Since v3.0.0** — Moves contracts and/or products from personal storage into the organization. Requires org or orgId parameter. Transfer is all-or-nothing.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"transferArtifacts_2","parameters":[{"name":"org","in":"query","description":"Organization slug (required for transfer)","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (required for transfer)","required":false,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TransferItem"}}}},"required":true},"responses":{"200":{"description":"Artifacts transferred successfully","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Validation failed or no org specified","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Not a member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}},"500":{"description":"File transfer error","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"contract.transfer","description":"Transfer artifacts to org storage"}],"x-since":"3.0.0","x-sunset":"2027-01-01"}},"/v3/contracts/test-connection":{"post":{"tags":["Contracts"],"summary":"Test JDBC database connection (v3)","description":"**Since v3.0.0** — Tests connectivity to a database without introspecting the schema.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"testConnection_1","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/JdbcConnectionRequest"}}},"required":true},"responses":{"200":{"description":"Connection test result (status: ok or error)","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Missing required parameters","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"contract.database.test","description":"Test JDBC database connection"}],"x-since":"3.0.0","x-sunset":"2027-01-01"}},"/v3/contracts/publish-github":{"post":{"tags":["Contracts"],"summary":"Publish contract to GitHub (v3 — enhanced)","description":"**Since v2.6.1** — Enhanced publish with pre-publish version check and Git tagging. Compares local content against the last published version (via scoped Git tags). Returns SKIP if identical, CONFLICT (409) if version not bumped, or publishes and tags on success. Pass org, orgId, or orgSlug to publish from an organization's storage using the org's GitHub token.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"publishToGitHub_5","parameters":[{"name":"contractId","in":"query","description":"UUID of the data contract to publish","required":true,"schema":{"type":"string"}},{"name":"version","in":"query","description":"Semantic version of the contract to publish (e.g. 1.2.3). Defaults to the contract's current version when omitted.","required":false,"schema":{"type":"string"}},{"name":"branch","in":"query","description":"GitHub branch to publish to. Defaults to the branch encoded in the contract's canonicalUrl, falling back to the repo's default branch.","required":false,"schema":{"type":"string"}},{"name":"storage","in":"query","description":"Storage mode for the source file (\"permanent\" or \"draft\"). Defaults to permanent.","required":false,"schema":{"type":"string","default":"permanent"}},{"name":"force","in":"query","description":"Force publish — skip pre-publish version conflict check","required":false,"schema":{"type":"string"}},{"name":"orgSlug","in":"query","description":"Deprecated — use 'org' instead. Organization slug (legacy parameter, kept for backward compatibility).","required":false,"deprecated":true,"schema":{"type":"string"}},{"name":"org","in":"query","description":"Organization slug (canonical). Takes precedence over 'orgSlug' when both are present.","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org and orgSlug)","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Contract published (or skipped if identical). Includes tag and skipped flag","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Missing GitHub token, missing canonicalUrl, or invalid GitHub URL","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated or not a member of the organization","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Contract or organization not found","content":{"*/*":{"schema":{"type":"object"}}}},"409":{"description":"Version conflict — content changed but version not bumped. Returns localVersion, githubVersion, suggestedVersion, and diffs","content":{"*/*":{"schema":{"type":"object"}}}},"502":{"description":"GitHub API error","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"contract.publish","description":"Publish contract to GitHub"}],"x-since":"2.6.1","x-sunset":"2027-01-01"}},"/v3/catalogs/datasets/{datasetId}/import":{"post":{"tags":["External Catalogs"],"summary":"Import a dataset from an external catalog as a data contract","description":"**Since v4.4.0** — Fetches full dataset metadata from the catalog and generates an ODCS data contract. The contract is saved to disk and can be edited in the Workbench editor.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"importDataset_1","parameters":[{"name":"datasetId","in":"path","description":"Dataset ID in the external catalog","required":true,"schema":{"type":"string"}},{"name":"vendor","in":"query","description":"Catalog vendor (e.g., zeenea)","required":true,"schema":{"type":"string"}},{"name":"name","in":"query","description":"Override contract name","required":false,"schema":{"type":"string"}},{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Contract created successfully","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Unknown vendor","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Catalog credentials not configured","content":{"*/*":{"schema":{"type":"object"}}}},"409":{"description":"Contract already exists for this dataset","content":{"*/*":{"schema":{"type":"object"}}}},"502":{"description":"Upstream catalog API error","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"catalog.dataset.import","description":"Import a catalog dataset as a data contract"}],"x-since":"4.4.0","x-sunset":"2027-01-01"}},"/v2/users/me/integrations/{key}/test":{"post":{"tags":["Publishing"],"summary":"Test integration credentials","description":"**Since v2.12.0** — Tests the stored credentials for the specified integration. Always returns 200; check 'success' field.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"testCredentials_2","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"integration.github.test","description":"Test GitHub integration credentials"},{"name":"integration.zeenea.test","description":"Test Zeenea integration credentials"},{"name":"integration.kafka.test","description":"Test Control Center integration credentials"}],"x-since":"2.12.0","x-sunset":"2027-01-01"}},"/v2/users/me/integrations/{key}/test/field/{fieldName}":{"post":{"tags":["Publishing"],"summary":"Test a single integration field","description":"**Since v2.13.0** — Tests a specific field value without saving. Returns success/message/warning. Uses context or stored credentials for fields that require companion values.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"testField_2","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string"}},{"name":"fieldName","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","additionalProperties":{}}}},"required":true},"responses":{"200":{"description":"Test result (check 'success' field)","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Unknown integration or field name","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"integration.github.test","description":"Test a single GitHub integration field"},{"name":"integration.zeenea.test","description":"Test a single Zeenea integration field"},{"name":"integration.kafka.test","description":"Test a single Control Center integration field"}],"x-since":"2.13.0","x-sunset":"2027-01-01"}},"/v2/reference-tags":{"get":{"tags":["Tags"],"summary":"List all reference tags (v2)","description":"**Since v2.4.2** — Returns all reference tags created by the authenticated user\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"listTags_1","responses":{"200":{"description":"List of reference tags","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"reference-tag.list","description":"List all reference tags"}],"x-since":"2.4.2","x-sunset":"2027-01-01"},"post":{"tags":["Tags"],"summary":"Create a reference tag (v2)","description":"**Since v2.4.2** — Creates a new reference tag with the specified properties\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"createTag_1","parameters":[{"name":"tagName","in":"query","required":true,"schema":{"type":"string"}},{"name":"properties","in":"query","required":true,"schema":{"type":"string"}},{"name":"description","in":"query","required":false,"schema":{"type":"string","default":""}}],"responses":{"201":{"description":"Tag created successfully","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Invalid request or tag already exists","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"reference-tag.create","description":"Create a reference tag"}],"x-since":"2.4.2","x-sunset":"2027-01-01"}},"/v2/products":{"get":{"tags":["Products"],"summary":"List product headers (v2)","description":"**Since v2.2.0** — Deprecated — use GET /v3/products instead. Returns header fields for all data products belonging to the authenticated user.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"readHeaders_6","responses":{"200":{"description":"JSON array of product header objects","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"product.list","description":"List data product headers"}],"x-since":"2.2.0","x-sunset":"2027-01-01"},"post":{"tags":["Products"],"summary":"Upload a data product (v2)","description":"**Since v2.2.0** — Deprecated — use POST /v3/products (multipart) instead. Uploads an ODPS YAML data product file directly.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"create_7","parameters":[{"name":"contractId","in":"query","required":true,"schema":{"type":"string"}},{"name":"contractVersion","in":"query","required":true,"schema":{"type":"string"}},{"name":"version","in":"query","required":false,"schema":{"type":"string"}},{"name":"name","in":"query","required":false,"schema":{"type":"string"}},{"name":"domain","in":"query","required":false,"schema":{"type":"string"}},{"name":"tenant","in":"query","required":false,"schema":{"type":"string"}},{"name":"force","in":"query","required":false,"schema":{"type":"string"}}],"requestBody":{"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary"}},"required":["file"]}}}},"responses":{"200":{"description":"Product uploaded successfully","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated","content":{"*/*":{"schema":{"type":"object"}}}},"500":{"description":"File upload error","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Invalid file type","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"product.upload","description":"Upload an ODPS YAML data product file"}],"x-since":"2.2.0","x-sunset":"2027-01-01"},"delete":{"tags":["Products"],"summary":"Delete a data product (v2)","description":"**Since v2.2.0** — Deprecated — use DELETE /v3/products instead. Soft-deletes a specific product version.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"delete_8","parameters":[{"name":"productId","in":"query","required":true,"schema":{"type":"string"}},{"name":"version","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Product deleted successfully","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Product not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"product.delete","description":"Delete a data product version"}],"x-since":"2.2.0","x-sunset":"2027-01-01"}},"/v2/products/publish-github":{"post":{"tags":["Products"],"summary":"Publish product to GitHub (v2)","description":"**Since v2.2.0** — Deprecated — use POST /v3/products/publish-github instead. Pushes the product YAML to GitHub using the canonicalUrl.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"publishToGitHub_6","parameters":[{"name":"productId","in":"query","required":true,"schema":{"type":"string"}},{"name":"version","in":"query","required":false,"schema":{"type":"string"}},{"name":"branch","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Product published to GitHub","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Missing GitHub token or canonicalUrl","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Product not found","content":{"*/*":{"schema":{"type":"object"}}}},"502":{"description":"GitHub API error","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"product.publish","description":"Publish a data product to GitHub"}],"x-since":"2.2.0","x-sunset":"2027-01-01"}},"/v2/pdf-settings":{"post":{"tags":["Publishing"],"summary":"Update PDF settings (v2)","description":"**Since v2.4.0** — Updates PDF rendering settings (page size and footer message).\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"updatePdfSettings_2","parameters":[{"name":"size","in":"query","required":true,"schema":{"type":"string"}},{"name":"footer","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"PDF settings updated successfully","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated","content":{"*/*":{"schema":{"type":"object"}}}},"500":{"description":"Failed to update settings file","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"pdf-settings.update","description":"Update PDF rendering settings"}],"x-since":"2.4.0","x-sunset":"2027-01-01"}},"/v2/orgs":{"post":{"tags":["Organizations"],"summary":"Create an organization","description":"**Since v2.3.0** — Creates a new organization with the given name, slug, and optional domains. The authenticated user becomes the creator.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"createOrg_1","parameters":[{"name":"name","in":"query","required":true,"schema":{"type":"string"}},{"name":"slug","in":"query","required":true,"schema":{"type":"string"}},{"name":"domains","in":"query","required":false,"schema":{"type":"array","items":{"type":"string"}}}],"responses":{"201":{"description":"Organization created","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Invalid slug, duplicate slug, or domain already claimed","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"org.create","description":"Create a new organization"}],"x-since":"2.3.0","x-sunset":"2027-01-01"}},"/v2/orgs/{slug}/settings/pdf-settings":{"post":{"tags":["Org Settings"],"summary":"Update organization PDF settings","description":"**Since v2.7.0** — Updates PDF rendering settings (page size, footer) for the organization. Requires ADMIN+ role.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"updatePdfSettings_3","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"size","in":"query","required":true,"schema":{"type":"string"}},{"name":"footer","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"PDF settings updated","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Insufficient role","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}},"500":{"description":"Failed to update settings","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"org.settings.pdf.update","description":"Update organization PDF rendering settings"}],"x-since":"2.7.0","x-sunset":"2027-01-01"}},"/v2/orgs/{slug}/settings/logo":{"get":{"tags":["Org Settings"],"summary":"Get organization logo","description":"**Since v2.7.0** — Returns the organization's current SVG logo. Requires org membership.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"getLogo_2","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"SVG logo content","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Not a member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found or no logo","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"org.settings.logo.get","description":"Get the organization logo"}],"x-since":"2.7.0","x-sunset":"2027-01-01"},"post":{"tags":["Org Settings"],"summary":"Upload organization logo","description":"**Since v2.7.0** — Uploads an SVG logo for the organization's PDF contract renderings. Requires ADMIN+ role.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"uploadLogo_2","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"force","in":"query","required":false,"schema":{"type":"boolean","default":false}}],"requestBody":{"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary"}},"required":["file"]}}}},"responses":{"200":{"description":"Logo uploaded successfully","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Uploaded file is not a valid SVG","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Insufficient role","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}},"409":{"description":"Logo already exists (use force=true)","content":{"*/*":{"schema":{"type":"object"}}}},"500":{"description":"File I/O error","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"org.settings.logo.upload","description":"Upload the organization logo"}],"x-since":"2.7.0","x-sunset":"2027-01-01"}},"/v2/orgs/{slug}/products":{"get":{"tags":["Org Products"],"summary":"List organization product headers","description":"**Since v2.5.0** — Deprecated — use GET /v3/products?org={slug} instead. Returns header fields for all products in the organization.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"readHeaders_7","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"JSON array of product headers","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Not a member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"product.list","description":"List data product headers"}],"x-since":"2.5.0","x-sunset":"2027-01-01"},"post":{"tags":["Org Products"],"summary":"Upload a product to the organization","description":"**Since v2.5.0** — Deprecated — use POST /v3/products?org={slug} (multipart) instead. Uploads an ODPS YAML file directly to the organization's storage.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"create_8","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"contractId","in":"query","required":true,"schema":{"type":"string"}},{"name":"contractVersion","in":"query","required":true,"schema":{"type":"string"}},{"name":"version","in":"query","required":false,"schema":{"type":"string"}},{"name":"name","in":"query","required":false,"schema":{"type":"string"}},{"name":"domain","in":"query","required":false,"schema":{"type":"string"}},{"name":"tenant","in":"query","required":false,"schema":{"type":"string"}},{"name":"force","in":"query","required":false,"schema":{"type":"string"}}],"requestBody":{"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary"}},"required":["file"]}}}},"responses":{"200":{"description":"Product uploaded","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Not a member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}},"500":{"description":"Product creation error","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Invalid file type","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"product.upload","description":"Upload an ODPS YAML data product file"}],"x-since":"2.5.0","x-sunset":"2027-01-01"},"delete":{"tags":["Org Products"],"summary":"Delete an organization product","description":"**Since v2.5.0** — Deprecated — use DELETE /v3/products?org={slug} instead. Soft-deletes a specific product version from the organization.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"delete_9","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"productId","in":"query","required":true,"schema":{"type":"string"}},{"name":"version","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Product deleted","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Not a member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization or product not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"product.delete","description":"Delete a data product version"}],"x-since":"2.5.0","x-sunset":"2027-01-01"}},"/v2/orgs/{slug}/products/publish-github":{"post":{"tags":["Org Products"],"summary":"Publish organization product to GitHub","description":"**Since v2.5.0** — Deprecated — use POST /v3/products/publish-github?org={slug} instead. Pushes the product YAML to GitHub.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"publishToGitHub_7","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"productId","in":"query","required":true,"schema":{"type":"string"}},{"name":"version","in":"query","required":false,"schema":{"type":"string"}},{"name":"branch","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Product published","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Missing GitHub token or canonicalUrl","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Not a member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization or product not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"product.publish","description":"Publish a data product to GitHub"}],"x-since":"2.5.0","x-sunset":"2027-01-01"}},"/v2/orgs/{slug}/join":{"post":{"tags":["Membership"],"summary":"Request to join an organization","description":"**Since v2.5.0** — Submits a join request that must be approved by an org admin or owner.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"joinRequest_1","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"message","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"201":{"description":"Join request created","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Already a member or pending request exists","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"org.member.join","description":"Request to join an organization"}],"x-since":"2.5.0","x-sunset":"2027-01-01"}},"/v2/orgs/{slug}/invite":{"post":{"tags":["Membership"],"summary":"Invite a user to the organization","description":"**Since v2.5.0** — Admin/owner invites a user by email. The user must accept the invitation.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"invite_1","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"email","in":"query","required":true,"schema":{"type":"string"}},{"name":"message","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"201":{"description":"Invitation created","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Already a member or pending invitation","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Insufficient role","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"org.member.invite","description":"Invite a user to the organization"}],"x-since":"2.5.0","x-sunset":"2027-01-01"}},"/v2/orgs/{slug}/integrations/{key}/test":{"post":{"tags":["Org Settings"],"summary":"Test org integration credentials","description":"**Since v2.12.0**\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"testCredentials_3","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"key","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"integration.github.test","description":"Test org GitHub integration credentials"},{"name":"integration.zeenea.test","description":"Test org Zeenea integration credentials"},{"name":"integration.kafka.test","description":"Test org Control Center integration credentials"}],"x-since":"2.12.0","x-sunset":"2027-01-01"}},"/v2/orgs/{slug}/integrations/{key}/test/field/{fieldName}":{"post":{"tags":["Org Settings"],"summary":"Test a single org integration field","description":"**Since v2.13.0** — Tests a specific field value without saving. Returns success/message/warning. Uses context or stored credentials for fields that require companion values.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"testField_3","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"key","in":"path","required":true,"schema":{"type":"string"}},{"name":"fieldName","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","additionalProperties":{}}}},"required":true},"responses":{"200":{"description":"Test result (check 'success' field)","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Unknown integration or field name","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Insufficient role (requires ADMIN+)","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"integration.github.test","description":"Test a single org GitHub integration field"},{"name":"integration.zeenea.test","description":"Test a single org Zeenea integration field"},{"name":"integration.kafka.test","description":"Test a single org Control Center integration field"}],"x-since":"2.13.0","x-sunset":"2027-01-01"}},"/v2/orgs/{slug}/domains":{"post":{"tags":["Organizations"],"summary":"Add domain to organization","description":"**Since v2.7.0** — Adds an email domain to the organization for discovery. Requires ADMIN+ role.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"addDomain_1","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"domain","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"201":{"description":"Domain added","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Domain blocked or already claimed","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Insufficient role","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"org.domain.create","description":"Add an email domain to the organization"}],"x-since":"2.7.0","x-sunset":"2027-01-01"},"delete":{"tags":["Organizations"],"summary":"Remove domain from organization","description":"**Since v2.7.0** — Removes an email domain from the organization. Requires ADMIN+ role.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"removeDomain_1","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"domain","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Domain removed","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Domain not found or doesn't belong to this org","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Insufficient role","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"org.domain.delete","description":"Remove an email domain from the organization"}],"x-since":"2.7.0","x-sunset":"2027-01-01"}},"/v2/orgs/{slug}/contracts":{"get":{"tags":["Org Contracts"],"summary":"List organization contract headers","description":"**Since v2.5.0** — Deprecated — use GET /v3/contracts?org={slug} instead. Returns header fields for all contracts in the organization.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"readHeaders_8","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"storage","in":"query","required":false,"schema":{"type":"string","default":"permanent"}}],"responses":{"200":{"description":"JSON array of contract headers","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Not a member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"contract.list","description":"List organization contract headers"}],"x-since":"2.5.0","x-sunset":"2027-01-01"},"post":{"tags":["Org Contracts"],"summary":"Upload a contract to the organization","description":"**Since v2.5.0** — Deprecated — use POST /v3/contracts?org={slug} instead. Uploads an ODCS YAML or DDL file to the organization's storage. Requires org membership.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"create_9","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"contractId","in":"query","required":false,"schema":{"type":"string"}},{"name":"sourceFormat","in":"query","required":false,"schema":{"type":"string"}},{"name":"version","in":"query","required":false,"schema":{"type":"string"}},{"name":"name","in":"query","required":false,"schema":{"type":"string"}},{"name":"domain","in":"query","required":false,"schema":{"type":"string"}},{"name":"tenant","in":"query","required":false,"schema":{"type":"string"}},{"name":"force","in":"query","required":false,"schema":{"type":"string"}},{"name":"storage","in":"query","required":false,"schema":{"type":"string","default":"permanent"}},{"name":"ddlUrl","in":"query","required":false,"schema":{"type":"string"}},{"name":"dbmlUrl","in":"query","required":false,"schema":{"type":"string"}},{"name":"includeViews","in":"query","description":"When sourceFormat=jdbc, also introspect database views (#185 TD-5). Views are added as SchemaObjects tagged 'view'. Default false.","required":false,"schema":{"type":"boolean","default":false}},{"name":"includeRoutines","in":"query","description":"When sourceFormat=jdbc, also discover stored procedures and functions (#186 TD-6). Attached as JSON customProperties 'storedProcedures' and 'storedFunctions'. Default false.","required":false,"schema":{"type":"boolean","default":false}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary"},"jdbcConnection":{"$ref":"#/components/schemas/JdbcConnectionRequest"}}}}}},"responses":{"200":{"description":"Contract uploaded","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Invalid input","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Not a member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"contract.create","description":"Upload a contract to the organization"}],"x-since":"2.5.0","x-sunset":"2027-01-01"},"delete":{"tags":["Org Contracts"],"summary":"Delete an organization contract","description":"**Since v2.5.0** — Deprecated — use DELETE /v3/contracts?org={slug} instead. Soft-deletes a specific contract version from the organization.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"delete_10","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"contractId","in":"query","required":true,"schema":{"type":"string"}},{"name":"version","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Contract deleted","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Not a member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization or contract not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"contract.delete","description":"Delete an organization contract"}],"x-since":"2.5.0","x-sunset":"2027-01-01"}},"/v2/orgs/{slug}/contracts/transfer":{"post":{"tags":["Org Contracts"],"summary":"Transfer artifacts from personal to org storage","description":"**Since v2.5.1** — Deprecated — use POST /v3/contracts/transfer?org={slug} instead. Moves contracts and/or products from the authenticated user's personal storage into the organization. Transfer is all-or-nothing: if any item fails validation, nothing is transferred. The request body is a JSON array of TransferItem objects.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"transferArtifacts_3","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TransferItem"}}}},"required":true},"responses":{"200":{"description":"Artifacts transferred successfully","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Validation failed (missing artifacts, invalid types)","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Not a member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}},"500":{"description":"File transfer error","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"contract.transfer","description":"Transfer artifacts to org storage"}],"x-since":"2.5.1","x-sunset":"2027-01-01"}},"/v2/orgs/{slug}/contracts/publish-github":{"post":{"tags":["Org Contracts"],"summary":"Publish organization contract to GitHub","description":"**Since v2.5.0** — Deprecated — use POST /v3/contracts/publish-github?org={slug} instead. Pushes the contract YAML to GitHub. Uses the organization's GitHub token if configured.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"publishToGitHub_8","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"contractId","in":"query","required":true,"schema":{"type":"string"}},{"name":"version","in":"query","required":false,"schema":{"type":"string"}},{"name":"branch","in":"query","required":false,"schema":{"type":"string"}},{"name":"storage","in":"query","required":false,"schema":{"type":"string","default":"permanent"}}],"responses":{"200":{"description":"Contract published","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Missing GitHub token or canonicalUrl","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Not a member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization or contract not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"contract.publish","description":"Publish organization contract to GitHub"}],"x-since":"2.5.0","x-sunset":"2027-01-01"}},"/v2/logo":{"get":{"tags":["Publishing"],"summary":"Get logo (v2)","description":"**Since v2.4.0** — Returns the user's current SVG logo. User identified from JWT.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"getLogo_3","responses":{"200":{"description":"SVG logo content","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"No logo found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"logo.get","description":"Get the user's SVG logo"}],"x-since":"2.4.0","x-sunset":"2027-01-01"},"post":{"tags":["Publishing"],"summary":"Upload a logo (v2)","description":"**Since v2.4.0** — Uploads an SVG logo for PDF contract renderings. Use force=true to overwrite an existing logo.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"uploadLogo_3","parameters":[{"name":"force","in":"query","required":false,"schema":{"type":"boolean","default":false}}],"requestBody":{"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary"}},"required":["file"]}}}},"responses":{"200":{"description":"Logo uploaded successfully","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Uploaded file is not a valid SVG","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated","content":{"*/*":{"schema":{"type":"object"}}}},"409":{"description":"Logo already exists (use force=true to overwrite)","content":{"*/*":{"schema":{"type":"object"}}}},"500":{"description":"File I/O error","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"logo.upload","description":"Upload an SVG logo"}],"x-since":"2.4.0","x-sunset":"2027-01-01"}},"/v2/github/workflow":{"post":{"tags":["Automation"],"summary":"Install GitHub Actions workflow (v2)","description":"**Since v2.4.2** — Deprecated — use POST /v3/github/workflow instead. Requires Bearer JWT.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"installWorkflow_2","parameters":[{"name":"repoUrl","in":"query","required":false,"schema":{"type":"string"}},{"name":"branch","in":"query","required":false,"schema":{"type":"string","default":"main"}}],"responses":{"200":{"description":"Workflow installed","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"No GitHub token or invalid repo URL","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"502":{"description":"GitHub API error","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"github-action.workflow.install","description":"Install GitHub Actions workflow"}],"x-since":"2.4.2","x-sunset":"2027-01-01"}},"/v2/github/secrets":{"post":{"tags":["Automation"],"summary":"Set repository secrets (v2)","description":"**Since v2.4.2** — Deprecated — use POST /v3/github/secrets instead. Requires Bearer JWT.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"setSecrets_2","parameters":[{"name":"repoUrl","in":"query","required":false,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","additionalProperties":{}}}},"required":true},"responses":{"200":{"description":"Secrets set","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"No GitHub token, invalid repo URL, or no secrets provided","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"502":{"description":"GitHub API error","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"github-action.secrets.update","description":"Set repository secrets"}],"x-since":"2.4.2","x-sunset":"2027-01-01"}},"/v2/github/actions/trigger":{"post":{"tags":["Automation"],"summary":"Trigger workflow dispatch (v2)","description":"**Since v2.4.2** — Deprecated — use POST /v3/github/actions/trigger instead. Requires Bearer JWT.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"triggerWorkflow_2","parameters":[{"name":"repoUrl","in":"query","required":false,"schema":{"type":"string"}},{"name":"branch","in":"query","required":false,"schema":{"type":"string","default":"main"}},{"name":"workflowFile","in":"query","required":false,"schema":{"type":"string","default":"upload-data-products.yml"}}],"responses":{"200":{"description":"Workflow triggered","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"No GitHub token or invalid repo URL","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"502":{"description":"GitHub API error","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"github-action.workflow.trigger","description":"Trigger a workflow dispatch"}],"x-since":"2.4.2","x-sunset":"2027-01-01"}},"/v2/contracts":{"get":{"tags":["Contracts"],"summary":"List contract headers (v2)","description":"**Since v2.2.0** — Deprecated — use GET /v3/contracts instead. Returns header fields for all contracts belonging to the authenticated user.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"readHeaders_9","parameters":[{"name":"storage","in":"query","required":false,"schema":{"type":"string","default":"permanent"}}],"responses":{"200":{"description":"JSON array of contract header objects","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"contract.list","description":"List contract headers"}],"x-since":"2.2.0","x-sunset":"2027-01-01"},"post":{"tags":["Contracts"],"summary":"Upload a data contract (v2)","description":"**Since v2.2.0** — Deprecated — use POST /v3/contracts instead. Uploads an ODCS YAML file, a SQL DDL file, or creates a contract from a live JDBC database. For sourceFormat=jdbc, pass connection parameters as a 'jdbcConnection' JSON part to keep credentials out of URLs.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"create_10","parameters":[{"name":"contractId","in":"query","required":false,"schema":{"type":"string"}},{"name":"sourceFormat","in":"query","required":false,"schema":{"type":"string"}},{"name":"version","in":"query","required":false,"schema":{"type":"string"}},{"name":"name","in":"query","required":false,"schema":{"type":"string"}},{"name":"domain","in":"query","required":false,"schema":{"type":"string"}},{"name":"tenant","in":"query","required":false,"schema":{"type":"string"}},{"name":"force","in":"query","required":false,"schema":{"type":"string"}},{"name":"storage","in":"query","required":false,"schema":{"type":"string","default":"permanent"}},{"name":"ddlUrl","in":"query","required":false,"schema":{"type":"string"}},{"name":"dbmlUrl","in":"query","required":false,"schema":{"type":"string"}},{"name":"includeViews","in":"query","description":"When sourceFormat=jdbc, also introspect database views (#185 TD-5). Views are added as SchemaObjects tagged 'view'. Default false.","required":false,"schema":{"type":"boolean","default":false}},{"name":"includeRoutines","in":"query","description":"When sourceFormat=jdbc, also discover stored procedures and functions (#186 TD-6). Attached as JSON customProperties 'storedProcedures' and 'storedFunctions'. Default false.","required":false,"schema":{"type":"boolean","default":false}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary"},"jdbcConnection":{"$ref":"#/components/schemas/JdbcConnectionRequest"}}}}}},"responses":{"200":{"description":"Contract uploaded successfully","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Unsupported source format or invalid input","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated","content":{"*/*":{"schema":{"type":"object"}}}},"500":{"description":"File upload or processing error","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"contract.create","description":"Upload a data contract"}],"x-since":"2.2.0","x-sunset":"2027-01-01"},"delete":{"tags":["Contracts"],"summary":"Delete a data contract (v2)","description":"**Since v2.2.0** — Deprecated — use DELETE /v3/contracts instead. Soft-deletes a specific contract version.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"delete_11","parameters":[{"name":"contractId","in":"query","required":true,"schema":{"type":"string"}},{"name":"version","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Contract deleted successfully","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Contract not found","content":{"*/*":{"schema":{"type":"object"}}}},"409":{"description":"Contract is referenced by data products","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"contract.delete","description":"Delete a data contract"}],"x-since":"2.2.0","x-sunset":"2027-01-01"}},"/v2/contracts/test-connection":{"post":{"tags":["Contracts"],"summary":"Test JDBC database connection (v2)","description":"**Since v2.9.0** — Deprecated — use POST /v3/contracts/test-connection instead. Tests connectivity to a database without introspecting the schema. Connection parameters are sent as a JSON request body to keep credentials out of URLs.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"testConnection_2","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/JdbcConnectionRequest"}}},"required":true},"responses":{"200":{"description":"Connection test result (status: ok or error)","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"contract.database.test","description":"Test JDBC database connection"}],"x-since":"2.9.0","x-sunset":"2027-01-01"}},"/v2/contracts/publish-github":{"post":{"tags":["Contracts"],"summary":"Publish contract to GitHub (v2)","description":"**Since v2.2.0** — Deprecated — use POST /v3/contracts/publish-github instead. Pushes the contract YAML to GitHub using the canonicalUrl.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"publishToGitHub_9","parameters":[{"name":"contractId","in":"query","required":true,"schema":{"type":"string"}},{"name":"version","in":"query","required":false,"schema":{"type":"string"}},{"name":"branch","in":"query","required":false,"schema":{"type":"string"}},{"name":"storage","in":"query","required":false,"schema":{"type":"string","default":"permanent"}}],"responses":{"200":{"description":"Contract published to GitHub","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Missing GitHub token or canonicalUrl","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Contract not found","content":{"*/*":{"schema":{"type":"object"}}}},"502":{"description":"GitHub API error","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"contract.publish","description":"Publish contract to GitHub"}],"x-since":"2.2.0","x-sunset":"2027-01-01"}},"/v2/admin/signup-requests/{id}/reject":{"post":{"tags":["Administration"],"summary":"Reject a signup request","description":"**Since v2.7.0** — Marks the request rejected. Pass {\"sendEmail\": true} to email the requester a polite decline.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"reject_3","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","additionalProperties":{}}}}},"responses":{"200":{"description":"Rejected","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Admin privileges required","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Not found","content":{"*/*":{"schema":{"type":"object"}}}},"409":{"description":"Already reviewed","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"signup-request.reject","description":"Reject a signup request"}],"x-since":"2.7.0","x-sunset":"2027-01-01"}},"/v2/admin/signup-requests/{id}/approve":{"post":{"tags":["Administration"],"summary":"Approve a signup request","description":"**Since v2.7.0** — Marks the request approved and emails the requester a sign-up link. Idempotent — approving an already-reviewed request returns 409.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"approve_3","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"string"}}}}},"responses":{"200":{"description":"Approved","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Admin privileges required","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Not found","content":{"*/*":{"schema":{"type":"object"}}}},"409":{"description":"Already reviewed","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"signup-request.approve","description":"Approve a signup request"}],"x-since":"2.7.0","x-sunset":"2027-01-01"}},"/v2/admin/invitation-codes":{"get":{"tags":["Administration"],"summary":"List all admin invitation codes","description":"**Since v2.7.0** — Returns all admin-minted invitation codes with computed isExpired and isExhausted flags.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"list_4","responses":{"200":{"description":"List of codes","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Admin privileges required","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"invitation-code.list","description":"List all admin invitation codes"}],"x-since":"2.7.0","x-sunset":"2027-01-01"},"post":{"tags":["Administration"],"summary":"Mint a new admin invitation code","description":"**Since v2.7.0** — Admin-minted code for events, partners, etc. Server validates uniqueness across personal and admin tables. If 'code' is omitted, the server auto-generates one.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"mint_1","requestBody":{"content":{"application/json":{"schema":{"type":"object","additionalProperties":{}}}},"required":true},"responses":{"200":{"description":"Created code","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Bad request","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Admin privileges required","content":{"*/*":{"schema":{"type":"object"}}}},"409":{"description":"Duplicate code","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"invitation-code.mint","description":"Mint a new admin invitation code"}],"x-since":"2.7.0","x-sunset":"2027-01-01"}},"/v2/admin/blocked-domains":{"get":{"tags":["Administration"],"summary":"List blocked domains","description":"**Since v2.6.0** — Returns all blocked email domains.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"listBlockedDomains_1","responses":{"200":{"description":"List of blocked domains","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Admin privileges required","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"blocked-domain.list","description":"List blocked email domains"}],"x-since":"2.6.0","x-sunset":"2027-01-01"},"post":{"tags":["Administration"],"summary":"Block a domain","description":"**Since v2.6.0** — Adds an email domain to the blocklist.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"blockDomain_1","requestBody":{"content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"string"}}}},"required":true},"responses":{"200":{"description":"Domain blocked successfully","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Domain already blocked or invalid input","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Admin privileges required","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"blocked-domain.create","description":"Add an email domain to the blocklist"}],"x-since":"2.6.0","x-sunset":"2027-01-01"}},"/v1/verify-signature":{"post":{"tags":["Verification"],"summary":"Verify signature on uploaded file (public)","description":"**Since v4.4.32** — Accepts an ODCS YAML (.odcs.yaml), ODPS YAML (.odps.yaml), or ZIP bundle (.zip) containing data contracts and/or products. Returns verification results per file. No authentication required.","operationId":"verifyUpload","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary"}},"required":["file"]}}}},"responses":{"200":{"description":"Verification result(s)","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Unsupported file type or invalid content","content":{"*/*":{"schema":{"type":"object"}}}}},"x-intent":[{"name":"signature.verify","description":"Verify signature on an uploaded file"}],"x-since":"4.4.32"}},"/v1/users/reset-password":{"post":{"tags":["Users"],"summary":"Reset password with code","description":"**Since v2.1.4** — Resets a user's password using the 6-character code received via email. Code expires after 30 minutes. No authentication required.","operationId":"resetPassword","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResetPasswordRequest"}}},"required":true},"responses":{"200":{"description":"Password reset successfully","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Invalid or expired code, or password too short","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"User not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"ApiKeyAuth":[]},{"PasswordAuth":[]}],"x-since":"2.1.4"}},"/v1/users/resend-verification":{"post":{"tags":["Users"],"summary":"Resend verification email","description":"**Since v1.0.0** — Resends the verification email with the existing validation code. No authentication required. Rate-limited to one request per 2 minutes.","operationId":"resendVerification_1","parameters":[{"name":"email","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Verification email sent or user already validated","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"No validation code available","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"User not found","content":{"*/*":{"schema":{"type":"object"}}}},"429":{"description":"Too many requests (wait 2 minutes)","content":{"*/*":{"schema":{"type":"object"}}}},"500":{"description":"Failed to send email","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"ApiKeyAuth":[]},{"PasswordAuth":[]}],"x-intent":[{"name":"user.resend-verification","description":"Resend the email verification message"}],"x-since":"1.0.0"}},"/v1/users/forgot-password":{"post":{"tags":["Users"],"summary":"Forgot password","description":"**Since v2.1.4** — Sends a password reset code to the specified email address. Always returns 200 to prevent email enumeration. No authentication required.","operationId":"forgotPassword","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForgotPasswordRequest"}}},"required":true},"responses":{"200":{"description":"If the email is registered, a reset code has been sent","content":{"*/*":{"schema":{"type":"object"}}}},"429":{"description":"Too many reset requests (max 3 per 24 hours)","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"ApiKeyAuth":[]},{"PasswordAuth":[]}],"x-since":"2.1.4"}},"/v1/self-report":{"post":{"tags":["self-report-controller"],"summary":"Submit a self-report (deprecated)","description":"**Deprecated** — use `POST /v4/self-report` instead. Public Help-tab endpoint; anonymous and signed-in callers both allowed.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"submit_2","parameters":[{"name":"description","in":"query","required":true,"schema":{"type":"string"}},{"name":"context","in":"query","required":false,"schema":{"type":"string"}},{"name":"attachment","in":"query","required":false,"schema":{"type":"array","items":{"type":"string","format":"binary"}}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{}}}}}},"deprecated":true,"x-intent":[{"name":"self-report.create","description":"Submit an in-app help/feedback report"}],"x-sunset":"2027-01-01"}},"/v1/reference-tags":{"get":{"tags":["Tags"],"summary":"List all reference tags","description":"**Since v1.0.0** — Returns all reference tags created by the authenticated user","operationId":"listTags_2","parameters":[{"name":"X-API-KEY","in":"header","required":false,"schema":{"type":"string"}},{"name":"X-USER-PASSWORD","in":"header","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"List of reference tags","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Invalid API key or password","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"ApiKeyAuth":[]},{"PasswordAuth":[]}],"x-intent":[{"name":"reference-tag.list","description":"List all reference tags"}],"x-since":"1.0.0"},"post":{"tags":["Tags"],"summary":"Create a reference tag","description":"**Since v1.0.0** — Creates a new reference tag with the specified properties","operationId":"createTag_2","parameters":[{"name":"tagName","in":"query","required":true,"schema":{"type":"string"}},{"name":"properties","in":"query","required":true,"schema":{"type":"string"}},{"name":"description","in":"query","required":false,"schema":{"type":"string","default":""}},{"name":"X-API-KEY","in":"header","required":false,"schema":{"type":"string"}},{"name":"X-USER-PASSWORD","in":"header","required":false,"schema":{"type":"string"}}],"responses":{"201":{"description":"Tag created successfully","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Invalid request or tag already exists","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Invalid API key or password","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"ApiKeyAuth":[]},{"PasswordAuth":[]}],"x-intent":[{"name":"reference-tag.create","description":"Create a reference tag"}],"x-since":"1.0.0"}},"/v1/products":{"get":{"tags":["Products"],"summary":"List product headers","description":"**Since v1.0.0** — Returns header fields (id, version, name, domain, tenant, status) for all data products belonging to the authenticated user.","operationId":"readHeaders_10","parameters":[{"name":"X-API-KEY","in":"header","required":false,"schema":{"type":"string"}},{"name":"X-USER-PASSWORD","in":"header","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"JSON array of product header objects","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Invalid API key or password","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated","content":{"*/*":{"schema":{"type":"object"}}}},"500":{"description":"Error reading products from disk","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"ApiKeyAuth":[]},{"PasswordAuth":[]}],"x-intent":[{"name":"product.list","description":"List data product headers"}],"x-since":"1.0.0"},"post":{"tags":["Products"],"summary":"Upload a data product","description":"**Since v1.0.0** — Uploads an ODPS YAML data product file directly. Only .odps.yaml files are accepted.","operationId":"create_11","parameters":[{"name":"contractId","in":"query","required":true,"schema":{"type":"string"}},{"name":"contractVersion","in":"query","required":true,"schema":{"type":"string"}},{"name":"version","in":"query","required":false,"schema":{"type":"string"}},{"name":"name","in":"query","required":false,"schema":{"type":"string"}},{"name":"domain","in":"query","required":false,"schema":{"type":"string"}},{"name":"tenant","in":"query","required":false,"schema":{"type":"string"}},{"name":"force","in":"query","required":false,"schema":{"type":"string"}},{"name":"X-API-KEY","in":"header","required":false,"schema":{"type":"string"}},{"name":"X-USER-PASSWORD","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary"}},"required":["file"]}}}},"responses":{"200":{"description":"Product uploaded successfully","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Invalid API key or password","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated","content":{"*/*":{"schema":{"type":"object"}}}},"500":{"description":"File upload error","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Invalid file type (must be .odps.yaml)","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"ApiKeyAuth":[]},{"PasswordAuth":[]}],"x-intent":[{"name":"product.upload","description":"Upload an ODPS YAML data product file"}],"x-since":"1.0.0"},"delete":{"tags":["Products"],"summary":"Delete a data product","description":"**Since v1.0.0** — Soft-deletes a specific product version by renaming the file. Requires a validated account.","operationId":"delete_12","parameters":[{"name":"productId","in":"query","required":true,"schema":{"type":"string"}},{"name":"version","in":"query","required":true,"schema":{"type":"string"}},{"name":"X-API-KEY","in":"header","required":false,"schema":{"type":"string"}},{"name":"X-USER-PASSWORD","in":"header","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Product deleted successfully","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Invalid API key or password","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Product not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"ApiKeyAuth":[]},{"PasswordAuth":[]}],"x-intent":[{"name":"product.delete","description":"Delete a data product version"}],"x-since":"1.0.0"}},"/v1/products/publish-github":{"post":{"tags":["Products"],"summary":"Publish product to GitHub","description":"**Since v1.0.0** — Pushes the product YAML to GitHub using the canonicalUrl found in the product's authoritativeDefinitions. Requires a validated account with a GitHub token configured in the user profile.","operationId":"publishToGitHub_10","parameters":[{"name":"productId","in":"query","required":true,"schema":{"type":"string"}},{"name":"version","in":"query","required":false,"schema":{"type":"string"}},{"name":"branch","in":"query","required":false,"schema":{"type":"string"}},{"name":"X-API-KEY","in":"header","required":false,"schema":{"type":"string"}},{"name":"X-USER-PASSWORD","in":"header","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Product published to GitHub","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Missing GitHub token, missing canonicalUrl, or invalid GitHub URL","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Invalid API key or password","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Product not found","content":{"*/*":{"schema":{"type":"object"}}}},"502":{"description":"GitHub API error","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"ApiKeyAuth":[]},{"PasswordAuth":[]}],"x-intent":[{"name":"product.publish","description":"Publish a data product to GitHub"}],"x-since":"1.0.0"}},"/v1/pdf-settings":{"post":{"tags":["Publishing"],"summary":"Update PDF settings","description":"**Since v1.0.0** — Updates PDF rendering settings (page size and footer message) stored as a YAML file in the user's directory.","operationId":"updatePdfSettings_4","parameters":[{"name":"size","in":"query","required":true,"schema":{"type":"string"}},{"name":"footer","in":"query","required":true,"schema":{"type":"string"}},{"name":"X-API-KEY","in":"header","required":false,"schema":{"type":"string"}},{"name":"X-USER-PASSWORD","in":"header","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"PDF settings updated successfully","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Invalid API key or password","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not activated","content":{"*/*":{"schema":{"type":"object"}}}},"500":{"description":"Failed to update settings file","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"ApiKeyAuth":[]},{"PasswordAuth":[]}],"x-intent":[{"name":"pdf-settings.update","description":"Update PDF rendering settings"}],"x-since":"1.0.0"}},"/v1/logo":{"get":{"tags":["Publishing"],"summary":"Get logo","description":"**Since v1.0.0** — Returns the user's current SVG logo. Requires a validated account.","operationId":"getLogo_4","parameters":[{"name":"X-API-KEY","in":"header","required":false,"schema":{"type":"string"}},{"name":"X-USER-PASSWORD","in":"header","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"SVG logo content","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Invalid API key or password","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not activated","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"No logo found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"ApiKeyAuth":[]},{"PasswordAuth":[]}],"x-intent":[{"name":"logo.get","description":"Get the user's current SVG logo"}],"x-since":"1.0.0"},"post":{"tags":["Publishing"],"summary":"Upload a logo","description":"**Since v1.0.0** — Uploads an SVG logo for the user's PDF contract renderings. If a logo exists, use force=true to overwrite (the old logo is backed up with a timestamp).","operationId":"uploadLogo_4","parameters":[{"name":"force","in":"query","required":false,"schema":{"type":"boolean","default":false}},{"name":"X-API-KEY","in":"header","required":false,"schema":{"type":"string"}},{"name":"X-USER-PASSWORD","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary"}},"required":["file"]}}}},"responses":{"200":{"description":"Logo uploaded successfully","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Uploaded file is not a valid SVG","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Invalid API key or password","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not activated","content":{"*/*":{"schema":{"type":"object"}}}},"409":{"description":"Logo already exists (use force=true to overwrite)","content":{"*/*":{"schema":{"type":"object"}}}},"500":{"description":"File I/O error","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"ApiKeyAuth":[]},{"PasswordAuth":[]}],"x-intent":[{"name":"logo.upload","description":"Upload an SVG logo for PDF renderings"}],"x-since":"1.0.0"}},"/v1/github/workflow":{"post":{"tags":["Automation"],"summary":"Install GitHub Actions workflow","description":"**Since v1.0.0** — Installs the upload-data-products workflow file in the specified repository.","operationId":"installWorkflow_3","parameters":[{"name":"repoUrl","in":"query","required":false,"schema":{"type":"string"}},{"name":"branch","in":"query","required":false,"schema":{"type":"string","default":"main"}},{"name":"X-API-KEY","in":"header","required":false,"schema":{"type":"string"}},{"name":"X-USER-PASSWORD","in":"header","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"ApiKeyAuth":[]},{"PasswordAuth":[]}],"x-intent":[{"name":"github-action.workflow.install","description":"Install GitHub Actions workflow"}],"x-since":"1.0.0"}},"/v1/github/secrets":{"post":{"tags":["Automation"],"summary":"Set repository secrets","description":"**Since v1.0.0** — Sets encrypted repository secrets for Zeenea integration.","operationId":"setSecrets_3","parameters":[{"name":"repoUrl","in":"query","required":false,"schema":{"type":"string"}},{"name":"X-API-KEY","in":"header","required":false,"schema":{"type":"string"}},{"name":"X-USER-PASSWORD","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","additionalProperties":{}}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"ApiKeyAuth":[]},{"PasswordAuth":[]}],"x-intent":[{"name":"github-action.secrets.update","description":"Set repository secrets"}],"x-since":"1.0.0"}},"/v1/github/actions/trigger":{"post":{"tags":["Automation"],"summary":"Trigger workflow dispatch","description":"**Since v1.0.0** — Triggers a workflow_dispatch event for the upload workflow.","operationId":"triggerWorkflow_3","parameters":[{"name":"repoUrl","in":"query","required":false,"schema":{"type":"string"}},{"name":"branch","in":"query","required":false,"schema":{"type":"string","default":"main"}},{"name":"workflowFile","in":"query","required":false,"schema":{"type":"string","default":"upload-data-products.yml"}},{"name":"X-API-KEY","in":"header","required":false,"schema":{"type":"string"}},{"name":"X-USER-PASSWORD","in":"header","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"ApiKeyAuth":[]},{"PasswordAuth":[]}],"x-intent":[{"name":"github-action.workflow.trigger","description":"Trigger a workflow dispatch"}],"x-since":"1.0.0"}},"/v1/diagnostics":{"get":{"tags":["Diagnostics"],"summary":"List diagnostics reports (admin only)","description":"**Since v3.1.0** — Paginated. Filters: type, email, since, until, resolved, appVersion, search, provenance, app.","operationId":"list_5","parameters":[{"name":"X-API-KEY","in":"header","required":false,"schema":{"type":"string","default":""}},{"name":"X-USER-PASSWORD","in":"header","required":false,"schema":{"type":"string","default":""}},{"name":"X-CLI-KEY","in":"header","required":false,"schema":{"type":"string","default":""}},{"name":"type","in":"query","required":false,"schema":{"type":"string"}},{"name":"email","in":"query","required":false,"schema":{"type":"string"}},{"name":"since","in":"query","required":false,"schema":{"type":"string"}},{"name":"until","in":"query","required":false,"schema":{"type":"string"}},{"name":"resolved","in":"query","required":false,"schema":{"type":"boolean"}},{"name":"appVersion","in":"query","required":false,"schema":{"type":"string"}},{"name":"search","in":"query","required":false,"schema":{"type":"string"}},{"name":"provenance","in":"query","required":false,"schema":{"type":"string"}},{"name":"app","in":"query","required":false,"schema":{"type":"string"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":0}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":50}}],"responses":{"200":{"description":"Paginated list","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Invalid credentials","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Admin privileges required","content":{"*/*":{"schema":{"type":"object"}}}}},"x-intent":[{"name":"diagnostics.list","description":"List diagnostics reports"}],"x-since":"3.1.0"},"post":{"tags":["Diagnostics"],"summary":"Submit a diagnostics report","description":"**Since v3.1.0** — Unauthenticated. Accepts a single front-end error report.","operationId":"submit_3","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DiagnosticsReportRequest"}}},"required":true},"responses":{"201":{"description":"Report accepted","content":{"*/*":{"schema":{"type":"object"}}}},"500":{"description":"Internal error","content":{"*/*":{"schema":{"type":"object"}}}}},"x-intent":[{"name":"diagnostics.create","description":"Submit a front-end diagnostics report"}],"x-since":"3.1.0"}},"/v1/contracts":{"get":{"tags":["Contracts"],"summary":"List contract headers","description":"**Since v1.0.0** — Returns header fields (id, version, name, domain, tenant, status) for all contracts belonging to the authenticated user.","operationId":"readHeaders_11","parameters":[{"name":"X-API-KEY","in":"header","required":false,"schema":{"type":"string"}},{"name":"X-USER-PASSWORD","in":"header","required":false,"schema":{"type":"string"}},{"name":"storage","in":"query","required":false,"schema":{"type":"string","default":"permanent"}}],"responses":{"200":{"description":"JSON array of contract header objects","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Invalid API key or password","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated","content":{"*/*":{"schema":{"type":"object"}}}},"500":{"description":"Error reading contracts from disk","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"ApiKeyAuth":[]},{"PasswordAuth":[]}],"x-intent":[{"name":"contract.list","description":"List contract headers"}],"x-since":"1.0.0"},"post":{"tags":["Contracts"],"summary":"Upload a data contract","description":"**Since v1.0.0** — Uploads an ODCS YAML file or a SQL DDL file. DDL files can be uploaded directly or downloaded from a URL via the ddlUrl parameter. Requires a validated account.","operationId":"create_12","parameters":[{"name":"contractId","in":"query","required":false,"schema":{"type":"string"}},{"name":"sourceFormat","in":"query","required":false,"schema":{"type":"string"}},{"name":"version","in":"query","required":false,"schema":{"type":"string"}},{"name":"name","in":"query","required":false,"schema":{"type":"string"}},{"name":"domain","in":"query","required":false,"schema":{"type":"string"}},{"name":"tenant","in":"query","required":false,"schema":{"type":"string"}},{"name":"force","in":"query","required":false,"schema":{"type":"string"}},{"name":"storage","in":"query","required":false,"schema":{"type":"string","default":"permanent"}},{"name":"ddlUrl","in":"query","required":false,"schema":{"type":"string"}},{"name":"dbmlUrl","in":"query","required":false,"schema":{"type":"string"}},{"name":"includeViews","in":"query","description":"When sourceFormat=jdbc, also introspect database views (#185 TD-5). Views are added as SchemaObjects tagged 'view'. Default false: tables only.","required":false,"schema":{"type":"boolean","default":false}},{"name":"includeRoutines","in":"query","description":"When sourceFormat=jdbc, also discover stored procedures and functions (#186 TD-6). Results are attached to the contract as JSON customProperties 'storedProcedures' and 'storedFunctions'. Default false.","required":false,"schema":{"type":"boolean","default":false}},{"name":"X-API-KEY","in":"header","required":false,"schema":{"type":"string"}},{"name":"X-USER-PASSWORD","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary"},"jdbcConnection":{"$ref":"#/components/schemas/JdbcConnectionRequest"}}}}}},"responses":{"200":{"description":"Contract uploaded successfully. ODCS: returns a JSON UploadResult ({message, id, version}). DDL: returns contract header as JSON.","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Unsupported source format or invalid input combination","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Invalid API key or password","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated","content":{"*/*":{"schema":{"type":"object"}}}},"422":{"description":"Invalid or malformed contract file (not YAML, unreadable, missing id/version, schema-invalid)","content":{"*/*":{"schema":{"type":"object"}}}},"500":{"description":"File upload or processing error","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"ApiKeyAuth":[]},{"PasswordAuth":[]}],"x-intent":[{"name":"contract.create","description":"Upload a data contract"}],"x-since":"1.0.0"},"delete":{"tags":["Contracts"],"summary":"Delete a data contract","description":"**Since v1.0.0** — Soft-deletes a specific contract version by renaming the file. Blocked if any data product references the contract. Requires a validated account.","operationId":"delete_13","parameters":[{"name":"contractId","in":"query","required":true,"schema":{"type":"string"}},{"name":"version","in":"query","required":true,"schema":{"type":"string"}},{"name":"X-API-KEY","in":"header","required":false,"schema":{"type":"string"}},{"name":"X-USER-PASSWORD","in":"header","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Contract deleted successfully","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Invalid API key or password","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Contract not found","content":{"*/*":{"schema":{"type":"object"}}}},"409":{"description":"Contract is referenced by one or more data products","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"ApiKeyAuth":[]},{"PasswordAuth":[]}],"x-intent":[{"name":"contract.delete","description":"Delete a data contract"}],"x-since":"1.0.0"}},"/v1/contracts/test-connection":{"post":{"tags":["Contracts"],"summary":"Test JDBC database connection","description":"**Since v2.9.0** — Tests connectivity to a database without introspecting the schema. Connection parameters are sent as a JSON request body to keep credentials out of URLs.","operationId":"testConnection_3","parameters":[{"name":"X-API-KEY","in":"header","required":false,"schema":{"type":"string"}},{"name":"X-USER-PASSWORD","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/JdbcConnectionRequest"}}},"required":true},"responses":{"200":{"description":"Connection test result (status: ok or error)","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Missing required parameters","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid credentials","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"ApiKeyAuth":[]},{"PasswordAuth":[]}],"x-intent":[{"name":"contract.database.test","description":"Test JDBC database connection"}],"x-since":"2.9.0"}},"/v1/contracts/publish-github":{"post":{"tags":["Contracts"],"summary":"Publish contract to GitHub","description":"**Since v1.0.0** — Pushes the contract YAML to GitHub using the canonicalUrl found in the contract's authoritativeDefinitions. Requires a validated account with a GitHub token configured in the user profile.","operationId":"publishToGitHub_11","parameters":[{"name":"contractId","in":"query","required":true,"schema":{"type":"string"}},{"name":"version","in":"query","required":false,"schema":{"type":"string"}},{"name":"branch","in":"query","required":false,"schema":{"type":"string"}},{"name":"storage","in":"query","required":false,"schema":{"type":"string","default":"permanent"}},{"name":"X-API-KEY","in":"header","required":false,"schema":{"type":"string"}},{"name":"X-USER-PASSWORD","in":"header","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Contract published to GitHub","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Missing GitHub token, missing canonicalUrl, or invalid GitHub URL","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Invalid API key or password","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Contract not found","content":{"*/*":{"schema":{"type":"object"}}}},"502":{"description":"GitHub API error","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"ApiKeyAuth":[]},{"PasswordAuth":[]}],"x-intent":[{"name":"contract.publish","description":"Publish contract to GitHub"}],"x-since":"1.0.0"}},"/v1/contact":{"post":{"tags":["Contact Sync"],"summary":"Sync a contact to MailerLite","description":"Accepts contact data and syncs to MailerLite. Requires machine-identity auth.","operationId":"syncContact_1","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContactSyncRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{}}}}}},"security":[{"ApiKeyAuth":[]},{"PasswordAuth":[]}],"x-intent":[{"name":"contact.transfer","description":"Sync a contact to MailerLite"}]}},"/oauth2/register":{"post":{"tags":["o-auth-2-register-controller"],"operationId":"register_1","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Rfc7591RegistrationRequest"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/v4/users/profile":{"get":{"tags":["Users"],"summary":"Get user profile (v4)","description":"**Since v7.6.0** — Returns the authenticated user's profile. User is identified from JWT — no email param needed.","operationId":"getProfile","responses":{"200":{"description":"UserResponse with profile details","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"user.profile.get","description":"Get the authenticated user's profile"}],"x-since":"7.6.0"},"patch":{"tags":["Users"],"summary":"Patch user preferences (v4)","description":"**Since v7.6.0** — Partial-update the authenticated user's profile preferences. Currently supports `inviteDigestOptOut: boolean` (#297). Other fields are ignored.","operationId":"patchProfile","requestBody":{"content":{"application/json":{"schema":{"type":"object","additionalProperties":{}}}},"required":true},"responses":{"200":{"description":"Updated UserResponse","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"user.profile.update","description":"Update the authenticated user's preferences"}],"x-since":"7.6.0"}},"/v4/signing/auto-sign":{"patch":{"tags":["Signing"],"summary":"Toggle auto-sign setting","description":"**Since v4.5.0** — Enables or disables automatic signing before GitHub publish. Without ?org=, toggles the user's personal setting. With ?org=, toggles the organization's setting (requires ADMIN+ role).","operationId":"toggleAutoSign","parameters":[{"name":"enabled","in":"query","required":true,"schema":{"type":"boolean"}},{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Auto-sign setting updated","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"signing-key.auto-sign.update","description":"Toggle the auto-sign setting"}],"x-since":"4.5.0"}},"/v4/admin/platform/features":{"patch":{"tags":["Administration"],"summary":"Set a global feature flag","description":"**Since v8.16.12** — Upsert one global feature flag. Body: {\"key\": \"<catalog key>\", \"enabled\": true|false}. An unknown key returns 400. platform-admin only.","operationId":"setFeature","requestBody":{"content":{"application/json":{"schema":{"type":"object","additionalProperties":{}}}},"required":true},"responses":{"200":{"description":"Updated flag (effective state)","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Missing key/enabled or unknown feature key","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Admin privileges required","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"platform.setFeature","description":"Turn a global feature flag on or off for all users"}],"x-since":"8.16.12"}},"/v4/admin/orgs/{slug}":{"patch":{"tags":["Administration"],"summary":"Set organization feature flags (v4 admin)","description":"**Since v8.7.0** — Enables or disables per-org feature flags — conversational agent support (#984) and/or the Governance Coach (svc#983). Only the keys present in the request body are changed. When agent support is disabled the org's agent-provider endpoints return 403; when the coach is disabled the webapp editor hides the coach overlay. Admin only.","operationId":"setOrgFlags","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","additionalProperties":{}}}},"required":true},"responses":{"200":{"description":"Updated organization object","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Admin privileges required","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"admin.org.flags","description":"Enable/disable per-org feature flags (agent support, governance coach)"}],"x-since":"8.7.0"}},"/v4/admin/orgs/{slug}/features":{"get":{"tags":["Administration"],"summary":"Per-org features","description":"**Since v8.16.13** — The feature catalog for one organization: each entry has the raw per-org value (orgEnabled), the global flag (globalEnabled), and effective (orgEnabled OR globalEnabled).","operationId":"features","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Per-org feature list","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Admin privileges required","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"admin.org.features","description":"Per-org feature catalog with raw/global/effective state"}],"x-since":"8.16.13"},"patch":{"tags":["Administration"],"summary":"Set a per-org feature","description":"**Since v8.16.13** — Upsert one per-org feature. Body: {\"key\": \"<catalog key>\", \"enabled\": true|false}. Unknown key returns 400. platform-admin only.","operationId":"setFeature_1","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","additionalProperties":{}}}},"required":true},"responses":{"200":{"description":"Updated per-org feature list","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Missing key/enabled or unknown feature key","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Admin privileges required","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"admin.org.setFeature","description":"Turn a feature on/off for one organization"}],"x-since":"8.16.13"}},"/v4/admin/invitation-codes/{id}":{"delete":{"tags":["Administration"],"summary":"Delete an admin invitation code","description":"**Since v7.13.0** — Only allowed when uses_count = 0. To deactivate a used code, revoke instead.","operationId":"delete_14","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"204":{"description":"Deleted","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Admin privileges required","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Not found","content":{"*/*":{"schema":{"type":"object"}}}},"409":{"description":"Code has been used; revoke instead","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"invitation-code.delete","description":"Delete an unused admin invitation code"}],"x-since":"7.13.0"},"patch":{"tags":["Administration"],"summary":"Update or revoke an admin invitation code","description":"**Since v7.13.0** — Update label, expires_at, or revoke (revoke=true sets expires_at to now).","operationId":"update_2","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","additionalProperties":{}}}},"required":true},"responses":{"200":{"description":"Updated code","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Bad request","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Admin privileges required","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"invitation-code.update","description":"Update an admin invitation code"},{"name":"invitation-code.revoke","description":"Revoke an admin invitation code"}],"x-since":"7.13.0"}},"/v3/products/remove-contract":{"patch":{"tags":["Products"],"summary":"Remove a contract reference from a product (v3)","description":"**Since v3.4.0** — Removes a contract from the product's outputPorts without deleting the product. Used during safe deletion to detach a contract from referencing products.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"removeContract","parameters":[{"name":"productId","in":"query","required":true,"schema":{"type":"string"}},{"name":"version","in":"query","required":true,"schema":{"type":"string"}},{"name":"contractId","in":"query","required":true,"schema":{"type":"string"}},{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Contract reference removed successfully","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated or not an org member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Product or contract reference not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"product.contract.remove","description":"Remove a contract reference from a product"}],"x-since":"3.4.0","x-sunset":"2027-01-01"}},"/v2/users/profile":{"get":{"tags":["Users"],"summary":"Get user profile (v2)","description":"**Since v2.2.0** — Returns the authenticated user's profile. User is identified from JWT — no email param needed.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"getProfile_1","responses":{"200":{"description":"UserResponse with profile details","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"user.profile.get","description":"Get the authenticated user's profile"}],"x-since":"2.2.0","x-sunset":"2027-01-01"},"patch":{"tags":["Users"],"summary":"Patch user preferences (v2)","description":"**Since v2.7.0** — Partial-update the authenticated user's profile preferences. Currently supports `inviteDigestOptOut: boolean` (#297). Other fields are ignored.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"patchProfile_1","requestBody":{"content":{"application/json":{"schema":{"type":"object","additionalProperties":{}}}},"required":true},"responses":{"200":{"description":"Updated UserResponse","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"user.profile.update","description":"Update the authenticated user's preferences"}],"x-since":"2.7.0","x-sunset":"2027-01-01"}},"/v2/admin/invitation-codes/{id}":{"delete":{"tags":["Administration"],"summary":"Delete an admin invitation code","description":"**Since v2.7.0** — Only allowed when uses_count = 0. To deactivate a used code, revoke instead.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"delete_15","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"204":{"description":"Deleted","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Admin privileges required","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Not found","content":{"*/*":{"schema":{"type":"object"}}}},"409":{"description":"Code has been used; revoke instead","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"invitation-code.delete","description":"Delete an unused admin invitation code"}],"x-since":"2.7.0","x-sunset":"2027-01-01"},"patch":{"tags":["Administration"],"summary":"Update or revoke an admin invitation code","description":"**Since v2.7.0** — Update label, expires_at, or revoke (revoke=true sets expires_at to now).\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"update_3","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","additionalProperties":{}}}},"required":true},"responses":{"200":{"description":"Updated code","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Bad request","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Admin privileges required","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"invitation-code.update","description":"Update an admin invitation code"},{"name":"invitation-code.revoke","description":"Revoke an admin invitation code"}],"x-since":"2.7.0","x-sunset":"2027-01-01"}},"/v4/users/search":{"get":{"tags":["Users"],"summary":"Search users (org-invite autocomplete)","description":"**Since v7.22.0** — Case-insensitive substring match on first name, last name, and email, restricted to the invite pool: users whose email domain matches the caller's, plus users sharing at least one organization with the caller (#679). Queries shorter than 3 characters return an empty list; results are capped at 20. Never exposes admin-only fields (#599).","operationId":"search","parameters":[{"name":"q","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"JSON array of UserSearchResponse","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}}},"x-intent":[{"name":"user.search","description":"Search users for org-invite autocomplete"}],"x-since":"7.22.0"}},"/v4/users/me/integrations":{"get":{"tags":["Publishing"],"summary":"Get all integration statuses","description":"**Since v7.6.0** — Returns a summary of which integrations are configured for the authenticated user.","operationId":"getAllStatuses","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"integration.list","description":"List all integration statuses"}],"x-since":"7.6.0"}},"/v4/users/me/integrations/{key}/status":{"get":{"tags":["Publishing"],"summary":"Get integration status","description":"**Since v7.6.0** — Returns non-secret config, configured boolean, and last test result for the specified integration.","operationId":"getStatus","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"integration.get","description":"Get a single integration status"}],"x-since":"7.6.0"}},"/v4/templates":{"get":{"tags":["Templates"],"summary":"List the catalog of pre-built ODCS contract templates","description":"**Since v7.0.66** — Returns the global catalog of starter ODCS contract templates the Workbench Template Gallery offers when a user creates a new contract. Each item carries the raw ODCS v3.1.0 YAML body the webapp clones as the seed for the new contract.","operationId":"listTemplates","responses":{"200":{"description":"{ items: TemplateDto[], total: int }","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT bearer token","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"templates.list","description":"List pre-built ODCS contract templates"}],"x-since":"7.0.66"}},"/v4/tags":{"get":{"tags":["Tags"],"summary":"List tags with counts (v4)","description":"**Since v7.0.9** — Returns the flat list of tags with the count of artifacts that use each one. Counts mirror the per-tag artifact list returned by /v4/tags/cloud.","operationId":"listTags_3","parameters":[{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"{ items: [{name, count}] }","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated or not an org member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"reference-tag.list","description":"List tags with artifact counts"}],"x-since":"7.0.9"}},"/v4/tags/cloud":{"get":{"tags":["Tags"],"summary":"Get tag cloud (v4)","description":"**Since v7.0.9** — Returns all tags across the caller's (or an organization's) contracts and products, with the artifacts that use each tag. Reference-tag usages appear as `$ref:`-prefixed keys.","operationId":"getTagCloud","parameters":[{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"{ tags: { tagName: [{id, version, name, type}] } }","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated or not an org member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"tag-cloud.get","description":"Get the org-aware tag cloud"}],"x-since":"7.0.9"}},"/v4/products/{productId}":{"get":{"tags":["Products"],"summary":"Get a data product","description":"**Since v7.13.3** — Retrieves a data product by ID. Pass org or orgId for organization products.\n\n| Format | Content-Type | Description |\n|--------|--------------|-------------|\n| _(none)_ / `FULL` | `application/x-yaml` | The raw ODPS YAML |\n| `PrettyPDF` | `application/pdf` | Branded PDF with the workspace logo and PDF settings |\n| `DDL` | `text/plain` or `application/zip` | SQL DDL for every contract on the product's ports (#1047) |\n\nAn unrecognized format returns the ODPS YAML.\n\n**format=DDL** requires `subformat` (the SQL dialect). A product with exactly one referenced contract returns the bare `.sql`; two or more return a ZIP holding `input/`, `output/`, `src/` (the original ODPS + ODCS) and a `MANIFEST.md`. Pass `zip=true` to always get a ZIP.","operationId":"read","parameters":[{"name":"productId","in":"path","required":true,"schema":{"type":"string"}},{"name":"version","in":"query","required":false,"schema":{"type":"string"}},{"name":"format","in":"query","description":"Response format — PrettyPDF renders the branded product PDF (svc#941); DDL exports the product's contracts as SQL (#1047)","required":false,"schema":{"type":"string","enum":["FULL","PrettyPDF","DDL"]}},{"name":"subformat","in":"query","description":"SQL dialect. Required when format=DDL. Call GET /v4/ddl/dialects for the current list.","required":false,"schema":{"type":"string"}},{"name":"zip","in":"query","description":"With format=DDL, force a ZIP even when the product has a single contract","required":false,"schema":{"type":"boolean","default":false}},{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Product in the requested format","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"format=DDL with a missing or unsupported subformat","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated or not an org member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Product or organization not found","content":{"*/*":{"schema":{"type":"object"}}}},"500":{"description":"PDF or DDL generation failed","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"product.get","description":"Retrieve a data product by ID"}],"x-since":"7.13.3"}},"/v4/products/{productId}/verify-signature":{"get":{"tags":["Verification"],"summary":"Verify signature on a stored product (public)","description":"**Since v7.31.0** — Verifies the digital signature embedded in the specified product, resolved by id across all storage. No authentication required — product ids are unguessable UUIDs. Omit version for the latest.","operationId":"verifyProduct","parameters":[{"name":"productId","in":"path","required":true,"schema":{"type":"string"}},{"name":"version","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Verification result","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Product not found","content":{"*/*":{"schema":{"type":"object"}}}}},"x-intent":[{"name":"signature.verify","description":"Verify signature on a stored product"}],"x-since":"7.31.0"}},"/v4/products/maturity-level":{"get":{"tags":["Products"],"summary":"Measure product maturity level (OMMS v0.2.0)","description":"**Since v4.2.0** — Returns a maturity level (0-5) for the specified data product using the OMMS v0.2.0 maturity model for ODPS. Includes policy evaluation results and level caps. Pass org or orgId for organization products.","operationId":"getMaturityLevel","parameters":[{"name":"productId","in":"query","required":true,"schema":{"type":"string"}},{"name":"version","in":"query","required":false,"schema":{"type":"string"}},{"name":"storage","in":"query","required":false,"schema":{"type":"string","default":"permanent"}},{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Maturity assessment result with policy results","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated or not an org member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Product or organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"product.maturity","description":"Measure data product maturity level"}],"x-since":"4.2.0"}},"/v4/products/lifecycle":{"get":{"tags":["Lifecycle"],"summary":"Get product lifecycle history (v4, born-deprecated)","description":"**Since v7.1.6** — Verbatim copy of GET /v1/products/lifecycle.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"getProductLifecycle","parameters":[{"name":"productId","in":"query","required":true,"schema":{"type":"string"}},{"name":"version","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"lifecycle.product.list","description":"Get product lifecycle history"}],"x-since":"7.1.6","x-sunset":"2027-01-01"}},"/v4/products/delete-check":{"get":{"tags":["Products"],"summary":"Pre-delete dependency check","description":"**Since v7.13.3** — Returns prior versions and referenced contracts for a product, so the client can show a comprehensive delete confirmation modal. Read-only — no mutation.","operationId":"deleteCheck","parameters":[{"name":"productId","in":"query","required":true,"schema":{"type":"string"}},{"name":"version","in":"query","required":true,"schema":{"type":"string"}},{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Delete check result with prior versions and referenced contracts","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated or not an org member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"product.delete-check","description":"Check product dependencies before delete"}],"x-since":"7.13.3"}},"/v4/products/ddl":{"get":{"tags":["Products"],"summary":"Download data product DDL","description":"**Since v8.22.0** — Generates SQL DDL from the data contracts on each product's input and output ports and returns them as one ZIP (#1047).\n\nThe archive holds `input/` and `output/` folders — a contract used as both is emitted under each — plus `src/` with the original ODPS and ODCS documents verbatim, and a `MANIFEST.md` listing every file with its role. Each `.sql` opens with a banner naming the product, port, role and contract.\n\nA plain GET so a browser can download it directly. At most 50 products per request. Contracts that cannot be resolved in the workspace are reported in the manifest rather than failing the download; an unreadable **product** is a 404 naming the id.","operationId":"ddl","parameters":[{"name":"productId","in":"query","description":"Data product id; repeat the parameter for several products (max 50)","required":true,"schema":{"type":"array","items":{"type":"string"}}},{"name":"version","in":"query","description":"Version of the product, when a single one is requested. Latest by default.","required":false,"schema":{"type":"string"}},{"name":"subformat","in":"query","description":"SQL dialect. Call GET /v4/ddl/dialects for the current list.","required":false,"schema":{"type":"string","default":"PostgreSQL"}},{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"ZIP archive of generated DDL","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"No productId, more than 50, or a missing/unsupported subformat","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated or not an org member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"A requested data product was not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"product.ddl","description":"Download SQL DDL for one or more data products"}],"x-since":"8.22.0"}},"/v4/presence/{kind}/{id}":{"get":{"tags":["Presence"],"summary":"Active viewers of an artifact","description":"**Since v7.24.0** — Returns the users currently viewing the artifact and registers/refreshes the caller as a viewer (the poll IS the heartbeat). Viewers with no poll within 60 seconds disappear. kind is 'contract' or 'product'.","operationId":"getPresence","parameters":[{"name":"kind","in":"path","description":"Artifact kind: contract or product","required":true,"schema":{"type":"string"}},{"name":"id","in":"path","description":"Artifact id (same key space as /v4/artifacts)","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"PresenceResponse with the active viewers","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Invalid kind","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"presence.get","description":"List active viewers of an artifact (and register the caller)"}],"x-since":"7.24.0"}},"/v4/platform/features":{"get":{"tags":["Platform"],"summary":"Global feature flags","description":"**Since v8.16.12** — The full catalog of global (all-users) feature flags with each flag's effective on/off state — the persisted value when an admin has set it, else the compiled default. Readable by any authenticated user (no org required) so the client can gate features for personal-context users too.","operationId":"features_1","responses":{"200":{"description":"Feature catalog with effective state","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"platform.features","description":"Global feature flags with their effective on/off state"}],"x-since":"8.16.12"}},"/v4/orgs/{slug}/products/{productId}":{"get":{"tags":["Org Products"],"summary":"Get an organization product","description":"**Since v7.9.0** — Retrieves a product by ID from the organization.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"read_1","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"productId","in":"path","required":true,"schema":{"type":"string"}},{"name":"version","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"ODPS YAML content","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Not a member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization or product not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"product.get","description":"Retrieve a data product by ID"}],"x-since":"7.9.0","x-sunset":"2027-01-01"}},"/v4/orgs/{slug}/messages":{"get":{"tags":["Membership"],"summary":"List pending messages (deprecated slug path)","description":"**Since v7.11.0** — Admin/owner views pending join requests and invitations. Deprecated — use GET /v4/orgs/messages with org/orgId (#651).\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"listPendingMessagesBySlug","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"List of pending messages","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Insufficient role","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-since":"7.11.0","x-sunset":"2027-01-01"}},"/v4/orgs/{slug}/members":{"get":{"tags":["Membership"],"summary":"List organization members (deprecated slug path)","description":"**Since v7.11.0** — Returns all members of the organization. Requires membership. Deprecated — use GET /v4/orgs/members with org/orgId (#651).\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"listMembersBySlug","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"List of members","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Not a member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-since":"7.11.0","x-sunset":"2027-01-01"}},"/v4/orgs/{slug}/integrations":{"get":{"tags":["Org Settings"],"summary":"Get all org integration statuses (deprecated slug path)","description":"**Since v7.10.0** — Returns the status of every org integration. Requires org membership. Deprecated — use GET /v4/orgs/integrations with org/orgId (#651).\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"getAllStatusesBySlug","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-since":"7.10.0","x-sunset":"2027-01-01"}},"/v4/orgs/{slug}/integrations/{key}/status":{"get":{"tags":["Org Settings"],"summary":"Get org integration status (deprecated slug path)","description":"**Since v7.10.0** — Returns the status of a single org integration. Requires org membership. Deprecated — use GET /v4/orgs/integrations/{key}/status with org/orgId (#651).\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"getStatusBySlug","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"key","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-since":"7.10.0","x-sunset":"2027-01-01"}},"/v4/orgs/{slug}/credits/usage":{"get":{"tags":["Credits"],"summary":"Get organization Credits usage","description":"**Since v7.44.0** — Returns daily Credits consumption totals for the specified organization over the last 30 days. Only the org creator can access this.","operationId":"getOrgUsageBySlug","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Usage summary returned (date → amount map)","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Not the organization creator","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"credit.org.usage.get","description":"Get an organization's daily Credits usage summary"}],"x-since":"7.44.0"}},"/v4/orgs/{slug}/credits/transactions":{"get":{"tags":["Credits"],"summary":"Get organization Credits transactions","description":"**Since v7.44.0** — Returns the transaction history for the specified organization (paginated). Only the org creator can access this.","operationId":"getOrgTransactionsBySlug","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":0}},{"name":"size","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":50}}],"responses":{"200":{"description":"Org transaction list returned","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Not the organization creator","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"credit.org.transaction.list","description":"List an organization's Credits transactions"}],"x-since":"7.44.0"}},"/v4/orgs/{slug}/credits/balance":{"get":{"tags":["Credits"],"summary":"Get organization Credits balance","description":"**Since v7.44.0** — Returns the Credits balance for the specified organization. Only the org creator can access this.","operationId":"getOrgBalanceBySlug","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Org balance returned","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Not the organization creator","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"credit.org.balance.get","description":"Get an organization's Credits balance"}],"x-since":"7.44.0"}},"/v4/orgs/{slug}/contracts/{contractId}":{"get":{"tags":["Org Contracts"],"summary":"Get an organization contract","description":"**Since v7.8.0** — Retrieves a contract by ID in the specified format from the organization.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"read_2","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"contractId","in":"path","required":true,"schema":{"type":"string"}},{"name":"version","in":"query","required":false,"schema":{"type":"string"}},{"name":"format","in":"query","required":false,"schema":{"type":"string"}},{"name":"subformat","in":"query","required":false,"schema":{"type":"string"}},{"name":"storage","in":"query","required":false,"schema":{"type":"string","default":"permanent"}}],"responses":{"200":{"description":"Contract in requested format","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Not a member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization or contract not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"contract.get","description":"Get an organization contract"}],"x-since":"7.8.0","x-sunset":"2027-01-01"}},"/v4/orgs/service-accounts/scopes":{"get":{"tags":["Service Accounts"],"summary":"List the grantable service-account scopes","description":"**Since v7.54.0** — Returns every scope a service account may be granted, each with a domain, a short label, and a one-line description — the vocabulary a scope picker renders. Sourced from ServiceAccountService.ALLOWED_SCOPES so the API and any client picker can never disagree. Requires authentication only (not org-admin); the vocabulary is global and carries no secret material.","operationId":"scopes","responses":{"200":{"description":"Array of grantable scopes with domain/label/description","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"serviceaccount.scopes","description":"List grantable service-account scopes"}],"x-since":"7.54.0"}},"/v4/orgs/search":{"get":{"tags":["Organizations"],"summary":"Search organizations by name","description":"**Since v7.7.0** — Returns organizations whose name contains the query string (case-insensitive).","operationId":"search_1","parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"List of matching organizations","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"org.search","description":"Search organizations by name"}],"x-since":"7.7.0"}},"/v4/orgs/mine":{"get":{"tags":["Organizations"],"summary":"List my organizations","description":"**Since v7.7.0** — Returns all organizations the authenticated user belongs to, with their role in each.","operationId":"getMyOrgs","responses":{"200":{"description":"List of organizations with membership role","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"org.list","description":"List organizations the caller belongs to"}],"x-since":"7.7.0"}},"/v4/orgs/messages":{"get":{"tags":["Membership"],"summary":"List pending messages","description":"**Since v7.26.0** — Admin/owner views pending join requests and invitations. Pass org (slug) or orgId (UUID) to select the organization. Requires ADMIN+ role.","operationId":"listPendingMessages","parameters":[{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"List of pending messages","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Missing org/orgId parameter","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Insufficient role","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"org.member.message.list","description":"List pending join requests and invitations"}],"x-since":"7.26.0"}},"/v4/orgs/members":{"get":{"tags":["Membership"],"summary":"List organization members","description":"**Since v7.26.0** — Returns all members of the organization. Pass org (slug) or orgId (UUID) to select the organization. Requires membership — except platform-admins, who may read any org's members (the admin \"Manage org\" panel, #772).","operationId":"listMembers","parameters":[{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"List of members","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Missing org/orgId parameter","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Not a member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"org.member.list","description":"List organization members"}],"x-since":"7.26.0"}},"/v4/orgs/invitations/mine":{"get":{"tags":["Membership"],"summary":"List my pending organization invitations","description":"**Since v7.43.40** — Returns the pending organization invitations addressed to the authenticated user, newest first. Self-scoped: reachable by any authenticated user (not org-scoped, not admin-gated). Each row carries the org slug/name, inviter, and a messageId usable with PUT /v4/orgs/messages/{messageId}/accept|decline. Invitations to orgs the caller already belongs to are excluded.","operationId":"myInvitations","responses":{"200":{"description":"The caller's pending invitations (possibly empty)","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"org.invitation.list-mine","description":"List the caller's own pending org invitations"}],"x-since":"7.43.40"}},"/v4/orgs/integrations":{"get":{"tags":["Org Settings"],"summary":"Get all org integration statuses","description":"**Since v7.26.0** — Returns the status of every org integration. Pass org (slug) or orgId (UUID) to select the organization. Requires org membership.","operationId":"getAllStatuses_1","parameters":[{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Integration statuses","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Missing org/orgId parameter","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Not a member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"integration.list","description":"List all org integration statuses"}],"x-since":"7.26.0"}},"/v4/orgs/integrations/{key}/status":{"get":{"tags":["Org Settings"],"summary":"Get org integration status","description":"**Since v7.26.0** — Returns the status of a single org integration. Pass org (slug) or orgId (UUID) to select the organization. Requires org membership.","operationId":"getStatus_1","parameters":[{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"key","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Integration status","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Missing org/orgId parameter or unknown integration key","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Not a member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"integration.get","description":"Get a single org integration status"}],"x-since":"7.26.0"}},"/v4/orgs/discover":{"get":{"tags":["Organizations"],"summary":"Discover organization by email","description":"**Since v7.7.0** — Finds the organization whose domain matches the given email address.","operationId":"discover","parameters":[{"name":"email","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Organization found (or empty if no match)","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"org.discover","description":"Find an organization by email domain"}],"x-since":"7.7.0"}},"/v4/orgs/agents":{"get":{"tags":["Org Agent Providers"],"summary":"List imported agents","description":"**Since v8.6.0** — Returns the agents imported from the organization's enabled providers (de-duplicated). Pass org (slug) or orgId (UUID). Requires org membership.","operationId":"agents","parameters":[{"name":"org","in":"query","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Array of agent cards","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Missing org/orgId parameter","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Not a member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"org.agents.list","description":"List the organization's imported agents"}],"x-since":"8.6.0"}},"/v4/notifications":{"get":{"tags":["Notifications"],"summary":"List notifications","description":"**Since v7.23.0** — Returns the caller's notification feed — open task assignments plus unresolved threads they authored or are @mentioned in — newest first, with an unread count relative to the mark-all-read watermark. Derived live from the comment system; there is no notification table.","operationId":"list_6","responses":{"200":{"description":"{ notifications: [...], unreadCount: n }","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"notifications.list","description":"List the caller's notifications with unread count"}],"x-since":"7.23.0"}},"/v4/me":{"get":{"tags":["Users"],"summary":"Get the authenticated user","description":"**Since v7.0.41** — Returns the current user's profile, resolved from the bearer JWT. Includes a UI-ready displayName that is never a raw UUID.","operationId":"me","responses":{"200":{"description":"The authenticated user","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MeResponse"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MeResponse"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"me.get","description":"Get the authenticated user's profile"}],"x-since":"7.0.41"}},"/v4/me/api-key":{"get":{"tags":["Users"],"summary":"Get the caller's API key","description":"**Since v7.0.59** — Returns the authenticated caller's API key, resolved from the bearer JWT — no email or password is needed, so this works for accounts created via the OAuth 2.1 sign-in flow, which have no password the caller knows. The returned key is used in the X-API-KEY header for API-key-authenticated endpoints.","operationId":"apiKey","responses":{"200":{"description":"ApiKeyResponse containing the caller's API key","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiKeyResponse"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiKeyResponse"}}}},"403":{"description":"Account not validated","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiKeyResponse"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"me.api-key.get","description":"Get the caller's API key"}],"x-since":"7.0.59"}},"/v4/maturity-model":{"get":{"tags":["Maturity Model"],"summary":"Get a maturity-model definition","description":"**Since v7.43.5** — Returns the maturity model (metadata + levels[], each with its criteria[]) for the given kind (contract or product). Read-only reference data. Served from the caller's provisioned copy when present, falling back to the bundled default.","operationId":"getMaturityModel","parameters":[{"name":"kind","in":"query","description":"Which model to return: 'contract' (default) or 'product'","required":false,"schema":{"type":"string","default":"contract"}},{"name":"X-API-KEY","in":"header","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"The maturity-model definition as JSON","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Unknown kind (must be 'contract' or 'product')","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid credentials","content":{"*/*":{"schema":{"type":"object"}}}},"500":{"description":"The maturity model could not be read","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"maturity.model.get","description":"Get the maturity-model definition for contracts or products"}],"x-since":"7.43.5"}},"/v4/maturity-history":{"get":{"tags":["Maturity History"],"summary":"Get maturity history","description":"**Since v7.2.0** — Returns daily maturity level distribution snapshots for contracts or products. Pass org or orgId for org-scoped data; omit for personal data. Defaults to the last 90 days if from/to are omitted.","operationId":"getMaturityHistory","parameters":[{"name":"artifactType","in":"query","description":"Artifact type: 'contract' or 'product'","required":true,"schema":{"type":"string"}},{"name":"from","in":"query","description":"Start date (yyyy-MM-dd), defaults to 90 days ago","required":false,"schema":{"type":"string"}},{"name":"to","in":"query","description":"End date (yyyy-MM-dd), defaults to today","required":false,"schema":{"type":"string"}},{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"JSON array of {date, maturityLevel, count} objects","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Invalid artifactType or date format","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated or not an org member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"maturity.history.get","description":"Get maturity distribution history"}],"x-since":"7.2.0"}},"/v4/logs":{"get":{"tags":["Users"],"summary":"Get the caller's activity log","description":"**Since v7.43.37** — Returns the authenticated caller's own ActivityLog entries, newest first, resolved from the bearer JWT. Self-scoped: a user only ever sees their own log — cross-user and admin filtering lives on /v4/admin/logs. Use 'limit' to bound the count (default 20, capped at 200).","operationId":"myLogs","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"The caller's activity log entries, newest first","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ActivityLog"}}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ActivityLog"}}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"me.logs.get","description":"Get the authenticated user's own activity log"}],"x-since":"7.43.37"}},"/v4/health":{"get":{"tags":["Administration"],"summary":"Health check (v4)","description":"**Since v7.0.68** — Returns service version info and status for any authenticated caller. Admin users additionally see extended diagnostics (deployment time, database availability, environment variables, JRuby/Asciidoctor versions, classpath packages). Body shape matches GET /v1/health (#569).","operationId":"getHealth","responses":{"200":{"description":"JSON with version info (all callers) and extended diagnostics (admins).","content":{"*/*":{"schema":{"type":"object","additionalProperties":{}}}}},"401":{"description":"Missing or invalid Bearer JWT.","content":{"*/*":{"schema":{"type":"object","additionalProperties":{}}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"health.get","description":"Service health and version info"}],"x-since":"7.0.68"}},"/v4/github/verify-access":{"get":{"tags":["Automation"],"summary":"Verify repository access (v4, born-deprecated)","description":"**Since v7.1.2** — Verifies that the GitHub token has sufficient permissions to access and modify the repository. Supports org context (?org=/?orgId=) and integration-default repoUrl resolution; v3-aligned behavior (#640).\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"verifyAccess","parameters":[{"name":"repoUrl","in":"query","required":false,"schema":{"type":"string"}},{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Access verification result","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"No GitHub token or invalid repo URL","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Not a member of the organization","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}},"502":{"description":"GitHub API error","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"github-action.verify-access","description":"Verify GitHub repository access"}],"x-since":"7.1.2","x-sunset":"2027-01-01"}},"/v4/github/actions/runs":{"get":{"tags":["Automation"],"summary":"Get latest workflow run (v4, born-deprecated)","description":"**Since v7.1.2** — Returns the status of the latest workflow run. Org context and integration-default resolution; v3-aligned (#640).\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"getLatestRun","parameters":[{"name":"repoUrl","in":"query","required":false,"schema":{"type":"string"}},{"name":"workflowFile","in":"query","required":false,"schema":{"type":"string","default":"upload-data-products.yml"}},{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Latest workflow run status","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"No GitHub token or invalid repo URL","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Not a member of the organization","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}},"502":{"description":"GitHub API error","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"github-action.run.get","description":"Get the latest workflow run"}],"x-since":"7.1.2","x-sunset":"2027-01-01"}},"/v4/diagnostics/{id}/steps/{seq}/image":{"get":{"tags":["Diagnostics"],"summary":"Stream a story step's screenshot (admin only)","description":"**Since v7.34.10**","operationId":"stepImage","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"seq","in":"path","required":true,"schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"Image bytes","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid Bearer JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Admin privileges required","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"No screenshot for this step","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"diagnostics.step.image","description":"Stream a step's screenshot"}],"x-since":"7.34.10"}},"/v4/ddl/dialects":{"get":{"tags":["DDL"],"summary":"List supported SQL dialects","description":"**Since v8.22.0** — Returns every SQL dialect the DDL generator knows about, in display order. `id` is the value to pass as `subformat` to the DDL endpoints; `available` is false for dialects that are on the roadmap but not implemented — those are advertised so clients can show them as coming soon, and rejected with 400 if actually requested.","operationId":"listDialects","responses":{"200":{"description":"{ items: [{ id, label, available }], total: int, default: string }","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT bearer token","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"ddl.dialects.list","description":"List the SQL dialects DDL export can target"}],"x-since":"8.22.0"}},"/v4/data-sources":{"get":{"tags":["Data Sources"],"summary":"List reusable named data sources","description":"**Since v7.35.0** — Returns every named data source in the caller's scope (personal, or the org when org/orgId is supplied). Passwords are never included.","operationId":"list_7","parameters":[{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Data sources (no secret material)","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated or not an org member","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"datasource.list","description":"List reusable named data sources"}],"x-since":"7.35.0"}},"/v4/credits/usage":{"get":{"tags":["Credits"],"summary":"Get Credits usage summary","description":"**Since v7.44.0** — Returns a daily usage breakdown for the last 30 days.","operationId":"getUsageSummary","responses":{"200":{"description":"Usage summary returned","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"credit.usage.get","description":"Get the user's daily Credits usage summary"}],"x-since":"7.44.0"}},"/v4/credits/transactions":{"get":{"tags":["Credits"],"summary":"Get Credits transactions","description":"**Since v7.44.0** — Returns the authenticated user's transaction history (paginated).","operationId":"getTransactions","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":0}},{"name":"size","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":50}}],"responses":{"200":{"description":"Transaction list returned","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"credit.transaction.list","description":"List the user's Credits transactions"}],"x-since":"7.44.0"}},"/v4/credits/org-balances":{"get":{"tags":["Credits"],"summary":"Get all organization Credits balances (admin)","description":"**Since v7.44.0** — Returns aggregate Credits balances for every organization. Admin only.","operationId":"getAllOrgBalances","responses":{"200":{"description":"Org balance list returned","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Admin privileges required","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"credit.org-balance.list","description":"List Credits balances for all orgs (admin)"}],"x-since":"7.44.0"}},"/v4/credits/balance":{"get":{"tags":["Credits"],"summary":"Get Credits balance","description":"**Since v7.44.0** — Returns the authenticated user's current Credits balance.","operationId":"getBalance","responses":{"200":{"description":"Balance returned","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"credit.balance.get","description":"Get the user's Credits balance"}],"x-since":"7.44.0"}},"/v4/contracts/{contractId}":{"get":{"tags":["Contracts"],"summary":"Get a data contract","description":"**Since v7.13.4** — Retrieves a contract by ID in the specified format. Pass org or orgId for organization contracts.","operationId":"read_3","parameters":[{"name":"contractId","in":"path","required":true,"schema":{"type":"string"}},{"name":"version","in":"query","required":false,"schema":{"type":"string"}},{"name":"format","in":"query","required":false,"schema":{"type":"string"}},{"name":"subformat","in":"query","required":false,"schema":{"type":"string"}},{"name":"storage","in":"query","required":false,"schema":{"type":"string","default":"permanent"}},{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Contract in the requested format","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated or not an org member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Contract or organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"contract.get","description":"Get a data contract"}],"x-since":"7.13.4"}},"/v4/contracts/{contractId}/verify-signature":{"get":{"tags":["Verification"],"summary":"Verify signature on a stored contract (public)","description":"**Since v7.31.0** — Verifies the digital signature embedded in the specified contract, resolved by id across all storage. No authentication required — contract ids are unguessable UUIDs. Omit version for the latest.","operationId":"verifyContract","parameters":[{"name":"contractId","in":"path","required":true,"schema":{"type":"string"}},{"name":"version","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Verification result","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Contract not found","content":{"*/*":{"schema":{"type":"object"}}}}},"x-intent":[{"name":"signature.verify","description":"Verify signature on a stored contract"}],"x-since":"7.31.0"}},"/v4/contracts/{contractId}/products":{"get":{"tags":["Contracts"],"summary":"List the data products using a contract","description":"**Since v8.19.1** — Returns every data product that references this contract, and for each one the ports that reference it with the direction of use.\n\nThree ODPS shapes are matched:\n- `outputPorts[].contractId` — the product publishes under this contract (`output`)\n- `outputPorts[].inputContracts[].id` — the output port consumes this contract (`input`)\n- `inputPorts[].contractId` or `inputPorts[].id` — (`input`)\n\nThe match is version-agnostic by default; pass `version` to narrow to ports pinning that version. A port that pins no version always matches, since it references every version.\n\nA contract used by nothing returns `products: []` with a 200, not a 404.\n\nDistinct from `GET /v4/contracts/delete-check`, which is a pre-delete check: it matches only `outputPorts[].contractId`, requires an exact version match, and reports no direction.","operationId":"productsUsingContract","parameters":[{"name":"contractId","in":"path","required":true,"schema":{"type":"string"}},{"name":"version","in":"query","description":"Narrow to ports referencing this contract version","required":false,"schema":{"type":"string"}},{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"The products using this contract, each with its referencing ports","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated or not an org member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"contract.used-by","description":"List the data products that use a contract"}],"x-since":"8.19.1"}},"/v4/contracts/supported-databases":{"get":{"tags":["Contracts"],"summary":"List supported JDBC databases","description":"**Since v7.13.4** — Returns the list of supported database types for JDBC contract creation.","operationId":"getSupportedDatabases","responses":{"200":{"description":"List of supported database types","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"contract.database.list","description":"List supported JDBC databases"}],"x-since":"7.13.4"}},"/v4/contracts/maturity-level":{"get":{"tags":["Contracts"],"summary":"Measure contract maturity level (OMMS v0.2.0)","description":"**Since v4.0.0** — Returns a maturity level (0-5) for the specified contract using the OMMS v0.2.0 maturity model. Includes policy evaluation results and level caps. Pass org or orgId for organization contracts.","operationId":"getMaturityLevel_1","parameters":[{"name":"contractId","in":"query","required":true,"schema":{"type":"string"}},{"name":"version","in":"query","required":false,"schema":{"type":"string"}},{"name":"storage","in":"query","required":false,"schema":{"type":"string","default":"permanent"}},{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Maturity assessment result with policy results","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated or not an org member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Contract or organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"maturity.get","description":"Measure contract maturity level"}],"x-since":"4.0.0"}},"/v4/contracts/lifecycle":{"get":{"tags":["Lifecycle"],"summary":"Get contract lifecycle history (v4, born-deprecated)","description":"**Since v7.1.6** — Verbatim copy of GET /v1/contracts/lifecycle.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"getContractLifecycle","parameters":[{"name":"contractId","in":"query","required":true,"schema":{"type":"string"}},{"name":"version","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"lifecycle.contract.list","description":"Get contract lifecycle history"}],"x-since":"7.1.6","x-sunset":"2027-01-01"}},"/v4/contracts/delete-check":{"get":{"tags":["Contracts"],"summary":"Pre-delete dependency check","description":"**Since v7.13.4** — Returns prior versions and referencing products for a contract, so the client can show a comprehensive delete confirmation modal. Read-only — no mutation.","operationId":"deleteCheck_1","parameters":[{"name":"contractId","in":"query","required":true,"schema":{"type":"string"}},{"name":"version","in":"query","required":true,"schema":{"type":"string"}},{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Delete check result with prior versions and referencing products","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated or not an org member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"contract.delete.check","description":"Pre-delete dependency check"}],"x-since":"7.13.4"}},"/v4/contracts/compare":{"get":{"tags":["Contracts"],"summary":"Compare two contracts","description":"**Since v7.13.4** — Compares two data contracts and returns a DiffResult. Pass org or orgId to compare organization contracts.","operationId":"compareContracts","parameters":[{"name":"id1","in":"query","required":true,"schema":{"type":"string"}},{"name":"version1","in":"query","required":false,"schema":{"type":"string"}},{"name":"storage1","in":"query","required":false,"schema":{"type":"string","default":"permanent"}},{"name":"id2","in":"query","required":true,"schema":{"type":"string"}},{"name":"version2","in":"query","required":false,"schema":{"type":"string"}},{"name":"storage2","in":"query","required":false,"schema":{"type":"string","default":"permanent"}},{"name":"scope","in":"query","required":false,"schema":{"type":"string","default":"all"}},{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"DiffResult JSON with differences and suggested version","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated or not an org member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}},"500":{"description":"Comparison failure","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"contract.compare","description":"Compare two contracts"}],"x-since":"7.13.4"}},"/v4/comments/tasks":{"get":{"tags":["Comments"],"summary":"List open tasks for the authenticated user","description":"**Since v5.0.0** — Returns all open task assignments (from @[email]! mentions) for the currently authenticated user.","operationId":"listTasks","responses":{"200":{"description":"Open task list","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Feature disabled","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"comment.task.list","description":"List the user's open comment tasks"}],"x-since":"5.0.0"}},"/v4/comments/my-threads":{"get":{"tags":["Comments"],"summary":"List open threads for the authenticated user","description":"**Since v5.0.7** — Returns all unresolved top-level comment threads where the user is either the author or was @mentioned.","operationId":"listMyThreads","responses":{"200":{"description":"Open thread list","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Feature disabled","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"comment.thread.list","description":"List the user's open comment threads"}],"x-since":"5.0.7"}},"/v4/comments/count":{"get":{"tags":["Comments"],"summary":"Count unresolved comments","description":"**Since v5.0.0** — Returns the number of unresolved top-level comment threads for an artifact.","operationId":"countUnresolved","parameters":[{"name":"orgId","in":"query","description":"Organization UUID","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"artifactKind","in":"query","description":"Artifact kind","required":true,"schema":{"type":"string"}},{"name":"artifactId","in":"query","description":"Artifact UUID","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Unresolved count","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Feature disabled","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"comment.count.get","description":"Count unresolved comment threads"}],"x-since":"5.0.0"}},"/v4/catalogs/properties":{"get":{"tags":["External Catalogs"],"summary":"Discover available properties on a catalog vendor","description":"**Since v7.2.0** — Probes the catalog to discover which properties are available on datasets, fields, and contacts.","operationId":"discoverProperties","parameters":[{"name":"vendor","in":"query","description":"Catalog vendor","required":true,"schema":{"type":"string"}},{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"catalog.property.list","description":"Discover available properties on a catalog vendor"}],"x-since":"7.2.0"}},"/v4/catalogs/datasets":{"get":{"tags":["External Catalogs"],"summary":"List datasets from an external catalog","description":"**Since v7.2.0** — Returns a list of datasets from the specified catalog vendor. Credentials are resolved from the user's or organization's integration settings.","operationId":"listDatasets","parameters":[{"name":"vendor","in":"query","description":"Catalog vendor (e.g., zeenea)","required":true,"schema":{"type":"string"}},{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Dataset list returned","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Unknown vendor","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Catalog credentials not configured","content":{"*/*":{"schema":{"type":"object"}}}},"502":{"description":"Upstream catalog API error","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"catalog.dataset.list","description":"List datasets from an external catalog"}],"x-since":"7.2.0"}},"/v4/artifacts":{"get":{"tags":["Artifacts"],"summary":"List the caller's artifacts (contracts + products) across personal + every org","description":"**Since v7.0.10** — Returns a unified header list of every contract and product the caller can see — their personal storage plus every organization they are a member of. Detail and YAML are fetched per artifact via /v3/{contracts,products}/{id}.","operationId":"listArtifacts","responses":{"200":{"description":"The caller's artifact headers plus a total count","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ArtifactListResponse"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ArtifactListResponse"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"artifact.list","description":"List all artifacts across personal and org storage"}],"x-since":"7.0.10"}},"/v4/artifacts/supported-versions":{"get":{"tags":["Artifacts"],"summary":"List supported ODCS/ODPS apiVersions","description":"**Since v7.48.0** — Returns the ODCS and ODPS apiVersion values the bundled validator supports, derived from the packaged JSON schemas, grouped by standard with each standard's current/default flagged. Consumed by the Workbench editor's API-version combobox (WB#866).","operationId":"getSupportedVersions","responses":{"200":{"description":"Supported versions per standard, e.g. {\"odcs\": {\"current\": \"v3.1.0\", \"versions\": [...]}, \"odps\": {...}}","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"artifact.versions.list","description":"List supported ODCS/ODPS apiVersions"}],"x-since":"7.48.0"}},"/v4/admin/validate":{"get":{"tags":["Administration"],"summary":"Force-validate a user (v4 admin)","description":"**Since v7.13.0** — Admin force-validates a user account by email, bypassing the validation code.","operationId":"forceValidateUser","parameters":[{"name":"email","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"User successfully validated (or already validated)","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Admin privileges required","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"User not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"admin.user.validate","description":"Force-validate a user account (admin)"}],"x-since":"7.13.0"}},"/v4/admin/users":{"get":{"tags":["Administration"],"summary":"List all users (v4 admin)","description":"**Since v7.13.0** — Returns all registered users with full details.","operationId":"listUsers_1","responses":{"200":{"description":"List of AdminUserResponse objects","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Admin privileges required","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"admin.user.list","description":"List all users (admin)"}],"x-since":"7.13.0"},"delete":{"tags":["Administration"],"summary":"Delete a user (v4 admin)","description":"**Since v7.13.0** — Deletes a user by email. User data is backed up before deletion.","operationId":"deleteUser","parameters":[{"name":"email","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"User successfully deleted","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Admin privileges required","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"User not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"admin.user.delete","description":"Delete a user by email (admin)"}],"x-since":"7.13.0"}},"/v4/admin/users/active":{"get":{"tags":["Administration"],"summary":"List recently active users (v4 admin, experimental)","description":"**Since v7.13.0** — Returns users who made any API call within the specified time window. Defaults to the last 60 minutes.","operationId":"activeUsers","parameters":[{"name":"minutes","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":60}}],"responses":{"200":{"description":"List of AdminUserResponse objects for active users","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Admin privileges required","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"admin.user.list-active","description":"List recently active users (admin)"}],"x-since":"7.13.0"}},"/v4/admin/signup-requests":{"get":{"tags":["Administration"],"summary":"List signup requests","description":"**Since v7.13.0** — Returns a page of signup requests, optionally filtered by status (pending/approved/rejected/expired — expired = auto-expired stale pending, #1003).","operationId":"list_8","parameters":[{"name":"status","in":"query","required":false,"schema":{"type":"string"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":0}},{"name":"size","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"Paged list","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Admin privileges required","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"signup-request.list","description":"List signup requests"}],"x-since":"7.13.0"}},"/v4/admin/shotz":{"get":{"tags":["Administration"],"summary":"List camera frames (v4 admin)","description":"**Since v7.15.0** — Returns metadata for every frame uploaded by the \"dash on the go\" device via POST /v4/health/shotz, newest first, with EXIF GPS latitude/longitude surfaced when the frame is geotagged.","operationId":"listShotz","responses":{"200":{"description":"JSON array of ShotzResponse objects","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Admin privileges required","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"admin.shotz.list","description":"List device camera frames (admin)"}],"x-since":"7.15.0"}},"/v4/admin/shotz/{id}":{"get":{"tags":["Administration"],"summary":"Stream a camera frame (v4 admin)","description":"**Since v7.15.0** — Streams the JPEG bytes of a single uploaded frame by id (the id returned by GET /v4/admin/shotz).","operationId":"getShotz","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The JPEG image","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Admin privileges required","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"No frame with that id","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"admin.shotz.get","description":"Stream one device camera frame (admin)"}],"x-since":"7.15.0"},"delete":{"tags":["Administration"],"summary":"Delete a camera frame (v4 admin)","description":"**Since v7.49.0** — Deletes a single uploaded frame by id (the id returned by GET /v4/admin/shotz). The backing file is removed; the operation is not undoable (#880).","operationId":"deleteShotz","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Frame deleted","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Admin privileges required","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"No frame with that id","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"admin.shotz.delete","description":"Delete one device camera frame (admin)"}],"x-since":"7.49.0"}},"/v4/admin/orgs":{"get":{"tags":["Administration"],"summary":"List all organizations (v4 admin)","description":"**Since v7.17.0** — Returns every organization in the system regardless of the caller's memberships, in the same shape as GET /v4/orgs/{slug} plus a numeric \"members\" field (count of memberships, excluding pending invitations) so the admin orgs panel can render \"N members\". The admin orgs panel uses this instead of the membership-scoped GET /v4/orgs/mine.","operationId":"listAllOrgs","responses":{"200":{"description":"JSON array of org objects","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Admin privileges required","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"admin.org.list","description":"List ALL organizations (admin)"}],"x-since":"7.17.0"}},"/v4/admin/onboarding/journeys":{"get":{"tags":["Administration"],"summary":"Onboarding journeys","description":"**Since v8.16.7** — One row per stitched journey (visitor and/or email) with per-stage first-seen timestamps, reminder count, and a derived status (in_progress, converted, stuck_after_approval, dropped). status=stuck filters to stuck_after_approval. excludeTest (default true) drops E2E test journeys before sort/paging so the totals reflect real users.","operationId":"journeys","parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":30}},{"name":"status","in":"query","required":false,"schema":{"type":"string"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":0}},{"name":"size","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20}},{"name":"excludeTest","in":"query","required":false,"schema":{"type":"boolean","default":true}}],"responses":{"200":{"description":"Paged journey rows","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Admin privileges required","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"onboarding.journeys","description":"Onboarding journeys: one row per visitor/email"}],"x-since":"8.16.7"}},"/v4/admin/onboarding/funnel":{"get":{"tags":["Administration"],"summary":"Onboarding funnel","description":"**Since v8.16.7** — Per-stage distinct-journey counts over the trailing window, with step-to-step conversion % and headline totals (visitors, requests, approvals, registrations, conversions). excludeTest (default true) drops E2E test journeys before counts/conversions are computed.","operationId":"funnel","parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":30}},{"name":"excludeTest","in":"query","required":false,"schema":{"type":"boolean","default":true}}],"responses":{"200":{"description":"Funnel report","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Admin privileges required","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"onboarding.funnel","description":"Onboarding funnel: per-stage counts and conversion rates"}],"x-since":"8.16.7"}},"/v4/admin/onboarding/funnel/stage/{stage}":{"get":{"tags":["Administration"],"summary":"Onboarding stage drill-down","description":"**Since v8.16.11** — The journeys that reached {stage} within the window, each annotated with the next step it took — nextStage is the earliest later ordered stage the journey reached, or null when it stopped here (dropped). reachedCount is the true total; droppedCount counts journeys that stopped at this stage; items is capped at 200. days (default 30) and excludeTest (default true) match /funnel.","operationId":"stageDetail","parameters":[{"name":"stage","in":"path","required":true,"schema":{"type":"string"}},{"name":"days","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":30}},{"name":"excludeTest","in":"query","required":false,"schema":{"type":"boolean","default":true}}],"responses":{"200":{"description":"Stage drill-down report","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Unknown stage","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Admin privileges required","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"onboarding.stageDetail","description":"Onboarding stage drill-down: who reached a stage + their next step"}],"x-since":"8.16.11"}},"/v4/admin/onboarding/anomalies":{"get":{"tags":["Administration"],"summary":"Onboarding anomalies","description":"**Since v8.16.7** — Things going wrong: FAILED Email Log rows for onboarding mails, v4 register failures/rollbacks, approved invitees with 3 reminders exhausted who never joined, and unverified accounts whose verification code expired and was never resent. excludeTest (default true) drops rows belonging to E2E test accounts, using the same prefix rule as /funnel and /journeys — register failures are matched on the addresses named in the activity text.","operationId":"anomalies","parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":7}},{"name":"excludeTest","in":"query","required":false,"schema":{"type":"boolean","default":true}}],"responses":{"200":{"description":"Anomaly report","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Admin privileges required","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"onboarding.anomalies","description":"Onboarding anomalies: failures across the funnel"}],"x-since":"8.16.7"}},"/v4/admin/logs":{"get":{"tags":["Administration"],"summary":"Get activity logs (v4 admin)","description":"**Since v7.0.55** — Returns recent activity log entries. v4 replacement for the deprecated GET /v2/admin/logs.","operationId":"getActivityLogs","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20}},{"name":"userId","in":"query","required":false,"schema":{"type":"integer","format":"int64"}},{"name":"email","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"JSON array of ActivityLog objects","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Admin privileges required","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"admin.log.list","description":"Get activity logs (admin)"}],"x-since":"7.0.55"}},"/v4/admin/invitation-history":{"get":{"tags":["Administration"],"summary":"List invite-driven signup history","description":"**Since v7.13.0** — Paginated (20 per page), searchable audit trail of every user who signed up with an invitation code. Each row carries the invitee email, the code used, the code type (personal | admin), the inviter email (em dash for admin codes), and the signup date. The optional 'search' parameter filters server-side across code, inviter email, and invitee email. Newest signups first.","operationId":"list_9","parameters":[{"name":"search","in":"query","required":false,"schema":{"type":"string"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":0}}],"responses":{"200":{"description":"Paged history","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Admin privileges required","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"invitation-history.list","description":"List invite-driven signup history (admin)"}],"x-since":"7.13.0"}},"/v4/admin/emails":{"get":{"tags":["Administration"],"summary":"Get email logs (v4 admin)","description":"**Since v7.13.0** — Returns recent email delivery logs with recipient, subject, status, and timestamp.","operationId":"getEmailLogs","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":50}}],"responses":{"200":{"description":"JSON array of EmailLog objects","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Admin privileges required","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"admin.email-log.list","description":"Get email delivery logs (admin)"}],"x-since":"7.13.0"}},"/v4/admin/credits/balances":{"get":{"tags":["Credits"],"summary":"List all Credits balances (admin)","description":"**Since v7.44.0** — Admin view of all users' Credits balances.","operationId":"getAllBalances","responses":{"200":{"description":"Balance list returned","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Admin privileges required","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"admin.credit-balance.list","description":"List all Credits balances (admin)"}],"x-since":"7.44.0"}},"/v3/products/{productId}":{"get":{"tags":["Products"],"summary":"Get a data product (v3)","description":"**Since v3.0.0** — Retrieves a data product by ID. Pass org or orgId for organization products.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"read_4","parameters":[{"name":"productId","in":"path","required":true,"schema":{"type":"string"}},{"name":"version","in":"query","required":false,"schema":{"type":"string"}},{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"ODPS YAML content","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated or not an org member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Product or organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"product.get","description":"Retrieve a data product by ID"}],"x-since":"3.0.0","x-sunset":"2027-01-01"}},"/v3/products/lifecycle":{"get":{"tags":["Lifecycle"],"summary":"Get product lifecycle history (v3)","description":"**Since v3.1.4** — Returns the lifecycle history of a data product. Pass org or orgId to query org-scoped lifecycle entries.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"getProductLifecycle_1","parameters":[{"name":"productId","in":"query","required":true,"schema":{"type":"string"}},{"name":"version","in":"query","required":false,"schema":{"type":"string"}},{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"JSON array of lifecycle entries; each entry carries an `actor` object {userId, email, firstName, lastName} resolved from the recorded user (null when the user no longer exists)","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated or not an org member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"lifecycle.product.list","description":"Get product lifecycle history"}],"x-since":"3.1.4","x-sunset":"2027-01-01"}},"/v3/products/delete-check":{"get":{"tags":["Products"],"summary":"Pre-delete dependency check (v3)","description":"**Since v3.5.0** — Returns prior versions and referenced contracts for a product, so the client can show a comprehensive delete confirmation modal. Read-only — no mutation.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"deleteCheck_2","parameters":[{"name":"productId","in":"query","required":true,"schema":{"type":"string"}},{"name":"version","in":"query","required":true,"schema":{"type":"string"}},{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Delete check result with prior versions and referenced contracts","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated or not an org member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"product.delete-check","description":"Check product dependencies before delete"}],"x-since":"3.5.0","x-sunset":"2027-01-01"}},"/v3/maturity-history":{"get":{"tags":["Maturity History"],"summary":"Get maturity history","description":"**Since v4.3.0** — Returns daily maturity level distribution snapshots for contracts or products. Pass org or orgId for org-scoped data; omit for personal data. Defaults to the last 90 days if from/to are omitted.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"getMaturityHistory_1","parameters":[{"name":"artifactType","in":"query","description":"Artifact type: 'contract' or 'product'","required":true,"schema":{"type":"string"}},{"name":"from","in":"query","description":"Start date (yyyy-MM-dd), defaults to 90 days ago","required":false,"schema":{"type":"string"}},{"name":"to","in":"query","description":"End date (yyyy-MM-dd), defaults to today","required":false,"schema":{"type":"string"}},{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"JSON array of {date, maturityLevel, count} objects","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Invalid artifactType or date format","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated or not an org member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"maturity.history.get","description":"Get maturity distribution history"}],"x-since":"4.3.0","x-sunset":"2027-01-01"}},"/v3/github/verify-access":{"get":{"tags":["Automation"],"summary":"Verify repository access","description":"**Since v3.2.3** — Verifies that the GitHub token has sufficient permissions to access and modify the repository.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"verifyAccess_1","parameters":[{"name":"repoUrl","in":"query","required":false,"schema":{"type":"string"}},{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Access verification result","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"No GitHub token or invalid repo URL","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Not a member of the organization","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}},"502":{"description":"GitHub API error","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"github-action.verify-access","description":"Verify GitHub repository access"}],"x-since":"3.2.3","x-sunset":"2027-01-01"}},"/v3/github/actions/runs":{"get":{"tags":["Automation"],"summary":"Get latest workflow run","description":"**Since v3.2.3** — Returns the status of the latest workflow run.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"getLatestRun_1","parameters":[{"name":"repoUrl","in":"query","required":false,"schema":{"type":"string"}},{"name":"workflowFile","in":"query","required":false,"schema":{"type":"string","default":"upload-data-products.yml"}},{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Latest workflow run status","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"No GitHub token or invalid repo URL","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Not a member of the organization","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}},"502":{"description":"GitHub API error","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"github-action.run.get","description":"Get the latest workflow run"}],"x-since":"3.2.3","x-sunset":"2027-01-01"}},"/v3/contracts/{contractId}":{"get":{"tags":["Contracts"],"summary":"Get a data contract (v3)","description":"**Since v3.0.0** — Retrieves a contract by ID in the specified format. Pass org or orgId for organization contracts.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"read_5","parameters":[{"name":"contractId","in":"path","required":true,"schema":{"type":"string"}},{"name":"version","in":"query","required":false,"schema":{"type":"string"}},{"name":"format","in":"query","required":false,"schema":{"type":"string"}},{"name":"subformat","in":"query","required":false,"schema":{"type":"string"}},{"name":"storage","in":"query","required":false,"schema":{"type":"string","default":"permanent"}},{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Contract in the requested format","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated or not an org member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Contract or organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"contract.get","description":"Get a data contract"}],"x-since":"3.0.0","x-sunset":"2027-01-01"}},"/v3/contracts/supported-databases":{"get":{"tags":["Contracts"],"summary":"List supported JDBC databases (v3)","description":"**Since v3.0.0** — Returns the list of supported database types for JDBC contract creation.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"getSupportedDatabases_1","responses":{"200":{"description":"List of supported database types","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"contract.database.list","description":"List supported JDBC databases"}],"x-since":"3.0.0","x-sunset":"2027-01-01"}},"/v3/contracts/maturity-level":{"get":{"tags":["Contracts"],"summary":"Measure contract maturity level (v3, deprecated)","description":"**Since v3.0.0** — **Deprecated** — use `GET /v4/contracts/maturity-level` instead. Returns a maturity level (1-5) for the specified contract. Pass org or orgId for organization contracts.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"getMaturityLevel_2","parameters":[{"name":"contractId","in":"query","required":true,"schema":{"type":"string"}},{"name":"version","in":"query","required":false,"schema":{"type":"string"}},{"name":"storage","in":"query","required":false,"schema":{"type":"string","default":"permanent"}},{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Maturity assessment result","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated or not an org member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Contract or organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"maturity.get","description":"Measure contract maturity level"}],"x-since":"3.0.0","x-sunset":"2027-01-01"}},"/v3/contracts/lifecycle":{"get":{"tags":["Lifecycle"],"summary":"Get contract lifecycle history (v3)","description":"**Since v3.1.4** — Returns the lifecycle history of a data contract. Pass org or orgId to query org-scoped lifecycle entries.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"getContractLifecycle_1","parameters":[{"name":"contractId","in":"query","required":true,"schema":{"type":"string"}},{"name":"version","in":"query","required":false,"schema":{"type":"string"}},{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"JSON array of lifecycle entries; each entry carries an `actor` object {userId, email, firstName, lastName} resolved from the recorded user (null when the user no longer exists)","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated or not an org member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"lifecycle.contract.list","description":"Get contract lifecycle history"}],"x-since":"3.1.4","x-sunset":"2027-01-01"}},"/v3/contracts/delete-check":{"get":{"tags":["Contracts"],"summary":"Pre-delete dependency check (v3)","description":"**Since v3.4.0** — Returns prior versions and referencing products for a contract, so the client can show a comprehensive delete confirmation modal. Read-only — no mutation.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"deleteCheck_3","parameters":[{"name":"contractId","in":"query","required":true,"schema":{"type":"string"}},{"name":"version","in":"query","required":true,"schema":{"type":"string"}},{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Delete check result with prior versions and referencing products","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated or not an org member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"contract.delete.check","description":"Pre-delete dependency check"}],"x-since":"3.4.0","x-sunset":"2027-01-01"}},"/v3/contracts/compare":{"get":{"tags":["Contracts"],"summary":"Compare two contracts (v3)","description":"**Since v3.0.0** — Compares two data contracts and returns a DiffResult. Pass org or orgId to compare organization contracts.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"compareContracts_1","parameters":[{"name":"id1","in":"query","required":true,"schema":{"type":"string"}},{"name":"version1","in":"query","required":false,"schema":{"type":"string"}},{"name":"storage1","in":"query","required":false,"schema":{"type":"string","default":"permanent"}},{"name":"id2","in":"query","required":true,"schema":{"type":"string"}},{"name":"version2","in":"query","required":false,"schema":{"type":"string"}},{"name":"storage2","in":"query","required":false,"schema":{"type":"string","default":"permanent"}},{"name":"scope","in":"query","required":false,"schema":{"type":"string","default":"all"}},{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"DiffResult JSON with differences and suggested version","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated or not an org member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}},"500":{"description":"Comparison failure","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"contract.compare","description":"Compare two contracts"}],"x-since":"3.0.0","x-sunset":"2027-01-01"}},"/v3/catalogs/properties":{"get":{"tags":["External Catalogs"],"summary":"Discover available properties on a catalog vendor","description":"**Since v4.4.11** — Probes the catalog to discover which properties are available on datasets, fields, and contacts.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"discoverProperties_1","parameters":[{"name":"vendor","in":"query","description":"Catalog vendor","required":true,"schema":{"type":"string"}},{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"catalog.property.list","description":"Discover available properties on a catalog vendor"}],"x-since":"4.4.11","x-sunset":"2027-01-01"}},"/v3/catalogs/datasets":{"get":{"tags":["External Catalogs"],"summary":"List datasets from an external catalog","description":"**Since v4.4.0** — Returns a list of datasets from the specified catalog vendor. Credentials are resolved from the user's or organization's integration settings.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"listDatasets_1","parameters":[{"name":"vendor","in":"query","description":"Catalog vendor (e.g., zeenea)","required":true,"schema":{"type":"string"}},{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Dataset list returned","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Unknown vendor","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Catalog credentials not configured","content":{"*/*":{"schema":{"type":"object"}}}},"502":{"description":"Upstream catalog API error","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"catalog.dataset.list","description":"List datasets from an external catalog"}],"x-since":"4.4.0","x-sunset":"2027-01-01"}},"/v2/users/me/integrations":{"get":{"tags":["Publishing"],"summary":"Get all integration statuses","description":"**Since v2.12.0** — Returns a summary of which integrations are configured for the authenticated user.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"getAllStatuses_2","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"integration.list","description":"List all integration statuses"}],"x-since":"2.12.0","x-sunset":"2027-01-01"}},"/v2/users/me/integrations/{key}/status":{"get":{"tags":["Publishing"],"summary":"Get integration status","description":"**Since v2.12.0** — Returns non-secret config, configured boolean, and last test result for the specified integration.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"getStatus_2","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"integration.get","description":"Get a single integration status"}],"x-since":"2.12.0","x-sunset":"2027-01-01"}},"/v2/products/{productId}":{"get":{"tags":["Products"],"summary":"Get a data product (v2)","description":"**Since v2.2.0** — Deprecated — use GET /v3/products/{productId} instead. Retrieves a data product by ID. Returns full ODPS YAML content.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"read_6","parameters":[{"name":"productId","in":"path","required":true,"schema":{"type":"string"}},{"name":"version","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"ODPS YAML content","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated","content":{"*/*":{"schema":{"type":"object"}}}},"500":{"description":"Product not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"product.get","description":"Retrieve a data product by ID"}],"x-since":"2.2.0","x-sunset":"2027-01-01"}},"/v2/products/lifecycle":{"get":{"tags":["Lifecycle"],"summary":"Get product lifecycle history (v2)","description":"**Since v2.2.0** — Deprecated — use GET /v3/products/lifecycle instead. Requires Bearer JWT.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"getProductLifecycle_2","parameters":[{"name":"productId","in":"query","required":true,"schema":{"type":"string"}},{"name":"version","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"JSON array of lifecycle entries","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"lifecycle.product.list","description":"Get product lifecycle history"}],"x-since":"2.2.0","x-sunset":"2027-01-01"}},"/v2/orgs/{slug}/products/{productId}":{"get":{"tags":["Org Products"],"summary":"Get an organization product","description":"**Since v2.5.0** — Deprecated — use GET /v3/products/{productId}?org={slug} instead. Retrieves a product by ID from the organization.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"read_7","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"productId","in":"path","required":true,"schema":{"type":"string"}},{"name":"version","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"ODPS YAML content","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Not a member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization or product not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"product.get","description":"Retrieve a data product by ID"}],"x-since":"2.5.0","x-sunset":"2027-01-01"}},"/v2/orgs/{slug}/messages":{"get":{"tags":["Membership"],"summary":"List pending messages","description":"**Since v2.5.0** — Admin/owner views pending join requests and invitations.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"listPendingMessages_1","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"List of pending messages","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Insufficient role","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"org.member.message.list","description":"List pending join requests and invitations"}],"x-since":"2.5.0","x-sunset":"2027-01-01"}},"/v2/orgs/{slug}/members":{"get":{"tags":["Membership"],"summary":"List organization members","description":"**Since v2.5.0** — Returns all members of the organization. Requires membership.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"listMembers_1","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"List of members","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Not a member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"org.member.list","description":"List organization members"}],"x-since":"2.5.0","x-sunset":"2027-01-01"}},"/v2/orgs/{slug}/integrations":{"get":{"tags":["Org Settings"],"summary":"Get all org integration statuses","description":"**Since v2.12.0**\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"getAllStatuses_3","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"integration.list","description":"List all org integration statuses"}],"x-since":"2.12.0","x-sunset":"2027-01-01"}},"/v2/orgs/{slug}/integrations/{key}/status":{"get":{"tags":["Org Settings"],"summary":"Get org integration status","description":"**Since v2.12.0**\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"getStatus_3","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"key","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"integration.get","description":"Get a single org integration status"}],"x-since":"2.12.0","x-sunset":"2027-01-01"}},"/v2/orgs/{slug}/contracts/{contractId}":{"get":{"tags":["Org Contracts"],"summary":"Get an organization contract","description":"**Since v2.5.0** — Deprecated — use GET /v3/contracts/{contractId}?org={slug} instead. Retrieves a contract by ID in the specified format from the organization.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"read_8","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"contractId","in":"path","required":true,"schema":{"type":"string"}},{"name":"version","in":"query","required":false,"schema":{"type":"string"}},{"name":"format","in":"query","required":false,"schema":{"type":"string"}},{"name":"subformat","in":"query","required":false,"schema":{"type":"string"}},{"name":"storage","in":"query","required":false,"schema":{"type":"string","default":"permanent"}}],"responses":{"200":{"description":"Contract in requested format","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Not a member","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization or contract not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"contract.get","description":"Get an organization contract"}],"x-since":"2.5.0","x-sunset":"2027-01-01"}},"/v2/orgs/search":{"get":{"tags":["Organizations"],"summary":"Search organizations by name","description":"**Since v2.3.0** — Returns organizations whose name contains the query string (case-insensitive).\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"search_2","parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"List of matching organizations","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"org.search","description":"Search organizations by name"}],"x-since":"2.3.0","x-sunset":"2027-01-01"}},"/v2/orgs/mine":{"get":{"tags":["Organizations"],"summary":"List my organizations","description":"**Since v2.8.0** — Returns all organizations the authenticated user belongs to, with their role in each.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"getMyOrgs_1","responses":{"200":{"description":"List of organizations with membership role","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"org.list","description":"List organizations the caller belongs to"}],"x-since":"2.8.0","x-sunset":"2027-01-01"}},"/v2/orgs/discover":{"get":{"tags":["Organizations"],"summary":"Discover organization by email","description":"**Since v2.3.0** — Finds the organization whose domain matches the given email address.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"discover_1","parameters":[{"name":"email","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Organization found (or empty if no match)","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"org.discover","description":"Find an organization by email domain"}],"x-since":"2.3.0","x-sunset":"2027-01-01"}},"/v2/health":{"get":{"tags":["Administration"],"summary":"Health check (v2)","description":"**Since v2.2.0** — Returns service version info. Authenticated users get extended diagnostics.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"getHealthStatus","parameters":[{"name":"X-TEST","in":"header","required":false,"schema":{"type":"string","default":""}}],"responses":{"200":{"description":"JSON with version info and optional diagnostics","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"x-intent":[{"name":"health.get","description":"Service health and version info"}],"x-since":"2.2.0","x-sunset":"2027-01-01"}},"/v2/github/verify-access":{"get":{"tags":["Automation"],"summary":"Verify repository access (v2)","description":"**Since v2.4.2** — Deprecated — use GET /v3/github/verify-access instead. Requires Bearer JWT.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"verifyAccess_2","parameters":[{"name":"repoUrl","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Access verification result","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"No GitHub token or invalid repo URL","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"502":{"description":"GitHub API error","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"github-action.verify-access","description":"Verify GitHub repository access"}],"x-since":"2.4.2","x-sunset":"2027-01-01"}},"/v2/github/actions/runs":{"get":{"tags":["Automation"],"summary":"Get latest workflow run (v2)","description":"**Since v2.4.2** — Deprecated — use GET /v3/github/actions/runs instead. Requires Bearer JWT.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"getLatestRun_2","parameters":[{"name":"repoUrl","in":"query","required":false,"schema":{"type":"string"}},{"name":"workflowFile","in":"query","required":false,"schema":{"type":"string","default":"upload-data-products.yml"}}],"responses":{"200":{"description":"Latest workflow run status","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"No GitHub token or invalid repo URL","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"502":{"description":"GitHub API error","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"github-action.run.get","description":"Get the latest workflow run"}],"x-since":"2.4.2","x-sunset":"2027-01-01"}},"/v2/credits/transactions":{"get":{"tags":["Credits"],"summary":"Get Credits transactions (v2)","description":"**Since v7.44.0** — Returns the authenticated user's transaction history (paginated).","operationId":"getTransactions_1","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":0}},{"name":"size","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":50}}],"responses":{"200":{"description":"Transaction list returned","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"credit.transaction.list.v2","description":"List the user's Credits transactions (v2)"}],"x-since":"7.44.0"}},"/v2/contracts/{contractId}":{"get":{"tags":["Contracts"],"summary":"Get a data contract (v2)","description":"**Since v2.2.0** — Deprecated — use GET /v3/contracts/{contractId} instead. Retrieves a contract by ID in the specified format.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"read_9","parameters":[{"name":"contractId","in":"path","required":true,"schema":{"type":"string"}},{"name":"version","in":"query","required":false,"schema":{"type":"string"}},{"name":"format","in":"query","required":false,"schema":{"type":"string"}},{"name":"subformat","in":"query","required":false,"schema":{"type":"string"}},{"name":"storage","in":"query","required":false,"schema":{"type":"string","default":"permanent"}}],"responses":{"200":{"description":"Contract in the requested format","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Contract or version not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"contract.get","description":"Get a data contract"}],"x-since":"2.2.0","x-sunset":"2027-01-01"}},"/v2/contracts/maturity-level":{"get":{"tags":["Contracts"],"summary":"Measure contract maturity level (v2)","description":"**Since v2.2.0** — Deprecated — use GET /v3/contracts/maturity-level instead. Returns a maturity level (1-5) for the specified data contract. Pass org (canonical) or orgSlug (legacy) to assess a contract stored in an organization's storage.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"getMaturityLevel_3","parameters":[{"name":"contractId","in":"query","required":true,"schema":{"type":"string"}},{"name":"version","in":"query","required":false,"schema":{"type":"string"}},{"name":"storage","in":"query","required":false,"schema":{"type":"string","default":"permanent"}},{"name":"org","in":"query","description":"Organization slug (canonical). Takes precedence over 'orgSlug' when both are present.","required":false,"schema":{"type":"string"}},{"name":"orgSlug","in":"query","description":"Deprecated — use 'org' instead. Organization slug (legacy parameter, kept for backward compatibility).","required":false,"deprecated":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Maturity assessment result","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated or not a member of the organization","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Contract or organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"maturity.get","description":"Measure contract maturity level"}],"x-since":"2.2.0","x-sunset":"2027-01-01"}},"/v2/contracts/lifecycle":{"get":{"tags":["Lifecycle"],"summary":"Get contract lifecycle history (v2)","description":"**Since v2.2.0** — Deprecated — use GET /v3/contracts/lifecycle instead. Requires Bearer JWT.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"getContractLifecycle_2","parameters":[{"name":"contractId","in":"query","required":true,"schema":{"type":"string"}},{"name":"version","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"JSON array of lifecycle entries","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"lifecycle.contract.list","description":"Get contract lifecycle history"}],"x-since":"2.2.0","x-sunset":"2027-01-01"}},"/v2/contracts/compare":{"get":{"tags":["Contracts"],"summary":"Compare two contracts (v2)","description":"**Since v2.2.0** — Deprecated — use GET /v3/contracts/compare instead. Compares two data contracts and returns a DiffResult. Pass org (canonical) or orgSlug (legacy) to compare contracts stored in an organization's storage.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"compareContracts_2","parameters":[{"name":"id1","in":"query","required":true,"schema":{"type":"string"}},{"name":"version1","in":"query","required":false,"schema":{"type":"string"}},{"name":"storage1","in":"query","required":false,"schema":{"type":"string","default":"permanent"}},{"name":"id2","in":"query","required":true,"schema":{"type":"string"}},{"name":"version2","in":"query","required":false,"schema":{"type":"string"}},{"name":"storage2","in":"query","required":false,"schema":{"type":"string","default":"permanent"}},{"name":"scope","in":"query","required":false,"schema":{"type":"string","default":"all"}},{"name":"org","in":"query","description":"Organization slug (canonical). Takes precedence over 'orgSlug' when both are present.","required":false,"schema":{"type":"string"}},{"name":"orgSlug","in":"query","description":"Deprecated — use 'org' instead. Organization slug (legacy parameter, kept for backward compatibility).","required":false,"deprecated":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"DiffResult JSON with differences and suggested version","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated or not a member of the organization","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}},"500":{"description":"Comparison failure","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"contract.compare","description":"Compare two contracts"}],"x-since":"2.2.0","x-sunset":"2027-01-01"}},"/v2/admin/validate":{"get":{"tags":["Administration"],"summary":"Force-validate a user (v2 admin)","description":"**Since v2.2.2** — Admin force-validates a user account by email, bypassing the validation code.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"forceValidateUser_1","parameters":[{"name":"email","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"User successfully validated (or already validated)","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Admin privileges required","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"User not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"admin.user.validate","description":"Force-validate a user account (admin)"}],"x-since":"2.2.2","x-sunset":"2027-01-01"}},"/v2/admin/users":{"get":{"tags":["Administration"],"summary":"List all users (v2 admin)","description":"**Since v2.2.0** — Returns all registered users with full details.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"listUsers_2","responses":{"200":{"description":"List of AdminUserResponse objects","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Admin privileges required","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"admin.user.list","description":"List all users (admin)"}],"x-since":"2.2.0","x-sunset":"2027-01-01"},"delete":{"tags":["Administration"],"summary":"Delete a user (v2 admin)","description":"**Since v2.2.0** — Deletes a user by email. User data is backed up before deletion.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"deleteUser_1","parameters":[{"name":"email","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"User successfully deleted","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Admin privileges required","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"User not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"admin.user.delete","description":"Delete a user by email (admin)"}],"x-since":"2.2.0","x-sunset":"2027-01-01"}},"/v2/admin/users/active":{"get":{"tags":["Administration"],"summary":"List recently active users (v2 admin, experimental)","description":"**Since v2.2.3** — Returns users who made any API call within the specified time window. Defaults to the last 60 minutes.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"activeUsers_1","parameters":[{"name":"minutes","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":60}}],"responses":{"200":{"description":"List of AdminUserResponse objects for active users","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Admin privileges required","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"admin.user.list-active","description":"List recently active users (admin)"}],"x-since":"2.2.3","x-sunset":"2027-01-01"}},"/v2/admin/signup-requests":{"get":{"tags":["Administration"],"summary":"List signup requests","description":"**Since v2.7.0** — Returns a page of signup requests, optionally filtered by status (pending/approved/rejected).\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"list_10","parameters":[{"name":"status","in":"query","required":false,"schema":{"type":"string"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":0}},{"name":"size","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"Paged list","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Admin privileges required","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"signup-request.list","description":"List signup requests"}],"x-since":"2.7.0","x-sunset":"2027-01-01"}},"/v2/admin/logs":{"get":{"tags":["Administration"],"summary":"Get activity logs (v2 admin) — DEPRECATED","description":"**Since v2.2.0** — Deprecated: use GET /v4/admin/logs. Retained for Workbench v1 (WB); the Workbench webapp (WB2) calls the v4 endpoint.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"getActivityLogs_1","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20}},{"name":"userId","in":"query","required":false,"schema":{"type":"integer","format":"int64"}},{"name":"email","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"JSON array of ActivityLog objects","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Admin privileges required","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"admin.log.list","description":"Get activity logs (admin)"}],"x-since":"2.2.0","x-sunset":"2027-01-01"}},"/v2/admin/invitation-history":{"get":{"tags":["Administration"],"summary":"List invite-driven signup history","description":"**Since v2.15.0** — Paginated (20 per page), searchable audit trail of every user who signed up with an invitation code. Each row carries the invitee email, the code used, the code type (personal | admin), the inviter email (em dash for admin codes), and the signup date. The optional 'search' parameter filters server-side across code, inviter email, and invitee email. Newest signups first.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"list_11","parameters":[{"name":"search","in":"query","required":false,"schema":{"type":"string"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":0}}],"responses":{"200":{"description":"Paged history","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Admin privileges required","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"invitation-history.list","description":"List invite-driven signup history (admin)"}],"x-since":"2.15.0","x-sunset":"2027-01-01"}},"/v2/admin/emails":{"get":{"tags":["Administration"],"summary":"Get email logs (v2 admin)","description":"**Since v2.8.1** — Returns recent email delivery logs with recipient, subject, status, and timestamp.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"getEmailLogs_1","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":50}}],"responses":{"200":{"description":"JSON array of EmailLog objects","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Admin privileges required","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"admin.email-log.list","description":"Get email delivery logs (admin)"}],"x-since":"2.8.1","x-sunset":"2027-01-01"}},"/v2/admin/credits/balances":{"get":{"tags":["Credits"],"summary":"List all Credits balances (v2 admin)","description":"**Since v7.44.0** — Admin view of all users' Credits balances.","operationId":"getAllBalances_1","responses":{"200":{"description":"Balance list returned","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Admin privileges required","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"admin.credit-balance.list.v2","description":"List all Credits balances (v2 admin)"}],"x-since":"7.44.0"}},"/v1/validate":{"get":{"tags":["Users"],"summary":"Validate email address","description":"**Since v1.0.0** — Activates a user account by verifying the 6-character code sent during registration. No authentication required.","operationId":"validateUser","parameters":[{"name":"email","in":"query","required":true,"schema":{"type":"string"}},{"name":"validationCode","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"User successfully validated (or already validated)","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Invalid validation code","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"User not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"ApiKeyAuth":[]},{"PasswordAuth":[]}],"x-intent":[{"name":"user.validate","description":"Validate a user's email address with a code"}],"x-since":"1.0.0"}},"/v1/users/{id}":{"get":{"tags":["Users"],"summary":"Get user by ID","description":"**Since v1.0.0** — Retrieves user information by internal ID. Users can view their own data; admins can view any user.","operationId":"read_10","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"X-API-KEY","in":"header","required":false,"schema":{"type":"string"}},{"name":"X-USER-PASSWORD","in":"header","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"UserResponse with profile details and API key","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Invalid API key or password","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Access denied (not own profile and not admin)","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"User not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"ApiKeyAuth":[]},{"PasswordAuth":[]}],"x-intent":[{"name":"user.get","description":"Get a user by ID"}],"x-since":"1.0.0"}},"/v1/users/profile":{"get":{"tags":["Users"],"summary":"Get user by email","description":"**Since v1.0.0** — Retrieves user information by email address. Users can view their own data; admins can view any user.","operationId":"readByEmail","parameters":[{"name":"email","in":"query","required":true,"schema":{"type":"string"}},{"name":"X-API-KEY","in":"header","required":false,"schema":{"type":"string"}},{"name":"X-USER-PASSWORD","in":"header","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"UserResponse with profile details and API key","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Invalid API key or password","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Access denied (not own profile and not admin)","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"User not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"ApiKeyAuth":[]},{"PasswordAuth":[]}],"x-intent":[{"name":"user.get","description":"Get a user by email"}],"x-since":"1.0.0"}},"/v1/users/key":{"get":{"tags":["Users"],"summary":"Retrieve API key","description":"**Since v1.0.0** — Authenticates with email and password, returns the user's API key. Use this to recover a lost key or as a login equivalent.","operationId":"read_11","parameters":[{"name":"email","in":"query","required":true,"schema":{"type":"string"}},{"name":"X-USER-PASSWORD","in":"header","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"ApiKeyResponse containing the API key","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Invalid email or password","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"ApiKeyAuth":[]},{"PasswordAuth":[]}],"x-since":"1.0.0"}},"/v1/tags/cloud":{"get":{"tags":["Tags"],"summary":"Get tag cloud (deprecated)","description":"**Since v1.0.0** — **Deprecated** — use `GET /v4/tags` instead. Returns all tags across contracts and products with their associated artifacts.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"getTagCloud_1","parameters":[{"name":"X-API-KEY","in":"header","required":false,"schema":{"type":"string"}},{"name":"X-USER-PASSWORD","in":"header","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Tag cloud data","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Invalid API key or password","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"ApiKeyAuth":[]},{"PasswordAuth":[]}],"x-intent":[{"name":"tag-cloud.get","description":"Get the tag cloud"}],"x-since":"1.0.0","x-sunset":"2027-01-01"}},"/v1/products/{productId}":{"get":{"tags":["Products"],"summary":"Get a data product","description":"**Since v1.0.0** — Retrieves a data product by ID. If no version is specified, the latest version is returned. Returns the full ODPS YAML content.","operationId":"read_12","parameters":[{"name":"productId","in":"path","required":true,"schema":{"type":"string"}},{"name":"version","in":"query","required":false,"schema":{"type":"string"}},{"name":"X-API-KEY","in":"header","required":false,"schema":{"type":"string"}},{"name":"X-USER-PASSWORD","in":"header","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"ODPS YAML content as text","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Invalid API key or password","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated","content":{"*/*":{"schema":{"type":"object"}}}},"500":{"description":"Product not found or retrieval error","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"ApiKeyAuth":[]},{"PasswordAuth":[]}],"x-intent":[{"name":"product.get","description":"Retrieve a data product by ID"}],"x-since":"1.0.0"}},"/v1/products/{productId}/verify-signature":{"get":{"tags":["Verification"],"summary":"Verify signature on a stored product (public)","description":"**Since v4.4.32** — Verifies the digital signature embedded in the specified product. No authentication required.","operationId":"verifyProduct_1","parameters":[{"name":"productId","in":"path","required":true,"schema":{"type":"string"}},{"name":"version","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object"}}}}},"x-intent":[{"name":"signature.verify","description":"Verify signature on a stored product"}],"x-since":"4.4.32"}},"/v1/products/lifecycle":{"get":{"tags":["Lifecycle"],"summary":"Get product lifecycle history","description":"**Since v1.0.0** — Returns the lifecycle history of a data product, including status changes and deletion events.","operationId":"getProductLifecycle_3","parameters":[{"name":"productId","in":"query","required":true,"schema":{"type":"string"}},{"name":"version","in":"query","required":false,"schema":{"type":"string"}},{"name":"X-API-KEY","in":"header","required":false,"schema":{"type":"string"}},{"name":"X-USER-PASSWORD","in":"header","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"JSON array of lifecycle entries; each entry carries an `actor` object {userId, email, firstName, lastName} resolved from the recorded user (null when the user no longer exists)","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Invalid API key or password","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"ApiKeyAuth":[]},{"PasswordAuth":[]}],"x-intent":[{"name":"lifecycle.product.list","description":"Get product lifecycle history"}],"x-since":"1.0.0"}},"/v1/logs":{"get":{"tags":["Administration"],"summary":"Get activity logs (admin only, deprecated)","description":"**Since v1.0.0** — **Deprecated** — use `GET /v4/admin/logs` instead. Returns recent activity log entries. Use 'limit' to control count, 'userId' or 'email' to filter by user.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"getActivityLogs_2","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20}},{"name":"userId","in":"query","required":false,"schema":{"type":"integer","format":"int64"}},{"name":"email","in":"query","required":false,"schema":{"type":"string"}},{"name":"X-API-KEY","in":"header","required":false,"schema":{"type":"string"}},{"name":"X-USER-PASSWORD","in":"header","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"JSON array of ActivityLog objects","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Invalid API key or password","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Admin privileges required","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"User not found (when filtering by email)","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"ApiKeyAuth":[]},{"PasswordAuth":[]}],"x-intent":[{"name":"activity-log.list","description":"Get recent activity logs (admin only)"}],"x-since":"1.0.0","x-sunset":"2027-01-01"}},"/v1/health":{"get":{"tags":["Administration"],"summary":"Health check","description":"**Since v1.0.0** — Returns service version info and status. Without authentication, returns basic version info. With authentication, admins get extended diagnostics (deployment time, database status, environment, classpath). Optional X-TEST header for diagnostic modes: html, pdf, richpdf.","operationId":"getHealthStatus_1","parameters":[{"name":"X-TEST","in":"header","required":false,"schema":{"type":"string","default":""}},{"name":"X-API-KEY","in":"header","required":false,"schema":{"type":"string","default":""}},{"name":"X-USER-PASSWORD","in":"header","required":false,"schema":{"type":"string","default":""}}],"responses":{"200":{"description":"JSON with version info (all callers) and extended diagnostics (admins). Test modes return HTML or PDF.","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Invalid API key or password (only when headers are provided)","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated","content":{"*/*":{"schema":{"type":"object"}}}},"500":{"description":"Error during diagnostic test mode","content":{"*/*":{"schema":{"type":"object"}}}}},"x-intent":[{"name":"health.get","description":"Service health and version info"}],"x-since":"1.0.0"}},"/v1/github/verify-access":{"get":{"tags":["Automation"],"summary":"Verify repository access","description":"**Since v1.0.0** — Verifies that the GitHub token has sufficient permissions to access and modify the repository.","operationId":"verifyAccess_3","parameters":[{"name":"repoUrl","in":"query","required":false,"schema":{"type":"string"}},{"name":"X-API-KEY","in":"header","required":false,"schema":{"type":"string"}},{"name":"X-USER-PASSWORD","in":"header","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"ApiKeyAuth":[]},{"PasswordAuth":[]}],"x-intent":[{"name":"github-action.verify-access","description":"Verify GitHub repository access"}],"x-since":"1.0.0"}},"/v1/github/actions/runs":{"get":{"tags":["Automation"],"summary":"Get latest workflow run","description":"**Since v1.0.0** — Returns the status of the latest workflow run.","operationId":"getLatestRun_3","parameters":[{"name":"repoUrl","in":"query","required":false,"schema":{"type":"string"}},{"name":"workflowFile","in":"query","required":false,"schema":{"type":"string","default":"upload-data-products.yml"}},{"name":"X-API-KEY","in":"header","required":false,"schema":{"type":"string"}},{"name":"X-USER-PASSWORD","in":"header","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"ApiKeyAuth":[]},{"PasswordAuth":[]}],"x-intent":[{"name":"github-action.run.get","description":"Get the latest workflow run"}],"x-since":"1.0.0"}},"/v1/contracts/{contractId}":{"get":{"tags":["Contracts"],"summary":"Get a data contract","description":"**Since v1.0.0** — Retrieves a contract by ID in the specified format. If no version is given, the latest is returned.\n\n**Available formats (via `format` query parameter):**\n| format | Content-Type | Description |\n|--------|-------------|-------------|\n| `FULL` (default) | `application/x-yaml` | Complete ODCS YAML contract |\n| `HEADER` | `application/json` | Metadata only (id, version, name, domain, tenant, status) |\n| `DDL` | `text/plain` | SQL DDL (requires `subformat=PostgreSQL`) |\n| `PDF` | `application/pdf` | Basic PDF rendering of the contract |\n| `PrettyPDF` | `application/pdf` | Branded PDF with user's logo and custom PDF settings |\n","operationId":"read_13","parameters":[{"name":"contractId","in":"path","description":"Contract identifier (UUID)","required":true,"schema":{"type":"string"},"example":"34cae6d7-7648-38b2-8f66-8db79e1e2ce4"},{"name":"version","in":"query","description":"Semantic version (e.g. \"1.0.0\"). Omit for latest version.","required":false,"schema":{"type":"string"},"example":"1.0.0"},{"name":"format","in":"query","description":"Output format for the contract.","required":false,"schema":{"type":"string","enum":["FULL","HEADER","DDL","PDF","PrettyPDF"]}},{"name":"subformat","in":"query","description":"SQL dialect. Required when format=DDL. Currently only \"PostgreSQL\" is supported.","required":false,"schema":{"type":"string","enum":["PostgreSQL"]}},{"name":"storage","in":"query","description":"Storage location","required":false,"schema":{"type":"string","enum":["permanent","temporary"]}},{"name":"X-API-KEY","in":"header","required":false,"schema":{"type":"string"}},{"name":"X-USER-PASSWORD","in":"header","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Contract in the requested format (YAML, JSON, SQL text, or PDF bytes)","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Unsupported subformat for DDL conversion","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Invalid API key or password","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Contract or version not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"ApiKeyAuth":[]},{"PasswordAuth":[]}],"x-intent":[{"name":"contract.get","description":"Get a data contract"}],"x-since":"1.0.0"},"delete":{"tags":["Contracts"],"summary":"Delete a data contract (path-form)","description":"**Since v7.0.64** — Same as DELETE /v1/contracts but with the contractId in the URL path. `version` is required as a query parameter.","operationId":"deleteByPath","parameters":[{"name":"contractId","in":"path","description":"Contract identifier (UUID)","required":true,"schema":{"type":"string"},"example":"34cae6d7-7648-38b2-8f66-8db79e1e2ce4"},{"name":"version","in":"query","description":"Semantic version (e.g. \"1.0.0\"). Required.","required":true,"schema":{"type":"string"},"example":"1.0.0"},{"name":"X-API-KEY","in":"header","required":false,"schema":{"type":"string"}},{"name":"X-USER-PASSWORD","in":"header","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Contract deleted successfully","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Invalid API key or password","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Contract not found","content":{"*/*":{"schema":{"type":"object"}}}},"409":{"description":"Contract is referenced by one or more data products","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"ApiKeyAuth":[]},{"PasswordAuth":[]}],"x-intent":[{"name":"contract.delete","description":"Delete a data contract (path-form)"}],"x-since":"7.0.64"}},"/v1/contracts/{contractId}/verify-signature":{"get":{"tags":["Verification"],"summary":"Verify signature on a stored contract (public)","description":"**Since v4.4.32** — Verifies the digital signature embedded in the specified contract. No authentication required. The contract must be publicly accessible.","operationId":"verifyContract_1","parameters":[{"name":"contractId","in":"path","required":true,"schema":{"type":"string"}},{"name":"version","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Verification result","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Contract not found","content":{"*/*":{"schema":{"type":"object"}}}}},"x-intent":[{"name":"signature.verify","description":"Verify signature on a stored contract"}],"x-since":"4.4.32"}},"/v1/contracts/supported-databases":{"get":{"tags":["Contracts"],"summary":"List supported JDBC databases","description":"**Since v2.10.2** — Returns the list of database types supported for JDBC-based contract creation, with default port and schema info.","operationId":"getSupportedDatabases_2","responses":{"200":{"description":"List of supported database types","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"ApiKeyAuth":[]},{"PasswordAuth":[]}],"x-intent":[{"name":"contract.database.list","description":"List supported JDBC databases"}],"x-since":"2.10.2"}},"/v1/contracts/maturity-level":{"get":{"tags":["Contracts"],"summary":"Measure contract maturity level (deprecated)","description":"**Since v1.0.0** — **Deprecated** — use `GET /v4/contracts/maturity-level` instead. Returns a maturity level (1-5) and explanation for the specified data contract. If no version is given, the latest is used.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"getMaturityLevel_4","parameters":[{"name":"contractId","in":"query","required":true,"schema":{"type":"string"}},{"name":"version","in":"query","required":false,"schema":{"type":"string"}},{"name":"storage","in":"query","required":false,"schema":{"type":"string","default":"permanent"}},{"name":"X-API-KEY","in":"header","required":false,"schema":{"type":"string"}},{"name":"X-USER-PASSWORD","in":"header","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"JSON with maturityLevel (1-5), maturityLevelLabel, explanation, and nextLevelAdvice","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Invalid API key or password","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Contract or version not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"ApiKeyAuth":[]},{"PasswordAuth":[]}],"x-intent":[{"name":"maturity.get","description":"Measure contract maturity level"}],"x-since":"1.0.0","x-sunset":"2027-01-01"}},"/v1/contracts/lifecycle":{"get":{"tags":["Lifecycle"],"summary":"Get contract lifecycle history","description":"**Since v1.0.0** — Returns the lifecycle history of a data contract, including status changes, maturity assessments, and deletion events.","operationId":"getContractLifecycle_3","parameters":[{"name":"contractId","in":"query","required":true,"schema":{"type":"string"}},{"name":"version","in":"query","required":false,"schema":{"type":"string"}},{"name":"X-API-KEY","in":"header","required":false,"schema":{"type":"string"}},{"name":"X-USER-PASSWORD","in":"header","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"JSON array of lifecycle entries; each entry carries an `actor` object {userId, email, firstName, lastName} resolved from the recorded user (null when the user no longer exists)","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Invalid API key or password","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"ApiKeyAuth":[]},{"PasswordAuth":[]}],"x-intent":[{"name":"lifecycle.contract.list","description":"Get contract lifecycle history"}],"x-since":"1.0.0"}},"/v1/contracts/compare":{"get":{"tags":["Contracts"],"summary":"Compare two contracts","description":"**Since v1.0.0** — Compares two data contracts and returns a DiffResult with differences, semver impact levels (MAJOR/MINOR/PATCH), and a suggested next version.","operationId":"compareContracts_3","parameters":[{"name":"id1","in":"query","required":true,"schema":{"type":"string"}},{"name":"version1","in":"query","required":false,"schema":{"type":"string"}},{"name":"storage1","in":"query","required":false,"schema":{"type":"string","default":"permanent"}},{"name":"id2","in":"query","required":true,"schema":{"type":"string"}},{"name":"version2","in":"query","required":false,"schema":{"type":"string"}},{"name":"storage2","in":"query","required":false,"schema":{"type":"string","default":"permanent"}},{"name":"scope","in":"query","required":false,"schema":{"type":"string","default":"all"}},{"name":"X-API-KEY","in":"header","required":false,"schema":{"type":"string"}},{"name":"X-USER-PASSWORD","in":"header","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"DiffResult JSON with list of differences and suggested version","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Invalid API key or password","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Account not validated","content":{"*/*":{"schema":{"type":"object"}}}},"500":{"description":"File error or comparison failure","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"ApiKeyAuth":[]},{"PasswordAuth":[]}],"x-intent":[{"name":"contract.compare","description":"Compare two contracts"}],"x-since":"1.0.0"}},"/signin":{"get":{"tags":["signin-controller"],"operationId":"showForm","parameters":[{"name":"return","in":"query","required":false,"schema":{"type":"string"}},{"name":"error","in":"query","required":false,"schema":{"type":"string"}},{"name":"email","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/macos-installer":{"get":{"tags":["installer-controller"],"operationId":"macosInstaller","responses":{"200":{"description":"OK","content":{"application/x-sh":{"schema":{"type":"string"}}}}},"x-intent":[{"name":"installer.download","description":"Download the macOS MCP installer script"}]}},"/.well-known/openid-configuration":{"get":{"tags":["oidc-discovery-controller"],"operationId":"openidConfiguration","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":{}}}}}}}},"/v4/orgs/{slug}/messages/{messageId}":{"delete":{"tags":["Membership"],"summary":"Revoke a pending invitation (deprecated slug path)","description":"**Since v7.43.15** — Owner/admin revokes a PENDING invitation. Deprecated — use DELETE /v4/orgs/messages/{messageId} with org/orgId (#651).\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"revokeInvitationBySlug","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"messageId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"Invitation revoked","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Message not found, not pending, or not an invitation","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Insufficient role","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-since":"7.43.15","x-sunset":"2027-01-01"}},"/v4/orgs/{slug}/members/{userId}":{"delete":{"tags":["Membership"],"summary":"Remove a member from the organization (deprecated slug path)","description":"**Since v7.11.0** — Admin/owner removes a member. Cannot remove the last owner. Deprecated — use DELETE /v4/orgs/members/{userId} with org/orgId (#651).\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"removeMemberBySlug","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"userId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"Member removed","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Cannot remove last owner","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Insufficient role","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-since":"7.11.0","x-sunset":"2027-01-01"}},"/v4/orgs/{slug}/members/me":{"delete":{"tags":["Membership"],"summary":"Leave the organization (deprecated slug path)","description":"**Since v7.11.0** — Authenticated user leaves the organization. Cannot leave if last owner. Deprecated — use DELETE /v4/orgs/members/me with org/orgId (#651).\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"leaveOrgBySlug","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Left organization","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Cannot leave as last owner","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-since":"7.11.0","x-sunset":"2027-01-01"}},"/v4/orgs/service-accounts/{id}":{"delete":{"tags":["Service Accounts"],"summary":"Revoke a service account (org-ADMIN only)","description":"**Since v7.34.0** — Sets revoked_at. Token issuance fails immediately; outstanding tokens are rejected on their next call (revocation is re-checked per request).","operationId":"revoke","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Service account revoked","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Caller is not an ADMIN of the org","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization or service account not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"serviceaccount.revoke","description":"Revoke a service account"}],"x-since":"7.34.0"}},"/v4/orgs/messages/{messageId}":{"delete":{"tags":["Membership"],"summary":"Revoke a pending invitation","description":"**Since v7.43.15** — Owner/admin revokes a PENDING invitation so it stops appearing in GET /v4/orgs/messages. Distinct from invitee decline; keeps the row (status REVOKED) for an audit trail. Pass org (slug) or orgId (UUID). Requires ADMIN+ role.","operationId":"revokeInvitation","parameters":[{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"messageId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"Invitation revoked","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Missing org/orgId, message not found, not pending, or not an invitation","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Insufficient role","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"org.invitation.revoke","description":"Revoke a pending organization invitation"}],"x-since":"7.43.15"}},"/v4/orgs/members/{userId}":{"delete":{"tags":["Membership"],"summary":"Remove a member from the organization","description":"**Since v7.26.0** — Admin/owner removes a member. Cannot remove the last owner. Pass org (slug) or orgId (UUID) to select the organization.","operationId":"removeMember","parameters":[{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"userId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"Member removed","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Missing org/orgId parameter or cannot remove last owner","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Insufficient role","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"org.member.remove","description":"Remove a member from the organization"}],"x-since":"7.26.0"}},"/v4/orgs/members/me":{"delete":{"tags":["Membership"],"summary":"Leave the organization","description":"**Since v7.26.0** — Authenticated user leaves the organization. Cannot leave if last owner. Pass org (slug) or orgId (UUID) to select the organization.","operationId":"leaveOrg","parameters":[{"name":"org","in":"query","description":"Organization slug","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","description":"Organization UUID (takes precedence over org)","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Left organization","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Missing org/orgId parameter or cannot leave as last owner","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"org.member.leave","description":"Leave the organization"}],"x-since":"7.26.0"}},"/v4/orgs/agent-providers/{id}":{"delete":{"tags":["Org Agent Providers"],"summary":"Remove an agent provider","description":"**Since v8.6.0** — Removes a registered agent provider. Pass org (slug) or orgId (UUID). Requires ADMIN+ role.","operationId":"remove","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"org","in":"query","required":false,"schema":{"type":"string"}},{"name":"orgId","in":"query","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"204":{"description":"Removed","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Insufficient role","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"org.agents.providers.remove","description":"Remove an agent provider"}],"x-since":"8.6.0"}},"/v4/admin/blocked-domains/{id}":{"delete":{"tags":["Administration"],"summary":"Unblock a domain","description":"**Since v7.13.0** — Removes an email domain from the blocklist.","operationId":"unblockDomain","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"Domain unblocked successfully","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Domain not found","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Admin privileges required","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"BearerAuth":[]}],"x-intent":[{"name":"blocked-domain.delete","description":"Remove an email domain from the blocklist"}],"x-since":"7.13.0"}},"/v2/orgs/{slug}/members/{userId}":{"delete":{"tags":["Membership"],"summary":"Remove a member from the organization","description":"**Since v2.5.0** — Admin/owner removes a member. Cannot remove the last owner.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"removeMember_1","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"userId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"Member removed","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Cannot remove last owner","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Insufficient role","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"org.member.remove","description":"Remove a member from the organization"}],"x-since":"2.5.0","x-sunset":"2027-01-01"}},"/v2/orgs/{slug}/members/me":{"delete":{"tags":["Membership"],"summary":"Leave the organization","description":"**Since v2.5.0** — Authenticated user leaves the organization. Cannot leave if last owner.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"leaveOrg_1","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Left organization","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Cannot leave as last owner","content":{"*/*":{"schema":{"type":"object"}}}},"404":{"description":"Organization not found","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"org.member.leave","description":"Leave the organization"}],"x-since":"2.5.0","x-sunset":"2027-01-01"}},"/v2/admin/blocked-domains/{id}":{"delete":{"tags":["Administration"],"summary":"Unblock a domain","description":"**Since v2.6.0** — Removes an email domain from the blocklist.\n\n_Sunset: 2027-01-01 — this endpoint will be removed at the v8 major bump._","operationId":"unblockDomain_1","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"Domain unblocked successfully","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Domain not found","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Admin privileges required","content":{"*/*":{"schema":{"type":"object"}}}}},"deprecated":true,"security":[{"BearerAuth":[]}],"x-intent":[{"name":"blocked-domain.delete","description":"Remove an email domain from the blocklist"}],"x-since":"2.6.0","x-sunset":"2027-01-01"}}},"components":{"schemas":{"GitHubDefaultsRequest":{"type":"object","description":"Request body for setting GitHub integration defaults","properties":{"defaultRepository":{"type":"string","description":"Default GitHub repository URL for publishing","example":"https://github.com/acme/data-contracts"},"defaultBranch":{"type":"string","description":"Default Git branch for publishing (e.g. main, dev, or any custom branch name)","example":"main"},"defaultCommitMessage":{"type":"string","description":"Default commit message template. Supports placeholders: {{name}}, {{version}}, {{type}}, {{id}}, {{timestamp}}","example":"Update {{type}} {{name}} v{{version}}"},"autoPublish":{"type":"boolean","description":"Automatically publish to GitHub when a contract or product is created/updated","example":false}}},"LifecycleUpdateRequest":{"type":"object","description":"Request body for editing a lifecycle entry comment","properties":{"comment":{"type":"string","description":"The new comment text","example":"Reviewed and approved by data governance team."}}},"TransferOwnershipRequest":{"type":"object","description":"Request body for transferring organization ownership to another member.","properties":{"newOwnerUserId":{"type":"integer","format":"int64","description":"Internal user ID of the new owner. Must be an existing member of the organization.","example":42},"newOwnerEmail":{"type":"string","description":"Email address of the new owner. Must be an existing member of the organization.","example":"newowner@company.com"}}},"DiagnosticsReportRequest":{"type":"object","description":"Inbound diagnostics report from front end","properties":{"type":{"type":"string","description":"Issue type","example":"api_error"},"sequenceNumber":{"type":"integer","format":"int32","description":"Session-local sequence number for ordering","example":3},"timestamp":{"type":"string","description":"Client-side ISO-8601 timestamp","example":"2026-02-27T12:00:00.000Z"},"appVersion":{"type":"string","description":"Workbench app version","example":"0.12.22"},"serverVersion":{"type":"string","description":"Libot API version reported by front end","example":"3.1.0"},"coreLibraryVersion":{"type":"string","description":"Core library version","example":"3.1.16"},"userEmail":{"type":"string","description":"User email (self-reported)","example":"user@example.com"},"errorMessage":{"type":"string","description":"Error message","example":"HTTP 500 Internal Server Error"},"currentUrl":{"type":"string","description":"Page URL where error occurred"},"userAgent":{"type":"string","description":"Browser user agent"},"userComment":{"type":"string","description":"User-provided comment"},"reportType":{"type":"string","description":"automatic or user","example":"automatic"},"payload":{"description":"Full diagnostic payload (JSON object) for Playwright replay"},"provenance":{"type":"string","description":"Client provenance (api, webapp, iosapp)","example":"webapp"},"app":{"type":"string","description":"Application name (bitol, workbench, badge, jyo)","example":"workbench"}}},"JdbcConnectionRequest":{"type":"object","description":"JDBC database connection parameters. Sent as a JSON request body to keep credentials out of URLs.","properties":{"dbType":{"type":"string","description":"Database vendor type","example":"postgresql"},"dbHost":{"type":"string","description":"Database hostname or IP","example":"localhost"},"dbPort":{"type":"integer","format":"int32","description":"Database port (-1 for vendor default)","example":5432},"dbName":{"type":"string","description":"Database name","example":"mydb"},"dbSchema":{"type":"string","description":"Schema name (null for vendor default)","example":"public"},"dbUsername":{"type":"string","description":"Database username","example":"admin"},"dbPassword":{"type":"string","description":"Database password","example":"secret"},"dataSource":{"type":"string","description":"Optional reference to a reusable named data source (#718). When set on a contract-server binding, the inline connection fields are ignored and the connection is resolved from the data-source registry within the caller's scope.","example":"warehouse-prod"}},"required":["dbHost","dbName","dbType"]},"UserUpdateRequest":{"type":"object","description":"Profile update fields. Authentication is via X-API-KEY and X-USER-PASSWORD headers (no password in body).","properties":{"firstName":{"type":"string","description":"Must not contain \"<<\", \">>\", or the word \"name\".","example":"Jean-Georges"},"lastName":{"type":"string","description":"Must not contain \"<<\", \">>\", or the word \"name\".","example":"Perrin"},"company":{"type":"string","description":"Must not contain \"<<\", \">>\" or \"your company\".","example":"Bitol"},"dob":{"type":"string","format":"date","description":"Date of birth (YYYY-MM-DD)","example":"1990-01-01"},"comment":{"type":"string","description":"Must not contain \"<<\" or \">>\".","example":"Updated profile."},"githubToken":{"type":"string","description":"GitHub Personal Access Token for publishing contracts to GitHub. The token is stored securely and never returned in API responses.","example":"ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"},"autoSign":{"type":"boolean","description":"When true, contracts and products are automatically signed before GitHub publish.","example":false}}},"PasswordChangeRequest":{"type":"object","description":"Request body for changing a user's password","properties":{"currentPassword":{"type":"string","description":"Current password. Required for non-admin callers; omit when admin changes another user's password.","example":"oldSecurePassword123"},"newPassword":{"type":"string","description":"New password. Must be at least 8 characters.","example":"newSecurePassword456"}},"required":["newPassword"]},"V2VerifyRequest":{"type":"object","description":"Request body for v2 email verification","properties":{"email":{"type":"string","description":"Email address of the account to verify","example":"user@company.com"},"code":{"type":"string","description":"6-character verification code sent via email","example":"A1B2C3"}},"required":["code","email"]},"UserCreateRequest":{"type":"object","description":"Request body for creating a new user account","properties":{"email":{"type":"string","description":"Must be a valid email format. Must not contain a `+` character. Personal email domains are blocked: gmail.com, yahoo.com, hotmail.com, outlook.com, aol.com, protonmail.com, icloud.com, mail.com, yandex.com, live.com, msn.com, gmx.com, zoho.com, tutanota.com, pm.me.","example":"user@company.com"},"firstName":{"type":"string","description":"Must not contain \"<<\", \">>\", or the word \"name\".","example":"Jane"},"lastName":{"type":"string","description":"Must not contain \"<<\", \">>\", or the word \"name\".","example":"Smith"},"company":{"type":"string","description":"Must not contain \"<<\", \">>\" or \"your company\".","example":"Acme Corp"},"dob":{"type":"string","format":"date","description":"Date of birth (YYYY-MM-DD)","example":"1990-05-15"},"comment":{"type":"string","description":"Must not contain \"<<\" or \">>\".","example":"Data engineering team lead."},"password":{"type":"string","description":"Optional. If omitted, the service generates a password.","example":"mySecurePassword123"},"code":{"type":"string","description":"Optional tracking code (e.g. promotional or referral code).","example":"PROMO2026"},"invitationCode":{"type":"string","description":"Optional Grand Opening invitation code. If set, signup is allowed even when bitol.signup.requires-code is true. Validated case-insensitively against personal and admin codes.","example":"bluedata42"}},"required":["email"]},"TransferItem":{"type":"object","description":"A single artifact to transfer from personal to org storage","properties":{"type":{"type":"string","description":"Artifact type","enum":["contract","product"],"example":"contract"},"id":{"type":"string","description":"Artifact ID (UUID)","example":"34cae6d7-7648-38b2-8f66-8db79e1e2ce4"},"version":{"type":"string","description":"Semantic version","example":"1.0.0"}}},"CreateRequest":{"type":"object","description":"Service-account creation request","properties":{"name":{"type":"string"},"description":{"type":"string"},"scopes":{"type":"array","items":{"type":"string"},"uniqueItems":true}}},"AgentAttachmentDto":{"type":"object","description":"An editor artifact attached to an agent invocation","properties":{"kind":{"type":"string","description":"Artifact kind","enum":["contract","product"],"example":"contract"},"id":{"type":"string","description":"Artifact id (optional)"},"version":{"type":"string","description":"Artifact version (optional)"},"name":{"type":"string","description":"Human-readable artifact name (optional)"},"format":{"type":"string","description":"Content format","enum":["odcs-yaml","odps-yaml"],"example":"odcs-yaml"},"content":{"type":"string","description":"The artifact content (YAML)"},"role":{"type":"string","description":"Role of this attachment relative to the open artifact","enum":["primary","input","output"],"example":"primary"}}},"AgentInvokeRequest":{"type":"object","description":"Send a message to an imported A2A agent via the server-side proxy","properties":{"cardUrl":{"type":"string","description":"cardUrl of the target agent, as returned by GET /v4/orgs/agents","example":"https://quokka.actianlabs.com/agents/smalltalk/.well-known/agent-card.json"},"message":{"type":"string","description":"The user's message text"},"contextId":{"type":"string","description":"Optional A2A contextId to continue a conversation"},"attachments":{"type":"array","description":"Open editor artifact(s) to attach as agent context (svc#985)","items":{"$ref":"#/components/schemas/AgentAttachmentDto"}}}},"AgentProviderRequest":{"type":"object","description":"Register an A2A agent provider (registry URL) for an organization","properties":{"url":{"type":"string","description":"A2A registry discovery URL","example":"https://quokka.actianlabs.com/agents"},"label":{"type":"string","description":"Optional display label","example":"Quokka"},"authToken":{"type":"string","description":"Optional bearer token sent to the provider; stored encrypted, never returned"}}},"CoachInteractionRequest":{"type":"object","description":"One pseudonymous Governance Coach interaction record","properties":{"pseudonymId":{"type":"string","description":"Client-generated random UUID v4 — the only correlation key"},"questionText":{"type":"string","description":"The user's question, verbatim (max 8000 chars)"},"answerText":{"type":"string","description":"The coach's full answer (max 32000 chars)"},"retrievedPaths":{"type":"array","description":"Schema paths / corpus keys the RAG retrieval injected (max 8, 256 chars each)","items":{"type":"string"}},"maturityGaps":{"type":"array","description":"Failing maturity criterion ids at ask-time (max 32, 256 chars each)","items":{"type":"string"}},"artifactKind":{"type":"string","description":"contract | product","example":"contract"},"section":{"type":"string","description":"Editor section active at ask-time (max 128 chars)","example":"fundamentals"},"appVersion":{"type":"string","description":"Client APP_VERSION (max 128 chars)","example":"2.11.0"},"source":{"type":"string","description":"Source application (max 128 chars)","example":"tutor"}},"required":["answerText","artifactKind","pseudonymId","questionText"]},"CrawlImportRequest":{"type":"object","properties":{"repoUrl":{"type":"string"},"branch":{"type":"string"},"folders":{"type":"array","items":{"type":"string"}}}},"SseEmitter":{"type":"object","properties":{"timeout":{"type":"integer","format":"int64"}}},"ContractTestRequest":{"type":"object","description":"Data-contract test-execution request","properties":{"server":{"type":"string","description":"The servers[].server name declared in the contract to test against","example":"production"},"version":{"type":"string","description":"Optional contract version to pin; defaults to the latest","example":"1.0.0"}},"required":["server"]},"ContactSyncRequest":{"type":"object","properties":{"email":{"type":"string"},"name":{"type":"string"},"message":{"type":"string"},"subject":{"type":"string"},"sourcePage":{"type":"string"},"sourceSystem":{"type":"string"},"formName":{"type":"string"},"groups":{"type":"array","items":{"type":"string"}},"submittedAt":{"type":"string"}}},"CommentRequest":{"type":"object","description":"Request body for creating or editing a comment","properties":{"orgId":{"type":"string","description":"Organization UUID (priority over org slug)","example":"a1b2c3d4-e5f6-7890-abcd-ef1234567890"},"org":{"type":"string","description":"Organization slug (alternative to orgId)","example":"oplo-llc"},"artifactKind":{"type":"string","description":"Artifact kind: DataContract or DataProduct","example":"DataContract"},"artifactId":{"type":"string","description":"Artifact UUID","example":"f47ac10b-58cc-4372-a567-0e02b2c3d479"},"artifactVersion":{"type":"string","description":"Artifact version (optional)","example":"v1.0.0"},"anchorType":{"type":"string","description":"Anchor granularity: ARTIFACT, SECTION, or ELEMENT","example":"SECTION"},"anchorSection":{"type":"string","description":"Top-level YAML section name","example":"schema"},"anchorElementId":{"type":"string","description":"Element id within the section"},"parentId":{"type":"string","description":"Parent comment UUID for replies; omit for top-level comments"},"body":{"type":"string","description":"Comment body in Markdown with @[email] mentions","example":"The customer_id field needs a description. @[alice@example.com]! can you add one?"}}},"AiSuggestRequest":{"type":"object","description":"AI text-suggestion request","properties":{"field":{"type":"string","description":"Field to suggest text for; defaults to description","example":"description"},"context":{"type":"string","description":"Surrounding artifact context the model grounds the suggestion in","example":"Contract Name: Sales\nDomain: seller\nSchemas: tbl_sales"},"currentValue":{"type":"string","description":"Existing text to improve; empty for a fresh suggestion"}}},"ResetPasswordRequest":{"type":"object","description":"Request body for completing a password reset with verification code","properties":{"email":{"type":"string","description":"Email address of the account.","example":"user@company.com"},"code":{"type":"string","description":"6-character reset code received via email.","example":"A3F2B1"},"newPassword":{"type":"string","description":"New password. Must be at least 8 characters.","example":"newSecurePassword456"}},"required":["code","email","newPassword"]},"ForgotPasswordRequest":{"type":"object","description":"Request body for initiating a password reset","properties":{"email":{"type":"string","description":"Email address of the account to reset.","example":"user@company.com"}},"required":["email"]},"Rfc7591RegistrationRequest":{"type":"object","properties":{"client_name":{"type":"string"},"redirect_uris":{"type":"array","items":{"type":"string"}},"token_endpoint_auth_method":{"type":"string"},"grant_types":{"type":"array","items":{"type":"string"}},"response_types":{"type":"array","items":{"type":"string"}},"scope":{"type":"string"}}},"DiagnosticsResolveRequest":{"type":"object","description":"Request to resolve or reopen a diagnostics report","properties":{"resolved":{"type":"boolean","description":"true to resolve, false to reopen","example":true},"email":{"type":"string","description":"Admin email performing the action","example":"admin@example.com"},"comment":{"type":"string","description":"Optional comment for the resolution log"}}},"PdfSettingsResponse":{"type":"object","description":"The page size and footer a workspace renders its branded PDFs with.","properties":{"size":{"type":"string","description":"Saved page size.","enum":["letter","a4"],"example":"letter"},"footer":{"type":"string","description":"The footer the workspace explicitly set, or null when it has never set one — blank, absent, or still the string the platform shipped. A client should render null as an empty field meaning \"use the automatic workspace copyright\".","example":"Confidential — internal use only"},"effectiveFooter":{"type":"string","description":"The footer actually printed on this workspace's PDFs today. When 'footer' is null this is the automatic copyright built from the workspace owner's name; it is empty when no owner can be identified. Read-only.","example":"Copyright © 2026, Rotten Tometrics, Inc."}}},"MeResponse":{"type":"object","description":"The authenticated user's profile, resolved from the bearer JWT.","properties":{"id":{"type":"integer","format":"int64","description":"Internal numeric user id"},"email":{"type":"string","description":"User email address"},"firstName":{"type":"string","description":"Given name, may be null"},"lastName":{"type":"string","description":"Family name, may be null"},"displayName":{"type":"string","description":"Human-friendly name for the UI greeting — never a UUID"},"isAdmin":{"type":"boolean","description":"Whether the user has platform-admin rights"},"company":{"type":"string","description":"Company name, may be null"},"hasGithubToken":{"type":"boolean","description":"Whether a GitHub token is stored for this user"}}},"ApiKeyResponse":{"type":"object","description":"Response containing the user's API key","properties":{"apiKey":{"type":"string","description":"The user's API key","example":"e7d151da-75e8-40ac-80e8-9e197ed91d61"},"admin":{"type":"boolean","description":"Only present when true. Omitted for non-admin users.","example":true}}},"ActivityLog":{"type":"object","description":"An entry in the activity audit log","properties":{"id":{"type":"integer","format":"int64","example":1042},"userId":{"type":"integer","format":"int64","description":"Associated user ID (null for unauthenticated actions)","example":1},"action":{"type":"string","description":"Human-readable action description (truncated to 254 chars)","example":"User authenticated for ODCS contract upload."},"activityType":{"type":"string","description":"Type of activity recorded in the audit log","enum":["WRONG_RIGHTS","ADMIN_CALL","WRONG_KEY","CREATE_CONTRACT","INFO","ERROR","ERROR_USER","WARNING_SECURITY","CREATE_USER","UPDATE_USER","READ_KEY","INFO_INCOMING_REQUEST","CREATE_PRODUCT","WRONG_PASSWORD","READ_PRODUCT","COMPARE_CONTRACT","DELETE_CONTRACT","DELETE_PRODUCT","SERVER_RESTART","CREDIT_DEDUCT","CREDIT_GRANT","CREDIT_REDEEM","LIST_REFERENCE_TAGS","CREATE_REFERENCE_TAG","UPDATE_REFERENCE_TAG","DELETE_REFERENCE_TAG","V2_REGISTER","V2_VERIFY","V2_LOGIN","V2_REFRESH","V2_ERROR","KEYCLOAK_MIGRATION","CHANGE_PASSWORD","PASSWORD_RESET","ORG_JOIN_REQUEST","ORG_INVITE","ORG_APPROVE","ORG_REJECT","ORG_ACCEPT","ORG_DECLINE","ORG_INVITE_RESEND","ORG_INVITE_REVOKE","ORG_MEMBER_ROLE_CHANGE","ORG_MEMBER_REMOVE","ORG_MEMBER_LEAVE","ORG_TRANSFER_OWNERSHIP","USER_DELETE_BLOCKED_SOLE_OWNER","ORG_CONTRACT_UPLOAD","ORG_PRODUCT_UPLOAD","ORG_ARTIFACT_TRANSFER","OAUTH_REGISTER_SUCCESS","OAUTH_REGISTER_FAILURE","OAUTH_AUTHORIZE_SUCCESS","OAUTH_AUTHORIZE_FAILURE","OAUTH_TOKEN_SUCCESS","OAUTH_TOKEN_FAILURE"],"example":"CREATE_CONTRACT"},"timestamp":{"type":"string","format":"date-time","example":"2026-02-07T10:30:00"},"apiKey":{"type":"string","description":"API key associated with the action","example":"e7d151da-75e8-40ac-80e8-9e197ed91d61"},"apiVersion":{"type":"string","description":"API version used for the call (v1 or v2)","example":"v1"},"activityTypeAsString":{"type":"string"}}},"ArtifactHeader":{"type":"object","description":"Unified artifact header (contract or product)","properties":{"id":{"type":"string","description":"Artifact ID (UUID for products, slug/UUID for contracts)"},"kind":{"type":"string","description":"Artifact kind","enum":["contract","product"]},"name":{"type":"string","description":"Display name"},"version":{"type":"string","description":"Semantic version (e.g., 1.0.0)"},"status":{"type":"string","description":"Lifecycle status (e.g., draft, active, deprecated)"},"domain":{"type":"string","description":"Domain the artifact belongs to (free-form)"},"owner":{"type":"string","description":"Owner / tenant identifier"},"updated":{"type":"string","description":"ISO-8601 last-updated timestamp, when available"},"tags":{"type":"array","description":"Free-form tags from the artifact YAML","items":{"type":"string"}},"maturityLevel":{"type":"integer","format":"int32","description":"Maturity level (null when no assessment is available)"},"maturityLevelLabel":{"type":"string","description":"Maturity level label (null when no assessment is available)"},"org":{"type":"string","description":"Org slug the artifact lives in (null = personal storage)"},"commentCount":{"type":"integer","format":"int32","description":"Number of unresolved top-level comment threads. Always 0 for personal artifacts, since comments are an org-scoped feature."},"signed":{"type":"boolean","description":"True when the artifact carries a signature block"},"signedAt":{"type":"string","description":"ISO-8601 signing timestamp (null when unsigned)"},"signerName":{"type":"string","description":"Signer display name (null when unsigned or not recorded)"},"autosign":{"type":"boolean","description":"Per-artifact auto-sign opt-out (#855/#864): false when the document carries customProperties autosign=false (stamped by an unsign; cleared by a manual sign). Null when the artifact never opted out."},"certificateFingerprint":{"type":"string","description":"Leaf-certificate SHA-256 fingerprint of the signature (null when unsigned or the signature could not be read)"},"signatureValid":{"type":"boolean","description":"Signature validity: true = verified, false = invalid/tampered, null = unsigned (no crypto run)"},"syncStatus":{"type":"string","description":"Latest Zeenea sync status for this version: success | failed (null when never synced) (#758)"},"syncedAt":{"type":"string","description":"ISO-8601 timestamp of the latest Zeenea sync (null when never synced)"},"syncUploadId":{"type":"string","description":"Dispatcher upload id of the latest sync (null when absent)"},"syncError":{"type":"string","description":"Failure message from the latest Zeenea sync (null unless it failed)"}}},"ArtifactListResponse":{"type":"object","description":"Unified artifact listing: header rows plus a total count","properties":{"items":{"type":"array","description":"The caller's artifact headers across personal + every org they belong to","items":{"$ref":"#/components/schemas/ArtifactHeader"}},"total":{"type":"integer","format":"int32","description":"Number of headers in items (== items.length)"}}}},"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","description":"UUID API key obtained during registration","name":"X-API-KEY","in":"header"},"PasswordAuth":{"type":"apiKey","description":"User's plaintext password","name":"X-USER-PASSWORD","in":"header"},"BearerAuth":{"type":"http","description":"Bearer JWT token from Keycloak. Used by v2 endpoints.","scheme":"bearer","bearerFormat":"JWT"}}}}