{"openapi":"3.1.0","info":{"title":"FastAPI","version":"0.1.0"},"paths":{"/_startup":{"get":{"summary":" Startup Endpoint","description":"The startup probe is used by Kubernetes to delay probing liveness and readiness.\n\nSince it is only run in the beginning, we're building the slightly expensive context in the\nhandler. We want to be sure that context works before serving traffic.","operationId":"_startup_endpoint__startup_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"x-client-secret","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Client secret","description":"A secret token identifying the client connecting to the API","examples":["Syou3EZiO5vuMEgNyBeA8cjEMYOnQDwP"]},"description":"A secret token identifying the client connecting to the API"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/_liveness":{"get":{"summary":" Liveness Endpoint","description":"The liveness probe is used by Kubernetes to restart unresponsive containers. If the application\nfails a specified number of liveness probes in a row, its container is killed.","operationId":"_liveness_endpoint__liveness_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"x-client-secret","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Client secret","description":"A secret token identifying the client connecting to the API","examples":["Syou3EZiO5vuMEgNyBeA8cjEMYOnQDwP"]},"description":"A secret token identifying the client connecting to the API"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/_readiness":{"get":{"summary":" Readiness Endpoint","description":"The readiness probe is used by Kubernetes to establish whether the container is capable of\nserving requests. It won't receive traffic unless it successfully responds.","operationId":"_readiness_endpoint__readiness_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"x-client-secret","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Client secret","description":"A secret token identifying the client connecting to the API","examples":["Syou3EZiO5vuMEgNyBeA8cjEMYOnQDwP"]},"description":"A secret token identifying the client connecting to the API"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/.well-known/oauth-protected-resource/mcp":{"get":{"summary":"Get Public Mcp Protected Resource Metadata","description":"Protected resource metadata for the public MCP server (RFC 9728).\n\nDirects MCP clients to the authorization server that can issue tokens\nfor the `/mcp/` resource.","operationId":"get_public_mcp_protected_resource_metadata__well_known_oauth_protected_resource_mcp_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/.well-known/oauth-protected-resource/internal/mcp":{"get":{"summary":"Get Internal Mcp Protected Resource Metadata","description":"Protected resource metadata for the internal MCP server (RFC 9728).\n\nDirects MCP clients to the authorization server that can issue tokens\nfor the `/internal/mcp/` resource.","operationId":"get_internal_mcp_protected_resource_metadata__well_known_oauth_protected_resource_internal_mcp_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/.well-known/oauth-authorization-server/oauth/mcp":{"get":{"summary":"Get Authorization Server Metadata","description":"Authorization server metadata for MCP OAuth (RFC 8414).\n\nAdvertises OAuth endpoints and supported features so MCP clients can\ndiscover how to initiate the authorization flow.","operationId":"get_authorization_server_metadata__well_known_oauth_authorization_server_oauth_mcp_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/.well-known/openai-apps-challenge":{"get":{"summary":"Get Openai Apps Challenge","operationId":"get_openai_apps_challenge__well_known_openai_apps_challenge_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/problems/{problem_type}":{"get":{"summary":"Get Problem Type","operationId":"get_problem_type_problems__problem_type__get","parameters":[{"name":"problem_type","in":"path","required":true,"schema":{"$ref":"#/components/schemas/ProblemType"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProblemTypeDescription"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/graphql":{"post":{"summary":"Handle Http Post","operationId":"handle_http_post_graphql_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"x-client-secret","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Client secret","description":"A secret token identifying the client connecting to the API","examples":["Syou3EZiO5vuMEgNyBeA8cjEMYOnQDwP"]},"description":"A secret token identifying the client connecting to the API"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/graphql/schema.graphql":{"get":{"summary":"Serve Public Schema File","operationId":"serve_public_schema_file_graphql_schema_graphql_get","parameters":[{"name":"x-client-secret","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Client secret","description":"A secret token identifying the client connecting to the API","examples":["Syou3EZiO5vuMEgNyBeA8cjEMYOnQDwP"]},"description":"A secret token identifying the client connecting to the API"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/internal/graphql":{"post":{"summary":"Handle Http Post","operationId":"handle_http_post_internal_graphql_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"x-client-secret","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Client secret","description":"A secret token identifying the client connecting to the API","examples":["Syou3EZiO5vuMEgNyBeA8cjEMYOnQDwP"]},"description":"A secret token identifying the client connecting to the API"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/oauth/mcp/authorize":{"get":{"summary":"Authorize","description":"OAuth 2.1 authorization endpoint for MCP clients.","operationId":"authorize_oauth_mcp_authorize_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"response_type","in":"query","required":true,"schema":{"const":"code","type":"string","title":"Response Type"}},{"name":"code_challenge","in":"query","required":true,"schema":{"type":"string","title":"Code Challenge"}},{"name":"code_challenge_method","in":"query","required":true,"schema":{"const":"S256","type":"string","title":"Code Challenge Method"}},{"name":"client_id","in":"query","required":true,"schema":{"type":"string","title":"Client Id"}},{"name":"redirect_uri","in":"query","required":true,"schema":{"type":"string","format":"uri","minLength":1,"maxLength":2083,"title":"Redirect Uri"}},{"name":"resource","in":"query","required":true,"schema":{"type":"string","format":"uri","minLength":1,"maxLength":2083,"title":"Resource"}},{"name":"state","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"State"}},{"name":"x-client-secret","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Client secret","description":"A secret token identifying the client connecting to the API","examples":["Syou3EZiO5vuMEgNyBeA8cjEMYOnQDwP"]},"description":"A secret token identifying the client connecting to the API"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/oauth/mcp/token":{"post":{"summary":"Token","description":"OAuth 2.1 token endpoint for MCP clients.","operationId":"token_oauth_mcp_token_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"x-client-secret","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Client secret","description":"A secret token identifying the client connecting to the API","examples":["Syou3EZiO5vuMEgNyBeA8cjEMYOnQDwP"]},"description":"A secret token identifying the client connecting to the API"}],"requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/Body_token_oauth_mcp_token_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/_webhooks/stripe":{"post":{"summary":"Handle Stripe Webhook","description":"This endpoint receives webhook events from Stripe on our own account.","operationId":"handle_stripe_webhook__webhooks_stripe_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"x-client-secret","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Client secret","description":"A secret token identifying the client connecting to the API","examples":["Syou3EZiO5vuMEgNyBeA8cjEMYOnQDwP"]},"description":"A secret token identifying the client connecting to the API"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/_webhooks/stripe/connect":{"post":{"summary":"Handle Stripe Connect Webhook","description":"This endpoint receives webhook events from Stripe Connect, ie. events from connected accounts.","operationId":"handle_stripe_connect_webhook__webhooks_stripe_connect_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"x-client-secret","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Client secret","description":"A secret token identifying the client connecting to the API","examples":["Syou3EZiO5vuMEgNyBeA8cjEMYOnQDwP"]},"description":"A secret token identifying the client connecting to the API"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StripeConnectEvent"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/_webhooks/tiptap":{"post":{"summary":"Handle Tiptap Webhook","description":"Receive collaboration webhook events from Tiptap Cloud.\n\nCurrently we only act on the first comment in a thread (i.e. a new thread being created)\nand post a Slack notification.","operationId":"handle_tiptap_webhook__webhooks_tiptap_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"x-client-secret","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Client secret","description":"A secret token identifying the client connecting to the API","examples":["Syou3EZiO5vuMEgNyBeA8cjEMYOnQDwP"]},"description":"A secret token identifying the client connecting to the API"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TiptapWebhookEvent"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/_webhooks/xero":{"post":{"summary":"Handle Xero Webhook","description":"Receive webhook events from Xero.\n\nXero sends an empty `events` list to validate the endpoint (\"intent to receive\"); a valid\nsignature (checked in the route dependency) is enough for that handshake, so we simply\nacknowledge with 200. Real events are handed to a service that publishes a domain event per\ninvoice for out-of-band processing.","operationId":"handle_xero_webhook__webhooks_xero_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"x-client-secret","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Client secret","description":"A secret token identifying the client connecting to the API","examples":["Syou3EZiO5vuMEgNyBeA8cjEMYOnQDwP"]},"description":"A secret token identifying the client connecting to the API"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/XeroWebhookPayload"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}},"components":{"schemas":{"Body_token_oauth_mcp_token_post":{"properties":{"grant_type":{"type":"string","enum":["authorization_code","refresh_token"],"title":"Grant Type"},"client_id":{"type":"string","title":"Client Id"},"code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Code"},"code_verifier":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Code Verifier"},"redirect_uri":{"anyOf":[{"type":"string","maxLength":2083,"minLength":1,"format":"uri"},{"type":"null"}],"title":"Redirect Uri"},"resource":{"anyOf":[{"type":"string","maxLength":2083,"minLength":1,"format":"uri"},{"type":"null"}],"title":"Resource"},"refresh_token":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Refresh Token"}},"type":"object","required":["grant_type","client_id"],"title":"Body_token_oauth_mcp_token_post"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ProblemType":{"type":"string","enum":["token-expired"],"title":"ProblemType","description":"An RFC 9457 problem type of ours, for a problem whose status code alone doesn't say what a\nclient must do. `GET /problems/<value>` describes it."},"ProblemTypeDescription":{"properties":{"type":{"type":"string","title":"Type"},"title":{"type":"string","title":"Title"},"status":{"type":"integer","title":"Status"},"description":{"type":"string","title":"Description"}},"type":"object","required":["type","title","status","description"],"title":"ProblemTypeDescription"},"StripeConnectEvent":{"properties":{"id":{"type":"string","title":"Id"},"type":{"type":"string","title":"Type"},"data":{"$ref":"#/components/schemas/StripeEventData"},"account":{"type":"string","title":"Account"}},"type":"object","required":["id","type","data","account"],"title":"StripeConnectEvent"},"StripeEventData":{"properties":{"object":{"additionalProperties":true,"type":"object","title":"Object"}},"type":"object","required":["object"],"title":"StripeEventData"},"TiptapCommentData":{"properties":{"id":{"type":"string","title":"Id"},"createdAt":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Createdat"},"updatedAt":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Updatedat"},"content":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Content"},"data":{"$ref":"#/components/schemas/TiptapCommentUserData","default":{}}},"type":"object","required":["id"],"title":"TiptapCommentData"},"TiptapCommentUserData":{"properties":{"userName":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Username"},"userAvatar":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Useravatar"}},"type":"object","title":"TiptapCommentUserData"},"TiptapThread":{"properties":{"id":{"type":"string","title":"Id"},"comments":{"items":{"$ref":"#/components/schemas/TiptapCommentData"},"type":"array","title":"Comments","default":[]}},"type":"object","required":["id"],"title":"TiptapThread"},"TiptapWebhookEvent":{"properties":{"trigger":{"type":"string","title":"Trigger"},"name":{"type":"string","title":"Name","default":""},"thread":{"anyOf":[{"$ref":"#/components/schemas/TiptapThread"},{"items":{"$ref":"#/components/schemas/TiptapCommentData"},"type":"array"},{"type":"null"}],"title":"Thread"},"comment":{"anyOf":[{"$ref":"#/components/schemas/TiptapCommentData"},{"type":"null"}]},"appName":{"type":"string","title":"Appname","default":""},"user":{"type":"string","title":"User","default":""}},"type":"object","required":["trigger"],"title":"TiptapWebhookEvent"},"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"},"XeroWebhookEvent":{"properties":{"resourceUrl":{"type":"string","title":"Resourceurl"},"resourceId":{"type":"string","title":"Resourceid"},"eventDateUtc":{"type":"string","format":"date-time","title":"Eventdateutc"},"eventType":{"type":"string","title":"Eventtype"},"eventCategory":{"type":"string","title":"Eventcategory"},"tenantId":{"type":"string","title":"Tenantid"},"tenantType":{"type":"string","title":"Tenanttype"}},"type":"object","required":["resourceUrl","resourceId","eventDateUtc","eventType","eventCategory","tenantId","tenantType"],"title":"XeroWebhookEvent"},"XeroWebhookPayload":{"properties":{"events":{"items":{"$ref":"#/components/schemas/XeroWebhookEvent"},"type":"array","title":"Events"},"firstEventSequence":{"type":"integer","title":"Firsteventsequence"},"lastEventSequence":{"type":"integer","title":"Lasteventsequence"}},"type":"object","required":["events","firstEventSequence","lastEventSequence"],"title":"XeroWebhookPayload"}},"securitySchemes":{"HTTPBearer":{"type":"http","description":"A JWT Bearer token header for authentication and authorization, in the format `Authorization: Bearer <token>`","scheme":"bearer","bearerFormat":"JWT"}}}}