{"openapi":"3.1.0","info":{"title":"NovumOS","description":"Block-based kanban where agents are first-class users.","version":"0.0.0"},"paths":{"/v1/auth/google/start":{"get":{"tags":["auth"],"summary":"Google Start","operationId":"google_start_v1_auth_google_start_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/v1/auth/google/callback":{"get":{"tags":["auth"],"summary":"Google Callback","description":"Complete the Authorization-Code + PKCE flow Google bounced back to us.\n\nSpec §4.1.1. Every failure path is a ``302`` to the SPA login with an\n``?oauth_error=`` reason (never a JSON error body) so the user lands\nsomewhere usable. On success we mint the same session state as the\nemail/password path and bounce to ``{app_base_url}{return_to}``.\n\nCSRF is intentionally *not* enforced on this GET — the signed, single-use\n``state`` carried in the ``novumos_oauth`` flow cookie is the CSRF defense.","operationId":"google_callback_v1_auth_google_callback_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/v1/auth/csrf":{"get":{"tags":["auth"],"summary":"Csrf Token","description":"Issue a CSRF token cookie (double-submit). Safe to call before login.","operationId":"csrf_token_v1_auth_csrf_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":{"type":"string"},"type":"object","title":"Response Csrf Token V1 Auth Csrf Get"}}}}},"parameters":[{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}]}},"/v1/auth/signup":{"post":{"tags":["auth"],"summary":"Signup","operationId":"signup_v1_auth_signup_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignupRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"parameters":[{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}]}},"/v1/auth/verify-email":{"post":{"tags":["auth"],"summary":"Verify Email","operationId":"verify_email_v1_auth_verify_email_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyEmailRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthSessionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"parameters":[{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}]}},"/v1/auth/login":{"post":{"tags":["auth"],"summary":"Login","operationId":"login_v1_auth_login_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthSessionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"parameters":[{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}]}},"/v1/auth/logout":{"post":{"tags":["auth"],"summary":"Logout","operationId":"logout_v1_auth_logout_post","responses":{"204":{"description":"Successful Response"}},"parameters":[{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}]}},"/v1/auth/password-reset/request":{"post":{"tags":["auth"],"summary":"Password Reset Request","operationId":"password_reset_request_v1_auth_password_reset_request_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PasswordResetRequest"}}},"required":true},"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"parameters":[{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}]}},"/v1/auth/password-reset/confirm":{"post":{"tags":["auth"],"summary":"Password Reset Confirm","operationId":"password_reset_confirm_v1_auth_password_reset_confirm_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PasswordResetConfirmRequest"}}},"required":true},"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"parameters":[{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}]}},"/v1/auth/resend-verification":{"post":{"tags":["auth"],"summary":"Resend Verification","operationId":"resend_verification_v1_auth_resend_verification_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResendVerificationRequest"}}},"required":true},"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"parameters":[{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}]}},"/v1/me":{"get":{"tags":["me"],"summary":"Get Me","operationId":"get_me_v1_me_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserResponse"}}}}},"security":[{"IntegrationToken":[]}],"parameters":[{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}]}},"/v1/me/memberships":{"get":{"tags":["me"],"summary":"List My Memberships","operationId":"list_my_memberships_v1_me_memberships_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_MembershipResponse_"}}}}},"security":[{"IntegrationToken":[]}],"parameters":[{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}]}},"/v1/me/profile":{"get":{"tags":["me"],"summary":"Get My Profile","operationId":"get_my_profile_v1_me_profile_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserProfileResponse"}}}}},"security":[{"IntegrationToken":[]}],"parameters":[{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}]},"patch":{"tags":["me"],"summary":"Update My Profile","operationId":"update_my_profile_v1_me_profile_patch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateProfileRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserProfileResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}],"parameters":[{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}]}},"/v1/me/password":{"post":{"tags":["me"],"summary":"Change My Password","operationId":"change_my_password_v1_me_password_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChangePasswordRequest"}}},"required":true},"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}],"parameters":[{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}]}},"/v1/me/password/set":{"post":{"tags":["me"],"summary":"Set My Initial Password","operationId":"set_my_initial_password_v1_me_password_set_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetPasswordRequest"}}},"required":true},"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}],"parameters":[{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}]}},"/v1/me/sessions":{"get":{"tags":["me"],"summary":"List My Sessions","operationId":"list_my_sessions_v1_me_sessions_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_UserSessionResponse_"}}}}},"security":[{"IntegrationToken":[]}],"parameters":[{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}]},"delete":{"tags":["me"],"summary":"Revoke All My Sessions","operationId":"revoke_all_my_sessions_v1_me_sessions_delete","responses":{"204":{"description":"Successful Response"}},"security":[{"IntegrationToken":[]}],"parameters":[{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}]}},"/v1/me/sessions/{session_id}":{"delete":{"tags":["me"],"summary":"Revoke My Session","operationId":"revoke_my_session_v1_me_sessions__session_id__delete","parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Session Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/me/preferences":{"get":{"tags":["me"],"summary":"Get My Preferences","operationId":"get_my_preferences_v1_me_preferences_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserPreferencesResponse"}}}}},"security":[{"IntegrationToken":[]}],"parameters":[{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}]},"patch":{"tags":["me"],"summary":"Update My Preferences","operationId":"update_my_preferences_v1_me_preferences_patch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdatePreferencesRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserPreferencesResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}],"parameters":[{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}]}},"/v1/notifications":{"get":{"tags":["notifications"],"summary":"Get Notifications","description":"List the caller's notifications, newest first (spec §22.2).","operationId":"get_notifications_v1_notifications_get","parameters":[{"name":"org_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Org Id"}},{"name":"unread","in":"query","required":false,"schema":{"type":"boolean","description":"Only return unread notifications.","default":false,"title":"Unread"},"description":"Only return unread notifications."},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":25,"title":"Page Size"}},{"name":"start_cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Start Cursor"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Notifications V1 Notifications Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/notifications/count":{"get":{"tags":["notifications"],"summary":"Get Unread Count","description":"Unread notification count for the caller (spec §22.2).","operationId":"get_unread_count_v1_notifications_count_get","parameters":[{"name":"org_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Org Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnreadCountResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/notifications/{notification_id}:read":{"post":{"tags":["notifications"],"summary":"Mark Notification Read","description":"Mark one of the caller's notifications read. 404 if it isn't theirs.","operationId":"mark_notification_read_v1_notifications__notification_id__read_post","parameters":[{"name":"notification_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Notification Id"}},{"name":"org_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Org Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotificationResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/notifications:readAll":{"post":{"tags":["notifications"],"summary":"Mark All Notifications Read","description":"Mark every unread notification for the caller read (spec §22.2).","operationId":"mark_all_notifications_read_v1_notifications_readAll_post","parameters":[{"name":"org_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Org Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Mark All Notifications Read V1 Notifications Readall Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/feedback":{"post":{"tags":["feedback"],"summary":"Submit Feedback","description":"Submit one feedback report (spec §25.4).\n\nThe share-link refusal, the workspace resolution and the hourly caps all run\nin ``require_submit_context`` — a dependency, so they run before the body is\nvalidated (see the module docstring). It hands back the resolved ``org_id``,\nwhich is what the row is stamped with.\n\n``surface`` is derived from HOW the caller authenticated, not claimed by\nthem: an integration token is the ``api`` surface, a browser session is\n``web``. (``mcp`` is set by the §25.11 tools.)","operationId":"submit_feedback_v1_feedback_post","parameters":[{"name":"org_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"description":"The workspace this call acts in. Browser sessions may name any org the user is a live member of; integration tokens stay pinned to their own.","title":"Org Id"},"description":"The workspace this call acts in. Browser sessions may name any org the user is a live member of; integration tokens stay pinned to their own."},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateFeedbackRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FeedbackResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]},"get":{"tags":["feedback"],"summary":"List Own Feedback","description":"List the caller's OWN submissions, newest first (spec §25.4).","operationId":"list_own_feedback_v1_feedback_get","parameters":[{"name":"type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by feedback type.","title":"Type"},"description":"Filter by feedback type."},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by triage status.","title":"Status"},"description":"Filter by triage status."},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":25,"title":"Page Size"}},{"name":"start_cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Start Cursor"}},{"name":"org_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"description":"The workspace this call acts in. Browser sessions may name any org the user is a live member of; integration tokens stay pinned to their own.","title":"Org Id"},"description":"The workspace this call acts in. Browser sessions may name any org the user is a live member of; integration tokens stay pinned to their own."},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response List Own Feedback V1 Feedback Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/feedback/screenshots:presign":{"post":{"tags":["feedback"],"summary":"Presign Feedback Screenshot","description":"Mint a presigned POST for a feedback screenshot (spec §25.4).\n\nBody: ``{filename, content_type, size_bytes?}``. Returns the standard file\nenvelope plus ``upload_url`` + ``upload_url_fields`` + ``upload_url_method``\n(POST — the multipart form is what carries the ``content-length-range``\npolicy). The client posts the bytes straight to S3, calls\n``POST /v1/feedback/screenshots/{id}:commit`` below to flip the row to\n``available``, and then passes the id as ``screenshot_file_id`` on\n``POST /v1/feedback``.\n\nOrdering is ``submit_feedback``'s, because it is the same dependency: the\nshare-link refusal, the workspace resolution and the hourly cap all run in\n``require_screenshot_presign_context`` — before the body is validated, which\nis what makes the cap count malformed requests too.\n\nThe ``org_id`` the row is stamped with is the one the dependency RESOLVED,\nnot ``principal.org_id``. ``?org_id=`` hints are honored here as everywhere\non this router, so the principal's org is the cookie's possibly-stale active\nworkspace; stamping from it would file the object under one org while the\nrequest ran scoped to another.","operationId":"presign_feedback_screenshot_v1_feedback_screenshots_presign_post","parameters":[{"name":"org_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"description":"The workspace this call acts in. Browser sessions may name any org the user is a live member of; integration tokens stay pinned to their own.","title":"Org Id"},"description":"The workspace this call acts in. Browser sessions may name any org the user is a live member of; integration tokens stay pinned to their own."},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateFeedbackScreenshotUploadRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Presign Feedback Screenshot V1 Feedback Screenshots Presign Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/feedback/screenshots/{file_id}:commit":{"post":{"tags":["feedback"],"summary":"Commit Feedback Screenshot","description":"Finalize a feedback screenshot upload (spec §25.4, NOV-442 review F1).\n\nThe screenshot's own commit rather than the shared ``POST\n/v1/files/{id}:commit``, because the two legs of one chain have to agree\nabout which workspace they are in. The presign resolves ``?org_id=`` and\nstamps the row with the SELECTED workspace; the shared route resolves its\norg from ``principal.org_id``, which for a browser session is the cookie's\npossibly-stale active org. For a multi-workspace user those differ, and the\nchain died at this step — presign 201 in B, commit 404 in A, the row left\n``pending`` forever with its object orphaned in S3. Mounting the commit on\n``/v1/feedback/*`` puts it behind the same resolution as its siblings, so\nthe disagreement cannot arise.\n\nThe alternative — teaching the shared route to take the hint — was\ndeliberately not taken: it would extend ``?org_id=`` workspace selection\nover the entire file surface to fix one route. This one accepts the hint\nonly for rows the feedback presign minted (anything else is a 404, in\n:func:`app.services.files.commit_feedback_screenshot_for_principal`).\n\nRate limit: its own ``feedback_upload_commit`` per-user window — see\n``require_screenshot_commit_context`` for why it is a third key rather than\na second charge against the presign's.\n\nPast_due: this path is the §25.4 carve-out from the §18.8 write-block, and\nsince NOV-442's review it is the ONLY commit path that carries one. The\nshared route went back to being blocked for every producer, screenshots\nincluded — a read-only workspace finishes its screenshot here.","operationId":"commit_feedback_screenshot_v1_feedback_screenshots__file_id__commit_post","parameters":[{"name":"file_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"File Id"}},{"name":"org_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"description":"The workspace this call acts in. Browser sessions may name any org the user is a live member of; integration tokens stay pinned to their own.","title":"Org Id"},"description":"The workspace this call acts in. Browser sessions may name any org the user is a live member of; integration tokens stay pinned to their own."},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Commit Feedback Screenshot V1 Feedback Screenshots  File Id  Commit Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/feedback/{feedback_id}":{"get":{"tags":["feedback"],"summary":"Get Own Feedback","description":"One of the caller's own submissions. Someone else's → 404, never 403.","operationId":"get_own_feedback_v1_feedback__feedback_id__get","parameters":[{"name":"feedback_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Feedback Id"}},{"name":"org_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"description":"The workspace this call acts in. Browser sessions may name any org the user is a live member of; integration tokens stay pinned to their own.","title":"Org Id"},"description":"The workspace this call acts in. Browser sessions may name any org the user is a live member of; integration tokens stay pinned to their own."},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FeedbackResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/orgs/{org_id}/email-outbox/{outbox_id}:requeue":{"post":{"tags":["email-outbox"],"summary":"Requeue Email Outbox Endpoint","description":"Re-drive one failed row. Owner/admin only; repeated requests are safe.","operationId":"requeue_email_outbox_endpoint_v1_orgs__org_id__email_outbox__outbox_id__requeue_post","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"name":"outbox_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Outbox Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailOutboxRequeueResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/orgs":{"get":{"tags":["orgs"],"summary":"List Orgs","operationId":"list_orgs_v1_orgs_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_OrganizationResponse_"}}}}},"security":[{"IntegrationToken":[]}],"parameters":[{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}]},"post":{"tags":["orgs"],"summary":"Create Org","operationId":"create_org_v1_orgs_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}],"parameters":[{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}]}},"/v1/orgs/{org_id}":{"get":{"tags":["orgs"],"summary":"Get Org","operationId":"get_org_v1_orgs__org_id__get","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]},"patch":{"tags":["orgs"],"summary":"Update Org","operationId":"update_org_v1_orgs__org_id__patch","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateOrganizationRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/orgs/{org_id}:switch":{"post":{"tags":["orgs"],"summary":"Switch Org","description":"Set ``org_id`` as the caller's active org and re-issue the session cookie.\n\nNOV-119: the org switcher was purely client-side (localStorage + the\n``/v1/orgs/{org_id}`` URL path hint). That left the session cookie's\n``org_id`` claim stale, so requests to routes with no org_id in the path\nresolved to the *old* (or no) org. This server-side switch re-stamps the\ncookie with the selected org so the active-org choice is durable across the\nwhole API surface, not just org-scoped paths.\n\n``require_org_access`` gates on real membership in ``org_id`` (404 for\nnon-members, never leaking org existence), so a caller can only switch into\nan org they actually belong to. The re-issued cookie carries that org's\nreal role. No-op cookie-wise for integration tokens (single-org by\ndefinition) — they get the org body back without a cookie.","operationId":"switch_org_v1_orgs__org_id__switch_post","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/orgs/{org_id}/members":{"get":{"tags":["orgs"],"summary":"List Members","operationId":"list_members_v1_orgs__org_id__members_get","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_MembershipResponse_"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]},"post":{"tags":["orgs"],"summary":"Add Member","operationId":"add_member_v1_orgs__org_id__members_post","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddMemberRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MembershipResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/orgs/{org_id}/members/{user_id}:resend-invite":{"post":{"tags":["orgs"],"summary":"Resend Member Invite","description":"Resend the verification / invite email for an org member.\n\nAdmin/owner-only. The endpoint inspects the target user's state and\npicks the right email template:\n  - email_verified=False → mint a fresh verification token and send\n    the `send_invite_new_user` template (the user finishes verifying\n    + setting up their account from the link).\n  - email_verified=True (already verified, just hasn't logged in\n    yet) → send `send_invite_existing_user` so they get a nudge with\n    a link back to the workspace.\n\nRate limit: once per minute per (org, target user). Returns 429 with\na clear retry message past that ceiling. Distinct from the\nuser-self path at `/v1/auth/resend-verification` (NOV-83 ticket).","operationId":"resend_member_invite_v1_orgs__org_id__members__user_id__resend_invite_post","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MembershipResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/orgs/{org_id}/members/{user_id}":{"patch":{"tags":["orgs"],"summary":"Update Member Role","operationId":"update_member_role_v1_orgs__org_id__members__user_id__patch","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateMembershipRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MembershipResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]},"delete":{"tags":["orgs"],"summary":"Remove Member","operationId":"remove_member_v1_orgs__org_id__members__user_id__delete","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/orgs/{org_id}/integrations":{"get":{"tags":["orgs"],"summary":"List Integrations","operationId":"list_integrations_v1_orgs__org_id__integrations_get","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_IntegrationResponse_"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]},"post":{"tags":["orgs"],"summary":"Create Integration","operationId":"create_integration_v1_orgs__org_id__integrations_post","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIntegrationRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIntegrationResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/orgs/{org_id}/integrations/{integration_id}":{"delete":{"tags":["orgs"],"summary":"Revoke Integration","description":"Revoke (hard-delete) an integration token (NOV-190 / spec §4.5).\n\nWorks for BOTH agent tokens (``user_id`` set) and raw tokens\n(``user_id IS NULL``). Org-scoped — an integration in another org 404s, so\nthere is no cross-tenant revoke. Revoking an agent's last token leaves the\nagent User / Membership / seat intact; killing the agent itself is a member\ndelete, not a token revoke.\n\nHARD delete, deliberately: ``AuditMixin`` carries ``in_trash`` / ``archived``\nflags, but the token-auth lookup (``_principal_from_integration_token``)\ndoes NOT filter on them — a soft-deleted row would still authenticate. Hard\ndelete is the only way to actually disable the credential. No seat\nrecompute: a token is not a seat (spec §18.1).","operationId":"revoke_integration_v1_orgs__org_id__integrations__integration_id__delete","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"name":"integration_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Integration Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/orgs/{org_id}/agents":{"post":{"tags":["orgs"],"summary":"Connect Agent","description":"Atomically connect an agent: User(kind='agent') + Membership + Integration.\n\nThe agent appears in assignee pickers and shows up with the\nsparkle badge on its avatar disc (NOV-92). The integration's\nbearer token is shown once in the response — the admin pastes it\ninto the agent runtime; we never serve it again.","operationId":"connect_agent_v1_orgs__org_id__agents_post","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConnectAgentRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConnectAgentResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/orgs/{org_id}/agents/{agent_user_id}/tokens":{"post":{"tags":["orgs"],"summary":"Add Agent Token","description":"Mint an ADDITIONAL credential for an existing agent (NOV-190 / spec §4.2, §4.5).\n\nTokens are children of an agent: an agent can own several (rotation, a\nmulti-Lambda fleet). The new ``Integration`` carries ``user_id=agent_user_id``\nso bearer-auth resolves to the same agent identity as its first token. The\nplaintext token is shown once.\n\nNO seat recompute: adding a token to an existing agent does not change the\nbillable count — the agent already counts as its (possibly free) seat; a\ntoken is a credential, not a member (spec §18.1). So this path skips the\nseat lock / recompute / Stripe sync that ``connect_agent`` runs.\n\nThe target must be a ``User(kind='agent')`` with a Membership in THIS org,\nor we 404 (no existence leak across tenants).","operationId":"add_agent_token_v1_orgs__org_id__agents__agent_user_id__tokens_post","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"name":"agent_user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Agent User Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddAgentTokenRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIntegrationResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/orgs/{org_id}/agents/{agent_user_id}:pause":{"post":{"tags":["orgs"],"summary":"Pause Agent","description":"Kill switch — pause an agent instantly (NOV-264 / spec §4.7).\n\nThin caller over :func:`app.services.agent_admin.pause_agent_for_principal`\n(shared with the ``pause_agent`` MCP tool). Available on ALL plans — safety\nis never paywalled. Owner/admin only.","operationId":"pause_agent_v1_orgs__org_id__agents__agent_user_id__pause_post","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"name":"agent_user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Agent User Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"requestBody":{"content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/PauseAgentRequest"},{"type":"null"}],"title":"Payload"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentKillSwitchResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/orgs/{org_id}/agents/{agent_user_id}:resume":{"post":{"tags":["orgs"],"summary":"Resume Agent","description":"Reverse a pause — re-admit the agent (NOV-264 / spec §4.7).\n\nThin caller over :func:`app.services.agent_admin.resume_agent_for_principal`\n(shared with the ``resume_agent`` MCP tool). Owner/admin only.","operationId":"resume_agent_v1_orgs__org_id__agents__agent_user_id__resume_post","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"name":"agent_user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Agent User Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentKillSwitchResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/orgs/{org_id}/agents/{agent_user_id}:revoke_tokens":{"post":{"tags":["orgs"],"summary":"Revoke Agent Tokens","description":"Hard kill — irreversibly delete ALL of an agent's tokens (NOV-264 / spec §4.7).\n\nUnlike :pause (reversible), this removes credentials outright: every\n``Integration`` the agent owns in this org is hard-deleted (same rationale as\n``revoke_integration`` — a soft-deleted row would still authenticate). It\ndoes NOT set paused/disabled and does NOT recompute seats (a token is not a\nseat, spec §18.1). Owner/admin only.","operationId":"revoke_agent_tokens_v1_orgs__org_id__agents__agent_user_id__revoke_tokens_post","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"name":"agent_user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Agent User Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RevokeAgentTokensResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/orgs/{org_id}/agents/{agent_user_id}/budget":{"get":{"tags":["orgs"],"summary":"Get Agent Budget","description":"Read an agent's budget caps + read-only kill-switch state + live usage.\n\nThin caller over :func:`app.services.agent_admin.get_agent_budget_for_principal`\n(shared with the ``get_agent_budget`` MCP tool). GATED to Scale/Agency\n(entitlement checked before the owner/admin role check); owner/admin only;\nthe target must be a ``kind='agent'`` member of this org. ``board_id`` absent\n= the org-wide budget (unchanged); present = the per-board override (NOV-271).","operationId":"get_agent_budget_v1_orgs__org_id__agents__agent_user_id__budget_get","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"name":"agent_user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Agent User Id"}},{"name":"board_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Board Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentBudgetResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]},"put":{"tags":["orgs"],"summary":"Set Agent Budget","description":"Set an agent's caps (PUT-replace; ``null`` clears a cap).\n\nThin caller over :func:`app.services.agent_admin.set_agent_budget_for_principal`\n(shared with the ``set_agent_budget`` MCP tool). GATED to Scale/Agency;\nowner/admin only; agent-target only. Writes an ``agent.budget_updated`` audit\nrow. Validation (``null`` or ``>=0``) is enforced by the request schema.\n``board_id`` absent = the org-wide budget (unchanged); present = the per-board\noverride (NOV-271; enforces writes/day only, per-board req/s deferred).","operationId":"set_agent_budget_v1_orgs__org_id__agents__agent_user_id__budget_put","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"name":"agent_user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Agent User Id"}},{"name":"board_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Board Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentBudgetUpdateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentBudgetResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/orgs/{org_id}/agents/activity":{"get":{"tags":["orgs"],"summary":"Get Org Agents Activity","description":"All-agents org (or per-client-board) activity rollup (NOV-266 / spec §4.7 ledger).\n\nThin caller over :func:`app.services.agent_admin.get_agent_activity_for_principal`\nwith ``agent_user_id=None`` (the all-agents rollup — no agent-target guard).\nShared with the ``get_agent_activity`` MCP tool. GATED to Scale/Agency;\nowner/admin only.","operationId":"get_org_agents_activity_v1_orgs__org_id__agents_activity_get","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"name":"window","in":"query","required":false,"schema":{"type":"string","default":"24h","title":"Window"}},{"name":"board_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Board Id"}},{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cursor"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":25,"title":"Limit"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentActivityResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/orgs/{org_id}/agents/{agent_user_id}/activity":{"get":{"tags":["orgs"],"summary":"Get Agent Activity","description":"Per-agent buyer-facing activity ledger — summary + reverse-chron feed (spec §4.7).\n\nThin caller over :func:`app.services.agent_admin.get_agent_activity_for_principal`\n(shared with the ``get_agent_activity`` MCP tool). GATED to Scale/Agency;\nowner/admin only; the target must resolve to a ``kind='agent'`` member of this\norg. ``window`` is ``24h`` or ``7d`` (400 otherwise); ``board_id`` scopes to\none client board.","operationId":"get_agent_activity_v1_orgs__org_id__agents__agent_user_id__activity_get","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"name":"agent_user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Agent User Id"}},{"name":"window","in":"query","required":false,"schema":{"type":"string","default":"24h","title":"Window"}},{"name":"board_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Board Id"}},{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cursor"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":25,"title":"Limit"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentActivityResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/orgs/{org_id}/presence/agents":{"get":{"tags":["orgs"],"summary":"List Live Agents","description":"Snapshot of agent Users with a live WS connection in ``org_id``.\n\nThe frontend's live-agents badge hits this on mount to hydrate before\nits WS opens (and starts streaming ``presence.agent.connected`` /\n``.disconnected`` events). Membership in ``org_id`` is the only gate\n— every member sees the same snapshot.","operationId":"list_live_agents_v1_orgs__org_id__presence_agents_get","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_AgentPresence_"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/orgs/{org_id}/domains":{"get":{"tags":["orgs"],"summary":"List Domains","operationId":"list_domains_v1_orgs__org_id__domains_get","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_DomainClaimResponse_"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]},"post":{"tags":["orgs"],"summary":"Claim Domain","operationId":"claim_domain_v1_orgs__org_id__domains_post","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDomainClaimRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DomainClaimResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/orgs/{org_id}/domains/{domain}:verify":{"post":{"tags":["orgs"],"summary":"Verify Domain","description":"Check the org's DNS TXT record and stamp verification on success (§4.3.1).\n\nOwner/admin only. Looks up `_novumos-verify.<domain>` and compares each TXT\nvalue against the claim's verification_code (exact, case-sensitive). On a\nmatch: stamp verified_at, write a `domain.verified` audit event. On any miss\nor DNS failure: leave the claim unverified and return it (never 5xx).\n`google_workspace` claims use the same DNS-TXT check in v1.","operationId":"verify_domain_v1_orgs__org_id__domains__domain__verify_post","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"name":"domain","in":"path","required":true,"schema":{"type":"string","title":"Domain"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DomainClaimResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/orgs/{org_id}/billing":{"get":{"tags":["billing"],"summary":"Get Billing","description":"Return the org's billing status object (spec §18.9).\n\nOwner-only. ``billable_seats`` and the humans/agents ``seat_breakdown`` are\nrecomputed **live** via :func:`seat_breakdown` — never the stale\n``billing_seats`` cache; the total derives from the breakdown's counts so\nthey agree by construction (the first-agent-free math is server-side). On\na free org, ``current_period_end``/``cancel_at_period_end`` are null and\n``has_payment_method`` is always false (spec §18.9 invariant), even if the\norg retains a ``stripe_customer_id`` from a prior Pro subscription (§18.7\nonly clears the subscription id on cancel). On Pro, ``has_payment_method``\nis derived offline from the Stripe customer id; no live Stripe call is made.","operationId":"get_billing_v1_orgs__org_id__billing_get","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/orgs/{org_id}/billing:checkout":{"post":{"tags":["billing"],"summary":"Checkout","description":"Start a Stripe Checkout to upgrade the org to Pro (spec §18.6 / §18.5).\n\nOwner-only (``admin`` is not sufficient — §18.1). Accepts an optional\n``{\"interval\": \"annual\"|\"monthly\"}`` body (NOV-242) selecting the billing\ncadence; an omitted body defaults to ``annual`` (the promoted option, §18.1).\nReturns a ``{\"checkout_url\": …}`` the owner is redirected to. Errors:\n\n* ``409`` if the org is already Pro (nothing to check out).\n* ``503 billing_unconfigured`` if Stripe isn't configured (dev has no keys),\n  surfaced by :func:`~app.core.stripe_client.get_stripe`.\n\nThe plan flip to Pro is **webhook-driven** (``checkout.session.completed`` →\n§18.7), never set here. The router stays thin; the Customer-create /\nsession-create logic lives in :func:`create_checkout_session`.","operationId":"checkout_v1_orgs__org_id__billing_checkout_post","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"requestBody":{"content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/CheckoutRequest"},{"type":"null"}],"title":"Payload"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckoutResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/orgs/{org_id}/billing:portal":{"post":{"tags":["billing"],"summary":"Portal","description":"Open a Stripe Customer Portal session for the org (spec §18.6).\n\nOwner-only (``admin`` is not sufficient — §18.1). Returns a\n``{\"portal_url\": …}`` the owner is redirected to. Errors:\n\n* ``409 no_subscription`` if the org has no ``stripe_customer_id`` (must\n  complete Checkout first to create the Stripe Customer).\n* ``503 billing_unconfigured`` if Stripe isn't configured (dev has no keys),\n  surfaced by :func:`~app.core.stripe_client.get_stripe`.\n\nThe router stays thin; the portal session logic lives in\n:func:`create_portal_session`.","operationId":"portal_v1_orgs__org_id__billing_portal_post","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PortalResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/orgs/{org_id}/automations":{"get":{"tags":["automations"],"summary":"List Automations Endpoint","description":"List the org's automations, newest first (keyset pagination). Admin/owner-only.","operationId":"list_automations_endpoint_v1_orgs__org_id__automations_get","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":25,"title":"Page Size"}},{"name":"start_cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Start Cursor"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_AutomationResponse_"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]},"post":{"tags":["automations"],"summary":"Create Automation Endpoint","description":"Create an automation rule (§20.8). Admin/owner-only.\n\nThe body's ``trigger`` / ``actions`` are validated (event_type ∈\nKNOWN_EVENT_TYPES; non-empty actions with known ``type``) — the schema rejects\na malformed body with 422 before the service, which re-validates for parity\nwith the MCP path. A ``notify`` action's ``params`` may set ``recipient``\n(``owner`` default | ``assignees``) and ``channels`` (any of ``comment``\ndefault | ``in_app`` | ``email``); unknown values are rejected at write time\n(422). Omitting both keys preserves the historical comment-to-owner behavior.","operationId":"create_automation_endpoint_v1_orgs__org_id__automations_post","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAutomationRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AutomationResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/orgs/{org_id}/automations/{automation_id}":{"get":{"tags":["automations"],"summary":"Get Automation Endpoint","description":"Fetch one automation. Admin/owner-only. Cross-org → ``404`` (no leak).","operationId":"get_automation_endpoint_v1_orgs__org_id__automations__automation_id__get","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"name":"automation_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Automation Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AutomationResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]},"patch":{"tags":["automations"],"summary":"Update Automation Endpoint","description":"Update / toggle an automation (§20.8). Admin/owner-only.\n\nOnly the fields the client sent are changed (``model_dump(exclude_unset=True)``\nforwards an explicit ``null`` but not an absent key). ``is_active`` supports the\nenable/disable toggle.","operationId":"update_automation_endpoint_v1_orgs__org_id__automations__automation_id__patch","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"name":"automation_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Automation Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateAutomationRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AutomationResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]},"delete":{"tags":["automations"],"summary":"Delete Automation Endpoint","description":"Delete an automation (§20.8). Admin/owner-only. Cross-org → ``404``.","operationId":"delete_automation_endpoint_v1_orgs__org_id__automations__automation_id__delete","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"name":"automation_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Automation Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/orgs/{org_id}/automations/{automation_id}/runs":{"get":{"tags":["automations"],"summary":"List Automation Runs Endpoint","description":"List one automation's run ledger, newest first (§20.8). Admin/owner-only.","operationId":"list_automation_runs_endpoint_v1_orgs__org_id__automations__automation_id__runs_get","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"name":"automation_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Automation Id"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":25,"title":"Page Size"}},{"name":"start_cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Start Cursor"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_AutomationRunResponse_"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/orgs/{org_id}/automations/{automation_id}/runs/{run_id}:replay":{"post":{"tags":["automations"],"summary":"Replay Automation Run Endpoint","description":"Re-arm a terminal-failed run (§20.6.2). Admin/owner-only.\n\nResets the run to ``pending`` + ``next_retry_at=now()`` in place (dedup_key\npreserved, NO new row); a non-terminal-failed run → ``409``; a run under\nanother automation/org → ``404``. The executor (NOV-281) drains the reset run.","operationId":"replay_automation_run_endpoint_v1_orgs__org_id__automations__automation_id__runs__run_id__replay_post","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"name":"automation_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Automation Id"}},{"name":"run_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Run Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AutomationRunResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/orgs/{org_id}/playbooks":{"get":{"tags":["playbooks"],"summary":"List Playbooks Endpoint","description":"List the org's Playbooks, newest first (keyset pagination). Admin/owner-only.","operationId":"list_playbooks_endpoint_v1_orgs__org_id__playbooks_get","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":25,"title":"Page Size"}},{"name":"start_cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Start Cursor"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_PlaybookResponse_"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]},"post":{"tags":["playbooks"],"summary":"Create Playbook Endpoint","description":"Create a Playbook (§23.4). Admin/owner-only.\n\nThe body's ``steps`` (non-empty, each with a ``prompt_md``) and ``output_target``\n(``append_body`` | ``replace_body``) are validated — the schema rejects a\nmalformed body with 422 before the service, which re-validates for parity with\nthe MCP path. ``on_success_move_to`` is the column a card advances to on success.","operationId":"create_playbook_endpoint_v1_orgs__org_id__playbooks_post","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePlaybookRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaybookResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/orgs/{org_id}/playbooks/{playbook_id}":{"get":{"tags":["playbooks"],"summary":"Get Playbook Endpoint","description":"Fetch one Playbook. Admin/owner-only. Cross-org → ``404`` (no leak).","operationId":"get_playbook_endpoint_v1_orgs__org_id__playbooks__playbook_id__get","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"name":"playbook_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Playbook Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaybookResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]},"patch":{"tags":["playbooks"],"summary":"Update Playbook Endpoint","description":"Update a Playbook (§23.4). Admin/owner-only.\n\nOnly the fields the client sent are changed (``model_dump(exclude_unset=True)``\nforwards an explicit ``null`` but not an absent key). ``steps`` / ``output_target``\nare re-validated.","operationId":"update_playbook_endpoint_v1_orgs__org_id__playbooks__playbook_id__patch","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"name":"playbook_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Playbook Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdatePlaybookRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaybookResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]},"delete":{"tags":["playbooks"],"summary":"Delete Playbook Endpoint","description":"Delete a Playbook (§23.4). Admin/owner-only. Cross-org → ``404``.","operationId":"delete_playbook_endpoint_v1_orgs__org_id__playbooks__playbook_id__delete","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"name":"playbook_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Playbook Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/orgs/{org_id}/ai-run-usage":{"get":{"tags":["autopilot"],"summary":"List Ai Run Usage Endpoint","description":"List the org's Autopilot run history, newest first (§23.6). Admin/owner-gated.\n\nOptional ``board_id`` / ``column_id`` / ``playbook_id`` narrow the feed to a\nsingle board, Autopilot column, or Playbook.","operationId":"list_ai_run_usage_endpoint_v1_orgs__org_id__ai_run_usage_get","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"name":"board_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Board Id"}},{"name":"column_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Column Id"}},{"name":"playbook_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Playbook Id"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":25,"title":"Page Size"}},{"name":"start_cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Start Cursor"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_AiRunUsageResponse_"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/orgs/{org_id}/import-jobs":{"post":{"tags":["import-jobs"],"summary":"Create Import Job Endpoint","description":"Create + start an import (spec §21.9). Admin/owner-only.\n\n``notion_api`` (default): body carries the transient Notion ``token`` (§21.10 —\nbody only, never a query string) plus ``database_id`` / ``whole_workspace`` and\noptional ``column_property``; the token is registered in the process-local store\nso the worker can claim it. ``export_file`` (NOV-297): body carries ``file_id``\nof a committed upload (from ``:upload`` → ``:commit``; usable as soon as the\nfile is ``status=available``) plus optional ``column_property``. Returns the\njob WITHOUT any token.","operationId":"create_import_job_endpoint_v1_orgs__org_id__import_jobs_post","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateImportJobRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportJobResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]},"get":{"tags":["import-jobs"],"summary":"List Import Jobs Endpoint","description":"List the org's import jobs, newest first (keyset pagination). Admin/owner-only.","operationId":"list_import_jobs_endpoint_v1_orgs__org_id__import_jobs_get","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":25,"title":"Page Size"}},{"name":"start_cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Start Cursor"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_ImportJobResponse_"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/orgs/{org_id}/import-jobs:upload":{"post":{"tags":["import-jobs"],"summary":"Create Import Upload Endpoint","description":"Mint a presigned POST for a Notion export ``.zip`` (NOV-297). Admin/owner-only.\n\nReturns the standard file envelope (``upload_url`` + form fields). Flow:\n``:upload`` → PUT bytes to S3 → ``POST /v1/files/{id}:commit`` → ``POST\n.../import-jobs`` with ``source=export_file`` + this ``file_id`` (the file is\nusable as soon as ``:commit`` returns ``status=available``). Only\n``application/zip`` is accepted (415 otherwise).","operationId":"create_import_upload_endpoint_v1_orgs__org_id__import_jobs_upload_post","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateImportUploadRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Create Import Upload Endpoint V1 Orgs  Org Id  Import Jobs Upload Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/orgs/{org_id}/import-jobs/{job_id}":{"get":{"tags":["import-jobs"],"summary":"Get Import Job Endpoint","description":"Return one import job's status/counts/error_log/board_id (the wizard polls this).\n\nAdmin/owner-only. A job in another org is a ``404`` (org-scoping, no leak).","operationId":"get_import_job_endpoint_v1_orgs__org_id__import_jobs__job_id__get","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"name":"job_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Job Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportJobResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/orgs/{org_id}/import-jobs/{job_id}:cancel":{"post":{"tags":["import-jobs"],"summary":"Cancel Import Job Endpoint","description":"Cancel a queued/running import (spec §21.9). Admin/owner-only.\n\nTerminal job → ``409 conflict``. A queued/running job is landed in ``failed``\n(no ``cancelled`` status) and its transient token dropped so an unclaimed job\nnever runs. Cancelling an already-running job is best-effort — the runner does\nnot poll for cancellation.","operationId":"cancel_import_job_endpoint_v1_orgs__org_id__import_jobs__job_id__cancel_post","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"name":"job_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Job Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportJobResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/orgs/{org_id}/import-jobs:databases":{"post":{"tags":["import-jobs"],"summary":"List Databases Endpoint","description":"List the Notion databases the token can see, to pick from (spec §21.9/§21.10).\n\nAdmin/owner-only. The transient token is carried in the request body (never a\nURL/query string — proxies log those) and is used once to build the Notion\nsource, then dropped; nothing is persisted. Returns ``[{id, title}]``.","operationId":"list_databases_endpoint_v1_orgs__org_id__import_jobs_databases_post","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListDatabasesRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListDatabasesResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/boards":{"get":{"tags":["boards"],"summary":"List Boards","operationId":"list_boards_v1_boards_get","parameters":[{"name":"archived","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Archived"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":25,"title":"Page Size"}},{"name":"start_cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Start Cursor"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_BoardResponse_"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]},"post":{"tags":["boards"],"summary":"Create Board","operationId":"create_board_v1_boards_post","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBoardRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BoardResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}],"parameters":[{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}]}},"/v1/boards/{board_id}":{"get":{"tags":["boards"],"summary":"Get Board","operationId":"get_board_v1_boards__board_id__get","parameters":[{"name":"board_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Board Id"}},{"name":"include_archived","in":"query","required":false,"schema":{"type":"boolean","description":"NOV-459 (§7.1): also return ARCHIVED property definitions in the ``properties`` map, each tagged ``\"archived\": true``. Archived definitions are hidden by default — the map is the board's live schema. Deleting a ``unique_id`` property archives rather than removes it, preserving its id, prefix and numbering; re-adding the same name reinstates it. Use this to discover what is archived, then reinstate it (PATCH with a body under that name) or delete it permanently (POST /v1/boards/{board_id}/properties:purge). Handing this response's ``properties`` map straight back to PATCH is safe: an entry echoed with ``\"archived\": true`` stays archived, so a read-modify-write that edits one property does not reinstate the rest. Reinstating is therefore always explicit — send a body under the archived name WITHOUT the flag.","default":false,"title":"Include Archived"},"description":"NOV-459 (§7.1): also return ARCHIVED property definitions in the ``properties`` map, each tagged ``\"archived\": true``. Archived definitions are hidden by default — the map is the board's live schema. Deleting a ``unique_id`` property archives rather than removes it, preserving its id, prefix and numbering; re-adding the same name reinstates it. Use this to discover what is archived, then reinstate it (PATCH with a body under that name) or delete it permanently (POST /v1/boards/{board_id}/properties:purge). Handing this response's ``properties`` map straight back to PATCH is safe: an entry echoed with ``\"archived\": true`` stays archived, so a read-modify-write that edits one property does not reinstate the rest. Reinstating is therefore always explicit — send a body under the archived name WITHOUT the flag."},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BoardResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]},"patch":{"tags":["boards"],"summary":"Update Board","operationId":"update_board_v1_boards__board_id__patch","parameters":[{"name":"board_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Board Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateBoardRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BoardResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]},"delete":{"tags":["boards"],"summary":"Delete Board","operationId":"delete_board_v1_boards__board_id__delete","parameters":[{"name":"board_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Board Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/boards/{board_id}/properties:purge":{"post":{"tags":["boards"],"summary":"Purge Board Property","description":"PERMANENTLY delete an archived property definition (NOV-459, §7.1).\n\nIRREVERSIBLE, and the only irreversible operation on a board's property\nschema. Deleting a ``unique_id`` property via ``PATCH /v1/boards/{id}`` with\n``{\"properties\": {\"ID\": null}}`` ARCHIVES it — the definition, its id, its\nprefix and its numbering all survive, and re-adding the same name reinstates\nevery one of them. This endpoint destroys that. Once purged, re-adding the\nname mints a brand-new property, and the name becomes free for any type.\n\nValues already stored on cards under the purged name are NOT deleted; only\nthe definition is. 404 if the board has no property under that name, 422 if\nit has a LIVE one (archive it first). Manager role required.","operationId":"purge_board_property_v1_boards__board_id__properties_purge_post","parameters":[{"name":"board_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Board Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PurgeBoardPropertyRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BoardResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/boards/{board_id}/query":{"post":{"tags":["boards"],"summary":"Query Board","description":"The primary board read — a page of cards in the spec §8 list envelope.\n\nNOV-457: the service still assembles the envelope as a dict (the MCP\n``list_cards`` wrapper and the public-board payload both consume it in that\nform), so the router validates it into the declared model. The published\nOpenAPI schema is then the same object the response is serialized from.","operationId":"query_board_v1_boards__board_id__query_post","parameters":[{"name":"board_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Board Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BoardQueryRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_CardResponse_"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/boards/{board_id}/labels":{"get":{"tags":["boards"],"summary":"List Board Labels","description":"The board's label vocabulary — ``{name, color, count}``, most-used first.\n\nNOV-437: Labels are a card BUILT-IN (``card.labels``). A board-schema\n``multi_select`` named \"Labels\" *can* be created — only ``Status`` is\nreserved — but the built-in shadows it on the card read, so nothing else on\nthe API exposes \"which labels does this board actually use\". This feeds the\ncard-detail label picker and the board's\nLabels filter; without it both offered an empty list and every reuse became\na fresh typo/color variant.\n\nAggregated over the board's non-archived cards. Names merge case- and\nspace-insensitively; a name used with several colors reports its\nmost-used color, and ``count`` is the number of distinct CARDS carrying the\nname (across all its colors). The board-query ``contains`` filter folds names\nthe same way, so a value taken from here matches every spelling variant on\nthe board. Same 404-on-no-access contract as every other board endpoint.","operationId":"list_board_labels_v1_boards__board_id__labels_get","parameters":[{"name":"board_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Board Id"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":100,"title":"Page Size"}},{"name":"start_cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Start Cursor"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_BoardLabelResponse_"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/boards/{board_id}/columns":{"get":{"tags":["boards"],"summary":"List Columns","operationId":"list_columns_v1_boards__board_id__columns_get","parameters":[{"name":"board_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Board Id"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Page Size"}},{"name":"start_cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Start Cursor"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_BoardColumnResponse_"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]},"post":{"tags":["boards"],"summary":"Create Column","operationId":"create_column_v1_boards__board_id__columns_post","parameters":[{"name":"board_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Board Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateColumnRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BoardColumnResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/boards/{board_id}/columns/{column_id}":{"patch":{"tags":["boards"],"summary":"Update Column","operationId":"update_column_v1_boards__board_id__columns__column_id__patch","parameters":[{"name":"board_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Board Id"}},{"name":"column_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Column Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateColumnRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BoardColumnResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]},"delete":{"tags":["boards"],"summary":"Delete Column","operationId":"delete_column_v1_boards__board_id__columns__column_id__delete","parameters":[{"name":"board_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Board Id"}},{"name":"column_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Column Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/property-types":{"get":{"tags":["boards"],"summary":"List Property Types","description":"Filter+sort vocabulary metadata for the frontend (NOV-73).\n\nReturns a static map of property type → allowed operators, plus the\nmax filter nesting depth. The frontend derives its filter-builder UI\nfrom this so the operator list never drifts from the backend\ntranslator's truth.\n\nAuthenticated callers only (any role): operator lists are not org-\nsensitive, but we don't want unauthenticated clients sniffing the\nsurface area.","operationId":"list_property_types_v1_property_types_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response List Property Types V1 Property Types Get"}}}}},"security":[{"IntegrationToken":[]}],"parameters":[{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}]}},"/v1/board-templates":{"get":{"tags":["boards"],"summary":"List Board Templates","description":"List curated board-template presets (NOV-350 / §7.8).\n\nEach entry carries a ``key``, display ``name``, one-line ``description``,\n``property_validation`` mode, and a preview of the columns + properties the\npreset would create. To instantiate one, POST /v1/boards with the ``template``\nkey. The catalogue is static (org-agnostic); authenticated callers only —\nsame gate as /property-types. Uses the standard list envelope so clients\nread every list surface uniformly; the whole catalogue always fits one page\n(``has_more`` is always false).","operationId":"list_board_templates_v1_board_templates_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_BoardTemplateResponse_"}}}}},"security":[{"IntegrationToken":[]}],"parameters":[{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}]}},"/v1/boards/{board_id}/access":{"get":{"tags":["board-access"],"summary":"Get Board Access","operationId":"get_board_access_v1_boards__board_id__access_get","parameters":[{"name":"board_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Board Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BoardAccessListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]},"post":{"tags":["board-access"],"summary":"Post Board Access","operationId":"post_board_access_v1_boards__board_id__access_post","parameters":[{"name":"board_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Board Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GrantBoardAccessRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BoardGrantResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/boards/{board_id}/access/{user_id}":{"patch":{"tags":["board-access"],"summary":"Patch Board Access","operationId":"patch_board_access_v1_boards__board_id__access__user_id__patch","parameters":[{"name":"board_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Board Id"}},{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateBoardAccessRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BoardGrantResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]},"delete":{"tags":["board-access"],"summary":"Delete Board Access","operationId":"delete_board_access_v1_boards__board_id__access__user_id__delete","parameters":[{"name":"board_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Board Id"}},{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/boards/{board_id}/access:reclaim":{"post":{"tags":["board-access"],"summary":"Reclaim Board Access","description":"Org-owner-only governance action: add (or raise to) the owner's manager\ngrant. Non-owners get a uniform ``403`` (the service closes the existence\noracle before any board load). See ``reclaim_board``.","operationId":"reclaim_board_access_v1_boards__board_id__access_reclaim_post","parameters":[{"name":"board_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Board Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BoardGrantResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/boards/{board_id}/share-links":{"post":{"tags":["share-links"],"summary":"Create Board Share Link","operationId":"create_board_share_link_v1_boards__board_id__share_links_post","parameters":[{"name":"board_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Board Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateShareLinkRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ShareLinkCreatedResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]},"get":{"tags":["share-links"],"summary":"List Board Share Links","operationId":"list_board_share_links_v1_boards__board_id__share_links_get","parameters":[{"name":"board_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Board Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_ShareLinkResponse_"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]},"delete":{"tags":["share-links"],"summary":"Revoke All Board Share Links","description":"Revoke every active link on the board — the NOV-219 kill-switch.\n\nManager-gated. Returns the links revoked by this call (empty when the board\nhad no active links). Closing external access here never touches the board's\n``visibility`` or internal access.","operationId":"revoke_all_board_share_links_v1_boards__board_id__share_links_delete","parameters":[{"name":"board_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Board Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_ShareLinkResponse_"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/boards/{board_id}/share-links/{link_id}":{"delete":{"tags":["share-links"],"summary":"Revoke Board Share Link","operationId":"revoke_board_share_link_v1_boards__board_id__share_links__link_id__delete","parameters":[{"name":"board_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Board Id"}},{"name":"link_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Link Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ShareLinkResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/public/boards/{board_id}":{"get":{"tags":["public"],"summary":"Get Public Board","description":"Read a shared board (board-scoped): metadata, columns, non-archived cards.\n\nProgrammatic / back-compat surface — the token rides as the ``token`` query\nparam and the path pins the board. Kept for callers that already hold a\nboard id; the client-facing web route uses the token-only sibling below.","operationId":"get_public_board_v1_public_boards__board_id__get","parameters":[{"name":"board_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Board Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Public Board V1 Public Boards  Board Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/public/share/{token}":{"get":{"tags":["public"],"summary":"Get Public Board By Token","description":"Resolve a share-link ``token`` and serve ITS bound board (token-only, NOV-200).\n\nThe client-facing share URL is ``{app_base_url}/share/{token}`` (a web route\nrendering the read-only board); this endpoint backs it. The token resolver\nis board-agnostic — it resolves the raw token via the ``last4`` index +\nargon2 verify and returns a principal carrying the bound ``board_id`` — so\nwe serve the principal's OWN board with no board id in the URL.\n\n404 (never reveal) when the token is absent, malformed, unknown, expired, or\nrevoked. The bound org is set as the tenant scope so the board/card queries\nare org-filtered; board *access* is still granted only on the bound board by\n``require_board_access`` inside :func:`_public_board_payload`.","operationId":"get_public_board_by_token_v1_public_share__token__get","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Public Board By Token V1 Public Share  Token  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/public/boards/{board_id}/cards/{card_id}/comments":{"post":{"tags":["public"],"summary":"Create Public Comment","description":"Post a comment through a ``commenter`` share link.\n\n``require_board_access(min_role='commenter')`` rejects a ``viewer`` link with\n403 and a cross-board token with 404. The card must live on the bound board.\nThe comment is authored anonymously (no User, no seat).\n\nThe app-level ``enforce_billing_writable`` dependency falls out at its \"no\nprincipal\" gate for a share-link token (it isn't a bearer), so the §18.8\nread-only-when-past_due invariant is enforced here explicitly: a past_due org\nrefuses this write with the same ``402 billing_past_due`` an internal write\nreturns. Checked after the role gate so a ``viewer`` link still 403s (and an\nunauthorized caller never learns the org's billing state).","operationId":"create_public_comment_v1_public_boards__board_id__cards__card_id__comments_post","parameters":[{"name":"board_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Board Id"}},{"name":"card_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Card Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicCommentRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommentResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/public/boards/{board_id}/agent-activity":{"get":{"tags":["public"],"summary":"Get Public Agent Activity","description":"Client-shareable, read-only agent-activity report for a shared board (NOV-271).\n\nBoard-scoped surface: the token rides as ``?token=`` and the path pins the\nboard. A viewer OR commenter token for THIS board sees the all-agents rollup;\na cross-board / expired / revoked token 404s (existence hidden); an\nun-entitled org 403s ``governance_not_entitled`` AFTER the board gate. GATED\nto the Scale/Agency tier (the agency's entitlement). ``window`` is ``24h`` or\n``7d`` (400 otherwise).","operationId":"get_public_agent_activity_v1_public_boards__board_id__agent_activity_get","parameters":[{"name":"board_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Board Id"}},{"name":"window","in":"query","required":false,"schema":{"type":"string","default":"24h","title":"Window"}},{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cursor"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":25,"title":"Limit"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicAgentActivityResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/public/share/{token}/agent-activity":{"get":{"tags":["public"],"summary":"Get Public Agent Activity By Token","description":"Token-only sibling of :func:`get_public_agent_activity` (NOV-200 pattern).\n\nResolves the share-link ``token`` board-agnostically and serves the report\nfor ITS bound board — no board id in the URL, mirroring\n:func:`get_public_board_by_token`. Same gates, same 404-on-invalid-token\ncontract.","operationId":"get_public_agent_activity_by_token_v1_public_share__token__agent_activity_get","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}},{"name":"window","in":"query","required":false,"schema":{"type":"string","default":"24h","title":"Window"}},{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cursor"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":25,"title":"Limit"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicAgentActivityResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/cards":{"post":{"tags":["cards"],"summary":"Create Card","operationId":"create_card_v1_cards_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCardRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CardResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}],"parameters":[{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}]}},"/v1/cards/{card_id}":{"get":{"tags":["cards"],"summary":"Get Card","operationId":"get_card_v1_cards__card_id__get","parameters":[{"name":"card_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Card Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CardResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]},"patch":{"tags":["cards"],"summary":"Update Card","description":"Patch a card. ``If-Match: \"v17\"`` against the etag honored (spec §8.1).\n\n``Prefer: merge-properties`` (spec §7.3, NOV-352): ``properties`` merges\nkey-by-key instead of replacing the map, and array-typed properties\n(``multi_select`` / ``people`` / ``files`` per the board schema)\nelement-UNION with the stored value — deduped by option id/name, user id,\nor file id/url/name — so concurrent agent appends never clobber each\nother. Explicit removal per key: ``{\"add\": [...], \"remove\": [...]}``\n(either optional). Without the header, writes replace (Notion default).","operationId":"update_card_v1_cards__card_id__patch","parameters":[{"name":"card_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Card Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCardRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CardResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]},"delete":{"tags":["cards"],"summary":"Delete Card","description":"Soft-archive a card. ``If-Match: \"v17\"`` honored when supplied (spec §8.1).","operationId":"delete_card_v1_cards__card_id__delete","parameters":[{"name":"card_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Card Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/cards/{card_id}/audit":{"get":{"tags":["cards"],"summary":"List Card Audit","operationId":"list_card_audit_v1_cards__card_id__audit_get","parameters":[{"name":"card_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Card Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":10,"title":"Limit"}},{"name":"start_cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Start Cursor"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_CardAuditEntry_"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/cards/{card_id}:move":{"post":{"tags":["cards"],"summary":"Move Card","description":"Move a card. ``If-Match: \"v17\"`` against the etag honored (spec §8.1).","operationId":"move_card_v1_cards__card_id__move_post","parameters":[{"name":"card_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Card Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MoveCardRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CardResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/cards:batchUpdate":{"post":{"tags":["cards"],"summary":"Batch Update Cards","description":"Transactional bulk ops. ``Prefer: merge-properties`` applies the same\nper-key merge + array element-union semantics as ``PATCH /v1/cards/{id}``\n(spec §7.3) to every ``set`` op in the batch.","operationId":"batch_update_cards_v1_cards_batchUpdate_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchUpdateRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchUpdateResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}],"parameters":[{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}]}},"/v1/cards/{card_id}/agent_activity":{"post":{"tags":["cards"],"summary":"Set Card Agent Activity","description":"Publish an agent's current claim on a card (NOV-91).\n\nLast-write-wins. The server stamps ``started_at`` to drive the\n10-minute lazy expiry on read. Broadcasts\n``card.agent_activity.set`` so the kanban board's WS subscribers\nflip the agent-motion frame on within ~200ms.","operationId":"set_card_agent_activity_v1_cards__card_id__agent_activity_post","parameters":[{"name":"card_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Card Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetAgentActivityRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CardResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]},"delete":{"tags":["cards"],"summary":"Clear Card Agent Activity","description":"Clear an agent's claim on a card (NOV-91).\n\nIdempotent — re-clearing an already-empty field is a no-op\n(no realtime event fires). The next card mutation also clears the\nfield automatically; this DELETE is the explicit \"I'm done\" path.","operationId":"clear_card_agent_activity_v1_cards__card_id__agent_activity_delete","parameters":[{"name":"card_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Card Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CardResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/boards/{board_id}/columns/{column_id}:claim-next":{"post":{"tags":["leases"],"summary":"Claim Next","description":"Lease the next eligible card in a column.\n\nOn success returns ``200`` with the lease + full card. When the queue is\ndrained (or the column's ``concurrency_limit`` is reached) returns ``200``\n``{object:\"lease\", card:null}`` (a single content-type, cheap to busy-poll) —\nnever a ``204``/``404`` (spec §7.5.3).\n\nAn optional ``Idempotency-Key`` header makes the claim safe to retry after a\ndropped response: a retry with the SAME key returns the SAME lease (never a\nsecond one) or replays the original ``no_work`` (NOV-259, spec §7.5.4).","operationId":"claim_next_v1_boards__board_id__columns__column_id__claim_next_post","parameters":[{"name":"board_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Board Id"}},{"name":"column_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Column Id"}},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Idempotency-Key"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"requestBody":{"content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/ClaimNextRequest"},{"type":"null"}],"title":"Payload"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClaimResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/leases/{lease_id}:heartbeat":{"post":{"tags":["leases"],"summary":"Renew Lease","description":"Extend a held lease's TTL + stamp its heartbeat. ``:heartbeat`` is an\nalias of ``:renew`` (same handler). ``409 lease_lost`` if the caller no\nlonger holds the active lease (spec §7.5.3).","operationId":"renew_lease_v1_leases__lease_id__heartbeat_post","parameters":[{"name":"lease_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Lease Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenewLeaseRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeaseResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/leases/{lease_id}:renew":{"post":{"tags":["leases"],"summary":"Renew Lease","description":"Extend a held lease's TTL + stamp its heartbeat. ``:heartbeat`` is an\nalias of ``:renew`` (same handler). ``409 lease_lost`` if the caller no\nlonger holds the active lease (spec §7.5.3).","operationId":"renew_lease_v1_leases__lease_id__renew_post","parameters":[{"name":"lease_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Lease Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenewLeaseRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeaseResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/leases/{lease_id}:complete":{"post":{"tags":["leases"],"summary":"Complete Lease","description":"Complete a held lease: optionally patch the card, advance it to the\ncontract's ``on_success_column_id``, release the lease. Idempotent on a\ncompleted lease with the same token; ``409 lease_lost`` on a stale token\n(spec §7.5.3).\n\nThe ``properties`` patch applies MERGE semantics (spec §7.3, NOV-352):\nkeys merge instead of replacing the map, and array-typed properties\n(``multi_select`` / ``people`` / ``files``) element-union with the stored\nvalue — an agent's result tags never wipe tags already on the card.\nPer-key ``{\"add\": [...], \"remove\": [...]}`` is honored.","operationId":"complete_lease_v1_leases__lease_id__complete_post","parameters":[{"name":"lease_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Lease Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompleteLeaseRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompleteResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/leases/{lease_id}:fail":{"post":{"tags":["leases"],"summary":"Fail Lease","description":"Release a held lease as failed; requeue with backoff while attempts\nremain, else dead-letter in place. Idempotent on an already-failed lease\nwith the same token; ``409 lease_lost`` on a stale token (spec §7.5.3).","operationId":"fail_lease_v1_leases__lease_id__fail_post","parameters":[{"name":"lease_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Lease Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FailLeaseRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeaseResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/leases/{lease_id}":{"get":{"tags":["leases"],"summary":"Get Lease","description":"Fetch one lease. Gated on board READ access via the lease's card — a\nnon-grantee of a restricted board (or a cross-org caller) gets ``404\nobject_not_found`` (existence never revealed). A read: never past_due-blocked\n(spec §7.5.3 observability).","operationId":"get_lease_v1_leases__lease_id__get","parameters":[{"name":"lease_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Lease Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeaseResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/boards/{board_id}/leases":{"get":{"tags":["leases"],"summary":"List Board Leases","description":"List a board's leases (Notion-shape envelope). Requires board READ access\n(viewer+); a non-grantee of a restricted board 404s. ``state`` is one of\n``active`` (default — currently held), ``expired`` (lapsed, awaiting the\nreaper — \"who is stuck\"), or ``all`` (full history incl. released); an\nunknown value is ``422``. ``column_id`` narrows to one column's queue.\nOrdered soonest-to-expire first. A read: never past_due-blocked.","operationId":"list_board_leases_v1_boards__board_id__leases_get","parameters":[{"name":"board_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Board Id"}},{"name":"column_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Column Id"}},{"name":"state","in":"query","required":false,"schema":{"type":"string","default":"active","title":"State"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":50,"title":"Page Size"}},{"name":"start_cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Start Cursor"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_LeaseResponse_"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/boards/{board_id}/columns/{column_id}/contract":{"get":{"tags":["leases"],"summary":"Get Column Contract","description":"Read a column's job contract (the durable-work queue config). MANAGER-only\n— a non-manager board role is ``403``; a missing/cross-org board or a column\nnot on this board is ``404`` (existence never revealed). Returns the fields as\nstored (a column with no contract reads back as the empty shape). A read:\nnever past_due-blocked (spec §7.5.3 admin).","operationId":"get_column_contract_v1_boards__board_id__columns__column_id__contract_get","parameters":[{"name":"board_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Board Id"}},{"name":"column_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Column Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobContractResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]},"put":{"tags":["leases"],"summary":"Set Column Contract","description":"Write a column's job contract (full replace). MANAGER-only (same 404/403\ncontract as the GET). Rejects a malformed ``input_schema``/``output_schema``\nor an off-board ``on_success_column_id``/``on_failure_column_id`` with ``422\ninvalid_contract``, and an unknown field with ``422`` (extra keys forbidden).\nEmits ``column.contract.updated``. The app-level past_due guard already blocks\nthis PUT for a delinquent org (spec §7.5.3 admin).","operationId":"set_column_contract_v1_boards__board_id__columns__column_id__contract_put","parameters":[{"name":"board_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Board Id"}},{"name":"column_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Column Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobContractRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobContractResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/card-templates":{"post":{"tags":["card-templates"],"summary":"Create Template","operationId":"create_template_v1_card_templates_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCardTemplateRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CardTemplateResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}],"parameters":[{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}]}},"/v1/boards/{board_id}/card-templates":{"get":{"tags":["card-templates"],"summary":"List Templates","operationId":"list_templates_v1_boards__board_id__card_templates_get","parameters":[{"name":"board_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Board Id"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":25,"title":"Page Size"}},{"name":"start_cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Start Cursor"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_CardTemplateResponse_"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/card-templates/{template_id}":{"get":{"tags":["card-templates"],"summary":"Get Template","operationId":"get_template_v1_card_templates__template_id__get","parameters":[{"name":"template_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Template Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CardTemplateResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]},"patch":{"tags":["card-templates"],"summary":"Update Template","operationId":"update_template_v1_card_templates__template_id__patch","parameters":[{"name":"template_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Template Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCardTemplateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CardTemplateResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]},"delete":{"tags":["card-templates"],"summary":"Delete Template","operationId":"delete_template_v1_card_templates__template_id__delete","parameters":[{"name":"template_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Template Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/cards/{card_id}:make-recurring":{"post":{"tags":["card-templates"],"summary":"Make Card Recurring","operationId":"make_card_recurring_v1_cards__card_id__make_recurring_post","parameters":[{"name":"card_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Card Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MakeRecurringRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CardTemplateResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/comments":{"get":{"tags":["comments"],"summary":"List Comments","description":"List comments on a card.\n\nAccepts ``block_id`` as a Notion-shape alias for ``card_id`` (NOV-63 B5).\nNotion's API uses ``GET /v1/comments?block_id=<page_id>`` to list\npage-level comments — content-forge does this verbatim. We treat the\ntwo parameters as equivalent so a Notion-shape client works unchanged.\nIf both are present, ``card_id`` wins.","operationId":"list_comments_v1_comments_get","parameters":[{"name":"card_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Card Id"}},{"name":"block_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Block Id"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":25,"title":"Page Size"}},{"name":"start_cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Start Cursor"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response List Comments V1 Comments Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]},"post":{"tags":["comments"],"summary":"Create Comment","operationId":"create_comment_v1_comments_post","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommentRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommentResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}],"parameters":[{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}]}},"/v1/comments/{comment_id}":{"patch":{"tags":["comments"],"summary":"Update Comment","description":"Patch a comment. ``If-Match: \"v17\"`` against the etag honored (spec §8.1).","operationId":"update_comment_v1_comments__comment_id__patch","parameters":[{"name":"comment_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Comment Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCommentRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommentResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]},"delete":{"tags":["comments"],"summary":"Delete Comment","description":"Soft-archive a comment. ``If-Match: \"v17\"`` honored when supplied.","operationId":"delete_comment_v1_comments__comment_id__delete","parameters":[{"name":"comment_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Comment Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/databases/{database_id}":{"get":{"tags":["notion-compat"],"summary":"Get Database","operationId":"get_database_v1_databases__database_id__get","parameters":[{"name":"database_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Database Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DatabaseResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]},"patch":{"tags":["notion-compat"],"summary":"Update Database","operationId":"update_database_v1_databases__database_id__patch","parameters":[{"name":"database_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Database Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateBoardRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DatabaseResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/databases/{database_id}/query":{"post":{"tags":["notion-compat"],"summary":"Query Database","operationId":"query_database_v1_databases__database_id__query_post","parameters":[{"name":"database_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Database Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BoardQueryRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_CardResponse_"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/data_sources/{data_source_id}":{"get":{"tags":["notion-compat"],"summary":"Get Data Source","operationId":"get_data_source_v1_data_sources__data_source_id__get","parameters":[{"name":"data_source_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Data Source Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataSourceResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/data_sources/{data_source_id}/query":{"post":{"tags":["notion-compat"],"summary":"Query Data Source","operationId":"query_data_source_v1_data_sources__data_source_id__query_post","parameters":[{"name":"data_source_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Data Source Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BoardQueryRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_CardResponse_"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/pages":{"post":{"tags":["notion-compat"],"summary":"Create Page","operationId":"create_page_v1_pages_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCardRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PageResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}],"parameters":[{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}]}},"/v1/pages/{page_id}":{"get":{"tags":["notion-compat"],"summary":"Get Page","operationId":"get_page_v1_pages__page_id__get","parameters":[{"name":"page_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Page Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PageResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]},"patch":{"tags":["notion-compat"],"summary":"Update Page","description":"Update a card via the Notion-shape `PATCH /v1/pages/{id}` alias.\n\nPromotes built-in Notion properties (Status, Assignees, Due, Labels) to\nfirst-class card columns before delegating (NOV-63 B6). Unknown\nproperty names pass through unchanged.\n\nNOV-82: a Status property write resolves to the named board column and\nmoves the card via the canonical move path. A name that matches no\ncolumn on the card's board is rejected as 400. The single emitted event\nis ``card.moved`` — the legacy ``card.status_changed`` event is gone\n(the column move IS the status change).","operationId":"update_page_v1_pages__page_id__patch","parameters":[{"name":"page_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Page Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCardRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PageResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/pages/{page_id}/properties/{prop_id}":{"get":{"tags":["notion-compat"],"summary":"Get Page Property","operationId":"get_page_property_v1_pages__page_id__properties__prop_id__get","parameters":[{"name":"page_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Page Id"}},{"name":"prop_id","in":"path","required":true,"schema":{"type":"string","title":"Prop Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PropertyItemResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/blocks/{parent_id}/children":{"get":{"tags":["blocks"],"summary":"List Block Children","description":"Fetch a card's body tree, recursing up to ``depth`` levels (spec §6.4).","operationId":"list_block_children_v1_blocks__parent_id__children_get","parameters":[{"name":"parent_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Parent Id"}},{"name":"depth","in":"query","required":false,"schema":{"type":"integer","maximum":10,"minimum":1,"default":1,"title":"Depth"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response List Block Children V1 Blocks  Parent Id  Children Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]},"patch":{"tags":["blocks"],"summary":"Append Block Children","description":"Append a run of blocks under ``parent_id`` (card or block).\n\nOptional ``after`` selects a sibling to insert AFTER (Notion shape);\notherwise blocks land at the end.\n\nNOV-168: an optional ``Idempotency-Key`` header makes the append safe to\nretry. Absent ⇒ today's behavior (append normally). Present ⇒ a replay\nwith the same key returns the original response without re-appending.","operationId":"append_block_children_v1_blocks__parent_id__children_patch","parameters":[{"name":"parent_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Parent Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppendBlocksRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Append Block Children V1 Blocks  Parent Id  Children Patch"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/blocks/{block_id}":{"patch":{"tags":["blocks"],"summary":"Update Block","description":"Modify a block. ``If-Match`` is ACCEPTED but ADVISORY (NOV-169, spec §8.1).\n\nBody blocks are server-authoritative last-write-wins: a stale/wrong\n``If-Match`` never 412s, the write merges. The header is still read and\nforwarded for back-compat (the frontend keeps sending it until P4/NOV-170);\n``update_block_for_principal`` parses-and-ignores it.","operationId":"update_block_v1_blocks__block_id__patch","parameters":[{"name":"block_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Block Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateBlockRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Update Block V1 Blocks  Block Id  Patch"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]},"delete":{"tags":["blocks"],"summary":"Delete Block","description":"Soft-archive a block + its descendants.","operationId":"delete_block_v1_blocks__block_id__delete","parameters":[{"name":"block_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Block Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/files:upload":{"post":{"tags":["files"],"summary":"Presign Upload","description":"Mint a presigned PUT URL for a card attachment.\n\nBody: ``{card_id, filename, content_type, size_bytes?}``. Returns the\nfile envelope plus ``upload_url`` + ``upload_url_expires_in``. The\nclient then PUTs the bytes to ``upload_url`` (NOT through us — direct\nto S3) and calls ``:commit`` once done.","operationId":"presign_upload_v1_files_upload_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateFileUploadRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Presign Upload V1 Files Upload Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}],"parameters":[{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}]}},"/v1/files/{file_id}:commit":{"post":{"tags":["files"],"summary":"Commit File","description":"Finalize an upload: HeadObject the bytes + flip status to available.","operationId":"commit_file_v1_files__file_id__commit_post","parameters":[{"name":"file_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"File Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Commit File V1 Files  File Id  Commit Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/files/{file_id}":{"get":{"tags":["files"],"summary":"Get File","description":"Metadata + presigned GET URL for an ``available`` file.","operationId":"get_file_v1_files__file_id__get","parameters":[{"name":"file_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"File Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get File V1 Files  File Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]},"delete":{"tags":["files"],"summary":"Delete File","description":"Soft-archive a file + fire `card.updated` webhook for the removal.","operationId":"delete_file_v1_files__file_id__delete","parameters":[{"name":"file_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"File Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/cards/{card_id}/attachments":{"get":{"tags":["files"],"summary":"List Card Attachments","description":"Notion-shape list of a card's `available` attachments.","operationId":"list_card_attachments_v1_cards__card_id__attachments_get","parameters":[{"name":"card_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Card Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response List Card Attachments V1 Cards  Card Id  Attachments Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/admin/orgs":{"get":{"tags":["admin"],"summary":"List Admin Orgs","operationId":"list_admin_orgs_v1_admin_orgs_get","parameters":[{"name":"q","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Q"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":25,"title":"Page Size"}},{"name":"start_cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Start Cursor"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_AdminOrgRow_"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/admin/orgs/{org_id}":{"get":{"tags":["admin"],"summary":"Get Admin Org","operationId":"get_admin_org_v1_admin_orgs__org_id__get","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminOrgRow"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/admin/billing/orgs":{"get":{"tags":["admin"],"summary":"List Admin Billing Orgs","description":"Per-org billing state across all tenants (spec §18.10).\n\nPaginated + searchable (name/slug). ``?status=past_due`` is the\nfailed-payment list. ``billable_seats`` is recomputed LIVE; revenue is a\nper-kind estimate (``humans × $1 + billable_agents × $1`` at the annual\nmonthly-equivalent display rates — NOV-370) on Pro, 0 on free; ``drift`` is\nthe reconciliation descriptor recorded by the daily cron.","operationId":"list_admin_billing_orgs_v1_admin_billing_orgs_get","parameters":[{"name":"q","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Q"}},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":25,"title":"Page Size"}},{"name":"start_cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Start Cursor"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_AdminBillingOrgRow_"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/admin/orgs/{org_id}/grants":{"post":{"tags":["admin"],"summary":"Create Org Grant","operationId":"create_org_grant_v1_admin_orgs__org_id__grants_post","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GrantOrgCompRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgGrantRow"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]},"get":{"tags":["admin"],"summary":"List Org Grants","operationId":"list_org_grants_v1_admin_orgs__org_id__grants_get","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"name":"include_history","in":"query","required":false,"schema":{"type":"boolean","default":true,"title":"Include History"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_OrgGrantRow_"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/admin/orgs/{org_id}/grants/{grant_id}":{"delete":{"tags":["admin"],"summary":"Revoke Org Grant","operationId":"revoke_org_grant_v1_admin_orgs__org_id__grants__grant_id__delete","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"name":"grant_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Grant Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"requestBody":{"content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/RevokeOrgGrantRequest"},{"type":"null"}],"title":"Payload"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgGrantRow"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/admin/users":{"get":{"tags":["admin"],"summary":"List Admin Users","operationId":"list_admin_users_v1_admin_users_get","parameters":[{"name":"q","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Q"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":25,"title":"Page Size"}},{"name":"start_cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Start Cursor"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_AdminUserRow_"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/admin/users/{user_id}":{"get":{"tags":["admin"],"summary":"Get Admin User","operationId":"get_admin_user_v1_admin_users__user_id__get","parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminUserRow"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/admin/audit":{"get":{"tags":["admin"],"summary":"List Admin Audit","operationId":"list_admin_audit_v1_admin_audit_get","parameters":[{"name":"org_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Org Id"}},{"name":"user_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"User Id"}},{"name":"event_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Event Type"}},{"name":"since","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Since"}},{"name":"until","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Until"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Page Size"}},{"name":"start_cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Start Cursor"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_AdminAuditRow_"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/admin/admins":{"get":{"tags":["admin"],"summary":"List Platform Admins Short","operationId":"list_platform_admins_short_v1_admin_admins_get","parameters":[{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":100,"title":"Page Size"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_PlatformAdminRow_"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]},"post":{"tags":["admin"],"summary":"Grant Platform Admin Short","operationId":"grant_platform_admin_short_v1_admin_admins_post","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GrantPlatformAdminRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlatformAdminRow"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}],"parameters":[{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}]}},"/v1/admin/platform-admins":{"get":{"tags":["admin"],"summary":"List Platform Admins","operationId":"list_platform_admins_v1_admin_platform_admins_get","parameters":[{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":100,"title":"Page Size"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_PlatformAdminRow_"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]},"post":{"tags":["admin"],"summary":"Grant Platform Admin","operationId":"grant_platform_admin_v1_admin_platform_admins_post","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GrantPlatformAdminRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlatformAdminRow"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}],"parameters":[{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}]}},"/v1/admin/admins/{user_id}":{"delete":{"tags":["admin"],"summary":"Revoke Platform Admin Short","operationId":"revoke_platform_admin_short_v1_admin_admins__user_id__delete","parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/admin/platform-admins/{user_id}":{"delete":{"tags":["admin"],"summary":"Revoke Platform Admin","operationId":"revoke_platform_admin_v1_admin_platform_admins__user_id__delete","parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/search":{"post":{"tags":["search"],"summary":"Search","description":"Full-text search across the caller's org (spec §8.2).\n\nNOV-457: the service still assembles the Notion-shape envelope as a dict —\nthe MCP wrapper consumes it in that form — so the router validates it into\nthe declared model. That is deliberate: the published schema is then the\nsame object the response is serialized from, rather than a promise made\nalongside an untyped blob.","operationId":"search_v1_search_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_SearchHitResponse_"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}],"parameters":[{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}]}},"/v1/orgs/{org_id}/export":{"get":{"tags":["export"],"summary":"Export Org","description":"Export the entire workspace as one JSON document (owner/admin only).","operationId":"export_org_v1_orgs__org_id__export_get","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/boards/{board_id}/export":{"get":{"tags":["export"],"summary":"Export Board","description":"Export a single board (columns + cards + block bodies + comments).","operationId":"export_board_v1_boards__board_id__export_get","parameters":[{"name":"board_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Board Id"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/webhooks":{"get":{"tags":["webhooks"],"summary":"List Webhooks","description":"List webhooks visible to the caller's org. Newest first.","operationId":"list_webhooks_v1_webhooks_get","parameters":[{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":25,"title":"Page Size"}},{"name":"start_cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Start Cursor"}},{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_WebhookResponse_"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]},"post":{"tags":["webhooks"],"summary":"Create Webhook","operationId":"create_webhook_v1_webhooks_post","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWebhookRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWebhookResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}],"parameters":[{"name":"X-Board-Version","in":"header","required":true,"schema":{"type":"string","default":"2026-06-19"},"description":"Required on every `/v1` request. Send `2026-06-19`. The middleware validates *presence*, not the value, so an older pinned date keeps working; `Notion-Version` is accepted as a Notion-SDK compatibility fallback when this header is absent."}]}},"/v1/webhooks/{webhook_id}":{"get":{"tags":["webhooks"],"summary":"Get Webhook","operationId":"get_webhook_v1_webhooks__webhook_id__get","parameters":[{"name":"webhook_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Webhook Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]},"patch":{"tags":["webhooks"],"summary":"Update Webhook","operationId":"update_webhook_v1_webhooks__webhook_id__patch","parameters":[{"name":"webhook_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Webhook Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateWebhookRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]},"delete":{"tags":["webhooks"],"summary":"Delete Webhook","operationId":"delete_webhook_v1_webhooks__webhook_id__delete","parameters":[{"name":"webhook_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Webhook Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/webhooks/{webhook_id}:rotate-secret":{"post":{"tags":["webhooks"],"summary":"Rotate Webhook Secret","description":"Mint a new secret. Old one is unusable from the next request on.\n\nReturns the new plaintext exactly once. There's a brief window between\nrotation and the receiver knowing about the new key, during which\nin-flight deliveries (already signed with the OLD secret) keep flowing.\nThat's intentional — pending rows were signed before rotation and the\nreceiver should still accept them; in steady state new events use the\nnew key.","operationId":"rotate_webhook_secret_v1_webhooks__webhook_id__rotate_secret_post","parameters":[{"name":"webhook_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Webhook Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWebhookResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/webhooks/{webhook_id}/deliveries":{"get":{"tags":["webhooks"],"summary":"List Deliveries","operationId":"list_deliveries_v1_webhooks__webhook_id__deliveries_get","parameters":[{"name":"webhook_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Webhook Id"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":25,"title":"Page Size"}},{"name":"start_cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Start Cursor"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_WebhookDeliveryResponse_"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/webhooks/{webhook_id}/deliveries/{delivery_id}:replay":{"post":{"tags":["webhooks"],"summary":"Replay Delivery","description":"Re-enqueue a past delivery. Same event_id so receivers dedup correctly.","operationId":"replay_delivery_v1_webhooks__webhook_id__deliveries__delivery_id__replay_post","parameters":[{"name":"webhook_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Webhook Id"}},{"name":"delivery_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Delivery Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookDeliveryResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"IntegrationToken":[]}]}},"/v1/sse/notifications":{"get":{"tags":["realtime"],"summary":"Notifications Sse","description":"Stream the caller's PRIVATE notifications over SSE (spec §22.3, NOV-362).\n\nThe SSE fallback for ``/v1/ws/notifications`` — same auth model, same\nper-user channel derived from the authenticated principal (never a\nclient-supplied id), for environments where WebSockets are blocked. 401 if\nanonymous; 404 if the principal has no attached user (no inbox), mirroring\nthe REST posture (defense-in-depth: the auth layer already rejects\nuserless integration tokens, NOV-299, so real tokens land on 401 first).\nOrg-bound integration tokens receive ONLY their org's frames\n(``user_frame_permitted``); credentials are re-validated mid-stream every\n``USER_CHANNEL_REAUTH_INTERVAL_S`` and the stream ends with\n``subscription.closed`` (``unauthorized``) once they no longer resolve.","operationId":"notifications_sse_v1_sse_notifications_get","parameters":[{"name":"token","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/sse":{"get":{"tags":["realtime"],"summary":"Board Sse","description":"Stream a board's realtime events over SSE (spec §22.3, NOV-28).\n\nNOV-392 / spec §9.2: ``?last_sequence=N`` resumes a reconnecting client by\nreplaying events with ``sequence > N`` before live streaming starts — full\nparity with the ``/v1/ws`` gateway (the SSE path previously had ZERO replay\nand silently lost every event created during a reconnect gap). If ``N``\npredates the retention window the server emits a ``snapshot_required`` frame\nand closes, and the client falls back to a full REST refetch.","operationId":"board_sse_v1_sse_get","parameters":[{"name":"board_id","in":"query","required":true,"schema":{"type":"string","title":"Board Id"}},{"name":"token","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Token"}},{"name":"last_sequence","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Last Sequence"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/healthz":{"get":{"tags":["meta"],"summary":"Health","operationId":"health_healthz_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":{"anyOf":[{"type":"string"},{"type":"null"}]},"type":"object","title":"Response Health Healthz Get"}}}}}}}},"components":{"schemas":{"AccessUser":{"properties":{"object":{"type":"string","title":"Object","default":"user"},"id":{"type":"string","format":"uuid","title":"Id"},"kind":{"type":"string","title":"Kind"},"display_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Display Name"},"avatar":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Avatar"}},"additionalProperties":false,"type":"object","required":["id","kind"],"title":"AccessUser","description":"The grantee, shaped like the Notion person reference (§5.1)."},"AddAgentTokenRequest":{"properties":{"name":{"type":"string","maxLength":200,"minLength":1,"title":"Name"},"role":{"type":"string","enum":["member","admin"],"title":"Role","default":"member"}},"type":"object","required":["name"],"title":"AddAgentTokenRequest","description":"Body for POST /v1/orgs/{org_id}/agents/{agent_user_id}/tokens (NOV-190).\n\nMints an additional Integration (credential) owned by an EXISTING agent —\nthe rotation / multi-Lambda-fleet case (spec §4.2, §4.5). Tokens are\nchildren of an agent; adding one does not add a seat (the agent already\ncounts), so there is no billing recompute."},"AddMemberRequest":{"properties":{"email":{"type":"string","title":"Email"},"role":{"type":"string","title":"Role","default":"member"}},"type":"object","required":["email"],"title":"AddMemberRequest"},"AdminAuditRow":{"properties":{"object":{"type":"string","title":"Object","default":"audit_event"},"id":{"type":"string","format":"uuid","title":"Id"},"org_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Org Id"},"actor_kind":{"type":"string","title":"Actor Kind"},"actor_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Actor Id"},"event_type":{"type":"string","title":"Event Type"},"target_kind":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Target Kind"},"target_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Target Id"},"metadata":{"additionalProperties":true,"type":"object","title":"Metadata"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"occurred_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Occurred At"}},"type":"object","required":["id","actor_kind","event_type","created_at"],"title":"AdminAuditRow"},"AdminBillingOrgRow":{"properties":{"object":{"type":"string","title":"Object","default":"billing_org"},"org_id":{"type":"string","format":"uuid","title":"Org Id"},"name":{"type":"string","title":"Name"},"slug":{"type":"string","title":"Slug"},"plan":{"type":"string","title":"Plan","default":"free"},"status":{"type":"string","title":"Status","default":"active"},"billable_seats":{"type":"integer","title":"Billable Seats","default":0},"monthly_revenue_usd":{"type":"integer","title":"Monthly Revenue Usd","default":0},"stripe_customer_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Stripe Customer Id"},"stripe_subscription_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Stripe Subscription Id"},"current_period_end":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Current Period End"},"cancel_at_period_end":{"type":"boolean","title":"Cancel At Period End","default":false},"seats_synced_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Seats Synced At"},"drift":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Drift"}},"type":"object","required":["org_id","name","slug"],"title":"AdminBillingOrgRow","description":"One row of the admin billing overview (spec §18.10).\n\n``billable_seats`` is recomputed LIVE via ``count_billable_seats`` —\nnever the stale ``billing_seats`` cache. ``monthly_revenue_usd`` is a\nper-kind estimate on Pro (``humans × $1 + billable_agents × $1`` at the\nannual monthly-equivalent display rates — NOV-370), ``0`` on free. ``drift``\nis the reconciliation-cron descriptor (``None`` when reconciled)."},"AdminOrgRow":{"properties":{"object":{"type":"string","title":"Object","default":"organization"},"id":{"type":"string","format":"uuid","title":"Id"},"name":{"type":"string","title":"Name"},"slug":{"type":"string","title":"Slug"},"primary_domain":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Primary Domain"},"billing_plan":{"type":"string","title":"Billing Plan","default":"free"},"billing_status":{"type":"string","title":"Billing Status","default":"active"},"billing_seats":{"type":"integer","title":"Billing Seats","default":0},"member_count":{"type":"integer","title":"Member Count","default":0},"board_count":{"type":"integer","title":"Board Count","default":0},"last_active_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Active At"},"created_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Created At"}},"type":"object","required":["id","name","slug"],"title":"AdminOrgRow"},"AdminUserRow":{"properties":{"object":{"type":"string","title":"Object","default":"user"},"id":{"type":"string","format":"uuid","title":"Id"},"email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"avatar_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Avatar Url"},"email_verified":{"type":"boolean","title":"Email Verified","default":false},"disabled":{"type":"boolean","title":"Disabled","default":false},"signup_source":{"type":"string","title":"Signup Source","default":"email"},"last_login_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Login At"},"created_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Created At"},"orgs":{"items":{"$ref":"#/components/schemas/MembershipResponse"},"type":"array","title":"Orgs"}},"type":"object","required":["id"],"title":"AdminUserRow"},"AgentActivity":{"properties":{"agent_name":{"type":"string","title":"Agent Name"},"doing":{"type":"string","title":"Doing"},"started_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Started At"}},"additionalProperties":false,"type":"object","required":["agent_name","doing"],"title":"AgentActivity","description":"NOV-86 / NOV-91: \"an agent is working on this card right now\" payload.\n\nStored as ``cards.agent_activity`` JSONB. Set via\n``POST /v1/cards/{id}/agent_activity``, cleared via the matching\nDELETE, the next mutation on the card, or a 10-minute TTL on read\n(NOV-91 lifecycle).\n\nThe model is strict (``extra=\"forbid\"`` + required fields) but\n``started_at`` is optional so legacy blobs written before NOV-91\ndon't fail validation. The outer ``CardResponse.agent_activity``\nvalidator silently downgrades a malformed stored blob to ``None``\nso a bad write from the agent runtime can't 500 every card read."},"AgentActivityEntry":{"properties":{"object":{"type":"string","title":"Object","default":"agent_activity_entry"},"action":{"type":"string","title":"Action"},"label":{"type":"string","title":"Label"},"board_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Board Id"},"card_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Card Id"},"outcome":{"type":"string","title":"Outcome"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["action","label","outcome","created_at"],"title":"AgentActivityEntry","description":"One reverse-chron feed row — a single successful agent action."},"AgentActivityResponse":{"properties":{"object":{"type":"string","title":"Object","default":"agent_activity"},"agent_user_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Agent User Id"},"summary":{"$ref":"#/components/schemas/AgentActivitySummary"},"entries":{"items":{"$ref":"#/components/schemas/AgentActivityEntry"},"type":"array","title":"Entries"},"has_more":{"type":"boolean","title":"Has More","default":false},"next_cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Cursor"},"page_size":{"type":"integer","title":"Page Size","default":25}},"type":"object","required":["summary","entries"],"title":"AgentActivityResponse","description":"Response for the per-agent and all-agents activity endpoints (spec §4.7 ledger).\n\n``agent_user_id`` is set for the per-agent view and ``None`` for the org-wide\nrollup. ``entries`` is the cursor-paginated feed; ``next_cursor`` is present\nonly when ``has_more``."},"AgentActivitySummary":{"properties":{"object":{"type":"string","title":"Object","default":"agent_activity_summary"},"by_action":{"additionalProperties":{"type":"integer"},"type":"object","title":"By Action"},"errors":{"type":"integer","title":"Errors"},"window":{"type":"string","title":"Window"}},"type":"object","required":["by_action","errors","window"],"title":"AgentActivitySummary","description":"Rollup line for the activity drawer — \"47 drafts, 3 card-moves, 0 errors · 24h\".\n\n``by_action`` maps a human label (``draft`` / ``card-move`` / ``card-create``\n/ ``card-update``) to its count within ``window``. ``errors`` = ledger\nfailures (0 in MVP) PLUS ``agent.request_denied`` budget denials in-window\n(see :func:`app.services.agent_ledger.agent_activity_summary`)."},"AgentBudgetResponse":{"properties":{"object":{"type":"string","title":"Object","default":"agent_budget"},"agent_user_id":{"type":"string","format":"uuid","title":"Agent User Id"},"board_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Board Id"},"writes_per_day":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Writes Per Day"},"requests_per_sec":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Requests Per Sec"},"auto_pause":{"type":"boolean","title":"Auto Pause","default":false},"paused":{"type":"boolean","title":"Paused"},"paused_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Paused Reason"},"paused_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Paused At"},"usage":{"$ref":"#/components/schemas/AgentBudgetUsage"}},"type":"object","required":["agent_user_id","paused","usage"],"title":"AgentBudgetResponse","description":"Response for GET / PUT of an agent's budget (spec §4.7 budgets).\n\nSurfaces the two caps plus the read-only kill-switch state (``paused`` /\n``paused_reason`` / ``paused_at`` — the kill switch is mutated only via\n:pause / :resume, but is DISCOVERABLE here per the team-lead ruling) and live\ncounter ``usage``. ``board_id`` is ``null`` for the ORG-WIDE budget and set\nfor a per-board override (NOV-271)."},"AgentBudgetUpdateRequest":{"properties":{"writes_per_day":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Writes Per Day"},"requests_per_sec":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Requests Per Sec"},"auto_pause":{"type":"boolean","title":"Auto Pause","default":false}},"type":"object","title":"AgentBudgetUpdateRequest","description":"Body for PUT /v1/orgs/{org_id}/agents/{agent_user_id}/budget.\n\nPUT-replace semantics: each cap is set to the supplied value; a field set to\n``null`` (or omitted) CLEARS that cap (unlimited / fall back to the flat\nintegration limit). Each must be ``null`` or a non-negative int (``ge=0``);\na negative value fails validation (422). This never touches paused /\nprovenance — that is the kill switch's job (:pause / :resume).\n\n``auto_pause`` (NOV-272) toggles whether tripping this row's writes/day cap\nauto-pauses the agent (its own kill switch). PUT-replace like the caps:\nomitted / ``false`` clears it. It is the one non-cap governance knob set here\nbecause it is a property of the budget, not a manual pause action."},"AgentBudgetUsage":{"properties":{"object":{"type":"string","title":"Object","default":"agent_budget_usage"},"writes_24h":{"type":"integer","title":"Writes 24H"},"requests_last_sec":{"type":"integer","title":"Requests Last Sec"}},"type":"object","required":["writes_24h","requests_last_sec"],"title":"AgentBudgetUsage","description":"Live per-agent counter usage, read from the limiter's Redis windows.\n\nBoth counts come from :func:`app.core.rate_limit.peek_window_count` (read-only\n— surfacing them never consumes budget), and both fail open to ``0`` when\nRedis is unset/unreachable."},"AgentKillSwitchResponse":{"properties":{"object":{"type":"string","title":"Object","default":"agent_kill_switch"},"agent_user_id":{"type":"string","format":"uuid","title":"Agent User Id"},"paused":{"type":"boolean","title":"Paused"},"paused_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Paused At"},"paused_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Paused Reason"}},"type":"object","required":["agent_user_id","paused"],"title":"AgentKillSwitchResponse","description":"Response for :pause / :resume (spec §4.7 kill switch).\n\nMirrors the reversible ``agent_budgets`` kill-switch columns so the caller\n(UI / MCP wrapper) can render the new paused state without a re-read."},"AgentPresence":{"properties":{"object":{"type":"string","title":"Object","default":"agent_presence"},"user_id":{"type":"string","title":"User Id"},"display_name":{"type":"string","title":"Display Name"}},"type":"object","required":["user_id","display_name"],"title":"AgentPresence","description":"One live-agent row, returned by GET /v1/orgs/{org_id}/presence/agents."},"AiRunUsageResponse":{"properties":{"object":{"type":"string","title":"Object","default":"ai_run_usage"},"id":{"type":"string","format":"uuid","title":"Id"},"org_id":{"type":"string","format":"uuid","title":"Org Id"},"board_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Board Id"},"card_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Card Id"},"column_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Column Id"},"playbook_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Playbook Id"},"automation_run_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Automation Run Id"},"model":{"type":"string","title":"Model"},"step_count":{"type":"integer","title":"Step Count"},"tokens_in":{"type":"integer","title":"Tokens In"},"tokens_out":{"type":"integer","title":"Tokens Out"},"cost_estimate_usd":{"type":"string","title":"Cost Estimate Usd"},"status":{"type":"string","title":"Status"},"created_time":{"type":"string","format":"date-time","title":"Created Time"}},"type":"object","required":["id","org_id","board_id","card_id","column_id","playbook_id","automation_run_id","model","step_count","tokens_in","tokens_out","cost_estimate_usd","status","created_time"],"title":"AiRunUsageResponse","description":"One metered Autopilot run in the run-history feed (spec §23.6)."},"AppendBlocksRequest":{"properties":{"children":{"items":{"$ref":"#/components/schemas/BlockInput"},"type":"array","maxItems":100,"minItems":1,"title":"Children"},"after":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"After"}},"additionalProperties":false,"type":"object","required":["children"],"title":"AppendBlocksRequest","description":"`PATCH /v1/blocks/{parent_id}/children` body."},"AuthSessionResponse":{"properties":{"object":{"type":"string","title":"Object","default":"auth_session"},"user":{"$ref":"#/components/schemas/UserResponse"},"memberships":{"items":{"$ref":"#/components/schemas/MembershipResponse"},"type":"array","title":"Memberships"}},"type":"object","required":["user","memberships"],"title":"AuthSessionResponse","description":"Returned by login / verify-email: who you are + your orgs."},"AutomationResponse":{"properties":{"object":{"type":"string","title":"Object","default":"automation"},"id":{"type":"string","format":"uuid","title":"Id"},"org_id":{"type":"string","format":"uuid","title":"Org Id"},"board_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Board Id"},"name":{"type":"string","title":"Name"},"is_active":{"type":"boolean","title":"Is Active"},"trigger":{"additionalProperties":true,"type":"object","title":"Trigger"},"conditions":{"items":{},"type":"array","title":"Conditions"},"actions":{"items":{},"type":"array","title":"Actions"},"run_as_agent_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Run As Agent Id"},"created_time":{"type":"string","format":"date-time","title":"Created Time"},"last_edited_time":{"type":"string","format":"date-time","title":"Last Edited Time"}},"type":"object","required":["id","org_id","board_id","name","is_active","trigger","conditions","actions","run_as_agent_id","created_time","last_edited_time"],"title":"AutomationResponse"},"AutomationRunResponse":{"properties":{"object":{"type":"string","title":"Object","default":"automation_run"},"id":{"type":"string","format":"uuid","title":"Id"},"automation_id":{"type":"string","format":"uuid","title":"Automation Id"},"org_id":{"type":"string","format":"uuid","title":"Org Id"},"card_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Card Id"},"source_sequence":{"type":"integer","title":"Source Sequence"},"status":{"type":"string","title":"Status"},"attempts":{"type":"integer","title":"Attempts"},"next_retry_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Next Retry At"},"chain_depth":{"type":"integer","title":"Chain Depth"},"action_results":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Action Results"},"created_time":{"type":"string","format":"date-time","title":"Created Time"}},"type":"object","required":["id","automation_id","org_id","card_id","source_sequence","status","attempts","next_retry_at","chain_depth","action_results","created_time"],"title":"AutomationRunResponse"},"BatchOp":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"op":{"type":"string","enum":["set","move","delete"],"title":"Op"},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"properties":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Properties"},"assignees":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Assignees"},"due_date":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Due Date"},"labels":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Labels"},"remove_labels":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Remove Labels"},"is_archived":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Archived"},"column_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Column Id"},"position":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Position"}},"additionalProperties":false,"type":"object","required":["id","op"],"title":"BatchOp"},"BatchOpResult":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"op":{"type":"string","enum":["set","move","delete"],"title":"Op"},"ok":{"type":"boolean","title":"Ok"},"card":{"anyOf":[{"$ref":"#/components/schemas/CardResponse"},{"type":"null"}]},"error":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Error"}},"additionalProperties":false,"type":"object","required":["id","op","ok"],"title":"BatchOpResult"},"BatchUpdateRequest":{"properties":{"ops":{"items":{"$ref":"#/components/schemas/BatchOp"},"type":"array","maxItems":200,"minItems":1,"title":"Ops"}},"additionalProperties":false,"type":"object","required":["ops"],"title":"BatchUpdateRequest"},"BatchUpdateResponse":{"properties":{"object":{"type":"string","title":"Object","default":"list"},"results":{"items":{"$ref":"#/components/schemas/BatchOpResult"},"type":"array","title":"Results"}},"additionalProperties":false,"type":"object","required":["results"],"title":"BatchUpdateResponse"},"BillingResponse":{"properties":{"object":{"type":"string","title":"Object","default":"billing"},"org_id":{"type":"string","format":"uuid","title":"Org Id"},"plan":{"type":"string","title":"Plan"},"status":{"type":"string","title":"Status"},"billable_seats":{"type":"integer","title":"Billable Seats"},"seat_breakdown":{"$ref":"#/components/schemas/SeatBreakdown"},"free_caps":{"$ref":"#/components/schemas/FreeCaps"},"current_period_end":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Current Period End"},"cancel_at_period_end":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Cancel At Period End"},"has_payment_method":{"type":"boolean","title":"Has Payment Method","default":false},"governance_enabled":{"type":"boolean","title":"Governance Enabled","default":false}},"type":"object","required":["org_id","plan","status","billable_seats","seat_breakdown","free_caps"],"title":"BillingResponse","description":"Billing status object for ``GET /v1/orgs/{org_id}/billing`` (spec §18.9).\n\n``billable_seats`` is the **live** count (``count_billable_seats``), never\nthe denormalized ``billing_seats`` cache. ``seat_breakdown`` is the\nserver-computed humans/agents split (the first-agent-free math lives there,\nnot the client — NOV-189). On a free org ``current_period_end`` and\n``cancel_at_period_end`` are null and ``has_payment_method`` is false."},"BlockInput":{"properties":{"object":{"type":"string","title":"Object","default":"block"},"type":{"type":"string","title":"Type"}},"additionalProperties":true,"type":"object","required":["type"],"title":"BlockInput","description":"One node in a `PATCH /v1/blocks/{id}/children` request body.\n\nMatches Notion's append-children shape: ``{\"object\": \"block\", \"type\":\n\"paragraph\", \"paragraph\": {...}}``. ``object`` is optional — clients\nsometimes omit it."},"BoardAccessListResponse":{"properties":{"object":{"type":"string","title":"Object","default":"list"},"visibility":{"type":"string","title":"Visibility"},"workspace_access":{"type":"string","title":"Workspace Access","default":"edit"},"permissions":{"additionalProperties":{"type":"string"},"type":"object","title":"Permissions"},"your_role":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Your Role"},"can_manage":{"type":"boolean","title":"Can Manage","default":false},"results":{"items":{"$ref":"#/components/schemas/BoardGrantResponse"},"type":"array","title":"Results"}},"additionalProperties":false,"type":"object","required":["visibility","results"],"title":"BoardAccessListResponse","description":"List of grants plus the board's access posture (§4.6).\n\nIncludes the board's ``visibility`` (NOV-195) and the ``workspace_access`` /\n``permissions`` configuration (NOV-216) so a sharing client — REST or an MCP\nagent — has the full picture in one call.\n\nNOV-218: also carries the CALLER's effective board role (``your_role``) and a\nderived ``can_manage`` flag, so a client can gate manage affordances on the\nbackend's real board-role resolution instead of approximating from org role.\n``your_role`` is one of ``viewer``/``commenter``/``editor``/``manager`` (or\n``None`` when the caller has no access — in practice never ``None`` here,\nsince listing already requires viewer); ``can_manage`` is exactly\n``role_satisfies(your_role, \"manager\")``."},"BoardColumnResponse":{"properties":{"object":{"type":"string","title":"Object","default":"board_column"},"id":{"type":"string","format":"uuid","title":"Id"},"board_id":{"type":"string","format":"uuid","title":"Board Id"},"name":{"type":"string","title":"Name"},"color":{"type":"string","title":"Color"},"role":{"type":"string","title":"Role"},"position":{"type":"number","title":"Position"},"is_default":{"type":"boolean","title":"Is Default"},"status_group":{"type":"string","title":"Status Group"},"autopilot":{"type":"boolean","title":"Autopilot","default":false},"playbook_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Playbook Id"},"autopilot_label_gate":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Autopilot Label Gate"},"created_time":{"type":"string","format":"date-time","title":"Created Time"},"last_edited_time":{"type":"string","format":"date-time","title":"Last Edited Time"},"etag":{"type":"integer","title":"Etag"}},"additionalProperties":false,"type":"object","required":["id","board_id","name","color","role","position","is_default","status_group","created_time","last_edited_time","etag"],"title":"BoardColumnResponse"},"BoardGrantResponse":{"properties":{"object":{"type":"string","title":"Object","default":"board_grant"},"id":{"type":"string","format":"uuid","title":"Id"},"user":{"$ref":"#/components/schemas/AccessUser"},"role":{"type":"string","title":"Role"},"granted_by":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Granted By"},"granted_at":{"type":"string","format":"date-time","title":"Granted At"}},"additionalProperties":false,"type":"object","required":["id","user","role","granted_at"],"title":"BoardGrantResponse"},"BoardLabelResponse":{"properties":{"object":{"type":"string","title":"Object","default":"board_label"},"name":{"type":"string","title":"Name"},"color":{"type":"string","title":"Color"},"count":{"type":"integer","title":"Count"}},"type":"object","required":["name","color","count"],"title":"BoardLabelResponse","description":"One entry in a board's label vocabulary (NOV-437 / §7).\n\nLabels are a card built-in, not a board schema property. Nothing stops\nsomeone creating a ``multi_select`` property named \"Labels\" — only ``Status``\nis reserved (``app/services/properties.py``) — but the built-in shadows it on\nthe card read, so a schema entry can never describe a card's actual labels.\nGET /v1/boards/{id}/labels aggregates the labels\nactually in use on the board's non-archived cards: one entry per distinct\nname (merged case-insensitively), carrying the name's most-used ``color``\nand the total ``count`` across every color it has been written with."},"BoardQueryRequest":{"properties":{"filter":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Filter"},"sorts":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Sorts"},"page_size":{"type":"integer","title":"Page Size","default":25},"start_cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Start Cursor"}},"additionalProperties":false,"type":"object","title":"BoardQueryRequest"},"BoardResponse":{"properties":{"object":{"type":"string","title":"Object","default":"board"},"id":{"type":"string","format":"uuid","title":"Id"},"org_id":{"type":"string","format":"uuid","title":"Org Id"},"name":{"type":"string","title":"Name"},"slug":{"type":"string","title":"Slug"},"description":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Description"},"icon":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Icon"},"cover":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Cover"},"default_view_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Default View Id"},"status_groups":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Status Groups"},"properties":{"additionalProperties":{"additionalProperties":true,"type":"object"},"type":"object","title":"Properties"},"visibility":{"type":"string","title":"Visibility","default":"org"},"workspace_access":{"type":"string","title":"Workspace Access","default":"edit"},"permissions":{"additionalProperties":{"type":"string"},"type":"object","title":"Permissions"},"property_validation":{"type":"string","title":"Property Validation","default":"permissive"},"has_active_share_links":{"type":"boolean","title":"Has Active Share Links","default":false},"is_archived":{"type":"boolean","title":"Is Archived"},"created_time":{"type":"string","format":"date-time","title":"Created Time"},"last_edited_time":{"type":"string","format":"date-time","title":"Last Edited Time"},"etag":{"type":"integer","title":"Etag"}},"additionalProperties":false,"type":"object","required":["id","org_id","name","slug","status_groups","is_archived","created_time","last_edited_time","etag"],"title":"BoardResponse"},"BoardTemplateColumnPreview":{"properties":{"name":{"type":"string","title":"Name"},"status_group":{"type":"string","title":"Status Group"},"color":{"type":"string","title":"Color"},"role":{"type":"string","title":"Role"}},"type":"object","required":["name","status_group","color","role"],"title":"BoardTemplateColumnPreview","description":"One column in a board-template discovery preview (NOV-350 / §7.8)."},"BoardTemplatePropertyPreview":{"properties":{"name":{"type":"string","title":"Name"},"type":{"type":"string","title":"Type"},"show_on_card":{"type":"boolean","title":"Show On Card","default":false},"options":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Options"}},"type":"object","required":["name","type"],"title":"BoardTemplatePropertyPreview","description":"One property in a board-template discovery preview (NOV-350 / §7.8)."},"BoardTemplateResponse":{"properties":{"object":{"type":"string","title":"Object","default":"board_template"},"key":{"type":"string","title":"Key"},"name":{"type":"string","title":"Name"},"description":{"type":"string","title":"Description"},"property_validation":{"type":"string","title":"Property Validation"},"columns":{"items":{"$ref":"#/components/schemas/BoardTemplateColumnPreview"},"type":"array","title":"Columns"},"properties":{"items":{"$ref":"#/components/schemas/BoardTemplatePropertyPreview"},"type":"array","title":"Properties"}},"type":"object","required":["key","name","description","property_validation"],"title":"BoardTemplateResponse","description":"A board-template preset as exposed by GET /v1/board-templates and the\n``list_board_templates`` MCP tool (NOV-350 / §7.8). A curated preview —\nthe actual instantiation happens via POST /v1/boards ``template``."},"CardAuditActor":{"properties":{"kind":{"type":"string","title":"Kind"},"id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Id"},"display_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Display Name"}},"additionalProperties":false,"type":"object","required":["kind"],"title":"CardAuditActor","description":"Actor inline-expansion for card audit entries."},"CardAuditEntry":{"properties":{"object":{"type":"string","title":"Object","default":"audit_entry"},"id":{"type":"string","format":"uuid","title":"Id"},"event_type":{"type":"string","title":"Event Type"},"actor":{"$ref":"#/components/schemas/CardAuditActor"},"metadata":{"additionalProperties":true,"type":"object","title":"Metadata"},"created_time":{"type":"string","format":"date-time","title":"Created Time"}},"additionalProperties":false,"type":"object","required":["id","event_type","actor","metadata","created_time"],"title":"CardAuditEntry","description":"One row of card audit_log, with the actor joined into display form."},"CardResponse":{"properties":{"object":{"type":"string","title":"Object","default":"card"},"id":{"type":"string","format":"uuid","title":"Id"},"board_id":{"type":"string","format":"uuid","title":"Board Id"},"column_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Column Id"},"title":{"type":"string","title":"Title"},"properties":{"additionalProperties":true,"type":"object","title":"Properties"},"position":{"type":"number","title":"Position"},"assignees":{"items":{"type":"string"},"type":"array","title":"Assignees"},"due_date":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Due Date"},"labels":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Labels"},"is_archived":{"type":"boolean","title":"Is Archived"},"agent_activity":{"anyOf":[{"$ref":"#/components/schemas/AgentActivity"},{"type":"null"}]},"created_time":{"type":"string","format":"date-time","title":"Created Time"},"last_edited_time":{"type":"string","format":"date-time","title":"Last Edited Time"},"body_last_edited_time":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Body Last Edited Time"},"etag":{"type":"integer","title":"Etag"},"attachment_count":{"type":"integer","title":"Attachment Count","default":0},"unique_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Unique Id"}},"additionalProperties":false,"type":"object","required":["id","board_id","title","properties","position","assignees","labels","is_archived","created_time","last_edited_time","etag"],"title":"CardResponse"},"CardTemplateResponse":{"properties":{"object":{"type":"string","title":"Object","default":"card_template"},"id":{"type":"string","format":"uuid","title":"Id"},"board_id":{"type":"string","format":"uuid","title":"Board Id"},"column_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Column Id"},"title":{"type":"string","title":"Title"},"properties":{"additionalProperties":true,"type":"object","title":"Properties"},"body_blocks":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Body Blocks"},"assignees":{"items":{"type":"string"},"type":"array","title":"Assignees"},"labels":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Labels"},"recurrence_rule":{"additionalProperties":true,"type":"object","title":"Recurrence Rule"},"next_materialization_at":{"type":"string","format":"date-time","title":"Next Materialization At"},"until":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Until"},"count_remaining":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Count Remaining"},"is_active":{"type":"boolean","title":"Is Active"},"created_time":{"type":"string","format":"date-time","title":"Created Time"},"last_edited_time":{"type":"string","format":"date-time","title":"Last Edited Time"},"etag":{"type":"integer","title":"Etag"}},"additionalProperties":false,"type":"object","required":["id","board_id","title","properties","body_blocks","assignees","labels","recurrence_rule","next_materialization_at","is_active","created_time","last_edited_time","etag"],"title":"CardTemplateResponse"},"ChangePasswordRequest":{"properties":{"current_password":{"type":"string","minLength":1,"title":"Current Password"},"new_password":{"type":"string","minLength":1,"title":"New Password"}},"type":"object","required":["current_password","new_password"],"title":"ChangePasswordRequest"},"CheckoutRequest":{"properties":{"interval":{"type":"string","enum":["annual","monthly"],"title":"Interval","default":"annual"}},"type":"object","title":"CheckoutRequest","description":"Body for ``POST /v1/orgs/{org_id}/billing:checkout`` (spec §18.6, NOV-242).\n\n``interval`` selects the billing cadence for the Pro subscription: ``\"annual\"``\n(the promoted default — §18.1) or ``\"monthly\"`` (the deliberate premium). It\ndetermines which of the four per-kind Stripe prices Checkout uses. The body is\noptional on the wire; an omitted body defaults to annual."},"CheckoutResponse":{"properties":{"checkout_url":{"type":"string","title":"Checkout Url"}},"type":"object","required":["checkout_url"],"title":"CheckoutResponse","description":"Response for ``POST /v1/orgs/{org_id}/billing:checkout`` (spec §18.6).\n\nThe owner is redirected to ``checkout_url`` (a Stripe-hosted Checkout\nSession) to enter payment details. The plan flip to Pro is **webhook-driven**\n(``checkout.session.completed`` → §18.7), never set by this endpoint — the\nredirect can be lost, the webhook can't."},"ClaimNextRequest":{"properties":{"lease_ttl_seconds":{"anyOf":[{"type":"integer","maximum":86400.0,"minimum":1.0},{"type":"null"}],"title":"Lease Ttl Seconds"}},"additionalProperties":false,"type":"object","title":"ClaimNextRequest","description":"Body for ``POST /v1/boards/{board_id}/columns/{column_id}:claim-next``.\n\n``lease_ttl_seconds`` overrides the column contract's TTL for this claim\n(and every subsequent renew defaults to it). Absent → the contract's\n``lease_ttl_seconds`` else the platform default."},"ClaimResponse":{"properties":{"object":{"type":"string","title":"Object","default":"lease"},"id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Id"},"card_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Card Id"},"board_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Board Id"},"column_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Column Id"},"lease_token":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Lease Token"},"attempt":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Attempt"},"expires_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Expires At"},"card":{"anyOf":[{"$ref":"#/components/schemas/CardResponse"},{"type":"null"}]}},"type":"object","title":"ClaimResponse","description":"``:claim-next`` result. All lease fields are Optional so the drained-queue\ncase serializes as ``{object:\"lease\", card:null}`` with a single\ncontent-type (spec §7.5.3)."},"CommentResponse":{"properties":{"object":{"type":"string","title":"Object","default":"comment"},"id":{"type":"string","format":"uuid","title":"Id"},"card_id":{"type":"string","format":"uuid","title":"Card Id"},"author_user_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Author User Id"},"body":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Body"},"is_archived":{"type":"boolean","title":"Is Archived"},"is_edited":{"type":"boolean","title":"Is Edited"},"created_time":{"type":"string","format":"date-time","title":"Created Time"},"last_edited_time":{"type":"string","format":"date-time","title":"Last Edited Time"},"etag":{"type":"integer","title":"Etag"},"parent":{"additionalProperties":true,"type":"object","title":"Parent","readOnly":true},"created_by":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Created By","readOnly":true},"rich_text":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Rich Text","readOnly":true}},"additionalProperties":false,"type":"object","required":["id","card_id","body","is_archived","is_edited","created_time","last_edited_time","etag","parent","created_by","rich_text"],"title":"CommentResponse"},"CompleteLeaseRequest":{"properties":{"lease_token":{"type":"string","maxLength":64,"minLength":1,"title":"Lease Token"},"output":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Output"},"properties":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Properties"}},"additionalProperties":false,"type":"object","required":["lease_token"],"title":"CompleteLeaseRequest","description":"Body for ``POST /v1/leases/{lease_id}:complete``.\n\n``output`` is stored on the lease row (validated against the column's\n``output_schema`` in P1). ``properties`` is an optional card field-patch\napplied through the normal card update path before the card is advanced to\n``on_success_column_id``."},"CompleteResponse":{"properties":{"object":{"type":"string","title":"Object","default":"lease"},"id":{"type":"string","format":"uuid","title":"Id"},"card_id":{"type":"string","format":"uuid","title":"Card Id"},"board_id":{"type":"string","format":"uuid","title":"Board Id"},"column_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Column Id"},"lease_token":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Lease Token"},"attempt":{"type":"integer","title":"Attempt"},"expires_at":{"type":"string","format":"date-time","title":"Expires At"},"claimed_at":{"type":"string","format":"date-time","title":"Claimed At"},"last_heartbeat_at":{"type":"string","format":"date-time","title":"Last Heartbeat At"},"released_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Released At"},"release_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Release Reason"},"not_before":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Not Before"},"deadlettered":{"type":"boolean","title":"Deadlettered","default":false},"card":{"$ref":"#/components/schemas/CardResponse"}},"type":"object","required":["id","card_id","board_id","attempt","expires_at","claimed_at","last_heartbeat_at","card"],"title":"CompleteResponse","description":"``:complete`` result — the released lease plus the updated card (which has\nbeen advanced to ``on_success_column_id`` when the contract sets one)."},"ConnectAgentRequest":{"properties":{"display_name":{"type":"string","maxLength":200,"minLength":1,"title":"Display Name"},"role":{"type":"string","title":"Role","default":"member"},"avatar_url":{"anyOf":[{"type":"string","maxLength":1024},{"type":"null"}],"title":"Avatar Url"},"runtime_url":{"anyOf":[{"type":"string","maxLength":1024},{"type":"null"}],"title":"Runtime Url"}},"type":"object","required":["display_name"],"title":"ConnectAgentRequest","description":"Body for POST /v1/orgs/{org_id}/agents."},"ConnectAgentResponse":{"properties":{"object":{"type":"string","title":"Object","default":"agent_connection"},"agent":{"$ref":"#/components/schemas/UserResponse"},"membership":{"$ref":"#/components/schemas/MembershipResponse"},"integration":{"$ref":"#/components/schemas/CreateIntegrationResponse"},"agent_dispatch_secret":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Agent Dispatch Secret"}},"type":"object","required":["agent","membership","integration"],"title":"ConnectAgentResponse","description":"Response on agent creation.\n\nThe integration's plaintext token is included exactly once — the admin\nmust capture it now or rotate. Subsequent reads only see ``last_4``."},"CreateAutomationRequest":{"properties":{"name":{"type":"string","maxLength":200,"minLength":1,"title":"Name"},"board_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Board Id"},"trigger":{"additionalProperties":true,"type":"object","title":"Trigger"},"conditions":{"items":{},"type":"array","title":"Conditions"},"actions":{"items":{},"type":"array","title":"Actions"},"run_as_agent_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Run As Agent Id"}},"type":"object","required":["name","trigger","actions"],"title":"CreateAutomationRequest","description":"Body for ``POST /v1/orgs/{org_id}/automations`` (§20.8)."},"CreateBoardRequest":{"properties":{"name":{"type":"string","title":"Name"},"slug":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Slug"},"description":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Description"},"icon":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Icon"},"cover":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Cover"},"status_groups":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Status Groups"},"properties":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Properties"},"create_default_columns":{"type":"boolean","title":"Create Default Columns","default":true},"visibility":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Visibility"},"workspace_access":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Workspace Access"},"permissions":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Permissions"},"property_validation":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Property Validation"},"template":{"anyOf":[{"type":"string","maxLength":64},{"type":"null"}],"title":"Template"},"unique_id_prefix":{"anyOf":[{"type":"string","maxLength":16},{"type":"null"}],"title":"Unique Id Prefix"}},"additionalProperties":false,"type":"object","required":["name"],"title":"CreateBoardRequest"},"CreateCardRequest":{"properties":{"board_id":{"type":"string","format":"uuid","title":"Board Id"},"column_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Column Id"},"title":{"type":"string","title":"Title"},"properties":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Properties"},"position":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Position"},"assignees":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Assignees"},"due_date":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Due Date"},"labels":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Labels"}},"additionalProperties":false,"type":"object","required":["board_id","title"],"title":"CreateCardRequest","description":"POST /v1/cards body.\n\nNOV-104: no ``body_blocks`` field. Cards are created empty; clients\nfollow up with ``PATCH /v1/blocks/{card_id}/children`` to seed body\ncontent. The pre-NOV-104 one-shot seed field was always asymmetric\n(POST accepted it, PATCH rejected it) and the JSONB cache it wrote to\nis gone.\n\nNOV-379: ``column_id`` is optional — when omitted (or explicitly\n``null``) the card lands on the board's default column so it is visible\non the kanban board from birth. A column-less card only results from a\nboard that has no columns."},"CreateCardTemplateRequest":{"properties":{"board_id":{"type":"string","format":"uuid","title":"Board Id"},"column_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Column Id"},"title":{"type":"string","title":"Title"},"properties":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Properties"},"body_blocks":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Body Blocks"},"assignees":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Assignees"},"labels":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Labels"},"recurrence_rule":{"additionalProperties":true,"type":"object","title":"Recurrence Rule"},"next_materialization_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Next Materialization At"},"until":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Until"},"count":{"anyOf":[{"type":"integer","maximum":10000.0,"minimum":1.0},{"type":"null"}],"title":"Count"}},"additionalProperties":false,"type":"object","required":["board_id","title","recurrence_rule"],"title":"CreateCardTemplateRequest"},"CreateColumnRequest":{"properties":{"name":{"type":"string","title":"Name"},"status_group":{"type":"string","title":"Status Group"},"color":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Color"},"position":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Position"}},"additionalProperties":false,"type":"object","required":["name","status_group"],"title":"CreateColumnRequest"},"CreateCommentRequest":{"properties":{"card_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Card Id"},"body":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Body"}},"additionalProperties":true,"type":"object","title":"CreateCommentRequest","description":"Comment-create accepts both native and Notion-shape payloads (NOV-63 B5).\n\nNative:    ``{\"card_id\": \"<uuid>\", \"body\": [<block>, …]}``\nNotion:    ``{\"parent\": {\"page_id\": \"<uuid>\"}, \"rich_text\": [<rt>, …]}``\n\nThe Notion-shape input is normalized at validation time:\n\n- ``parent.page_id`` → ``card_id``\n- ``rich_text`` segments concatenated into a single paragraph block\n  ``[{\"object\": \"block\", \"type\": \"paragraph\", \"paragraph\":\n  {\"rich_text\": [...], \"color\": \"default\"}}]``.\n\nMixed payloads (both shapes present) prefer the native fields and log\nnothing — the API is permissive on extras because pydantic discards\nthem once normalization completes."},"CreateDomainClaimRequest":{"properties":{"domain":{"type":"string","title":"Domain"},"verification_type":{"type":"string","title":"Verification Type","default":"dns_txt"},"allowlist":{"items":{"type":"string"},"type":"array","title":"Allowlist","default":[]},"blocklist":{"items":{"type":"string"},"type":"array","title":"Blocklist","default":[]}},"type":"object","required":["domain"],"title":"CreateDomainClaimRequest"},"CreateFeedbackRequest":{"properties":{"type":{"type":"string","title":"Type"},"route":{"type":"string","title":"Route"},"content":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Content"},"expected":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Expected"},"severity":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Severity"},"category":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category"},"exit_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Exit Reason"},"rating":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Rating"},"board_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Board Id"},"card_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Card Id"},"automation_run_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Automation Run Id"},"context":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Context"},"screenshot_file_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Screenshot File Id"},"app_version":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"App Version"}},"additionalProperties":false,"type":"object","required":["type","route"],"title":"CreateFeedbackRequest","description":"Body for ``POST /v1/feedback`` (spec §25.4)."},"CreateFeedbackScreenshotUploadRequest":{"properties":{"filename":{"type":"string","maxLength":255,"minLength":1,"title":"Filename"},"content_type":{"type":"string","maxLength":255,"minLength":1,"title":"Content Type"},"size_bytes":{"anyOf":[{"type":"integer","minimum":1.0},{"type":"null"}],"title":"Size Bytes"}},"additionalProperties":false,"type":"object","required":["filename","content_type"],"title":"CreateFeedbackScreenshotUploadRequest","description":"Body for ``POST /v1/feedback/screenshots:presign`` (NOV-442, spec §25.4).\n\nDeliberately NOT a reuse of\n:class:`~app.schemas.file.CreateFileUploadRequest`: that one requires a\n``card_id``, and a feedback screenshot is card-less by construction. The\nthree fields it does share carry the same wire meaning and the same column\nwidths.\n\nNo ``org_id`` — the org comes from the principal (§25.10). ``content_type``\nis a plain ``str`` rather than a ``Literal`` of the four allowed types for\nthe same reason the submission body keeps its enums loose: the allow-list\nlives in :func:`app.services.files._validate_screenshot_content_type`, which\nanswers ``415 unsupported_content_type`` — the §13.1 shape for a rejected\nupload type — where a Literal would answer 422 and split the rule across two\nlayers. ``size_bytes`` is a hint: the real ceiling is the\n``content-length-range`` in the S3 policy, which the client cannot lie past."},"CreateFileUploadRequest":{"properties":{"card_id":{"type":"string","format":"uuid","title":"Card Id"},"filename":{"type":"string","maxLength":255,"minLength":1,"title":"Filename"},"content_type":{"type":"string","maxLength":255,"minLength":1,"title":"Content Type"},"size_bytes":{"anyOf":[{"type":"integer","minimum":1.0},{"type":"null"}],"title":"Size Bytes"}},"additionalProperties":false,"type":"object","required":["card_id","filename","content_type"],"title":"CreateFileUploadRequest","description":"`POST /v1/files:upload` body."},"CreateImportJobRequest":{"properties":{"source":{"type":"string","enum":["notion_api","export_file"],"title":"Source","default":"notion_api"},"token":{"anyOf":[{"type":"string","minLength":1},{"type":"null"}],"title":"Token"},"file_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"File Id"},"database_id":{"anyOf":[{"type":"string","minLength":1},{"type":"null"}],"title":"Database Id"},"column_property":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Column Property"},"whole_workspace":{"type":"boolean","title":"Whole Workspace","default":false}},"type":"object","title":"CreateImportJobRequest","description":"Body for ``POST /v1/orgs/{org_id}/import-jobs`` (spec §21.9 / §21.10).\n\nTwo transports, selected by ``source``:\n\n* **``notion_api``** (default) — ``token`` is the Notion internal-integration\n  token, a transient secret carried ONLY in this request body (never a query\n  string / URL, which proxies log; §21.10). ``file_id`` is forbidden. Two\n  sub-modes: single-DB (``database_id`` names the one database; optional\n  ``column_property`` names the Notion status/select property whose options\n  become columns — blank ⇒ auto-detect) or whole-workspace\n  (``whole_workspace: true`` — walk ALL shared databases → one board each with\n  best-effort inter-DB relation links; ``database_id`` omitted).\n* **``export_file``** (NOV-297) — import a previously-uploaded Notion export\n  ``.zip``. ``file_id`` names the committed File\n  (upload → commit → create; usable as soon as the file is ``status=available``;\n  see the ``:upload`` endpoint). ``token``/``database_id``/``whole_workspace``\n  are forbidden;\n  ``column_property`` is an optional per-database column-driver hint. Always a\n  whole-file import (one board per database in the export).\n\nThese seed the job's ``cursor_state`` exactly as the runner reads it."},"CreateImportUploadRequest":{"properties":{"filename":{"type":"string","maxLength":255,"minLength":1,"title":"Filename"},"content_type":{"type":"string","maxLength":255,"minLength":1,"title":"Content Type","default":"application/zip"},"size_bytes":{"anyOf":[{"type":"integer","minimum":1.0},{"type":"null"}],"title":"Size Bytes"}},"type":"object","required":["filename"],"title":"CreateImportUploadRequest","description":"Body for ``POST /v1/orgs/{org_id}/import-jobs:upload`` (NOV-297, §21.10).\n\nMints a presigned POST for the Notion export ``.zip``. ``content_type`` MUST\nbe ``application/zip`` (415 otherwise). ``size_bytes`` is an optional presign\nhint; the server caps via the configured upload limit regardless. The client\nPUTs the bytes, calls the existing ``POST /v1/files/{id}:commit``, then creates\nthe import job with ``source=export_file`` + this ``file_id`` (importable as\nsoon as the file is ``status=available``)."},"CreateIntegrationRequest":{"properties":{"name":{"type":"string","title":"Name"},"role":{"type":"string","enum":["member","admin"],"title":"Role","default":"member"}},"type":"object","required":["name"],"title":"CreateIntegrationRequest"},"CreateIntegrationResponse":{"properties":{"object":{"type":"string","title":"Object","default":"integration"},"id":{"type":"string","format":"uuid","title":"Id"},"org_id":{"type":"string","format":"uuid","title":"Org Id"},"name":{"type":"string","title":"Name"},"last_4":{"type":"string","title":"Last 4"},"role":{"type":"string","title":"Role","default":"member"},"owner_user_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Owner User Id"},"created_time":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Created Time"},"token":{"type":"string","title":"Token"}},"type":"object","required":["id","org_id","name","last_4","token"],"title":"CreateIntegrationResponse","description":"Response on creation includes the plaintext token — shown once."},"CreateOrganizationRequest":{"properties":{"name":{"type":"string","title":"Name"},"slug":{"type":"string","title":"Slug"},"primary_domain":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Primary Domain"}},"type":"object","required":["name","slug"],"title":"CreateOrganizationRequest"},"CreatePlaybookRequest":{"properties":{"name":{"type":"string","title":"Name"},"steps":{"items":{},"type":"array","title":"Steps"},"output_target":{"type":"string","title":"Output Target","default":"append_body"},"on_success_move_to":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"On Success Move To"}},"type":"object","required":["name","steps"],"title":"CreatePlaybookRequest","description":"Body for ``POST /v1/orgs/{org_id}/playbooks`` (§23.4)."},"CreateShareLinkRequest":{"properties":{"role":{"type":"string","title":"Role","default":"viewer"},"label":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Label"},"expires_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Expires At"}},"additionalProperties":false,"type":"object","title":"CreateShareLinkRequest","description":"Create a board share link (NOV-199, spec §4.6).\n\n``role`` is capped at ``commenter`` — a share link never edits structure or\nmanages access. ``label`` is an optional human tag for the management list\n(e.g. \"Client: Acme\"). ``expires_at`` is an optional hard expiry; omit for a\nlink that lives until revoked."},"CreateWebhookRequest":{"properties":{"url":{"type":"string","title":"Url"},"event_types":{"items":{"type":"string"},"type":"array","title":"Event Types"},"board_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Board Id"},"notion_handshake":{"type":"boolean","title":"Notion Handshake","default":false}},"type":"object","required":["url"],"title":"CreateWebhookRequest"},"CreateWebhookResponse":{"properties":{"object":{"type":"string","title":"Object","default":"webhook"},"id":{"type":"string","format":"uuid","title":"Id"},"org_id":{"type":"string","format":"uuid","title":"Org Id"},"url":{"type":"string","title":"Url"},"event_types":{"items":{"type":"string"},"type":"array","title":"Event Types"},"board_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Board Id"},"is_active":{"type":"boolean","title":"Is Active"},"secret_last4":{"type":"string","title":"Secret Last4"},"created_time":{"type":"string","format":"date-time","title":"Created Time"},"last_edited_time":{"type":"string","format":"date-time","title":"Last Edited Time"},"secret":{"type":"string","title":"Secret"}},"type":"object","required":["id","org_id","url","event_types","board_id","is_active","secret_last4","created_time","last_edited_time","secret"],"title":"CreateWebhookResponse","description":"Same as WebhookResponse plus the plaintext secret — returned ONCE."},"DataSourceColumn":{"properties":{"object":{"type":"string","title":"Object","default":"board_column"},"id":{"type":"string","format":"uuid","title":"Id"},"board_id":{"type":"string","format":"uuid","title":"Board Id"},"name":{"type":"string","title":"Name"},"color":{"type":"string","title":"Color"},"position":{"type":"number","title":"Position"},"is_default":{"type":"boolean","title":"Is Default"},"status_group":{"type":"string","title":"Status Group"},"role":{"type":"string","title":"Role"},"created_time":{"type":"string","format":"date-time","title":"Created Time"},"last_edited_time":{"type":"string","format":"date-time","title":"Last Edited Time"},"etag":{"type":"integer","title":"Etag"}},"additionalProperties":false,"type":"object","required":["id","board_id","name","color","position","is_default","status_group","role","created_time","last_edited_time","etag"],"title":"DataSourceColumn","description":"One column inside a data_source response. Mirrors BoardColumnResponse."},"DataSourceResponse":{"properties":{"object":{"type":"string","title":"Object","default":"data_source"},"id":{"type":"string","format":"uuid","title":"Id"},"board_id":{"type":"string","format":"uuid","title":"Board Id"},"columns":{"items":{"$ref":"#/components/schemas/DataSourceColumn"},"type":"array","title":"Columns"},"status_groups":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Status Groups"}},"additionalProperties":false,"type":"object","required":["id","board_id","columns","status_groups"],"title":"DataSourceResponse","description":"Notion's `data_source` concept = board.columns + status_groups bundled.\n\nFor v0 the data_source id equals the board id (we collapse Notion's\ndatabase/data_source split — see spec §5.4)."},"DatabaseResponse":{"properties":{"object":{"type":"string","title":"Object","default":"database"},"id":{"type":"string","format":"uuid","title":"Id"},"org_id":{"type":"string","format":"uuid","title":"Org Id"},"name":{"type":"string","title":"Name"},"slug":{"type":"string","title":"Slug"},"description":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Description"},"icon":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Icon"},"cover":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Cover"},"default_view_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Default View Id"},"status_groups":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Status Groups"},"properties":{"additionalProperties":{"additionalProperties":true,"type":"object"},"type":"object","title":"Properties"},"visibility":{"type":"string","title":"Visibility","default":"org"},"workspace_access":{"type":"string","title":"Workspace Access","default":"edit"},"permissions":{"additionalProperties":{"type":"string"},"type":"object","title":"Permissions"},"property_validation":{"type":"string","title":"Property Validation","default":"permissive"},"has_active_share_links":{"type":"boolean","title":"Has Active Share Links","default":false},"is_archived":{"type":"boolean","title":"Is Archived"},"created_time":{"type":"string","format":"date-time","title":"Created Time"},"last_edited_time":{"type":"string","format":"date-time","title":"Last Edited Time"},"etag":{"type":"integer","title":"Etag"}},"additionalProperties":false,"type":"object","required":["id","org_id","name","slug","status_groups","is_archived","created_time","last_edited_time","etag"],"title":"DatabaseResponse","description":"Notion-compat wrapper for a Board. Identical payload except `object`."},"DomainClaimResponse":{"properties":{"object":{"type":"string","title":"Object","default":"domain_claim"},"id":{"type":"string","format":"uuid","title":"Id"},"org_id":{"type":"string","format":"uuid","title":"Org Id"},"domain":{"type":"string","title":"Domain"},"verification_type":{"type":"string","title":"Verification Type"},"verification_code":{"type":"string","title":"Verification Code"},"verified":{"type":"boolean","title":"Verified","default":false},"verified_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Verified At"},"allowlist":{"items":{"type":"string"},"type":"array","title":"Allowlist","default":[]},"blocklist":{"items":{"type":"string"},"type":"array","title":"Blocklist","default":[]},"verification_status":{"type":"string","enum":["pending","failed","verified"],"title":"Verification Status","default":"pending"},"last_checked_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Checked At"},"expected_record":{"anyOf":[{"$ref":"#/components/schemas/ExpectedDnsRecord"},{"type":"null"}]}},"type":"object","required":["id","org_id","domain","verification_type","verification_code"],"title":"DomainClaimResponse"},"EmailOutboxRequeueResponse":{"properties":{"object":{"type":"string","title":"Object","default":"email_outbox"},"id":{"type":"string","format":"uuid","title":"Id"},"status":{"type":"string","title":"Status"},"attempts":{"type":"integer","title":"Attempts"},"next_attempt_at":{"type":"string","format":"date-time","title":"Next Attempt At"},"requeued":{"type":"boolean","title":"Requeued"}},"type":"object","required":["id","status","attempts","next_attempt_at","requeued"],"title":"EmailOutboxRequeueResponse","description":"Safe operator-facing state; recipient address and payload stay private."},"ExpectedDnsRecord":{"properties":{"object":{"type":"string","title":"Object","default":"expected_dns_record"},"type":{"type":"string","title":"Type","default":"TXT"},"host":{"type":"string","title":"Host"},"value":{"type":"string","title":"Value"}},"type":"object","required":["host","value"],"title":"ExpectedDnsRecord","description":"The exact DNS record an admin must publish to verify ownership (§4.3.1)."},"FailLeaseRequest":{"properties":{"lease_token":{"type":"string","maxLength":64,"minLength":1,"title":"Lease Token"},"reason":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Reason"},"requeue":{"type":"boolean","title":"Requeue","default":true}},"additionalProperties":false,"type":"object","required":["lease_token"],"title":"FailLeaseRequest","description":"Body for ``POST /v1/leases/{lease_id}:fail``."},"FeedbackResponse":{"properties":{"object":{"type":"string","title":"Object","default":"feedback"},"id":{"type":"string","format":"uuid","title":"Id"},"reference":{"type":"string","title":"Reference"},"type":{"type":"string","title":"Type"},"status":{"type":"string","title":"Status"},"surface":{"type":"string","title":"Surface"},"severity":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Severity"},"category":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category"},"exit_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Exit Reason"},"rating":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Rating"},"content":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Content"},"expected":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Expected"},"board_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Board Id"},"card_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Card Id"},"automation_run_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Automation Run Id"},"route":{"type":"string","title":"Route"},"screenshot_file_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Screenshot File Id"},"app_version":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"App Version"},"api_version":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Api Version"},"jira_status":{"type":"string","title":"Jira Status"},"created_time":{"type":"string","format":"date-time","title":"Created Time"}},"additionalProperties":false,"type":"object","required":["id","reference","type","status","surface","route","jira_status","created_time"],"title":"FeedbackResponse","description":"One feedback row as its submitter sees it (spec §25.4).\n\n``org_id`` / ``user_id`` are omitted for the same reason\n:class:`~app.schemas.notification.NotificationResponse` omits them: the\ncaller IS the owner, so echoing the ownership keys back adds nothing and\nonly widens the surface.\n\n``jira_status`` is exposed (a submitter may see that their report is queued)\nbut ``jira_issue_key`` / ``jira_issue_url`` / ``jira_last_error`` are NOT:\n§25.9 is explicit that the user never sees an internal issue key, and the\nerror text is platform-admin-only (§25.10). ``context`` is likewise withheld\n— it is scrubbed diagnostic state for an operator, and re-serving it would\nhand a client back the server-side snapshot (plan, seat counts) it never\nsupplied."},"FreeCaps":{"properties":{"max_human_seats":{"type":"integer","title":"Max Human Seats"},"max_agents":{"type":"integer","title":"Max Agents"}},"type":"object","required":["max_human_seats","max_agents"],"title":"FreeCaps","description":"Free-tier caps surfaced to the client (spec §18.1 / §18.9).\n\nMirrors ``settings.free_max_human_seats`` / ``free_max_agents`` so the\nfrontend can render the upgrade prompt without hardcoding 5/1. Boards are\nuncapped on Free (NOV-242), so there is no board field."},"GrantBoardAccessRequest":{"properties":{"user_id":{"type":"string","format":"uuid","title":"User Id"},"role":{"type":"string","title":"Role"}},"additionalProperties":false,"type":"object","required":["user_id","role"],"title":"GrantBoardAccessRequest"},"GrantOrgCompRequest":{"properties":{"grant_type":{"type":"string","title":"Grant Type"},"reason":{"type":"string","minLength":1,"title":"Reason"},"idempotency_key":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Idempotency Key"},"free_seat_count":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Free Seat Count"},"percent_off":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Percent Off"},"expires_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Expires At"},"metadata":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Metadata"}},"type":"object","required":["grant_type","reason"],"title":"GrantOrgCompRequest","description":"Create-grant request body (POST /v1/admin/orgs/{org_id}/grants).\n\n``grant_type`` selects the per-type spec; the optional fields are validated\nper type by the service (``app/services/grants.py``):\n\n* ``free_seats``        → ``free_seat_count`` required (>= 1).\n* ``percent_off_coupon``→ ``percent_off`` required (1..100).\n* ``comped_subscription``→ always 100% off (``percent_off`` forced to 100).\n* ``plan_override``     → no extra fields.\n\n``idempotency_key`` dedupes a retried create; the server generates a UUID\nwhen absent. ``reason`` is REQUIRED (every comp is auditable)."},"GrantPlatformAdminRequest":{"properties":{"user_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"User Id"},"email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email"},"role":{"type":"string","title":"Role","default":"support"}},"type":"object","title":"GrantPlatformAdminRequest"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ImportJobResponse":{"properties":{"object":{"type":"string","title":"Object","default":"import_job"},"id":{"type":"string","format":"uuid","title":"Id"},"org_id":{"type":"string","format":"uuid","title":"Org Id"},"board_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Board Id"},"source":{"type":"string","title":"Source"},"status":{"type":"string","title":"Status"},"attempts":{"type":"integer","title":"Attempts"},"counts":{"additionalProperties":true,"type":"object","title":"Counts"},"error_log":{"items":{},"type":"array","title":"Error Log"},"last_page":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Page"},"created_time":{"type":"string","format":"date-time","title":"Created Time"},"last_edited_time":{"type":"string","format":"date-time","title":"Last Edited Time"}},"type":"object","required":["id","org_id","source","status","attempts","created_time","last_edited_time"],"title":"ImportJobResponse","description":"Status object for an ``ImportJob`` (spec §21.9). NEVER carries the token.\n\n``counts`` (boards/columns/cards/blocks) drives the wizard's progress bar and\n``error_log`` explains a ``partial``/``failed`` run; ``board_id`` is null until\nthe worker creates the board and is the deep-link target on success.\n``last_page`` is the runner's incremental resume marker\n(``cursor_state.last_page``) surfaced for the live \"importing card N…\" line —\nthe raw ``cursor_state`` (which also holds the target ``database_id`` /\n``column_property``) is intentionally NOT echoed; only this progress field is."},"IntegrationResponse":{"properties":{"object":{"type":"string","title":"Object","default":"integration"},"id":{"type":"string","format":"uuid","title":"Id"},"org_id":{"type":"string","format":"uuid","title":"Org Id"},"name":{"type":"string","title":"Name"},"last_4":{"type":"string","title":"Last 4"},"role":{"type":"string","title":"Role","default":"member"},"owner_user_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Owner User Id"},"created_time":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Created Time"}},"type":"object","required":["id","org_id","name","last_4"],"title":"IntegrationResponse"},"JobContractRequest":{"properties":{"enabled":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Enabled"},"lease_ttl_seconds":{"anyOf":[{"type":"integer","maximum":86400.0,"minimum":1.0},{"type":"null"}],"title":"Lease Ttl Seconds"},"max_attempts":{"anyOf":[{"type":"integer","maximum":100.0,"minimum":1.0},{"type":"null"}],"title":"Max Attempts"},"concurrency_limit":{"anyOf":[{"type":"integer","maximum":10000.0,"minimum":1.0},{"type":"null"}],"title":"Concurrency Limit"},"backoff_seconds":{"anyOf":[{"items":{"type":"integer"},"type":"array"},{"type":"null"}],"title":"Backoff Seconds"},"on_success_column_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"On Success Column Id"},"on_failure_column_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"On Failure Column Id"},"input_schema":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Input Schema"},"output_schema":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Output Schema"}},"additionalProperties":false,"type":"object","title":"JobContractRequest","description":"Body for ``PUT /v1/boards/{board_id}/columns/{column_id}/contract`` — the\ncolumn job-contract admin write (NOV-260, spec §7.5.3 admin / cards-as-jobs\n§4.6 / §9). Every field is Optional; the caller sends only the ones it wants\nto set.\n\n``extra=\"forbid\"`` rejects any unknown key: a typo'd contract field (say\n``lease_ttl`` instead of ``lease_ttl_seconds``) is a configuration error, not\na silently-ignored no-op, so it surfaces as a ``422`` at the write boundary\nrather than quietly failing to take effect.\n\nPUT is a full replace: the service stores exactly the fields the caller\nprovided (see :func:`app.services.leases.set_column_contract_for_principal`).\nType/range checks live here; the cross-field write validation (well-formed\nJSON Schemas, on-board column references) lives in the service."},"JobContractResponse":{"properties":{"object":{"type":"string","title":"Object","default":"job_contract"},"board_id":{"type":"string","format":"uuid","title":"Board Id"},"column_id":{"type":"string","format":"uuid","title":"Column Id"},"enabled":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Enabled"},"lease_ttl_seconds":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Lease Ttl Seconds"},"max_attempts":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Attempts"},"concurrency_limit":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Concurrency Limit"},"backoff_seconds":{"anyOf":[{"items":{"type":"integer"},"type":"array"},{"type":"null"}],"title":"Backoff Seconds"},"on_success_column_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"On Success Column Id"},"on_failure_column_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"On Failure Column Id"},"input_schema":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Input Schema"},"output_schema":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Output Schema"}},"type":"object","required":["board_id","column_id"],"title":"JobContractResponse","description":"The column's stored job contract on the wire (NOV-260, spec §7.5.3 admin).\n\nReturned by ``GET``/``PUT /v1/boards/{board_id}/columns/{column_id}/contract``.\nEchoes the fields as STORED on ``board_columns.job_contract`` — a field the\ncolumn never set reads back as ``null`` (the read side, not this response,\napplies platform defaults). A column with no contract at all serializes as\nthe empty shape (every field ``null``), so a fresh column and a\nfully-cleared one look identical (both \"not a queue\")."},"LeaseResponse":{"properties":{"object":{"type":"string","title":"Object","default":"lease"},"id":{"type":"string","format":"uuid","title":"Id"},"card_id":{"type":"string","format":"uuid","title":"Card Id"},"board_id":{"type":"string","format":"uuid","title":"Board Id"},"column_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Column Id"},"lease_token":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Lease Token"},"attempt":{"type":"integer","title":"Attempt"},"expires_at":{"type":"string","format":"date-time","title":"Expires At"},"claimed_at":{"type":"string","format":"date-time","title":"Claimed At"},"last_heartbeat_at":{"type":"string","format":"date-time","title":"Last Heartbeat At"},"released_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Released At"},"release_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Release Reason"},"not_before":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Not Before"},"deadlettered":{"type":"boolean","title":"Deadlettered","default":false}},"type":"object","required":["id","card_id","board_id","attempt","expires_at","claimed_at","last_heartbeat_at"],"title":"LeaseResponse","description":"The lease row on the wire — no nested card. Returned by ``:renew`` and\n``:fail``."},"ListDatabasesRequest":{"properties":{"token":{"type":"string","minLength":1,"title":"Token"}},"type":"object","required":["token"],"title":"ListDatabasesRequest","description":"Body for ``POST /v1/orgs/{org_id}/import-jobs:databases`` (spec §21.9/§21.10).\n\nToken-in-body (not a GET query string) so the transient Notion secret is\nnever written to an access log. The token is used once to list the databases\nthe integration can see and is then dropped — never stored."},"ListDatabasesResponse":{"properties":{"object":{"type":"string","title":"Object","default":"list"},"results":{"items":{"$ref":"#/components/schemas/NotionDatabaseSummary"},"type":"array","title":"Results"}},"type":"object","required":["results"],"title":"ListDatabasesResponse","description":"Envelope for the transient-token database listing (spec §21.9)."},"LoginRequest":{"properties":{"email":{"type":"string","title":"Email"},"password":{"type":"string","title":"Password"}},"type":"object","required":["email","password"],"title":"LoginRequest"},"MakeRecurringRequest":{"properties":{"recurrence_rule":{"additionalProperties":true,"type":"object","title":"Recurrence Rule"},"until":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Until"},"count":{"anyOf":[{"type":"integer","maximum":10000.0,"minimum":1.0},{"type":"null"}],"title":"Count"},"next_materialization_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Next Materialization At"}},"additionalProperties":false,"type":"object","required":["recurrence_rule"],"title":"MakeRecurringRequest","description":"POST /v1/cards/{id}:make-recurring body.\n\nTurns an existing card into a template anchored at the existing card's\ndue_date.start (or `next_materialization_at` if provided). The original\ncard is left in place — the template emits future occurrences."},"MembershipResponse":{"properties":{"object":{"type":"string","title":"Object","default":"membership"},"id":{"type":"string","format":"uuid","title":"Id"},"user_id":{"type":"string","format":"uuid","title":"User Id"},"org_id":{"type":"string","format":"uuid","title":"Org Id"},"role":{"type":"string","title":"Role"},"email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"kind":{"type":"string","title":"Kind","default":"human"},"joined_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Joined At"},"last_signed_in_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Signed In At"}},"type":"object","required":["id","user_id","org_id","role"],"title":"MembershipResponse"},"MoveCardRequest":{"properties":{"column_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Column Id"},"position":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Position"}},"additionalProperties":false,"type":"object","title":"MoveCardRequest"},"NotificationPreferencesResponse":{"properties":{"email":{"additionalProperties":{"type":"boolean"},"propertyNames":{"enum":["card_assigned","automation_notify"]},"type":"object","title":"Email"}},"type":"object","title":"NotificationPreferencesResponse","description":"Effective per-channel notification preferences (NOV-364, spec §22.3).\n\n``email`` maps EVERY v1 notification type to its EFFECTIVE boolean with\ndefaults resolved server-side (absence of a stored override => the type's\ndefault, ON in v1) — so the settings UI never re-derives the default logic.\nIn-app is intentionally omitted: it has no opt-out in v1 (always on)."},"NotificationResponse":{"properties":{"object":{"type":"string","title":"Object","default":"notification"},"id":{"type":"string","format":"uuid","title":"Id"},"type":{"type":"string","title":"Type"},"title":{"type":"string","title":"Title"},"body":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Body"},"board_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Board Id"},"card_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Card Id"},"comment_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Comment Id"},"actor_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Actor Id"},"read_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Read At"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"read":{"type":"boolean","title":"Read","readOnly":true}},"additionalProperties":false,"type":"object","required":["id","type","title","created_at","read"],"title":"NotificationResponse"},"NotionDatabaseSummary":{"properties":{"id":{"type":"string","title":"Id"},"title":{"type":"string","title":"Title"}},"type":"object","required":["id","title"],"title":"NotionDatabaseSummary","description":"One pickable Notion database: its id + human title (spec §21.9)."},"OrgGrantRow":{"properties":{"object":{"type":"string","title":"Object","default":"org_grant"},"id":{"type":"string","format":"uuid","title":"Id"},"org_id":{"type":"string","format":"uuid","title":"Org Id"},"grant_type":{"type":"string","title":"Grant Type"},"status":{"type":"string","title":"Status"},"reason":{"type":"string","title":"Reason"},"granted_by_user_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Granted By User Id"},"granted_at":{"type":"string","format":"date-time","title":"Granted At"},"expires_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Expires At"},"revoked_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Revoked At"},"revoked_by_user_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Revoked By User Id"},"free_seat_count":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Free Seat Count"},"percent_off":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Percent Off"},"stripe_object_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Stripe Object Id"},"idempotency_key":{"type":"string","title":"Idempotency Key"},"metadata":{"additionalProperties":true,"type":"object","title":"Metadata"}},"type":"object","required":["id","org_id","grant_type","status","reason","granted_at","idempotency_key"],"title":"OrgGrantRow","description":"One ``org_grants`` ledger row (response shape)."},"OrganizationResponse":{"properties":{"object":{"type":"string","title":"Object","default":"organization"},"id":{"type":"string","format":"uuid","title":"Id"},"name":{"type":"string","title":"Name"},"slug":{"type":"string","title":"Slug"},"primary_domain":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Primary Domain"},"billing_plan":{"type":"string","title":"Billing Plan","default":"free"},"billing_status":{"type":"string","title":"Billing Status","default":"active"},"billing_seats":{"type":"integer","title":"Billing Seats","default":0},"default_board_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Default Board Id"}},"type":"object","required":["id","name","slug"],"title":"OrganizationResponse"},"PageResponse":{"properties":{"object":{"type":"string","title":"Object","default":"page"},"id":{"type":"string","format":"uuid","title":"Id"},"board_id":{"type":"string","format":"uuid","title":"Board Id"},"column_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Column Id"},"title":{"type":"string","title":"Title"},"properties":{"additionalProperties":true,"type":"object","title":"Properties"},"position":{"type":"number","title":"Position"},"assignees":{"items":{"type":"string"},"type":"array","title":"Assignees"},"due_date":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Due Date"},"status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"},"labels":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Labels"},"is_archived":{"type":"boolean","title":"Is Archived"},"agent_activity":{"anyOf":[{"$ref":"#/components/schemas/AgentActivity"},{"type":"null"}]},"created_time":{"type":"string","format":"date-time","title":"Created Time"},"last_edited_time":{"type":"string","format":"date-time","title":"Last Edited Time"},"body_last_edited_time":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Body Last Edited Time"},"etag":{"type":"integer","title":"Etag"},"attachment_count":{"type":"integer","title":"Attachment Count","default":0},"unique_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Unique Id"}},"additionalProperties":false,"type":"object","required":["id","board_id","title","properties","position","assignees","labels","is_archived","created_time","last_edited_time","etag"],"title":"PageResponse","description":"Notion-compat wrapper for a Card (NOV-32, NOV-78).\n\n``properties`` is a Notion-shape **superset**: the synthesized built-ins\n(``Name``, ``Status``, ``Assignees``, ``Due date``, ``Labels``) are built\nin the router via ``app.services.cards.build_notion_properties`` and\nmerged with user-set keys from ``card.properties`` JSONB (user wins on\ncollisions). The column lookup needs a DB session, so this can't be a\npure ``@computed_field`` on the schema — the router constructs the dict\nand passes it via ``model_copy``.\n\nNotion-trained clients read ``properties.Name.title[0].plain_text`` and\n``properties.Status.status.name``; the native top-level fields below\nstay populated for the existing Novum frontend (NOV-78 is read-side\nadditive, frontend migration is a separate ticket)."},"PaginatedResponse_AdminAuditRow_":{"properties":{"object":{"type":"string","title":"Object","default":"list"},"results":{"items":{"$ref":"#/components/schemas/AdminAuditRow"},"type":"array","title":"Results"},"has_more":{"type":"boolean","title":"Has More","default":false},"next_cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Cursor"},"page_size":{"type":"integer","title":"Page Size","default":25}},"type":"object","required":["results"],"title":"PaginatedResponse[AdminAuditRow]"},"PaginatedResponse_AdminBillingOrgRow_":{"properties":{"object":{"type":"string","title":"Object","default":"list"},"results":{"items":{"$ref":"#/components/schemas/AdminBillingOrgRow"},"type":"array","title":"Results"},"has_more":{"type":"boolean","title":"Has More","default":false},"next_cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Cursor"},"page_size":{"type":"integer","title":"Page Size","default":25}},"type":"object","required":["results"],"title":"PaginatedResponse[AdminBillingOrgRow]"},"PaginatedResponse_AdminOrgRow_":{"properties":{"object":{"type":"string","title":"Object","default":"list"},"results":{"items":{"$ref":"#/components/schemas/AdminOrgRow"},"type":"array","title":"Results"},"has_more":{"type":"boolean","title":"Has More","default":false},"next_cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Cursor"},"page_size":{"type":"integer","title":"Page Size","default":25}},"type":"object","required":["results"],"title":"PaginatedResponse[AdminOrgRow]"},"PaginatedResponse_AdminUserRow_":{"properties":{"object":{"type":"string","title":"Object","default":"list"},"results":{"items":{"$ref":"#/components/schemas/AdminUserRow"},"type":"array","title":"Results"},"has_more":{"type":"boolean","title":"Has More","default":false},"next_cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Cursor"},"page_size":{"type":"integer","title":"Page Size","default":25}},"type":"object","required":["results"],"title":"PaginatedResponse[AdminUserRow]"},"PaginatedResponse_AgentPresence_":{"properties":{"object":{"type":"string","title":"Object","default":"list"},"results":{"items":{"$ref":"#/components/schemas/AgentPresence"},"type":"array","title":"Results"},"has_more":{"type":"boolean","title":"Has More","default":false},"next_cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Cursor"},"page_size":{"type":"integer","title":"Page Size","default":25}},"type":"object","required":["results"],"title":"PaginatedResponse[AgentPresence]"},"PaginatedResponse_AiRunUsageResponse_":{"properties":{"object":{"type":"string","title":"Object","default":"list"},"results":{"items":{"$ref":"#/components/schemas/AiRunUsageResponse"},"type":"array","title":"Results"},"has_more":{"type":"boolean","title":"Has More","default":false},"next_cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Cursor"},"page_size":{"type":"integer","title":"Page Size","default":25}},"type":"object","required":["results"],"title":"PaginatedResponse[AiRunUsageResponse]"},"PaginatedResponse_AutomationResponse_":{"properties":{"object":{"type":"string","title":"Object","default":"list"},"results":{"items":{"$ref":"#/components/schemas/AutomationResponse"},"type":"array","title":"Results"},"has_more":{"type":"boolean","title":"Has More","default":false},"next_cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Cursor"},"page_size":{"type":"integer","title":"Page Size","default":25}},"type":"object","required":["results"],"title":"PaginatedResponse[AutomationResponse]"},"PaginatedResponse_AutomationRunResponse_":{"properties":{"object":{"type":"string","title":"Object","default":"list"},"results":{"items":{"$ref":"#/components/schemas/AutomationRunResponse"},"type":"array","title":"Results"},"has_more":{"type":"boolean","title":"Has More","default":false},"next_cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Cursor"},"page_size":{"type":"integer","title":"Page Size","default":25}},"type":"object","required":["results"],"title":"PaginatedResponse[AutomationRunResponse]"},"PaginatedResponse_BoardColumnResponse_":{"properties":{"object":{"type":"string","title":"Object","default":"list"},"results":{"items":{"$ref":"#/components/schemas/BoardColumnResponse"},"type":"array","title":"Results"},"has_more":{"type":"boolean","title":"Has More","default":false},"next_cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Cursor"},"page_size":{"type":"integer","title":"Page Size","default":25}},"type":"object","required":["results"],"title":"PaginatedResponse[BoardColumnResponse]"},"PaginatedResponse_BoardLabelResponse_":{"properties":{"object":{"type":"string","title":"Object","default":"list"},"results":{"items":{"$ref":"#/components/schemas/BoardLabelResponse"},"type":"array","title":"Results"},"has_more":{"type":"boolean","title":"Has More","default":false},"next_cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Cursor"},"page_size":{"type":"integer","title":"Page Size","default":25}},"type":"object","required":["results"],"title":"PaginatedResponse[BoardLabelResponse]"},"PaginatedResponse_BoardResponse_":{"properties":{"object":{"type":"string","title":"Object","default":"list"},"results":{"items":{"$ref":"#/components/schemas/BoardResponse"},"type":"array","title":"Results"},"has_more":{"type":"boolean","title":"Has More","default":false},"next_cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Cursor"},"page_size":{"type":"integer","title":"Page Size","default":25}},"type":"object","required":["results"],"title":"PaginatedResponse[BoardResponse]"},"PaginatedResponse_BoardTemplateResponse_":{"properties":{"object":{"type":"string","title":"Object","default":"list"},"results":{"items":{"$ref":"#/components/schemas/BoardTemplateResponse"},"type":"array","title":"Results"},"has_more":{"type":"boolean","title":"Has More","default":false},"next_cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Cursor"},"page_size":{"type":"integer","title":"Page Size","default":25}},"type":"object","required":["results"],"title":"PaginatedResponse[BoardTemplateResponse]"},"PaginatedResponse_CardAuditEntry_":{"properties":{"object":{"type":"string","title":"Object","default":"list"},"results":{"items":{"$ref":"#/components/schemas/CardAuditEntry"},"type":"array","title":"Results"},"has_more":{"type":"boolean","title":"Has More","default":false},"next_cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Cursor"},"page_size":{"type":"integer","title":"Page Size","default":25}},"type":"object","required":["results"],"title":"PaginatedResponse[CardAuditEntry]"},"PaginatedResponse_CardResponse_":{"properties":{"object":{"type":"string","title":"Object","default":"list"},"results":{"items":{"$ref":"#/components/schemas/CardResponse"},"type":"array","title":"Results"},"has_more":{"type":"boolean","title":"Has More","default":false},"next_cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Cursor"},"page_size":{"type":"integer","title":"Page Size","default":25}},"type":"object","required":["results"],"title":"PaginatedResponse[CardResponse]"},"PaginatedResponse_CardTemplateResponse_":{"properties":{"object":{"type":"string","title":"Object","default":"list"},"results":{"items":{"$ref":"#/components/schemas/CardTemplateResponse"},"type":"array","title":"Results"},"has_more":{"type":"boolean","title":"Has More","default":false},"next_cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Cursor"},"page_size":{"type":"integer","title":"Page Size","default":25}},"type":"object","required":["results"],"title":"PaginatedResponse[CardTemplateResponse]"},"PaginatedResponse_DomainClaimResponse_":{"properties":{"object":{"type":"string","title":"Object","default":"list"},"results":{"items":{"$ref":"#/components/schemas/DomainClaimResponse"},"type":"array","title":"Results"},"has_more":{"type":"boolean","title":"Has More","default":false},"next_cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Cursor"},"page_size":{"type":"integer","title":"Page Size","default":25}},"type":"object","required":["results"],"title":"PaginatedResponse[DomainClaimResponse]"},"PaginatedResponse_ImportJobResponse_":{"properties":{"object":{"type":"string","title":"Object","default":"list"},"results":{"items":{"$ref":"#/components/schemas/ImportJobResponse"},"type":"array","title":"Results"},"has_more":{"type":"boolean","title":"Has More","default":false},"next_cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Cursor"},"page_size":{"type":"integer","title":"Page Size","default":25}},"type":"object","required":["results"],"title":"PaginatedResponse[ImportJobResponse]"},"PaginatedResponse_IntegrationResponse_":{"properties":{"object":{"type":"string","title":"Object","default":"list"},"results":{"items":{"$ref":"#/components/schemas/IntegrationResponse"},"type":"array","title":"Results"},"has_more":{"type":"boolean","title":"Has More","default":false},"next_cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Cursor"},"page_size":{"type":"integer","title":"Page Size","default":25}},"type":"object","required":["results"],"title":"PaginatedResponse[IntegrationResponse]"},"PaginatedResponse_LeaseResponse_":{"properties":{"object":{"type":"string","title":"Object","default":"list"},"results":{"items":{"$ref":"#/components/schemas/LeaseResponse"},"type":"array","title":"Results"},"has_more":{"type":"boolean","title":"Has More","default":false},"next_cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Cursor"},"page_size":{"type":"integer","title":"Page Size","default":25}},"type":"object","required":["results"],"title":"PaginatedResponse[LeaseResponse]"},"PaginatedResponse_MembershipResponse_":{"properties":{"object":{"type":"string","title":"Object","default":"list"},"results":{"items":{"$ref":"#/components/schemas/MembershipResponse"},"type":"array","title":"Results"},"has_more":{"type":"boolean","title":"Has More","default":false},"next_cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Cursor"},"page_size":{"type":"integer","title":"Page Size","default":25}},"type":"object","required":["results"],"title":"PaginatedResponse[MembershipResponse]"},"PaginatedResponse_OrgGrantRow_":{"properties":{"object":{"type":"string","title":"Object","default":"list"},"results":{"items":{"$ref":"#/components/schemas/OrgGrantRow"},"type":"array","title":"Results"},"has_more":{"type":"boolean","title":"Has More","default":false},"next_cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Cursor"},"page_size":{"type":"integer","title":"Page Size","default":25}},"type":"object","required":["results"],"title":"PaginatedResponse[OrgGrantRow]"},"PaginatedResponse_OrganizationResponse_":{"properties":{"object":{"type":"string","title":"Object","default":"list"},"results":{"items":{"$ref":"#/components/schemas/OrganizationResponse"},"type":"array","title":"Results"},"has_more":{"type":"boolean","title":"Has More","default":false},"next_cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Cursor"},"page_size":{"type":"integer","title":"Page Size","default":25}},"type":"object","required":["results"],"title":"PaginatedResponse[OrganizationResponse]"},"PaginatedResponse_PlatformAdminRow_":{"properties":{"object":{"type":"string","title":"Object","default":"list"},"results":{"items":{"$ref":"#/components/schemas/PlatformAdminRow"},"type":"array","title":"Results"},"has_more":{"type":"boolean","title":"Has More","default":false},"next_cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Cursor"},"page_size":{"type":"integer","title":"Page Size","default":25}},"type":"object","required":["results"],"title":"PaginatedResponse[PlatformAdminRow]"},"PaginatedResponse_PlaybookResponse_":{"properties":{"object":{"type":"string","title":"Object","default":"list"},"results":{"items":{"$ref":"#/components/schemas/PlaybookResponse"},"type":"array","title":"Results"},"has_more":{"type":"boolean","title":"Has More","default":false},"next_cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Cursor"},"page_size":{"type":"integer","title":"Page Size","default":25}},"type":"object","required":["results"],"title":"PaginatedResponse[PlaybookResponse]"},"PaginatedResponse_SearchHitResponse_":{"properties":{"object":{"type":"string","title":"Object","default":"list"},"results":{"items":{"$ref":"#/components/schemas/SearchHitResponse"},"type":"array","title":"Results"},"has_more":{"type":"boolean","title":"Has More","default":false},"next_cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Cursor"},"page_size":{"type":"integer","title":"Page Size","default":25}},"type":"object","required":["results"],"title":"PaginatedResponse[SearchHitResponse]"},"PaginatedResponse_ShareLinkResponse_":{"properties":{"object":{"type":"string","title":"Object","default":"list"},"results":{"items":{"$ref":"#/components/schemas/ShareLinkResponse"},"type":"array","title":"Results"},"has_more":{"type":"boolean","title":"Has More","default":false},"next_cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Cursor"},"page_size":{"type":"integer","title":"Page Size","default":25}},"type":"object","required":["results"],"title":"PaginatedResponse[ShareLinkResponse]"},"PaginatedResponse_UserSessionResponse_":{"properties":{"object":{"type":"string","title":"Object","default":"list"},"results":{"items":{"$ref":"#/components/schemas/UserSessionResponse"},"type":"array","title":"Results"},"has_more":{"type":"boolean","title":"Has More","default":false},"next_cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Cursor"},"page_size":{"type":"integer","title":"Page Size","default":25}},"type":"object","required":["results"],"title":"PaginatedResponse[UserSessionResponse]"},"PaginatedResponse_WebhookDeliveryResponse_":{"properties":{"object":{"type":"string","title":"Object","default":"list"},"results":{"items":{"$ref":"#/components/schemas/WebhookDeliveryResponse"},"type":"array","title":"Results"},"has_more":{"type":"boolean","title":"Has More","default":false},"next_cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Cursor"},"page_size":{"type":"integer","title":"Page Size","default":25}},"type":"object","required":["results"],"title":"PaginatedResponse[WebhookDeliveryResponse]"},"PaginatedResponse_WebhookResponse_":{"properties":{"object":{"type":"string","title":"Object","default":"list"},"results":{"items":{"$ref":"#/components/schemas/WebhookResponse"},"type":"array","title":"Results"},"has_more":{"type":"boolean","title":"Has More","default":false},"next_cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Cursor"},"page_size":{"type":"integer","title":"Page Size","default":25}},"type":"object","required":["results"],"title":"PaginatedResponse[WebhookResponse]"},"PasswordResetConfirmRequest":{"properties":{"token":{"type":"string","title":"Token"},"new_password":{"type":"string","minLength":1,"title":"New Password"}},"type":"object","required":["token","new_password"],"title":"PasswordResetConfirmRequest"},"PasswordResetRequest":{"properties":{"email":{"type":"string","title":"Email"}},"type":"object","required":["email"],"title":"PasswordResetRequest"},"PauseAgentRequest":{"properties":{"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason"}},"type":"object","title":"PauseAgentRequest","description":"Body for POST /v1/orgs/{org_id}/agents/{agent_user_id}:pause.\n\n``reason`` is optional and free-form; the handler trims it to fit the\n``agent_budgets.paused_reason`` ``varchar(200)`` column. The body itself is\noptional (``:pause`` with no body is allowed)."},"PlatformAdminRow":{"properties":{"object":{"type":"string","title":"Object","default":"platform_admin"},"id":{"type":"string","format":"uuid","title":"Id"},"user_id":{"type":"string","format":"uuid","title":"User Id"},"email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"role":{"type":"string","title":"Role"},"granted_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Granted At"},"granted_by_user_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Granted By User Id"}},"type":"object","required":["id","user_id","role"],"title":"PlatformAdminRow"},"PlaybookResponse":{"properties":{"object":{"type":"string","title":"Object","default":"playbook"},"id":{"type":"string","format":"uuid","title":"Id"},"org_id":{"type":"string","format":"uuid","title":"Org Id"},"name":{"type":"string","title":"Name"},"steps":{"items":{},"type":"array","title":"Steps"},"output_target":{"type":"string","title":"Output Target"},"on_success_move_to":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"On Success Move To"},"created_time":{"type":"string","format":"date-time","title":"Created Time"},"last_edited_time":{"type":"string","format":"date-time","title":"Last Edited Time"}},"type":"object","required":["id","org_id","name","steps","output_target","on_success_move_to","created_time","last_edited_time"],"title":"PlaybookResponse"},"PortalResponse":{"properties":{"portal_url":{"type":"string","title":"Portal Url"}},"type":"object","required":["portal_url"],"title":"PortalResponse","description":"Response for ``POST /v1/orgs/{org_id}/billing:portal`` (spec §18.6).\n\nThe owner is redirected to ``portal_url`` (a Stripe-hosted Customer Portal\nSession) to manage their subscription — cancel, update payment method, view\ninvoices. Requires an existing ``stripe_customer_id`` (``409 no_subscription``\nif absent)."},"PropertyItemResponse":{"properties":{"object":{"type":"string","title":"Object","default":"property_item"},"id":{"type":"string","title":"Id"},"type":{"type":"string","title":"Type"},"value":{"title":"Value"}},"additionalProperties":false,"type":"object","required":["id","type","value"],"title":"PropertyItemResponse","description":"Single property fetched from a card. Notion's `property_item` shape."},"PublicAgentActivityResponse":{"properties":{"object":{"type":"string","title":"Object","default":"public_agent_activity"},"board_id":{"type":"string","format":"uuid","title":"Board Id"},"summary":{"$ref":"#/components/schemas/AgentActivitySummary"},"entries":{"items":{"$ref":"#/components/schemas/AgentActivityEntry"},"type":"array","title":"Entries"},"has_more":{"type":"boolean","title":"Has More","default":false},"next_cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Cursor"}},"type":"object","required":["board_id","summary","entries"],"title":"PublicAgentActivityResponse","description":"Client-shareable, read-only agent-activity report for ONE board (NOV-271).\n\nServed on the seatless share-link surface (``/v1/public/...``) so an agency\ncan show a CLIENT holding a viewer/commenter share-link token exactly what\nagents did on THEIR board — the \"run bots on a client board and show that\nclient what happened\" trust flow (spec §4.6 + §4.7). Deliberately narrower\nthan :class:`AgentActivityResponse`: it is ALWAYS board-scoped (``board_id``\nis the bound board, never org-wide) and all-agents (no ``agent_user_id`` — a\nclient sees the board's activity, not internal per-agent breakdowns). No\n``page_size`` — the feed is still cursor-paginated via ``next_cursor``."},"PublicCommentRequest":{"properties":{"body":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Body"}},"additionalProperties":false,"type":"object","required":["body"],"title":"PublicCommentRequest","description":"A comment posted through a ``commenter`` share link (NOV-199).\n\nOnly the block ``body`` is accepted — the card is fixed by the path and the\nauthor is the (anonymous) link, never a User. Emptiness is enforced in the\ncomment service."},"PurgeBoardPropertyRequest":{"properties":{"name":{"type":"string","title":"Name"}},"additionalProperties":false,"type":"object","required":["name"],"title":"PurgeBoardPropertyRequest","description":"NOV-459 (§7.1): body of ``POST /v1/boards/{id}/properties:purge``.\n\nNames the ARCHIVED property definition to delete permanently. Separate from\nthe properties patch on purpose: ``{\"properties\": {\"ID\": null}}`` archives a\n``unique_id`` property (recoverable — re-adding the name reinstates the same\ndefinition, id, prefix and counter), and this is the one action that is not."},"RenewLeaseRequest":{"properties":{"lease_token":{"type":"string","maxLength":64,"minLength":1,"title":"Lease Token"},"lease_ttl_seconds":{"anyOf":[{"type":"integer","maximum":86400.0,"minimum":1.0},{"type":"null"}],"title":"Lease Ttl Seconds"}},"additionalProperties":false,"type":"object","required":["lease_token"],"title":"RenewLeaseRequest","description":"Body for ``POST /v1/leases/{lease_id}:renew`` (and ``:heartbeat``)."},"ResendVerificationRequest":{"properties":{"email":{"type":"string","title":"Email"}},"type":"object","required":["email"],"title":"ResendVerificationRequest"},"RevokeAgentTokensResponse":{"properties":{"object":{"type":"string","title":"Object","default":"agent_tokens_revoked"},"agent_user_id":{"type":"string","format":"uuid","title":"Agent User Id"},"revoked_count":{"type":"integer","title":"Revoked Count"}},"type":"object","required":["agent_user_id","revoked_count"],"title":"RevokeAgentTokensResponse","description":"Response for the hard, irreversible :revoke_tokens variant (spec §4.7).\n\n``revoked_count`` is how many ``Integration`` credentials were deleted for\nthe agent in this org. Unlike :pause, this sets no paused/disabled state — it\nonly wipes credentials."},"RevokeOrgGrantRequest":{"properties":{"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason"}},"type":"object","title":"RevokeOrgGrantRequest","description":"Optional revoke body — an operator note recorded in the audit trail."},"SearchHitResponse":{"properties":{"object":{"type":"string","title":"Object","default":"card"},"id":{"type":"string","format":"uuid","title":"Id"},"board_id":{"type":"string","format":"uuid","title":"Board Id"},"column_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Column Id"},"title":{"type":"string","title":"Title"},"properties":{"additionalProperties":true,"type":"object","title":"Properties"},"position":{"type":"number","title":"Position"},"assignees":{"items":{"type":"string"},"type":"array","title":"Assignees"},"due_date":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Due Date"},"labels":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Labels"},"is_archived":{"type":"boolean","title":"Is Archived"},"agent_activity":{"anyOf":[{"$ref":"#/components/schemas/AgentActivity"},{"type":"null"}]},"created_time":{"type":"string","format":"date-time","title":"Created Time"},"last_edited_time":{"type":"string","format":"date-time","title":"Last Edited Time"},"body_last_edited_time":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Body Last Edited Time"},"etag":{"type":"integer","title":"Etag"},"attachment_count":{"type":"integer","title":"Attachment Count","default":0},"unique_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Unique Id"},"_search":{"$ref":"#/components/schemas/SearchResultMeta"}},"additionalProperties":false,"type":"object","required":["id","board_id","title","properties","position","assignees","labels","is_archived","created_time","last_edited_time","etag","_search"],"title":"SearchHitResponse","description":"One ``POST /v1/search`` result: a card PLUS its relevance block (NOV-457).\n\nA search hit is a full ``CardResponse`` with one extra key — it is NOT a\ndifferent object, so this subclasses the card rather than wrapping it. That\nkeeps the wire flat (the hit *is* the card) and means every card field stays\nin one place; adding a field to ``CardResponse`` reaches search for free.\n\n``_search`` cannot be a Python field name — pydantic reserves the leading\nunderscore for private attributes — so the field is ``search`` carrying an\nexplicit alias. FastAPI serializes response models with ``by_alias=True``,\nand ``populate_by_name`` (inherited from ``APIModel``) lets the service's\nhand-built ``{\"_search\": ...}`` dict validate, so the key crosses the wire\nunchanged in both directions."},"SearchRequest":{"properties":{"query":{"type":"string","maxLength":500,"minLength":1,"title":"Query"},"types":{"anyOf":[{"items":{"type":"string","const":"card"},"type":"array"},{"type":"null"}],"title":"Types"},"board_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Board Id"},"page_size":{"anyOf":[{"type":"integer","maximum":100.0,"minimum":1.0},{"type":"null"}],"title":"Page Size"},"start_cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Start Cursor"}},"additionalProperties":false,"type":"object","required":["query"],"title":"SearchRequest"},"SearchResultMeta":{"properties":{"score":{"type":"number","title":"Score"},"highlight":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Highlight"}},"additionalProperties":false,"type":"object","required":["score"],"title":"SearchResultMeta","description":"Search-only envelope attached to result objects under the `_search` key.\n\nKept off the canonical Card shape so result consumers can ignore it and\ncallers wanting ranking signal can pluck it out."},"SeatBreakdown":{"properties":{"humans":{"type":"integer","title":"Humans"},"agents":{"type":"integer","title":"Agents"},"billable_agents":{"type":"integer","title":"Billable Agents"}},"type":"object","required":["humans","agents","billable_agents"],"title":"SeatBreakdown","description":"Humans-vs-agents seat split for the People/Billing UI (spec §18.9, NOV-189).\n\nComputed server-side from ``billing.seat_breakdown`` so the \"first agent\nfree\" rule (§18.1) is never re-derived in the frontend. ``billable_agents``\nis ``max(0, agents - 1)``; the top-level ``billable_seats`` on\n:class:`BillingResponse` equals ``humans + billable_agents``."},"SetAgentActivityRequest":{"properties":{"agent_name":{"type":"string","maxLength":200,"minLength":1,"title":"Agent Name"},"doing":{"type":"string","maxLength":500,"minLength":1,"title":"Doing"}},"additionalProperties":false,"type":"object","required":["agent_name","doing"],"title":"SetAgentActivityRequest","description":"Body for POST /v1/cards/{card_id}/agent_activity."},"SetPasswordRequest":{"properties":{"new_password":{"type":"string","minLength":1,"title":"New Password"}},"type":"object","required":["new_password"],"title":"SetPasswordRequest","description":"OAuth-only users who want to enable email/password login alongside\ntheir existing identity provider. Idempotent — once they have a password,\nthey must use ``POST /v1/me/password`` to change it."},"ShareLinkCreatedResponse":{"properties":{"object":{"type":"string","title":"Object","default":"board_share_link"},"id":{"type":"string","format":"uuid","title":"Id"},"board_id":{"type":"string","format":"uuid","title":"Board Id"},"role":{"type":"string","title":"Role"},"label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Label"},"token_last4":{"type":"string","title":"Token Last4"},"expires_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Expires At"},"revoked_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Revoked At"},"created_time":{"type":"string","format":"date-time","title":"Created Time"},"last_edited_time":{"type":"string","format":"date-time","title":"Last Edited Time"},"token":{"type":"string","title":"Token"},"url":{"type":"string","title":"Url"}},"additionalProperties":false,"type":"object","required":["id","board_id","role","token_last4","created_time","last_edited_time","token","url"],"title":"ShareLinkCreatedResponse","description":"Returned ONCE from create — carries the raw token + ready-to-share URL.\n\n``token`` and ``url`` are present only on this create response and are never\nretrievable again (only the argon2id hash is stored)."},"ShareLinkResponse":{"properties":{"object":{"type":"string","title":"Object","default":"board_share_link"},"id":{"type":"string","format":"uuid","title":"Id"},"board_id":{"type":"string","format":"uuid","title":"Board Id"},"role":{"type":"string","title":"Role"},"label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Label"},"token_last4":{"type":"string","title":"Token Last4"},"expires_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Expires At"},"revoked_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Revoked At"},"created_time":{"type":"string","format":"date-time","title":"Created Time"},"last_edited_time":{"type":"string","format":"date-time","title":"Last Edited Time"}},"additionalProperties":false,"type":"object","required":["id","board_id","role","token_last4","created_time","last_edited_time"],"title":"ShareLinkResponse","description":"A share link's management-side view — never includes the raw token.\n\n``token_last4`` identifies the link in the UI; the full token is shown only\nonce, in :class:`ShareLinkCreatedResponse`."},"SignupRequest":{"properties":{"email":{"type":"string","title":"Email"},"password":{"type":"string","title":"Password"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"}},"type":"object","required":["email","password"],"title":"SignupRequest"},"UnreadCountResponse":{"properties":{"object":{"type":"string","title":"Object","default":"notification_count"},"unread":{"type":"integer","title":"Unread"}},"type":"object","required":["unread"],"title":"UnreadCountResponse","description":"Envelope for ``GET /v1/notifications/count`` (spec §22.2)."},"UpdateAutomationRequest":{"properties":{"name":{"anyOf":[{"type":"string","maxLength":200,"minLength":1},{"type":"null"}],"title":"Name"},"board_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Board Id"},"trigger":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Trigger"},"conditions":{"anyOf":[{"items":{},"type":"array"},{"type":"null"}],"title":"Conditions"},"actions":{"anyOf":[{"items":{},"type":"array"},{"type":"null"}],"title":"Actions"},"run_as_agent_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Run As Agent Id"},"is_active":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Active"}},"type":"object","title":"UpdateAutomationRequest","description":"Body for ``PATCH /v1/orgs/{org_id}/automations/{id}`` (§20.8).\n\nEvery field is optional — a client sends only what it changes. ``is_active``\nsupports the enable/disable toggle. Fields the client omits are left untouched\n(the router forwards only ``model_dump(exclude_unset=True)`` to the service, so\nan explicit ``null`` is distinguishable from an absent key)."},"UpdateBlockRequest":{"properties":{"type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Type"},"archived":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Archived"}},"additionalProperties":true,"type":"object","title":"UpdateBlockRequest","description":"`PATCH /v1/blocks/{id}` body.\n\nThe shape mirrors Notion: a top-level key matching ``type`` carries the\nnew payload. ``archived`` toggles soft-delete. ``type`` is optional and\nonly used when changing block kind."},"UpdateBoardAccessRequest":{"properties":{"role":{"type":"string","title":"Role"}},"additionalProperties":false,"type":"object","required":["role"],"title":"UpdateBoardAccessRequest"},"UpdateBoardRequest":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"description":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Description"},"icon":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Icon"},"cover":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Cover"},"status_groups":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Status Groups"},"properties":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Properties"},"visibility":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Visibility"},"workspace_access":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Workspace Access"},"permissions":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Permissions"},"property_validation":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Property Validation"}},"additionalProperties":false,"type":"object","title":"UpdateBoardRequest"},"UpdateCardRequest":{"properties":{"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"properties":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Properties"},"assignees":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Assignees"},"due_date":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Due Date"},"labels":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Labels"},"remove_labels":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Remove Labels"},"is_archived":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Archived"}},"additionalProperties":false,"type":"object","title":"UpdateCardRequest"},"UpdateCardTemplateRequest":{"properties":{"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"properties":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Properties"},"body_blocks":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Body Blocks"},"assignees":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Assignees"},"labels":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Labels"},"recurrence_rule":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Recurrence Rule"},"next_materialization_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Next Materialization At"},"until":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Until"},"count_remaining":{"anyOf":[{"type":"integer","maximum":10000.0,"minimum":0.0},{"type":"null"}],"title":"Count Remaining"},"is_active":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Active"}},"additionalProperties":false,"type":"object","title":"UpdateCardTemplateRequest"},"UpdateColumnRequest":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"color":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Color"},"position":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Position"},"status_group":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status Group"},"autopilot":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Autopilot"},"playbook_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Playbook Id"},"autopilot_label_gate":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Autopilot Label Gate"}},"additionalProperties":false,"type":"object","title":"UpdateColumnRequest"},"UpdateCommentRequest":{"properties":{"body":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Body"}},"additionalProperties":false,"type":"object","required":["body"],"title":"UpdateCommentRequest"},"UpdateMembershipRequest":{"properties":{"role":{"type":"string","title":"Role"}},"type":"object","required":["role"],"title":"UpdateMembershipRequest"},"UpdateNotificationPreferencesRequest":{"properties":{"email":{"anyOf":[{"additionalProperties":{"anyOf":[{"type":"boolean"},{"type":"null"}]},"propertyNames":{"enum":["card_assigned","automation_notify"]},"type":"object"},{"type":"null"}],"title":"Email"}},"type":"object","title":"UpdateNotificationPreferencesRequest","description":"Partial per-type notification write (NOV-364).\n\n``email`` is a partial MERGE map: each key sets that type's email flag and\ntypes absent from the map are left untouched; an explicit ``None`` value\nCLEARS that type's stored override so it follows the default again (the\nsame tri-state as the ``board_card_view`` merge idiom). An unknown type is\nrejected by the ``NotificationType`` Literal (422), the same way an unknown\n``theme`` value is; ``StrictBool`` pins non-bool values (\"yes\", 1, …) to a\n422 as well — no lax coercion on a consent field. Omitting ``email`` (or\nthe whole ``notifications`` block) is a no-op."},"UpdateOrganizationRequest":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"primary_domain":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Primary Domain"}},"type":"object","title":"UpdateOrganizationRequest"},"UpdatePlaybookRequest":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"steps":{"anyOf":[{"items":{},"type":"array"},{"type":"null"}],"title":"Steps"},"output_target":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Output Target"},"on_success_move_to":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"On Success Move To"}},"type":"object","title":"UpdatePlaybookRequest","description":"Body for ``PATCH /v1/orgs/{org_id}/playbooks/{id}`` (§23.4).\n\nEvery field is optional — a client sends only what it changes. Fields the client\nomits are left untouched (the router forwards only ``model_dump(exclude_unset=\nTrue)``, so an explicit ``null`` clearing ``on_success_move_to`` is\ndistinguishable from an absent key)."},"UpdatePreferencesRequest":{"properties":{"theme":{"anyOf":[{"type":"string","enum":["dark","light","system"]},{"type":"null"}],"title":"Theme"},"default_card_view":{"anyOf":[{"type":"string","enum":["side_panel","center_peek","focused_overlay","full_page"]},{"type":"null"}],"title":"Default Card View"},"board_card_view":{"anyOf":[{"additionalProperties":{"anyOf":[{"type":"string","enum":["side_panel","center_peek","focused_overlay","full_page"]},{"type":"null"}]},"type":"object"},{"type":"null"}],"title":"Board Card View"},"notifications":{"anyOf":[{"$ref":"#/components/schemas/UpdateNotificationPreferencesRequest"},{"type":"null"}]},"dismissed_hints":{"anyOf":[{"additionalProperties":{"anyOf":[{"type":"boolean"},{"type":"null"}]},"propertyNames":{"const":"connect_agent"},"type":"object"},{"type":"null"}],"title":"Dismissed Hints"}},"type":"object","title":"UpdatePreferencesRequest","description":"PATCH /v1/me/preferences. Only the keys the caller wants to change.\n\nSending ``default_card_view: null`` explicitly clears it so the user\nfalls back to the client-side first-time default (NOV-81)."},"UpdateProfileRequest":{"properties":{"name":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Name"},"avatar_url":{"anyOf":[{"type":"string","maxLength":1024},{"type":"null"}],"title":"Avatar Url"}},"type":"object","title":"UpdateProfileRequest","description":"PATCH /v1/me/profile. Both fields are optional — caller sends only what\nthey want to change. ``None`` and \"omitted\" are different on the wire; we\ntreat \"omitted\" as no-op and an empty string as \"clear the field\"."},"UpdateWebhookRequest":{"properties":{"url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Url"},"event_types":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Event Types"},"board_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Board Id"},"is_active":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Active"}},"type":"object","title":"UpdateWebhookRequest"},"UserPreferencesResponse":{"properties":{"object":{"type":"string","title":"Object","default":"user_preferences"},"theme":{"type":"string","enum":["dark","light","system"],"title":"Theme","default":"system"},"default_card_view":{"anyOf":[{"type":"string","enum":["side_panel","center_peek","focused_overlay","full_page"]},{"type":"null"}],"title":"Default Card View"},"board_card_view":{"additionalProperties":{"type":"string","enum":["side_panel","center_peek","focused_overlay","full_page"]},"type":"object","title":"Board Card View"},"notifications":{"$ref":"#/components/schemas/NotificationPreferencesResponse"},"dismissed_hints":{"additionalProperties":{"type":"boolean"},"propertyNames":{"const":"connect_agent"},"type":"object","title":"Dismissed Hints"}},"type":"object","title":"UserPreferencesResponse"},"UserProfileResponse":{"properties":{"object":{"type":"string","title":"Object","default":"user_profile"},"id":{"type":"string","format":"uuid","title":"Id"},"email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email"},"email_verified":{"type":"boolean","title":"Email Verified","default":false},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"avatar_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Avatar Url"},"signup_source":{"type":"string","title":"Signup Source"},"has_password":{"type":"boolean","title":"Has Password"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"last_signed_in_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Signed In At"}},"type":"object","required":["id","signup_source","has_password","created_at"],"title":"UserProfileResponse","description":"GET /v1/me/profile shape. Self-only — never leaks across users."},"UserResponse":{"properties":{"object":{"type":"string","title":"Object","default":"user"},"id":{"type":"string","format":"uuid","title":"Id"},"email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"avatar_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Avatar Url"},"email_verified":{"type":"boolean","title":"Email Verified","default":false},"kind":{"type":"string","title":"Kind","default":"human"},"agent_runtime_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Agent Runtime Url"},"is_platform_admin":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Platform Admin"},"platform_admin_role":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Platform Admin Role"}},"type":"object","required":["id"],"title":"UserResponse"},"UserSessionResponse":{"properties":{"object":{"type":"string","title":"Object","default":"user_session"},"id":{"type":"string","format":"uuid","title":"Id"},"user_agent_hint":{"type":"string","title":"User Agent Hint"},"user_agent":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"User Agent"},"ip_address":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ip Address"},"last_active_at":{"type":"string","format":"date-time","title":"Last Active At"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"expires_at":{"type":"string","format":"date-time","title":"Expires At"},"is_current":{"type":"boolean","title":"Is Current","default":false}},"type":"object","required":["id","user_agent_hint","last_active_at","created_at","expires_at"],"title":"UserSessionResponse"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"},"VerifyEmailRequest":{"properties":{"token":{"type":"string","title":"Token"}},"type":"object","required":["token"],"title":"VerifyEmailRequest"},"WebhookDeliveryResponse":{"properties":{"object":{"type":"string","title":"Object","default":"webhook_delivery"},"id":{"type":"string","format":"uuid","title":"Id"},"webhook_id":{"type":"string","format":"uuid","title":"Webhook Id"},"event_id":{"type":"string","format":"uuid","title":"Event Id"},"event_type":{"type":"string","title":"Event Type"},"status":{"type":"string","title":"Status"},"attempts":{"type":"integer","title":"Attempts"},"last_response_status":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Last Response Status"},"last_response_body_excerpt":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Response Body Excerpt"},"next_retry_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Next Retry At"},"created_time":{"type":"string","format":"date-time","title":"Created Time"},"last_edited_time":{"type":"string","format":"date-time","title":"Last Edited Time"}},"type":"object","required":["id","webhook_id","event_id","event_type","status","attempts","last_response_status","last_response_body_excerpt","next_retry_at","created_time","last_edited_time"],"title":"WebhookDeliveryResponse"},"WebhookResponse":{"properties":{"object":{"type":"string","title":"Object","default":"webhook"},"id":{"type":"string","format":"uuid","title":"Id"},"org_id":{"type":"string","format":"uuid","title":"Org Id"},"url":{"type":"string","title":"Url"},"event_types":{"items":{"type":"string"},"type":"array","title":"Event Types"},"board_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Board Id"},"is_active":{"type":"boolean","title":"Is Active"},"secret_last4":{"type":"string","title":"Secret Last4"},"created_time":{"type":"string","format":"date-time","title":"Created Time"},"last_edited_time":{"type":"string","format":"date-time","title":"Last Edited Time"}},"type":"object","required":["id","org_id","url","event_types","board_id","is_active","secret_last4","created_time","last_edited_time"],"title":"WebhookResponse"}},"securitySchemes":{"IntegrationToken":{"type":"http","scheme":"bearer","description":"Integration token. Mint one in the app under **Settings → Integrations** and paste the `nov_…` value here — it is sent as `Authorization: Bearer nov_…`, the same credential the API enforces. Browser session cookies are NOT used by try-it-out (the cookie flow additionally requires an `X-CSRF-Token` header this page cannot mint)."}}}}