{"openapi":"3.1.0","info":{"title":"greatfeedback.ai","version":"0.1.0"},"paths":{"/api/health":{"get":{"summary":"Health","operationId":"health_api_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/llms.txt":{"get":{"tags":["agents"],"summary":"Llms Short","operationId":"llms_short_llms_txt_get","responses":{"200":{"description":"Successful Response"}}}},"/llms-full.txt":{"get":{"tags":["agents"],"summary":"Llms Full","operationId":"llms_full_llms_full_txt_get","responses":{"200":{"description":"Successful Response"}}}},"/mcp.json":{"get":{"tags":["agents"],"summary":"Mcp Descriptor","operationId":"mcp_descriptor_mcp_json_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/reviews":{"get":{"tags":["reviews"],"summary":"List Reviews","operationId":"list_reviews_api_reviews_get","parameters":[{"name":"widget_site_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Widget Site Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["reviews"],"summary":"Create Review","operationId":"create_review_api_reviews_post","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReviewCreate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/reviews/shared/{token}":{"get":{"tags":["reviews"],"summary":"Get Shared Review","operationId":"get_shared_review_api_reviews_shared__token__get","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/reviews/{review_id}":{"get":{"tags":["reviews"],"summary":"Get Review","operationId":"get_review_api_reviews__review_id__get","parameters":[{"name":"review_id","in":"path","required":true,"schema":{"type":"string","title":"Review Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["reviews"],"summary":"Delete Review","operationId":"delete_review_api_reviews__review_id__delete","parameters":[{"name":"review_id","in":"path","required":true,"schema":{"type":"string","title":"Review Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/reviews/{review_id}/share":{"post":{"tags":["reviews"],"summary":"Share Review","operationId":"share_review_api_reviews__review_id__share_post","parameters":[{"name":"review_id","in":"path","required":true,"schema":{"type":"string","title":"Review Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/reviews/{review_id}/showcase":{"post":{"tags":["showcase"],"summary":"Submit Showcase","operationId":"submit_showcase_api_reviews__review_id__showcase_post","parameters":[{"name":"review_id","in":"path","required":true,"schema":{"type":"string","title":"Review Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["showcase"],"summary":"Withdraw Showcase","operationId":"withdraw_showcase_api_reviews__review_id__showcase_delete","parameters":[{"name":"review_id","in":"path","required":true,"schema":{"type":"string","title":"Review Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/showcase/{slug}":{"get":{"tags":["showcase"],"summary":"Public Showcase","operationId":"public_showcase_api_showcase__slug__get","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/showcase/{slug}/report":{"post":{"tags":["showcase"],"summary":"Report Showcase","description":"Anonymous abuse report. Flips the row back to `pending` so the\nadmin queue catches it. Per-IP / per-slug we cap to 5 reports per\n24h via the existing widget rate-limit helper.","operationId":"report_showcase_api_showcase__slug__report_post","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReportBody"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/admin/showcase/pending":{"get":{"tags":["showcase-admin"],"summary":"Admin List Pending","operationId":"admin_list_pending_api_admin_showcase_pending_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/admin/showcase/{review_id}/approve":{"post":{"tags":["showcase-admin"],"summary":"Admin Approve","operationId":"admin_approve_api_admin_showcase__review_id__approve_post","parameters":[{"name":"review_id","in":"path","required":true,"schema":{"type":"string","title":"Review Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DecisionBody"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/admin/showcase/{review_id}/reject":{"post":{"tags":["showcase-admin"],"summary":"Admin Reject","operationId":"admin_reject_api_admin_showcase__review_id__reject_post","parameters":[{"name":"review_id","in":"path","required":true,"schema":{"type":"string","title":"Review Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DecisionBody"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/reviews/{review_id}/feedback":{"get":{"tags":["feedback"],"summary":"List Feedback","operationId":"list_feedback_api_reviews__review_id__feedback_get","parameters":[{"name":"review_id","in":"path","required":true,"schema":{"type":"string","title":"Review Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/reviews/shared/{token}/feedback":{"get":{"tags":["feedback"],"summary":"List Shared Feedback","operationId":"list_shared_feedback_api_reviews_shared__token__feedback_get","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/reviews/{review_id}/feedback/{feedback_id}/rate":{"post":{"tags":["feedback"],"summary":"Rate Feedback","operationId":"rate_feedback_api_reviews__review_id__feedback__feedback_id__rate_post","parameters":[{"name":"review_id","in":"path","required":true,"schema":{"type":"string","title":"Review Id"}},{"name":"feedback_id","in":"path","required":true,"schema":{"type":"string","title":"Feedback Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FeedbackRating"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/personas/mine":{"get":{"tags":["personas"],"summary":"List Mine","description":"Defaults + customs in the caller's current workspace, ordered.","operationId":"list_mine_api_personas_mine_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/personas/category/{category}":{"get":{"tags":["personas"],"summary":"List By Category","description":"Personas in `category` scoped to the caller's workspace.","operationId":"list_by_category_api_personas_category__category__get","parameters":[{"name":"category","in":"path","required":true,"schema":{"type":"string","title":"Category"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/personas/reset-defaults":{"post":{"tags":["personas"],"summary":"Reset Defaults","description":"Re-apply canonical seed values to default personas. Customs untouched.\n`slug=None` resets all defaults; passing a slug resets only that one.","operationId":"reset_defaults_api_personas_reset_defaults_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResetDefaultsRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/personas/{persona_id}":{"get":{"tags":["personas"],"summary":"Get Persona","operationId":"get_persona_api_personas__persona_id__get","parameters":[{"name":"persona_id","in":"path","required":true,"schema":{"type":"string","title":"Persona Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["personas"],"summary":"Patch Persona","operationId":"patch_persona_api_personas__persona_id__patch","parameters":[{"name":"persona_id","in":"path","required":true,"schema":{"type":"string","title":"Persona Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PersonaPatch"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["personas"],"summary":"Delete Persona","operationId":"delete_persona_api_personas__persona_id__delete","parameters":[{"name":"persona_id","in":"path","required":true,"schema":{"type":"string","title":"Persona Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/personas":{"post":{"tags":["personas"],"summary":"Create Persona","operationId":"create_persona_api_personas_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PersonaCreate"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/personas/{persona_id}/publish":{"post":{"tags":["personas"],"summary":"Publish Persona","description":"Publish a custom persona to the public marketplace.\n\nOnly the owning workspace can publish. Built-ins and defaults are\nrejected (they're already universally available). Idempotent — a\nsecond publish returns the same row with the updated timestamp.","operationId":"publish_persona_api_personas__persona_id__publish_post","parameters":[{"name":"persona_id","in":"path","required":true,"schema":{"type":"string","title":"Persona Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/personas/{persona_id}/unpublish":{"post":{"tags":["personas"],"summary":"Unpublish Persona","operationId":"unpublish_persona_api_personas__persona_id__unpublish_post","parameters":[{"name":"persona_id","in":"path","required":true,"schema":{"type":"string","title":"Persona Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/personas/{persona_id}/clone":{"post":{"tags":["personas"],"summary":"Clone Persona","description":"Clone a public marketplace persona into the caller's workspace.","operationId":"clone_persona_api_personas__persona_id__clone_post","parameters":[{"name":"persona_id","in":"path","required":true,"schema":{"type":"string","title":"Persona Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/marketplace/personas":{"get":{"tags":["marketplace"],"summary":"List Marketplace Personas","operationId":"list_marketplace_personas_api_marketplace_personas_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/widget/sites":{"get":{"tags":["widget"],"summary":"List Sites","operationId":"list_sites_api_widget_sites_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}},"post":{"tags":["widget"],"summary":"Create Site","operationId":"create_site_api_widget_sites_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WidgetSiteCreate"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/widget/sites/{site_id}":{"get":{"tags":["widget"],"summary":"Get Site","operationId":"get_site_api_widget_sites__site_id__get","parameters":[{"name":"site_id","in":"path","required":true,"schema":{"type":"string","title":"Site Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["widget"],"summary":"Patch Site","operationId":"patch_site_api_widget_sites__site_id__patch","parameters":[{"name":"site_id","in":"path","required":true,"schema":{"type":"string","title":"Site Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WidgetSitePatch"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["widget"],"summary":"Delete Site","operationId":"delete_site_api_widget_sites__site_id__delete","parameters":[{"name":"site_id","in":"path","required":true,"schema":{"type":"string","title":"Site Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/widget/sites/{site_id}/secrets":{"get":{"tags":["widget"],"summary":"Get Site Secrets","description":"OWNER-only secrets reveal. Dashboard-only by design.","operationId":"get_site_secrets_api_widget_sites__site_id__secrets_get","parameters":[{"name":"site_id","in":"path","required":true,"schema":{"type":"string","title":"Site Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/widget/sites/{site_id}/secrets/rotate-mcp-token":{"post":{"tags":["widget"],"summary":"Rotate Mcp Token","description":"OWNER-only rotation. Old token stops resolving immediately; new\ntoken shown ONCE in the response.","operationId":"rotate_mcp_token_api_widget_sites__site_id__secrets_rotate_mcp_token_post","parameters":[{"name":"site_id","in":"path","required":true,"schema":{"type":"string","title":"Site Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/widget/sites/{site_id}/annotations":{"get":{"tags":["widget"],"summary":"List Annotations","operationId":"list_annotations_api_widget_sites__site_id__annotations_get","parameters":[{"name":"site_id","in":"path","required":true,"schema":{"type":"string","title":"Site Id"}},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/widget/sites/{site_id}/annotations/export.pdf":{"get":{"tags":["widget"],"summary":"Export Annotations Pdf","operationId":"export_annotations_pdf_api_widget_sites__site_id__annotations_export_pdf_get","parameters":[{"name":"site_id","in":"path","required":true,"schema":{"type":"string","title":"Site Id"}},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/widget/annotations/{annotation_id}":{"get":{"tags":["widget"],"summary":"Get Annotation","operationId":"get_annotation_api_widget_annotations__annotation_id__get","parameters":[{"name":"annotation_id","in":"path","required":true,"schema":{"type":"string","title":"Annotation Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["widget"],"summary":"Patch Annotation","operationId":"patch_annotation_api_widget_annotations__annotation_id__patch","parameters":[{"name":"annotation_id","in":"path","required":true,"schema":{"type":"string","title":"Annotation Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnnotationPatch"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["widget"],"summary":"Delete Annotation","operationId":"delete_annotation_api_widget_annotations__annotation_id__delete","parameters":[{"name":"annotation_id","in":"path","required":true,"schema":{"type":"string","title":"Annotation Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/widget/annotations/{annotation_id}/replies":{"post":{"tags":["widget"],"summary":"Reply To Annotation","operationId":"reply_to_annotation_api_widget_annotations__annotation_id__replies_post","parameters":[{"name":"annotation_id","in":"path","required":true,"schema":{"type":"string","title":"Annotation Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnnotationReplyCreate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/widget/annotations/{annotation_id}/markdown":{"get":{"tags":["widget"],"summary":"Annotation Markdown","operationId":"annotation_markdown_api_widget_annotations__annotation_id__markdown_get","parameters":[{"name":"annotation_id","in":"path","required":true,"schema":{"type":"string","title":"Annotation Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/widget/annotations/{annotation_id}/run-personas":{"post":{"tags":["widget"],"summary":"Run Personas","description":"Bridge an annotation into the AI persona pipeline. Creates a synthetic\nREVIEW with `source: 'widget_annotation'` and kicks off the standard run.\n\nDecision #6: Guests cannot run personas (cost-bearing). The auth\nhelper raises 403 with \"Insufficient role\" when a Guest token tries.","operationId":"run_personas_api_widget_annotations__annotation_id__run_personas_post","parameters":[{"name":"annotation_id","in":"path","required":true,"schema":{"type":"string","title":"Annotation Id"}}],"requestBody":{"content":{"application/json":{"schema":{"anyOf":[{"type":"object","additionalProperties":true},{"type":"null"}],"title":"Body"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/widget/sites/{site_id}/stakeholders":{"post":{"tags":["widget"],"summary":"Create Stakeholder","operationId":"create_stakeholder_api_widget_sites__site_id__stakeholders_post","parameters":[{"name":"site_id","in":"path","required":true,"schema":{"type":"string","title":"Site Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StakeholderCreate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["widget"],"summary":"List Stakeholders","operationId":"list_stakeholders_api_widget_sites__site_id__stakeholders_get","parameters":[{"name":"site_id","in":"path","required":true,"schema":{"type":"string","title":"Site Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/widget/sites/{site_id}/stakeholders/{token}":{"patch":{"tags":["widget"],"summary":"Patch Stakeholder","description":"Mutate the editable fields on a stakeholder row (name, email,\nauto-fix permission). MEMBER required because changing the auto-fix\npermission is a security decision: it grants the stakeholder the\nright to flag submissions for unattended automated change.","operationId":"patch_stakeholder_api_widget_sites__site_id__stakeholders__token__patch","parameters":[{"name":"site_id","in":"path","required":true,"schema":{"type":"string","title":"Site Id"}},{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StakeholderPatch"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["widget"],"summary":"Revoke Stakeholder","operationId":"revoke_stakeholder_api_widget_sites__site_id__stakeholders__token__delete","parameters":[{"name":"site_id","in":"path","required":true,"schema":{"type":"string","title":"Site Id"}},{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/workspaces":{"post":{"tags":["workspaces"],"summary":"Create Workspace","description":"Create a new (non-personal) workspace owned by the caller.\n\nNo auth-helper call here because the user does not yet have a\nmembership in the workspace they're about to create.","operationId":"create_workspace_api_workspaces_post","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkspaceCreate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["workspaces"],"summary":"List My Workspaces","description":"List workspaces the caller is a member of.\n\n`?include=deleted` surfaces soft-deleted workspaces too (OWNER only;\nwe just filter out non-OWNER deleted rows so the FE banner appears\nonly where the caller can actually restore).","operationId":"list_my_workspaces_api_workspaces_get","parameters":[{"name":"include","in":"query","required":false,"schema":{"type":"string","default":"","title":"Include"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/workspaces/{ws_id}":{"get":{"tags":["workspaces"],"summary":"Get Workspace","operationId":"get_workspace_api_workspaces__ws_id__get","parameters":[{"name":"ws_id","in":"path","required":true,"schema":{"type":"string","title":"Ws Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["workspaces"],"summary":"Patch Workspace","operationId":"patch_workspace_api_workspaces__ws_id__patch","parameters":[{"name":"ws_id","in":"path","required":true,"schema":{"type":"string","title":"Ws Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkspacePatch"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["workspaces"],"summary":"Delete Workspace","description":"Soft-delete + 30-day grace. Personal workspaces are not deletable\n(Decision #8 — the FE prevents leaving the last personal one).","operationId":"delete_workspace_api_workspaces__ws_id__delete","parameters":[{"name":"ws_id","in":"path","required":true,"schema":{"type":"string","title":"Ws Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/workspaces/{ws_id}/restore":{"post":{"tags":["workspaces"],"summary":"Restore Workspace","description":"OWNER-only undelete during the grace window.\n\nThe standard auth helper rejects soft-deleted workspaces; this\nroute uses `require_workspace_access_for_deleted` which bypasses\nthat single check. Confirms OWNER membership before clearing the\ndeletion stamps.","operationId":"restore_workspace_api_workspaces__ws_id__restore_post","parameters":[{"name":"ws_id","in":"path","required":true,"schema":{"type":"string","title":"Ws Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/workspaces/{ws_id}/transfer-owner":{"post":{"tags":["workspaces"],"summary":"Transfer Owner","operationId":"transfer_owner_api_workspaces__ws_id__transfer_owner_post","parameters":[{"name":"ws_id","in":"path","required":true,"schema":{"type":"string","title":"Ws Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransferOwnerRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/workspaces/{ws_id}/members":{"get":{"tags":["workspaces"],"summary":"List Members","operationId":"list_members_api_workspaces__ws_id__members_get","parameters":[{"name":"ws_id","in":"path","required":true,"schema":{"type":"string","title":"Ws Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/workspaces/{ws_id}/members/{user_id}":{"patch":{"tags":["workspaces"],"summary":"Patch Member","operationId":"patch_member_api_workspaces__ws_id__members__user_id__patch","parameters":[{"name":"ws_id","in":"path","required":true,"schema":{"type":"string","title":"Ws Id"}},{"name":"user_id","in":"path","required":true,"schema":{"type":"string","title":"User Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MembershipPatch"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["workspaces"],"summary":"Remove Member","operationId":"remove_member_api_workspaces__ws_id__members__user_id__delete","parameters":[{"name":"ws_id","in":"path","required":true,"schema":{"type":"string","title":"Ws Id"}},{"name":"user_id","in":"path","required":true,"schema":{"type":"string","title":"User Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/workspaces/{ws_id}/invitations":{"post":{"tags":["workspaces"],"summary":"Create Invitation","operationId":"create_invitation_api_workspaces__ws_id__invitations_post","parameters":[{"name":"ws_id","in":"path","required":true,"schema":{"type":"string","title":"Ws Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvitationCreate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["workspaces"],"summary":"List Invitations","operationId":"list_invitations_api_workspaces__ws_id__invitations_get","parameters":[{"name":"ws_id","in":"path","required":true,"schema":{"type":"string","title":"Ws Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/workspaces/{ws_id}/invitations/{token}":{"delete":{"tags":["workspaces"],"summary":"Revoke Invitation","operationId":"revoke_invitation_api_workspaces__ws_id__invitations__token__delete","parameters":[{"name":"ws_id","in":"path","required":true,"schema":{"type":"string","title":"Ws Id"}},{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/workspaces/{ws_id}/invitations/{token}/resend":{"post":{"tags":["workspaces"],"summary":"Resend Invitation","description":"Re-send the same token's email. Rate-limited per token.","operationId":"resend_invitation_api_workspaces__ws_id__invitations__token__resend_post","parameters":[{"name":"ws_id","in":"path","required":true,"schema":{"type":"string","title":"Ws Id"}},{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/invitations/{token}":{"get":{"tags":["workspaces"],"summary":"Preview Invitation","description":"Public preview before accept. UNAUTHENTICATED.\n\nValidates HMAC + TTL + revoked/accepted state. 404 on any failure\nso signature probes can't enumerate workspaces.","operationId":"preview_invitation_api_invitations__token__get","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/invitations/accept":{"post":{"tags":["workspaces"],"summary":"Accept Invitation","description":"Authenticated accept. The accepting user's Cognito email must\nmatch the invite's email.","operationId":"accept_invitation_api_invitations_accept_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvitationAccept"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/workspaces/{ws_id}/api-tokens":{"post":{"tags":["workspaces"],"summary":"Create Api Token","description":"Mint a new `gfat_*` API token. OWNER-only by spec.\n\nThe token is shown ONCE in the response under `token`; subsequent\nGETs only carry the prefix + last-4 chars so a leaked listing never\nreveals a working credential.\n\nIdempotency-Key is honored: re-issuing with the same key returns the\nprior response (including the prior plaintext token, which is the\nonly place the caller can recover it without minting a new one).","operationId":"create_api_token_api_workspaces__ws_id__api_tokens_post","parameters":[{"name":"ws_id","in":"path","required":true,"schema":{"type":"string","title":"Ws Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiTokenCreate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["workspaces"],"summary":"List Api Tokens","description":"List the workspace's API tokens.\n\nOWNER sees every token. MEMBER sees only the tokens they personally\nminted (so a delegated member can rotate their own creds without\nlearning who else has access). GUEST has no listing surface — the\nauth helper rejects them at the door.","operationId":"list_api_tokens_api_workspaces__ws_id__api_tokens_get","parameters":[{"name":"ws_id","in":"path","required":true,"schema":{"type":"string","title":"Ws Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/workspaces/{ws_id}/api-tokens/{token_id}":{"delete":{"tags":["workspaces"],"summary":"Revoke Api Token","description":"Revoke an API token. OWNER can revoke any; MEMBER can revoke only\ntheir own. The verifier 401s every subsequent request that uses the\nrevoked token.","operationId":"revoke_api_token_api_workspaces__ws_id__api_tokens__token_id__delete","parameters":[{"name":"ws_id","in":"path","required":true,"schema":{"type":"string","title":"Ws Id"}},{"name":"token_id","in":"path","required":true,"schema":{"type":"string","title":"Token Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/demo/run":{"post":{"tags":["demo"],"summary":"Run Demo","operationId":"run_demo_api_demo_run_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DemoRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DemoResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/demo/personas":{"get":{"tags":["demo"],"summary":"List Demo Personas","description":"Stable read endpoint for the FE so the persona pool isn't duplicated\nin two places. Returns marketing-safe fields only.","operationId":"list_demo_personas_api_demo_personas_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/demo/config":{"get":{"tags":["demo"],"summary":"Demo Config","description":"Tells the FE whether to render the Turnstile widget and which\nsite key to use. The site key is public by design; the secret stays\nserver-side. `ai_live` lets the FE label the result panel honestly\nwhen the demo is still serving the templated stub.","operationId":"demo_config_api_demo_config_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/access-requests":{"post":{"tags":["access"],"summary":"Submit Access Request","operationId":"submit_access_request_api_access_requests_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccessRequestBody"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccessRequestResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/admin/usage/me":{"get":{"tags":["admin"],"summary":"Admin Usage Me","operationId":"admin_usage_me_api_admin_usage_me_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/admin/usage":{"get":{"tags":["admin"],"summary":"Admin Usage","description":"Aggregate per-user counters over a rolling 90-day window.\n\nReturns the raw per-user rows plus convenient pre-sorted Top-N\nbuckets so the FE can render leaderboard-style tables without\nre-sorting client-side.","operationId":"admin_usage_api_admin_usage_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/sites":{"get":{"tags":["api-v1"],"summary":"List Sites","description":"List sites in the caller's workspace. Excludes `mcp_token`.","operationId":"list_sites_api_v1_sites_get","parameters":[{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cursor"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/sites/{site_id}":{"get":{"tags":["api-v1"],"summary":"Get Site","description":"Site detail. Excludes `mcp_token`.","operationId":"get_site_api_v1_sites__site_id__get","parameters":[{"name":"site_id","in":"path","required":true,"schema":{"type":"string","title":"Site Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/sites/{site_id}/annotations":{"get":{"tags":["api-v1"],"summary":"List Annotations","description":"List annotations for a site. Filters: `status`, `kind`, `since`\n(epoch-ms), `auto_fix` (bool — restrict to auto-fix-flagged or\nnot-auto-fix submissions). Cursor pagination is HMAC-tamper-\nprotected. The `auto_fix=true` slice is the primary entry point for\nautomation-side consumers (CI bots, agents) that only want to see\nsubmissions the submitter authorised for unattended change.","operationId":"list_annotations_api_v1_sites__site_id__annotations_get","parameters":[{"name":"site_id","in":"path","required":true,"schema":{"type":"string","title":"Site Id"}},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"enum":["pending","new","ack","triaged","in_progress","blocked","resolved","won_t_fix","duplicate"],"type":"string"},{"type":"null"}],"title":"Status"}},{"name":"kind","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Kind"}},{"name":"since","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","minimum":0},{"type":"null"}],"title":"Since"}},{"name":"auto_fix","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Auto Fix"}},{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cursor"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/annotations/{annotation_id}":{"get":{"tags":["api-v1"],"summary":"Get Annotation","operationId":"get_annotation_api_v1_annotations__annotation_id__get","parameters":[{"name":"annotation_id","in":"path","required":true,"schema":{"type":"string","title":"Annotation Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["api-v1"],"summary":"Patch Annotation","description":"Update annotation status / summary / assignee. GUEST-allowed by\nspec (the FE inbox + agents both run through here).","operationId":"patch_annotation_api_v1_annotations__annotation_id__patch","parameters":[{"name":"annotation_id","in":"path","required":true,"schema":{"type":"string","title":"Annotation Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnnotationPatch"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/annotations/{annotation_id}/replies":{"post":{"tags":["api-v1"],"summary":"Reply To Annotation","description":"Append a reply. Author defaults to \"agent\" for API-token callers.","operationId":"reply_to_annotation_api_v1_annotations__annotation_id__replies_post","parameters":[{"name":"annotation_id","in":"path","required":true,"schema":{"type":"string","title":"Annotation Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnnotationReplyCreate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/annotations/{annotation_id}/markdown":{"get":{"tags":["api-v1"],"summary":"Annotation Markdown","description":"Agent-paste-friendly markdown blob (mirror of the FE markdown\nroute).","operationId":"annotation_markdown_api_v1_annotations__annotation_id__markdown_get","parameters":[{"name":"annotation_id","in":"path","required":true,"schema":{"type":"string","title":"Annotation Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/annotations/{annotation_id}/run-personas":{"post":{"tags":["api-v1"],"summary":"Run Personas","description":"Trigger an AI persona review. Cost-bearing, so MEMBER+ only.\nGUEST tokens 403 (matches the FE rule for cost-bearing actions).","operationId":"run_personas_api_v1_annotations__annotation_id__run_personas_post","parameters":[{"name":"annotation_id","in":"path","required":true,"schema":{"type":"string","title":"Annotation Id"}}],"requestBody":{"content":{"application/json":{"schema":{"anyOf":[{"type":"object","additionalProperties":true},{"type":"null"}],"title":"Body"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/annotations/{annotation_id}/resolutions/upload-url":{"post":{"tags":["api-v1"],"summary":"Presign Resolution Upload","description":"Issue a presigned PUT for a before/after screenshot. The resolver\nuploads the bytes to S3 directly, then attaches the returned `key`\nvia `POST /annotations/{id}/resolutions`. MEMBER required because\npublishing resolution evidence is an authoring action.","operationId":"presign_resolution_upload_api_v1_annotations__annotation_id__resolutions_upload_url_post","parameters":[{"name":"annotation_id","in":"path","required":true,"schema":{"type":"string","title":"Annotation Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResolutionPresignRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/annotations/{annotation_id}/resolutions":{"post":{"tags":["api-v1"],"summary":"Create Resolution","description":"Append a RESOLUTION to an annotation. At least one of\n`before_key`/`after_key`/`diff_url`/`explanation` must be present.\nMEMBER required.\n\nOn create, an SQS-style notification message is enqueued so the\nsubmitter (when identified) gets an email; anonymous submissions\npick up the resolution as a thread reply. The HTTP call returns\nonce the row is durable — fan-out is async.","operationId":"create_resolution_api_v1_annotations__annotation_id__resolutions_post","parameters":[{"name":"annotation_id","in":"path","required":true,"schema":{"type":"string","title":"Annotation Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResolutionCreate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["api-v1"],"summary":"List Resolutions","operationId":"list_resolutions_api_v1_annotations__annotation_id__resolutions_get","parameters":[{"name":"annotation_id","in":"path","required":true,"schema":{"type":"string","title":"Annotation Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/agents/register":{"post":{"tags":["agents"],"summary":"Register Agent","operationId":"register_agent_api_v1_agents_register_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentRegisterRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentRegisterResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}},"components":{"schemas":{"AccessRequestBody":{"properties":{"email":{"type":"string","maxLength":320,"minLength":3,"title":"Email"},"intent":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Intent"},"source":{"anyOf":[{"type":"string","maxLength":80},{"type":"null"}],"title":"Source"}},"type":"object","required":["email"],"title":"AccessRequestBody"},"AccessRequestResponse":{"properties":{"ok":{"type":"boolean","title":"Ok"},"queued":{"type":"boolean","title":"Queued"},"message":{"type":"string","title":"Message"}},"type":"object","required":["ok","queued","message"],"title":"AccessRequestResponse"},"AgentRegisterRequest":{"properties":{"agent_name":{"type":"string","maxLength":120,"minLength":1,"title":"Agent Name"},"contact_email":{"type":"string","maxLength":320,"minLength":3,"title":"Contact Email"},"purpose":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Purpose"}},"type":"object","required":["agent_name","contact_email"],"title":"AgentRegisterRequest"},"AgentRegisterResponse":{"properties":{"workspace_id":{"type":"string","title":"Workspace Id"},"workspace_slug":{"type":"string","title":"Workspace Slug"},"plan":{"type":"string","title":"Plan"},"token":{"type":"string","title":"Token"},"token_id":{"type":"string","title":"Token Id"},"billing_mode":{"type":"string","title":"Billing Mode"},"per_review_price_cents":{"type":"integer","title":"Per Review Price Cents"},"wallet_balance_cents":{"type":"integer","title":"Wallet Balance Cents"},"wallet_topup_url":{"type":"string","title":"Wallet Topup Url"},"api_base":{"type":"string","title":"Api Base"},"mcp_discovery":{"type":"string","title":"Mcp Discovery"},"docs_for_agents":{"type":"string","title":"Docs For Agents"}},"type":"object","required":["workspace_id","workspace_slug","plan","token","token_id","billing_mode","per_review_price_cents","wallet_balance_cents","wallet_topup_url","api_base","mcp_discovery","docs_for_agents"],"title":"AgentRegisterResponse"},"AnnotationPatch":{"properties":{"status":{"anyOf":[{"type":"string","enum":["pending","new","ack","triaged","in_progress","blocked","resolved","won_t_fix","duplicate"]},{"type":"null"}],"title":"Status"},"assignee_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Assignee Id"},"summary":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Summary"}},"type":"object","title":"AnnotationPatch"},"AnnotationReplyCreate":{"properties":{"body":{"type":"string","title":"Body"},"author":{"type":"string","enum":["owner","agent","stakeholder"],"title":"Author","default":"owner"},"author_name":{"type":"string","title":"Author Name","default":""}},"type":"object","required":["body"],"title":"AnnotationReplyCreate"},"ApiTokenCreate":{"properties":{"name":{"type":"string","maxLength":80,"minLength":1,"title":"Name"},"role":{"type":"string","enum":["MEMBER","GUEST"],"title":"Role","default":"MEMBER"},"expires_at":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Expires At"}},"type":"object","required":["name"],"title":"ApiTokenCreate"},"DecisionBody":{"properties":{"note":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Note"}},"type":"object","title":"DecisionBody"},"DemoDimension":{"properties":{"name":{"type":"string","title":"Name"},"score":{"type":"number","title":"Score"},"comment":{"type":"string","title":"Comment"}},"type":"object","required":["name","score","comment"],"title":"DemoDimension"},"DemoRequest":{"properties":{"url":{"type":"string","maxLength":2048,"title":"Url"},"persona_slug":{"type":"string","maxLength":32,"title":"Persona Slug"},"cf_turnstile_token":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cf Turnstile Token"}},"type":"object","required":["url","persona_slug"],"title":"DemoRequest"},"DemoResponse":{"properties":{"cached":{"type":"boolean","title":"Cached"},"persona":{"additionalProperties":true,"type":"object","title":"Persona"},"top_dimensions":{"items":{"$ref":"#/components/schemas/DemoDimension"},"type":"array","title":"Top Dimensions"},"paragraph":{"type":"string","title":"Paragraph"},"signup_url":{"type":"string","title":"Signup Url"},"daily_remaining":{"type":"integer","title":"Daily Remaining"},"ai_live":{"type":"boolean","title":"Ai Live"}},"type":"object","required":["cached","persona","top_dimensions","paragraph","signup_url","daily_remaining","ai_live"],"title":"DemoResponse"},"DimensionSchema":{"properties":{"name":{"type":"string","title":"Name"},"description":{"type":"string","title":"Description"},"weight":{"type":"number","title":"Weight"}},"type":"object","required":["name","description","weight"],"title":"DimensionSchema"},"FeedbackRating":{"properties":{"rating":{"type":"integer","title":"Rating"},"comment":{"type":"string","title":"Comment","default":""}},"type":"object","required":["rating"],"title":"FeedbackRating"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"InvitationAccept":{"properties":{"token":{"type":"string","title":"Token"}},"type":"object","required":["token"],"title":"InvitationAccept"},"InvitationCreate":{"properties":{"email":{"type":"string","title":"Email"},"role":{"type":"string","enum":["MEMBER","GUEST"],"title":"Role"},"site_grants":{"items":{"type":"string"},"type":"array","title":"Site Grants"}},"type":"object","required":["email","role"],"title":"InvitationCreate"},"MembershipPatch":{"properties":{"role":{"anyOf":[{"type":"string","enum":["OWNER","MEMBER","GUEST"]},{"type":"null"}],"title":"Role"},"site_grants":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Site Grants"}},"type":"object","title":"MembershipPatch"},"PersonaCreate":{"properties":{"name":{"type":"string","title":"Name"},"title":{"type":"string","title":"Title"},"category":{"type":"string","title":"Category"},"description":{"type":"string","title":"Description"},"evaluation_dimensions":{"items":{"$ref":"#/components/schemas/DimensionSchema"},"type":"array","title":"Evaluation Dimensions"},"custom_instructions":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Custom Instructions"}},"type":"object","required":["name","title","category","description","evaluation_dimensions"],"title":"PersonaCreate"},"PersonaPatch":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"category":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"evaluation_dimensions":{"anyOf":[{"items":{"$ref":"#/components/schemas/DimensionSchema"},"type":"array"},{"type":"null"}],"title":"Evaluation Dimensions"},"custom_instructions":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Custom Instructions"}},"type":"object","title":"PersonaPatch"},"ReportBody":{"properties":{"reason":{"type":"string","maxLength":500,"minLength":4,"title":"Reason"}},"type":"object","required":["reason"],"title":"ReportBody"},"ResetDefaultsRequest":{"properties":{"slug":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Slug"}},"type":"object","title":"ResetDefaultsRequest"},"ResolutionCreate":{"properties":{"before_key":{"anyOf":[{"type":"string","maxLength":512},{"type":"null"}],"title":"Before Key"},"after_key":{"anyOf":[{"type":"string","maxLength":512},{"type":"null"}],"title":"After Key"},"diff_url":{"anyOf":[{"type":"string","maxLength":2048},{"type":"null"}],"title":"Diff Url"},"explanation":{"anyOf":[{"type":"string","maxLength":4096},{"type":"null"}],"title":"Explanation"}},"type":"object","title":"ResolutionCreate","description":"Body for `POST /api/v1/annotations/{id}/resolutions`. At least\none of `before_key`/`after_key`/`diff_url`/`explanation` must be\nprovided; the route layer enforces that. URL-form fields use\npresigned uploads — the screenshot bytes never touch this payload."},"ResolutionPresignRequest":{"properties":{"kind":{"type":"string","enum":["before","after"],"title":"Kind"},"content_type":{"type":"string","maxLength":120,"title":"Content Type"}},"type":"object","required":["kind","content_type"],"title":"ResolutionPresignRequest","description":"Body for `POST /api/v1/annotations/{id}/resolutions/upload-url`.\n`kind` selects the S3 key prefix and the filename role; the resolver\nPUTs the file to the returned URL, then passes the `key` back via\n`ResolutionCreate.before_key` / `after_key`."},"ReviewCreate":{"properties":{"title":{"type":"string","title":"Title"},"input_type":{"type":"string","title":"Input Type","default":"text"},"persona_ids":{"items":{"type":"string"},"type":"array","title":"Persona Ids"},"inputs":{"items":{"$ref":"#/components/schemas/ReviewInputCreate"},"type":"array","title":"Inputs"},"widget_site_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Widget Site Id"}},"type":"object","required":["title","persona_ids","inputs"],"title":"ReviewCreate"},"ReviewInputCreate":{"properties":{"type":{"type":"string","title":"Type"},"file_key":{"type":"string","title":"File Key","default":""},"file_name":{"type":"string","title":"File Name","default":""},"mime_type":{"type":"string","title":"Mime Type","default":""},"url":{"type":"string","title":"Url","default":""},"text":{"type":"string","title":"Text","default":""}},"type":"object","required":["type"],"title":"ReviewInputCreate"},"StakeholderCreate":{"properties":{"name":{"type":"string","title":"Name","default":""},"email":{"type":"string","title":"Email","default":""},"auto_fix_default":{"type":"string","enum":["never","optional_off","optional_on"],"title":"Auto Fix Default","default":"optional_off"}},"type":"object","title":"StakeholderCreate"},"StakeholderPatch":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email"},"auto_fix_default":{"anyOf":[{"type":"string","enum":["never","optional_off","optional_on"]},{"type":"null"}],"title":"Auto Fix Default"}},"type":"object","title":"StakeholderPatch"},"TransferOwnerRequest":{"properties":{"to_user_id":{"type":"string","title":"To User Id"}},"type":"object","required":["to_user_id"],"title":"TransferOwnerRequest"},"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"},"WidgetSiteCreate":{"properties":{"name":{"type":"string","title":"Name"},"allowed_origins":{"items":{"type":"string"},"type":"array","title":"Allowed Origins"},"brand_primary":{"type":"string","title":"Brand Primary","default":"#000000"},"brand_font":{"type":"string","title":"Brand Font","default":"Inter"},"redact_pii":{"type":"boolean","title":"Redact Pii","default":true},"enable_mcp":{"type":"boolean","title":"Enable Mcp","default":true}},"type":"object","required":["name"],"title":"WidgetSiteCreate"},"WidgetSitePatch":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"allowed_origins":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Allowed Origins"},"brand_primary":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Brand Primary"},"brand_font":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Brand Font"},"redact_pii":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Redact Pii"},"enable_mcp":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Enable Mcp"}},"type":"object","title":"WidgetSitePatch"},"WorkspaceCreate":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"}},"type":"object","title":"WorkspaceCreate"},"WorkspacePatch":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"slug":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Slug"}},"type":"object","title":"WorkspacePatch"}}}}