{"openapi":"3.1.0","info":{"title":"UUM — Universal User Management","description":"Identity, SSO, multi-tenant organizations, per-service roles and subscriptions for Sandbox Labs. AI agents can register an organization and configure it entirely over this API: `POST /api/v1/public/signup`, then `POST /api/v1/auth/login`. Step-by-step guide with the live list of services open for signup: `GET /api/v1/public/agent-guide` (Markdown). Errors are JSON with `error_code` and `detail`.","version":"0.1.0"},"paths":{"/health":{"get":{"summary":"Health","operationId":"health_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":{"type":"string"},"type":"object","title":"Response Health Health Get"}}}}}}},"/logout":{"get":{"summary":"Logout Redirect","description":"Logout via GET — for external services that need a redirect URL.\n\nThe redirect_uri query param MUST match one of:\n- The landing_page hostname of any active, public service\n- The ADMIN_ORIGIN (UUM's own admin UI)\n\nThis prevents open-redirector attacks where an attacker crafts\na logout link pointing to a malicious site.","operationId":"logout_redirect_logout_get","parameters":[{"name":"uum_refresh_token","in":"cookie","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Uum Refresh Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/ready":{"get":{"summary":"Ready","operationId":"ready_ready_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":{"type":"string"},"type":"object","title":"Response Ready Ready Get"}}}}}}},"/api/v1/auth/login":{"post":{"tags":["auth"],"summary":"Login","description":"Authenticate a user and return tokens.","operationId":"login_api_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/LoginResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/refresh":{"post":{"tags":["auth"],"summary":"Refresh","description":"Refresh an expired access token using the refresh token cookie.","operationId":"refresh_api_v1_auth_refresh_post","parameters":[{"name":"uum_refresh_token","in":"cookie","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Uum Refresh Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefreshResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/logout":{"post":{"tags":["auth"],"summary":"Logout Route","description":"Logout — revoke refresh token, blocklist access token, and clear cookie.","operationId":"logout_route_api_v1_auth_logout_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Bearer <access token>","title":"Authorization"},"description":"Bearer <access token>"},{"name":"uum_refresh_token","in":"cookie","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Uum Refresh Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"string"},"title":"Response Logout Route Api V1 Auth Logout Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/activate":{"post":{"tags":["auth"],"summary":"Activate","description":"Activate account from invitation link. User sets their password.\n\nWith ``auto_login`` the user is signed in right away (refresh cookie set and\n``session`` returned), so they don't retype the password they just chose.","operationId":"activate_api_v1_auth_activate_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActivateRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActivateResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/invitations/{token}/preview":{"get":{"tags":["auth"],"summary":"Preview Invitation","description":"Public: status of an invitation link (read-only), shown before the password form.","operationId":"preview_invitation_api_v1_auth_invitations__token__preview_get","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvitationPreviewResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/invitations/{token}/request-new":{"post":{"tags":["auth"],"summary":"Request New Invitation","description":"Public: an invitee with an expired link asks the tenant admins for a new one.","operationId":"request_new_invitation_api_v1_auth_invitations__token__request_new_post","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"string"},"title":"Response Request New Invitation Api V1 Auth Invitations  Token  Request New Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/verify-email":{"post":{"tags":["auth"],"summary":"Verify Email Route","description":"Confirm ownership of the signup email using the emailed link's token. No auth.\n\nIdempotent: verifying twice succeeds. Invalid/expired tokens return 422 with\n``reason: INVALID_VERIFICATION_TOKEN``.","operationId":"verify_email_route_api_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":{"additionalProperties":true,"type":"object","title":"Response Verify Email Route Api V1 Auth Verify Email Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/signup":{"post":{"tags":["auth"],"summary":"Signup","description":"Self-service signup. Creates a tenant, subscribes to initial services, and\nsends an admin invitation if admin_email is provided.\n\nThis is the same logic as POST /admin/tenants but accessible without\nsuper_admin authentication.","operationId":"signup_api_v1_auth_signup_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TenantCreateRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TenantResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/request-password-reset":{"post":{"tags":["auth"],"summary":"Request Password Reset","description":"Request a password reset email.\n\nSe busca el usuario por email (case-insensitive, solo activos y no-deleted).\nSi no se encuentra, se responde OK silenciosamente (no revelar existencia).\nSe envía un enlace de uso único válido por 15 minutos.\n\nRate limiting: reutilizar la misma key que login (para que el mismo email\nno solicite muchos resets rápidamente).","operationId":"request_password_reset_api_v1_auth_request_password_reset_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PasswordResetRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":{"type":"string"},"type":"object","title":"Response Request Password Reset Api V1 Auth Request Password Reset Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/confirm-password-reset":{"post":{"tags":["auth"],"summary":"Confirm Password Reset","description":"Confirm password reset with a valid token from email.\n\nEl token debe tener: (1) existir, (2) no estar usado, (3) no estar expirado.\nSi es válido: se actualiza el password y se invalidan todos los refresh tokens.","operationId":"confirm_password_reset_api_v1_auth_confirm_password_reset_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PasswordResetConfirm"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":{"type":"string"},"type":"object","title":"Response Confirm Password Reset Api V1 Auth Confirm Password Reset Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/catalog":{"get":{"tags":["catalog"],"summary":"Get Catalog","description":"List all available services in the public catalog.\n\nThis endpoint requires no authentication. It returns a curated list of\nall active Sandbox Labs services with icon, title, category, description,\nand link for display on landing/marketing pages.","operationId":"get_catalog_api_v1_catalog_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CatalogResponse"}}}}}}},"/api/v1/public/agent-guide":{"get":{"tags":["public-agents"],"summary":"Get Agent Guide","description":"Markdown onboarding guide for AI agents: live signup-enabled services plus the rest of the catalog.\n\nNo auth required. Cached for 5 minutes.","operationId":"get_agent_guide_api_v1_public_agent_guide_get","responses":{"200":{"description":"Successful Response","content":{"text/plain":{"schema":{"type":"string"}}}}}}},"/api/v1/branding":{"get":{"tags":["public-branding"],"summary":"Get Public Branding","description":"Get portal branding for a tenant by slug, user email, or invitation token (public, no auth).\n\nUsed by the login page (slug/email lookup) and activation page (token lookup).\nReturns None if the tenant/user/invitation is not found.","operationId":"get_public_branding_api_v1_branding_get","parameters":[{"name":"slug","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Tenant slug to look up","title":"Slug"},"description":"Tenant slug to look up"},{"name":"email","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"User email to resolve tenant from","title":"Email"},"description":"User email to resolve tenant from"},{"name":"token","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Invitation token to resolve tenant from","title":"Token"},"description":"Invitation token to resolve tenant from"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/PortalBrandingResponse"},{"type":"null"}],"title":"Response Get Public Branding Api V1 Branding Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/public/services/{service_slug}/plans":{"get":{"tags":["public-plans"],"summary":"List Public Plans","description":"List active plans for a service. No auth required. Public endpoint.","operationId":"list_public_plans_api_v1_public_services__service_slug__plans_get","parameters":[{"name":"service_slug","in":"path","required":true,"schema":{"type":"string","title":"Service Slug"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicPlansResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/public/redirect-hosts":{"get":{"tags":["public-redirect-hosts"],"summary":"List Redirect Hosts","description":"Hostnames the portal may redirect to after login/logout.\n\nOnly hostnames are exposed (no paths, no inactive or internal services).","operationId":"list_redirect_hosts_api_v1_public_redirect_hosts_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":{"items":{"type":"string"},"type":"array"},"type":"object","title":"Response List Redirect Hosts Api V1 Public Redirect Hosts Get"}}}}}}},"/api/v1/public/signup/services":{"get":{"tags":["public-signup"],"summary":"List Signup Services","description":"List services available for signup. No auth required.","operationId":"list_signup_services_api_v1_public_signup_services_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignupServicesResponse"}}}}}}},"/api/v1/public/signup/checkout":{"post":{"tags":["public-signup"],"summary":"Initiate Signup Checkout","description":"Initiate signup checkout. Creates tenant + user + subscription.\n\nNo auth required. Rate limited to 5 requests per minute per IP.","operationId":"initiate_signup_checkout_api_v1_public_signup_checkout_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignupCheckoutRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignupCheckoutResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/public/signup":{"post":{"tags":["public-signup"],"summary":"Public Signup","description":"Simplified public signup — no checkout, no payment.\n\nCreates tenant, user, tenant_service, and active subscription directly.\nRate-limited per client IP.","operationId":"public_signup_api_v1_public_signup_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicSignupRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicSignupResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/public/services/{service_slug}/signup-config":{"get":{"tags":["public-signup-config"],"summary":"Get Signup Config","description":"Return public signup configuration for a service.\n\nReturns allow_public_signup flag, default plan info, and all active plans\n(for plan selector in the signup form). 404 if service not found or inactive.","operationId":"get_signup_config_api_v1_public_services__service_slug__signup_config_get","parameters":[{"name":"service_slug","in":"path","required":true,"schema":{"type":"string","title":"Service Slug"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignupConfigResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/me":{"get":{"tags":["me"],"summary":"Get Me","description":"Get current authenticated user's info.","operationId":"get_me_api_v1_me_get","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserInfoResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/me/resend-verification":{"post":{"tags":["me"],"summary":"Resend Verification","description":"Send a fresh email-verification link to the current user (max 3 per hour).","operationId":"resend_verification_api_v1_me_resend_verification_post","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"string"},"title":"Response Resend Verification Api V1 Me Resend Verification Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/me/language":{"patch":{"tags":["me"],"summary":"Update My Language","description":"Update the current user's preferred language.\n\nAllowed values: 'en', 'es', 'pt-BR', or null to clear the preference.","operationId":"update_my_language_api_v1_me_language_patch","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateLanguageRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"null"}]},"title":"Response Update My Language Api V1 Me Language Patch"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/me/finish-impersonation":{"post":{"tags":["me"],"summary":"Finish Impersonation","description":"End the impersonation session and return to the original admin user.\n\nLooks up the impersonation context from Redis, revokes the current session\nfor the impersonated user, and issues new tokens for the original admin.\n\nReturns a ``LoginResponse``-style payload that the frontend uses to\nre-establish the original admin's session.","operationId":"finish_impersonation_api_v1_me_finish_impersonation_post","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"},{"name":"uum_refresh_token","in":"cookie","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Uum Refresh Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FinishImpersonationResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/me/services":{"get":{"tags":["me"],"summary":"My Services","description":"List subscribed and discoverable services for current user.\n\nUses current_tenant_id from the JWT if the user has switched tenants,\notherwise uses the home tenant.","operationId":"my_services_api_v1_me_services_get","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response My Services Api V1 Me Services Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/me/services/{service_slug}/subscribe":{"post":{"tags":["me"],"summary":"Subscribe To Service","description":"Subscribe the current user's tenant to a service.\n\nIf the service has allow_public_signup enabled, any authenticated user can\nsubscribe. For paid plans, returns a Dodo checkout URL. For free/trial\nplans, activates immediately.","operationId":"subscribe_to_service_api_v1_me_services__service_slug__subscribe_post","parameters":[{"name":"service_slug","in":"path","required":true,"schema":{"type":"string","title":"Service Slug"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscribeServiceRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscribeCheckoutResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/me/password":{"put":{"tags":["me"],"summary":"Change Password","description":"Change the current user's password.\n\nEvery other session of the user is signed out (this one is kept), so a\npassword changed because of a suspected leak actually locks others out.","operationId":"change_password_api_v1_me_password_put","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"},{"name":"uum_refresh_token","in":"cookie","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Uum Refresh Token"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChangePasswordRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"integer"}]},"title":"Response Change Password Api V1 Me Password Put"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/me/tenants":{"get":{"tags":["me"],"summary":"Get My Tenants","description":"List tenants the current user can switch to.","operationId":"get_my_tenants_api_v1_me_tenants_get","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"},{"name":"uum_refresh_token","in":"cookie","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Uum Refresh Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MeTenantsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/me/switch-tenant":{"post":{"tags":["me"],"summary":"Switch Tenant","description":"Switch current session to a different tenant.","operationId":"switch_tenant_api_v1_me_switch_tenant_post","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"},{"name":"uum_refresh_token","in":"cookie","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Uum Refresh Token"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SwitchTenantRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SwitchTenantResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/me/tenant/deactivation-status":{"get":{"tags":["me"],"summary":"Get Tenant Deactivation Status","description":"Check whether the current user's tenant can be deactivated.\n\nReturns can_deactivate status and blocking services.\nA tenant cannot be deactivated if it has active users or active service subscriptions.","operationId":"get_tenant_deactivation_status_api_v1_me_tenant_deactivation_status_get","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TenantDeactivationCheck"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/me/tenant/deactivate":{"post":{"tags":["me"],"summary":"Deactivate My Tenant","description":"Deactivate the current user's tenant.\n\nPrerequisites must be met (verified client-side via /me/tenant/deactivation-status):\n- No active users\n- No active service subscriptions\n\nIf can_deactivate is False, returns 409 Conflict with details.","operationId":"deactivate_my_tenant_api_v1_me_tenant_deactivate_post","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TenantDeactivateResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/me/subscriptions":{"get":{"tags":["me"],"summary":"Get My Subscriptions","description":"List all plan-based subscriptions for the current user's tenant.","operationId":"get_my_subscriptions_api_v1_me_subscriptions_get","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserSubscriptionsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/me/subscriptions/{subscription_id}/portal":{"get":{"tags":["me"],"summary":"Get Subscription Portal","description":"Get the Dodo billing portal URL for a subscription.","operationId":"get_subscription_portal_api_v1_me_subscriptions__subscription_id__portal_get","parameters":[{"name":"subscription_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Subscription Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PortalSessionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/me/subscriptions/{subscription_id}":{"delete":{"tags":["me"],"summary":"Cancel My Subscription","description":"Cancel a subscription at the end of the current billing period.\n\nSets cancel_at_period_end=True locally and calls Dodo to cancel\nthe external subscription. The user is redirected to the Dodo\ncustomer portal if they wish to manage or reactivate.","operationId":"cancel_my_subscription_api_v1_me_subscriptions__subscription_id__delete","parameters":[{"name":"subscription_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Subscription Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CancelSubscriptionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/me/billing":{"get":{"tags":["me"],"summary":"Get My Billing","description":"Return billing summary for the current user's tenant.","operationId":"get_my_billing_api_v1_me_billing_get","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnifiedBillingResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/me/billing/payment-method":{"get":{"tags":["me"],"summary":"Get My Payment Method","description":"Return the stored/default payment method for the current user's tenant.\n\nQueries Dodo Payments for the customer's default payment method.\nReturns null if the tenant has no dodo_customer_id or no payment method is stored.","operationId":"get_my_payment_method_api_v1_me_billing_payment_method_get","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentMethodResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/me/billing/transactions":{"get":{"tags":["me"],"summary":"Get My Billing Transactions","description":"Return recent payments aggregated across ALL subscriptions for the current user's tenant.\n\n- limit: number of transactions to return (default 5, max 50)\n- Results are sorted by date descending.","operationId":"get_my_billing_transactions_api_v1_me_billing_transactions_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":5,"title":"Limit"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransactionListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/me/billing/export":{"get":{"tags":["me"],"summary":"Export My Billing","description":"Export billing data as CSV for download.\n\nReturns a CSV file with headers: Date, Description, Amount, Currency, Status, Invoice URL","operationId":"export_my_billing_api_v1_me_billing_export_get","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/me/subscriptions/{subscription_id}/payments":{"get":{"tags":["me"],"summary":"Get Subscription Payments","description":"Return payment history for a specific subscription.","operationId":"get_subscription_payments_api_v1_me_subscriptions__subscription_id__payments_get","parameters":[{"name":"subscription_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Subscription Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentHistoryResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/me/subscriptions/{subscription_id}/discounts":{"get":{"tags":["me"],"summary":"Get Subscription Discounts","description":"Return active discounts applied to a specific subscription.","operationId":"get_subscription_discounts_api_v1_me_subscriptions__subscription_id__discounts_get","parameters":[{"name":"subscription_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Subscription Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscriptionDiscountsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/me/subscriptions/{subscription_id}/change-plan":{"patch":{"tags":["me"],"summary":"Change My Subscription Plan","description":"Change (upgrade / downgrade) the plan for an active subscription.\n\nResolves the current tenant from the JWT (supports switched tenants).\nFor paid plan changes, returns a checkout_url for Dodo.","operationId":"change_my_subscription_plan_api_v1_me_subscriptions__subscription_id__change_plan_patch","parameters":[{"name":"subscription_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Subscription Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChangePlanRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChangePlanResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/me/subscriptions/{subscription_id}/payments/{payment_id}/invoice":{"get":{"tags":["me"],"summary":"Download Invoice","description":"Download invoice PDF for a payment, or redirect to existing invoice_url.","operationId":"download_invoice_api_v1_me_subscriptions__subscription_id__payments__payment_id__invoice_get","parameters":[{"name":"subscription_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Subscription Id"}},{"name":"payment_id","in":"path","required":true,"schema":{"type":"string","title":"Payment Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/me/subscriptions-status":{"get":{"tags":["me"],"summary":"My Subscriptions Status","description":"Return all subscriptions for the current user's home tenant, including incomplete ones.\n\nUsed by the frontend to show status banners (e.g., pending payment, missed webhook).","operationId":"my_subscriptions_status_api_v1_me_subscriptions_status_get","parameters":[{"name":"reconcile","in":"query","required":false,"schema":{"type":"boolean","description":"Ask Dodo about incomplete subscriptions first (checkout return page). Throttled to one Dodo pass per tenant every few seconds.","default":false,"title":"Reconcile"},"description":"Ask Dodo about incomplete subscriptions first (checkout return page). Throttled to one Dodo pass per tenant every few seconds."},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscriptionStatusResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/me/subscriptions/{subscription_id}/refresh-checkout":{"post":{"tags":["me"],"summary":"Refresh Subscription Checkout","description":"Generate a fresh Dodo checkout URL for an incomplete subscription.\n\nDodo checkout sessions expire after 24 hours. Instead of re-subscribing,\nuse this endpoint to get a new payment link.","operationId":"refresh_subscription_checkout_api_v1_me_subscriptions__subscription_id__refresh_checkout_post","parameters":[{"name":"subscription_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Subscription Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefreshCheckoutResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/me/services/{service_slug}/upgrade-url":{"get":{"tags":["me"],"summary":"Get Service Upgrade Url","description":"Generate a redirect URL with a fresh SSO token after plan upgrade.\n\nAfter a user upgrades their plan, this endpoint generates a new SSO token\nreflecting the updated plan_slug and returns the redirect URL with the token\nappended. The external service can then validate the token via\nPOST /provisioning/validate-token.\n\nSecurity: validates that redirect_uri matches the service's callback_url domain.","operationId":"get_service_upgrade_url_api_v1_me_services__service_slug__upgrade_url_get","parameters":[{"name":"service_slug","in":"path","required":true,"schema":{"type":"string","title":"Service Slug"}},{"name":"redirect_uri","in":"query","required":true,"schema":{"type":"string","description":"URL to redirect to after upgrade","title":"Redirect Uri"},"description":"URL to redirect to after upgrade"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpgradeUrlResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/sso/redirect":{"post":{"tags":["sso"],"summary":"Sso Redirect","description":"Generate an SSO redirect URL for the given service.\n\nThe tenant_id claim uses the current_tenant_id from the active session\n(from the JWT). Falls back to the user's home tenant if no session switch\nis active.","operationId":"sso_redirect_api_v1_sso_redirect_post","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSORedirectRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"string"},"title":"Response Sso Redirect Api V1 Sso Redirect Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/sso/validate-external":{"post":{"tags":["sso"],"summary":"Sso Validate External","description":"Validate a user identity from an external service and issue an SSO token.\n\nCalled by external services (Lexxto, InsightPBX) when a user initiates\nSSO from that service. The external service must have already authenticated\nthe user and sends the user's email directly — NOT a raw external token.\nUUM verifies the calling service via X-API-Key header, checks if the\nuser has a role on the specified service, and:\n\n- If the service has a callback_url set: redirect transparently with\n  a valid UUM SSO token (full transparent SSO flow).\n- Otherwise: return the UUM SSO token so the caller can redirect.\n\nAuth: X-API-Key header (the external service's API key).\nThis endpoint does NOT accept arbitrary external tokens — the calling\nservice must have already authenticated its user before calling UUM.","operationId":"sso_validate_external_api_v1_sso_validate_external_post","parameters":[{"name":"X-API-Key","in":"header","required":true,"schema":{"type":"string","title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOValidateExternalRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/sso/callback":{"get":{"tags":["sso"],"summary":"Sso Callback","description":"Handle GET-based SSO callback from external services.\n\nThe external service signs a payload containing the user's email using\nHMAC-SHA256 with its own API key as the shared secret. UUM verifies\nthe HMAC signature, preventing token forgery.\n\nToken format: base64url(payload).hex(hmac_sha256)\nPayload: {\"email\": \"...\", \"exp\": unix_timestamp, \"iat\": unix_timestamp}\n\nOn successful verification, UUM looks up the user, checks roles on the\nservice, and redirects to the service's callback_url with a valid UUM\nSSO token if the user has access.","operationId":"sso_callback_api_v1_sso_callback_get","parameters":[{"name":"token","in":"query","required":true,"schema":{"type":"string","description":"HMAC-signed token from the originating service","title":"Token"},"description":"HMAC-signed token from the originating service"},{"name":"service_slug","in":"query","required":true,"schema":{"type":"string","description":"Service slug for lookup","title":"Service Slug"},"description":"Service slug for lookup"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/services":{"get":{"tags":["admin-services"],"summary":"List Services","description":"List all registered services. Admin or super_admin.","operationId":"list_services_api_v1_admin_services_get","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ServiceResponse"},"title":"Response List Services Api V1 Admin Services Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["admin-services"],"summary":"Register Service","description":"Register a new service. Super admin only.\n\nAuto-assigns the registering admin a UserServiceRole on the new service so\nSSO is unblocked as soon as a subscription exists. If the service has a\nfree default plan and the root tenant already has a base Subscription, the\nadd-on is created automatically as well.","operationId":"register_service_api_v1_admin_services_post","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServiceCreateRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServiceResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/services/{service_id}":{"patch":{"tags":["admin-services"],"summary":"Update Service","description":"Update a service. Super admin only.","operationId":"update_service_api_v1_admin_services__service_id__patch","parameters":[{"name":"service_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Service Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServiceUpdateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServiceResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["admin-services"],"summary":"Delete Service","description":"Delete a service. Super admin only.","operationId":"delete_service_api_v1_admin_services__service_id__delete","parameters":[{"name":"service_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Service Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/services/{service_id}/api-key":{"post":{"tags":["admin-services"],"summary":"Generate Service Api Key","description":"Generate a new API key for a service. Key shown once. Super admin only.","operationId":"generate_service_api_key_api_v1_admin_services__service_id__api_key_post","parameters":[{"name":"service_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Service Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/services/{service_id}/webhook-secret":{"post":{"tags":["admin-services"],"summary":"Rotate Service Webhook Secret","description":"Generate or rotate the HMAC-SHA256 signing secret for a service's\noutbound webhook. The plaintext secret is returned exactly once — store it\non the receiving service to verify ``X-UUM-Webhook-Signature``.\n\nRequires the service to have a ``webhook_url`` already configured (no\npoint signing events that go nowhere). Super admin only.","operationId":"rotate_service_webhook_secret_api_v1_admin_services__service_id__webhook_secret_post","parameters":[{"name":"service_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Service Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookSecretResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/services/{slug}/request-plans":{"post":{"tags":["admin-services"],"summary":"Request Service Plans","description":"Trigger UUM to fetch plans from the service's catalog_url and sync them.\n\nThe service must expose a GET /plans endpoint (or the configured catalog_url).\nReturns the sync results with plan count.","operationId":"request_service_plans_api_v1_admin_services__slug__request_plans_post","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Request Service Plans Api V1 Admin Services  Slug  Request Plans Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/tenants":{"get":{"tags":["admin-tenants"],"summary":"List Tenants","description":"List tenants. Super admin sees all tenants; tenant admin sees their effective scope.\n\nQuery params:\n    - page, page_size: pagination (format=flat only)\n    - search: filter by name or slug (format=flat only)\n    - format: \"flat\" (default, paginated) or \"tree\" (full hierarchy, no pagination)\n    - parent_type: \"all\" (default), \"root\" (parent_tenant_id IS NULL), or \"sub\" (has parent)\n    - plan_id: filter tenants that have a subscription to this plan UUID (format=flat only)","operationId":"list_tenants_api_v1_admin_tenants_get","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":20,"title":"Page Size"}},{"name":"search","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Search"}},{"name":"format","in":"query","required":false,"schema":{"type":"string","pattern":"^(flat|tree)$","default":"flat","title":"Format"}},{"name":"parent_type","in":"query","required":false,"schema":{"type":"string","pattern":"^(all|root|sub)$","default":"all","title":"Parent Type"}},{"name":"plan_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Plan Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/TenantListResponse"},{"$ref":"#/components/schemas/TenantTreeResponse"}],"title":"Response List Tenants Api V1 Admin Tenants Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["admin-tenants"],"summary":"Create Tenant","description":"Create a new tenant. Super admin only.\n\nOptionally subscribes the tenant to services and sends an admin invitation.","operationId":"create_tenant_api_v1_admin_tenants_post","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TenantCreateRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TenantResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/tenants/invite":{"post":{"tags":["admin-tenants"],"summary":"Invite Tenant","description":"Invite a new tenant by name and admin email.\n\nCreates a new sub-tenant under the inviter's tenant (or the root tenant for super_admin).\nSends an invitation email to the admin_email with the inviter CC'd.\nThe invited admin becomes a regular user in the new tenant (not admin).\n\nAuth: super_admin (bypasses scope, uses root tenant) OR admin (uses their own tenant as parent).","operationId":"invite_tenant_api_v1_admin_tenants_invite_post","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InviteTenantRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TenantResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/tenants/{tenant_id}":{"get":{"tags":["admin-tenants"],"summary":"Get Tenant","description":"Get a single tenant by ID with parent and children metadata. Super admin only.","operationId":"get_tenant_api_v1_admin_tenants__tenant_id__get","parameters":[{"name":"tenant_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Tenant Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TenantResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["admin-tenants"],"summary":"Update Tenant","description":"Update a tenant (name, slug, parent_tenant_id, is_active). Super admin only.\n\nChanging parent_tenant_id moves the tenant in the hierarchy. Circular references\nare prevented (new parent cannot be a descendant of the tenant being moved).","operationId":"update_tenant_api_v1_admin_tenants__tenant_id__patch","parameters":[{"name":"tenant_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Tenant Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TenantUpdateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TenantResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["admin-tenants"],"summary":"Delete Tenant","description":"Delete a tenant if it has no users, sub-tenants, or subscriptions. Super admin only.","operationId":"delete_tenant_api_v1_admin_tenants__tenant_id__delete","parameters":[{"name":"tenant_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Tenant Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"string"},"title":"Response Delete Tenant Api V1 Admin Tenants  Tenant Id  Delete"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/tenants/{tenant_id}/subtenants":{"post":{"tags":["admin-tenants"],"summary":"Create Subtenant","description":"Create a sub-tenant directly under the specified parent.\n\nAuth: super_admin on uum (bypasses scope), OR admin on uum whose effective\nscope includes tenant_id (the admin's tenant or one of its ancestors).","operationId":"create_subtenant_api_v1_admin_tenants__tenant_id__subtenants_post","parameters":[{"name":"tenant_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Tenant Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubTenantCreateRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TenantResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["admin-tenants"],"summary":"List Subtenants","description":"List direct children of the specified tenant. Flat list, no recursion.\n\nAuth: super_admin on uum (bypasses scope), OR admin on uum whose effective\nscope includes tenant_id.","operationId":"list_subtenants_api_v1_admin_tenants__tenant_id__subtenants_get","parameters":[{"name":"tenant_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Tenant Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubTenantListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/tenants/{tenant_id}/tree":{"get":{"tags":["admin-tenants"],"summary":"Get Tenant Tree","description":"Get the full descendant tree rooted at the specified tenant.\n\nReturns all sub-tenants recursively in nested form.\n\nAuth: super_admin on uum (bypasses scope), OR admin on uum whose effective\nscope includes tenant_id.","operationId":"get_tenant_tree_api_v1_admin_tenants__tenant_id__tree_get","parameters":[{"name":"tenant_id","in":"path","required":true,"schema":{"type":"string","title":"Tenant Id"}},{"name":"max_depth","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","minimum":1},{"type":"null"}],"title":"Max Depth"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubTenantTreeResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/tenants/{tenant_id}/subscriptions":{"get":{"tags":["admin-tenants"],"summary":"List Subscriptions","description":"DEPRECATED: Use /admin/tenants/{tenant_id}/subscription-list instead.","operationId":"list_subscriptions_api_v1_admin_tenants__tenant_id__subscriptions_get","parameters":[{"name":"tenant_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Tenant Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["admin-tenants"],"summary":"Subscribe Tenant","description":"DEPRECATED: Use POST /admin/tenants/{tenant_id}/plan-subscriptions instead.","operationId":"subscribe_tenant_api_v1_admin_tenants__tenant_id__subscriptions_post","parameters":[{"name":"tenant_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Tenant Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscriptionRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/tenants/{tenant_id}/subscriptions/{service_slug}":{"delete":{"tags":["admin-tenants"],"summary":"Unsubscribe Tenant","description":"DEPRECATED: Use DELETE /admin/tenants/{tenant_id}/subscription-instances/{id} instead.","operationId":"unsubscribe_tenant_api_v1_admin_tenants__tenant_id__subscriptions__service_slug__delete","parameters":[{"name":"tenant_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Tenant Id"}},{"name":"service_slug","in":"path","required":true,"schema":{"type":"string","title":"Service Slug"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"string"},"title":"Response Unsubscribe Tenant Api V1 Admin Tenants  Tenant Id  Subscriptions  Service Slug  Delete"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/tenants/{tenant_id}/subscription-list":{"get":{"tags":["admin-tenants"],"summary":"List Tenant Plan Subscriptions","description":"List plan-based subscriptions for a tenant with full plan/service details. Admin or super_admin.","operationId":"list_tenant_plan_subscriptions_api_v1_admin_tenants__tenant_id__subscription_list_get","parameters":[{"name":"tenant_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Tenant Id"}},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by status","title":"Status"},"description":"Filter by status"},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Page Size"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminSubscriptionsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/tenants/{tenant_id}/plan-subscriptions":{"post":{"tags":["admin-tenants"],"summary":"Create Tenant Subscription","description":"Create a plan-based subscription for a tenant. Super admin only.\n\nHandles paid (checkout session), trial (direct Dodo subscription),\nand free plans (immediate activation).","operationId":"create_tenant_subscription_api_v1_admin_tenants__tenant_id__plan_subscriptions_post","parameters":[{"name":"tenant_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Tenant Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscribeRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscribeCheckoutResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/tenants/{tenant_id}/subscription-instances/{subscription_id}":{"delete":{"tags":["admin-tenants"],"summary":"Cancel Tenant Subscription","description":"Cancel a plan-based subscription at period end. Super admin or tenant admin.","operationId":"cancel_tenant_subscription_api_v1_admin_tenants__tenant_id__subscription_instances__subscription_id__delete","parameters":[{"name":"tenant_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Tenant Id"}},{"name":"subscription_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Subscription Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CancelSubscriptionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/tenants/{tenant_id}/subscriptions/{subscription_id}/force":{"delete":{"tags":["admin-tenants"],"summary":"Force Delete Tenant Subscription","description":"Force-delete a subscription and clean up all related records.\n\nSuper admin only. Hard-deletes the subscription and cleans up related\nTenantServiceAddon, TenantService, and UserServiceRole records for the\nservice. When the subscription has a ``dodo_subscription_id``, a best-effort\ncancel is attempted in Dodo first (non-blocking on failure). Use this to\nremove any subscription record from the tenant — the tenant will need to\nre-subscribe to regain access.","operationId":"force_delete_tenant_subscription_api_v1_admin_tenants__tenant_id__subscriptions__subscription_id__force_delete","parameters":[{"name":"tenant_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Tenant Id"}},{"name":"subscription_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Subscription Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"string"},"title":"Response Force Delete Tenant Subscription Api V1 Admin Tenants  Tenant Id  Subscriptions  Subscription Id  Force Delete"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/tenants/{tenant_id}/subscriptions/{subscription_id}/dodo-id":{"patch":{"tags":["admin-tenants"],"summary":"Update Subscription Dodo Id","description":"Manually update dodo_subscription_id and/or dodo_customer_id on a subscription.\n\nSuper admin only. Use this to fix subscriptions where the Dodo webhook was missed\n(dev local env, migration, Dodo outage). The audit event logs old → new values.","operationId":"update_subscription_dodo_id_api_v1_admin_tenants__tenant_id__subscriptions__subscription_id__dodo_id_patch","parameters":[{"name":"tenant_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Tenant Id"}},{"name":"subscription_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Subscription Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateDodoIdRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscriptionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/tenants/{tenant_id}/services":{"patch":{"tags":["admin-tenants"],"summary":"Update Tenant Services","description":"DEPRECATED: Bulk service management is no longer supported.","operationId":"update_tenant_services_api_v1_admin_tenants__tenant_id__services_patch","parameters":[{"name":"tenant_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Tenant Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TenantServicesUpdateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["admin-tenants"],"summary":"List Tenant Services","description":"DEPRECATED: Use /admin/tenants/{tenant_id}/subscription-list for plan-based subscriptions.","operationId":"list_tenant_services_api_v1_admin_tenants__tenant_id__services_get","parameters":[{"name":"tenant_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Tenant Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/tenants/{tenant_id}/services/{service_id}":{"get":{"tags":["admin-tenants"],"summary":"Get Tenant Service","description":"DEPRECATED: Service-level lookup via TenantService is deprecated.","operationId":"get_tenant_service_api_v1_admin_tenants__tenant_id__services__service_id__get","parameters":[{"name":"tenant_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Tenant Id"}},{"name":"service_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Service Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["admin-tenants"],"summary":"Remove Tenant Service","description":"DEPRECATED: Use DELETE /admin/tenants/{tenant_id}/subscription-instances/{id} to cancel individual subscriptions.","operationId":"remove_tenant_service_api_v1_admin_tenants__tenant_id__services__service_id__delete","parameters":[{"name":"tenant_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Tenant Id"}},{"name":"service_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Service Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"string"},"title":"Response Remove Tenant Service Api V1 Admin Tenants  Tenant Id  Services  Service Id  Delete"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/tenants/{tenant_id}/plan-subscriptions/force":{"post":{"tags":["admin-tenants"],"summary":"Admin Force Plan Subscription","description":"Admin-forced subscription — assign any plan to a tenant.\n\nSuper admin only. Uses ``ForceSubscribeRequest`` which allows the admin to\ndecide the subscription's initial status:\n\n- ``status=\"active\"`` (default) — activates immediately with a 1-year billing\n  period. No Dodo checkout is created; the tenant gets immediate access.\n- ``status=\"incomplete\"`` — creates a Dodo checkout requiring payment setup.\n  The subscription remains ``incomplete`` until the tenant completes checkout\n  or the admin processes payment externally.","operationId":"admin_force_plan_subscription_api_v1_admin_tenants__tenant_id__plan_subscriptions_force_post","parameters":[{"name":"tenant_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Tenant Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForceSubscribeRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscriptionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/tenants/{tenant_id}/billing-services":{"get":{"tags":["admin-tenants"],"summary":"List Tenant Billing Services","description":"List active add-on services for a tenant with plan info.\n\nReturns the same data as the billing summary but without totals.\nUsed by TenantDetailPage to render service cards.","operationId":"list_tenant_billing_services_api_v1_admin_tenants__tenant_id__billing_services_get","parameters":[{"name":"tenant_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Tenant Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/BillingServiceSummary"},"title":"Response List Tenant Billing Services Api V1 Admin Tenants  Tenant Id  Billing Services Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/tenants/{tenant_id}/billing-services/{service_slug}":{"delete":{"tags":["admin-tenants"],"summary":"Remove Tenant Billing Service","description":"Remove a service add-on from a tenant.\n\nCalls billing_service.remove_service_addon() which removes the Dodo add-on\nand marks TenantServiceAddon as removed.","operationId":"remove_tenant_billing_service_api_v1_admin_tenants__tenant_id__billing_services__service_slug__delete","parameters":[{"name":"tenant_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Tenant Id"}},{"name":"service_slug","in":"path","required":true,"schema":{"type":"string","title":"Service Slug"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"string"},"title":"Response Remove Tenant Billing Service Api V1 Admin Tenants  Tenant Id  Billing Services  Service Slug  Delete"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/dodo-sync":{"post":{"tags":["admin-tenants"],"summary":"Trigger Dodo Sync","description":"Manually trigger Dodo subscription sync. Super admin only.","operationId":"trigger_dodo_sync_api_v1_admin_dodo_sync_post","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"string"},"title":"Response Trigger Dodo Sync Api V1 Admin Dodo Sync Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/tenants/import":{"post":{"tags":["admin-tenants"],"summary":"Import Global Tenants","description":"Bulk-import tenants and users from a CSV blob.\n\nCreates or updates global tenants (top-level, under root). Also handles\nuser rows that reference existing tenant slugs.\n\nSuper admin only.","operationId":"import_global_tenants_api_v1_admin_tenants_import_post","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/tenants/{tenant_id}/import":{"post":{"tags":["admin-tenants"],"summary":"Import Tenant Users","description":"Bulk-import users into a specific tenant from a CSV blob.\n\nOnly processes 'user' rows — 'tenant' rows in the CSV are ignored.\nThe `tenant_slug` column in user rows is ignored; all users are\nassigned to the tenant specified in the URL path.\n\nAuth: super_admin (bypasses scope), OR admin whose effective scope\nincludes tenant_id.","operationId":"import_tenant_users_api_v1_admin_tenants__tenant_id__import_post","parameters":[{"name":"tenant_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Tenant Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/tenants/{tenant_id}/users/{user_id}/impersonate":{"post":{"tags":["admin-tenants"],"summary":"Impersonate User","description":"Generate an access + refresh token for a target user.\n\nAllows admins and super admins to impersonate any user within their\ntenant scope. The generated JWT contains the target user's identity,\ngiving the caller full access as that user (including their\npermissions/roles and home tenant).\n\nThe endpoint also creates a new refresh token session and sets it as an\nhttpOnly cookie. This ensures that on page reload, ``/auth/refresh`` uses\nthe impersonated user's session instead of the original admin's session.","operationId":"impersonate_user_api_v1_admin_tenants__tenant_id__users__user_id__impersonate_post","parameters":[{"name":"tenant_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Tenant Id"}},{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImpersonateResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/audit-logs":{"get":{"tags":["audit"],"summary":"List Audit Logs","description":"List audit logs.\n\n- super_admin on UUM: sees all events across all tenants.\n- admin on UUM: sees events for their tenant + all sub-tenants (effective scope).\n\nSupports filtering by event type and date range, plus pagination.","operationId":"list_audit_logs_api_v1_admin_audit_logs_get","parameters":[{"name":"event_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filtrar por tipo de evento (ej: login, logout)","title":"Event Type"},"description":"Filtrar por tipo de evento (ej: login, logout)"},{"name":"date_from","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"Fecha desde (ISO 8601)","title":"Date From"},"description":"Fecha desde (ISO 8601)"},{"name":"date_to","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"Fecha hasta (ISO 8601)","title":"Date To"},"description":"Fecha hasta (ISO 8601)"},{"name":"target_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"description":"Filter by target user/resource ID","title":"Target Id"},"description":"Filter by target user/resource ID"},{"name":"actor_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"description":"Filter by actor/user ID","title":"Actor Id"},"description":"Filter by actor/user ID"},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"description":"Página (1-indexed)","default":1,"title":"Page"},"description":"Página (1-indexed)"},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Tamaño de página","default":20,"title":"Page Size"},"description":"Tamaño de página"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditLogListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/plans":{"get":{"tags":["admin-plans"],"summary":"List Plans","description":"List all plans. Admin or super_admin.","operationId":"list_plans_api_v1_admin_plans_get","parameters":[{"name":"service_slug","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Service Slug"}},{"name":"is_active","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Active"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Page Size"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlanListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["admin-plans"],"summary":"Create Plan","description":"Create a plan. Super admin only.","operationId":"create_plan_api_v1_admin_plans_post","parameters":[{"name":"service_slug","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Service slug to create plan for","title":"Service Slug"},"description":"Service slug to create plan for"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlanCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlanResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/plans/{plan_id}":{"get":{"tags":["admin-plans"],"summary":"Get Plan","description":"Get a single plan. Super admin only.","operationId":"get_plan_api_v1_admin_plans__plan_id__get","parameters":[{"name":"plan_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Plan Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlanResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["admin-plans"],"summary":"Update Plan","description":"Update a plan. Super admin only.","operationId":"update_plan_api_v1_admin_plans__plan_id__patch","parameters":[{"name":"plan_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Plan Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlanUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlanResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["admin-plans"],"summary":"Delete Plan","description":"Deactivate a plan. Super admin only.","operationId":"delete_plan_api_v1_admin_plans__plan_id__delete","parameters":[{"name":"plan_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Plan Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Delete Plan Api V1 Admin Plans  Plan Id  Delete"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/dodo-addons":{"get":{"tags":["admin-plans"],"summary":"List Dodo Addons","description":"List all Dodo Payments add-ons for plan matching. Super admin only.","operationId":"list_dodo_addons_api_v1_admin_dodo_addons_get","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","additionalProperties":true},"title":"Response List Dodo Addons Api V1 Admin Dodo Addons Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/users":{"get":{"tags":["admin-users"],"summary":"List Users For Audit","description":"List users for audit log filtering.\n\n- super_admin on UUM: sees all users.\n- admin on UUM: sees users for their tenant + all sub-tenants (effective scope).","operationId":"list_users_for_audit_api_v1_admin_users_get","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":100,"title":"Page Size"}},{"name":"search","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Search by email","title":"Search"},"description":"Search by email"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/invoice-deliveries/dispatch":{"post":{"tags":["admin-invoices"],"summary":"Trigger Invoice Dispatch","description":"Manually trigger the invoice dispatch cycle.\n\nSuper admin only. Runs the same logic as the daily background task:\nfinds tenants with billing_email, checks for new Dodo payments,\ndownloads invoice PDFs, and emails them.","operationId":"trigger_invoice_dispatch_api_v1_admin_invoice_deliveries_dispatch_post","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DispatchTriggerResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/invoice-deliveries":{"get":{"tags":["admin-invoices"],"summary":"List Invoice Deliveries","description":"List invoice delivery records with optional filters.\n\nSuper admin only.","operationId":"list_invoice_deliveries_api_v1_admin_invoice_deliveries_get","parameters":[{"name":"tenant_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"description":"Filter by tenant ID","title":"Tenant Id"},"description":"Filter by tenant ID"},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by status (sent, failed)","title":"Status"},"description":"Filter by status (sent, failed)"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvoiceDeliveryListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/tenants/{tenant_id}/commission-rate":{"patch":{"tags":["admin-partners"],"summary":"Update Commission Rate","description":"Set the commission rate for a partner tenant.\n\nThe tenant must have ``can_create_subtenants=True``.","operationId":"update_commission_rate_api_v1_admin_tenants__tenant_id__commission_rate_patch","parameters":[{"name":"tenant_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Tenant Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommissionRateUpdateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommissionRateResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/partners":{"get":{"tags":["admin-partners"],"summary":"List Partners","description":"List all partner tenants with commission rates and sub-tenant counts.","operationId":"list_partners_api_v1_admin_partners_get","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Page Size"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/partners/{partner_id}/balance":{"get":{"tags":["admin-partners"],"summary":"Get Partner Balance","description":"Get a partner's current balance (accrued - transferred).","operationId":"get_partner_balance_api_v1_admin_partners__partner_id__balance_get","parameters":[{"name":"partner_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Partner Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerBalanceResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/partners/commissions":{"get":{"tags":["admin-partners"],"summary":"List All Commissions","description":"List all commission accruals across all partners.","operationId":"list_all_commissions_api_v1_admin_partners_commissions_get","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Page Size"}},{"name":"partner_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Partner Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommissionListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/partners/{partner_id}/transfers":{"post":{"tags":["admin-partners"],"summary":"Record Transfer","description":"Record a transfer/payment to a partner.","operationId":"record_transfer_api_v1_admin_partners__partner_id__transfers_post","parameters":[{"name":"partner_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Partner Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransferRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransferResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["admin-partners"],"summary":"List Transfers","description":"List transfers for a specific partner.","operationId":"list_transfers_api_v1_admin_partners__partner_id__transfers_get","parameters":[{"name":"partner_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Partner Id"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Page Size"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransferListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/tenants/{tenant_id}/users":{"get":{"tags":["tenant-users"],"summary":"List Users","description":"List users in a tenant (or across all sub-tenants). Requires admin role on UUM.","operationId":"list_users_api_v1_tenants__tenant_id__users_get","parameters":[{"name":"tenant_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Tenant Id"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Page Size"}},{"name":"search","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Search"}},{"name":"is_active","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Active"}},{"name":"has_role","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Has Role"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["tenant-users"],"summary":"Create User Route","description":"Create a user in a tenant (or sub-tenant). Requires admin role on UUM.","operationId":"create_user_route_api_v1_tenants__tenant_id__users_post","parameters":[{"name":"tenant_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Tenant Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserCreateRequest"}}}},"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"}}}}}}},"/api/v1/tenants/{tenant_id}/users/{user_id}":{"get":{"tags":["tenant-users"],"summary":"Get User Route","description":"Get a user by ID (tenant-scoped).","operationId":"get_user_route_api_v1_tenants__tenant_id__users__user_id__get","parameters":[{"name":"tenant_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Tenant Id"}},{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["tenant-users"],"summary":"Update User Route","description":"Update a user's email or active status.","operationId":"update_user_route_api_v1_tenants__tenant_id__users__user_id__patch","parameters":[{"name":"tenant_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Tenant Id"}},{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserUpdateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["tenant-users"],"summary":"Delete User Route","description":"Delete a user (cascade removes roles and refresh tokens).","operationId":"delete_user_route_api_v1_tenants__tenant_id__users__user_id__delete","parameters":[{"name":"tenant_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Tenant Id"}},{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"string"},"title":"Response Delete User Route Api V1 Tenants  Tenant Id  Users  User Id  Delete"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/tenants/{tenant_id}/users/{user_id}/password":{"patch":{"tags":["tenant-users"],"summary":"Reset User Password Route","description":"Reset a user's password (admin only).","operationId":"reset_user_password_route_api_v1_tenants__tenant_id__users__user_id__password_patch","parameters":[{"name":"tenant_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Tenant Id"}},{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminPasswordResetRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"string"},"title":"Response Reset User Password Route Api V1 Tenants  Tenant Id  Users  User Id  Password Patch"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/tenants/{tenant_id}/users/{user_id}/services/{service_slug}/status":{"patch":{"tags":["tenant-users"],"summary":"Toggle User Service Status","description":"Enable or disable a user's access to a specific service (keeps the role).","operationId":"toggle_user_service_status_api_v1_tenants__tenant_id__users__user_id__services__service_slug__status_patch","parameters":[{"name":"tenant_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Tenant Id"}},{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}},{"name":"service_slug","in":"path","required":true,"schema":{"type":"string","title":"Service Slug"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServiceStatusToggleRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/tenants/{tenant_id}/users/{user_id}/roles":{"get":{"tags":["tenant-roles"],"summary":"Get User Roles","description":"Get all role assignments for a user.","operationId":"get_user_roles_api_v1_tenants__tenant_id__users__user_id__roles_get","parameters":[{"name":"tenant_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Tenant Id"}},{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserRolesResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["tenant-roles"],"summary":"Assign User Roles","description":"Atomic role assignment: replaces all existing roles.","operationId":"assign_user_roles_api_v1_tenants__tenant_id__users__user_id__roles_put","parameters":[{"name":"tenant_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Tenant Id"}},{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleAssignmentRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserRolesResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/tenants/{tenant_id}/users/{user_id}/roles/{service_slug}":{"patch":{"tags":["tenant-roles"],"summary":"Update User Role","description":"Update (or assign) a user's role for a specific service. Set role to empty string to remove.","operationId":"update_user_role_api_v1_tenants__tenant_id__users__user_id__roles__service_slug__patch","parameters":[{"name":"tenant_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Tenant Id"}},{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}},{"name":"service_slug","in":"path","required":true,"schema":{"type":"string","title":"Service Slug"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleUpdateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserRolesResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/tenants/{tenant_id}/invitations":{"post":{"tags":["tenant-invitations"],"summary":"Create Invitation Route","description":"Create a pending invitation for an email within a tenant.\n\nRequires admin role on UUM.","operationId":"create_invitation_route_api_v1_tenants__tenant_id__invitations_post","parameters":[{"name":"tenant_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Tenant Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvitationCreateRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvitationResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["tenant-invitations"],"summary":"List Invitations Route","description":"List all invitations for a tenant (newest first).\n\nRequires admin role on UUM.","operationId":"list_invitations_route_api_v1_tenants__tenant_id__invitations_get","parameters":[{"name":"tenant_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Tenant Id"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Page Size"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvitationListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/tenants/{tenant_id}/invitations/{invitation_id}":{"delete":{"tags":["tenant-invitations"],"summary":"Revoke Invitation Route","description":"Revoke a pending invitation.\n\nRequires admin role on UUM.","operationId":"revoke_invitation_route_api_v1_tenants__tenant_id__invitations__invitation_id__delete","parameters":[{"name":"tenant_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Tenant Id"}},{"name":"invitation_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Invitation Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"string"},"title":"Response Revoke Invitation Route Api V1 Tenants  Tenant Id  Invitations  Invitation Id  Delete"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/tenants/{tenant_id}/invitations/{invitation_id}/resend":{"post":{"tags":["tenant-invitations"],"summary":"Resend Invitation Route","description":"Regenerate the activation token and resend the invitation email.\n\nRequires admin role on UUM.","operationId":"resend_invitation_route_api_v1_tenants__tenant_id__invitations__invitation_id__resend_post","parameters":[{"name":"tenant_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Tenant Id"}},{"name":"invitation_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Invitation Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvitationResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/tenants":{"get":{"tags":["tenant-info"],"summary":"List My Tenants","description":"List tenants visible to this admin.\n\n- super_admin: sees all tenants (delegates to /admin/tenants).\n- admin: sees own tenant + sub-tenants via effective scope.","operationId":"list_my_tenants_api_v1_tenants_get","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TenantListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/tenants/{tenant_id}":{"get":{"tags":["tenant-info"],"summary":"Get My Tenant","description":"Get a tenant by ID. Tenant admins can only view their own tenant or descendants.","operationId":"get_my_tenant_api_v1_tenants__tenant_id__get","parameters":[{"name":"tenant_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Tenant Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TenantResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/tenants/{tenant_id}/subtenants":{"get":{"tags":["tenant-info"],"summary":"List My Subtenants","description":"List direct sub-tenants. Tenant admins can only list sub-tenants of their own tenant or descendants.","operationId":"list_my_subtenants_api_v1_tenants__tenant_id__subtenants_get","parameters":[{"name":"tenant_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Tenant Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubTenantListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["tenant-info"],"summary":"Create My Subtenant","description":"Create a sub-tenant under a parent. Tenant admins can only create sub-tenants under their own tenant or descendants.","operationId":"create_my_subtenant_api_v1_tenants__tenant_id__subtenants_post","parameters":[{"name":"tenant_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Tenant Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubTenantCreateRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TenantResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/tenants/{tenant_id}/branding":{"patch":{"tags":["tenant-info"],"summary":"Update Tenant Branding","description":"Update portal branding for a tenant (admin accessible).","operationId":"update_tenant_branding_api_v1_tenants__tenant_id__branding_patch","parameters":[{"name":"tenant_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Tenant Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PortalBrandingUpdateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TenantResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["tenant-info"],"summary":"Get Tenant Portal Branding","description":"Get effective portal branding for a tenant.\n\nReturns the first portal name/logo found by walking up the parent chain.\nFalls back to default \"UUM Admin\" branding if no ancestor has custom\nbranding configured.\n\nAccessible to any authenticated user (not just admins) because branding\nis a read-only cosmetic concern needed by the Layout sidebar for all users.","operationId":"get_tenant_portal_branding_api_v1_tenants__tenant_id__branding_get","parameters":[{"name":"tenant_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Tenant Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PortalBrandingResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/tenants/{tenant_id}/subscription-list":{"get":{"tags":["tenant-info"],"summary":"List My Tenant Plan Subscriptions","description":"List plan-based subscriptions for a tenant. Tenant admins can view their own tenant or descendants.","operationId":"list_my_tenant_plan_subscriptions_api_v1_tenants__tenant_id__subscription_list_get","parameters":[{"name":"tenant_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Tenant Id"}},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by status","title":"Status"},"description":"Filter by status"},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Page Size"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminSubscriptionsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/tenants/{tenant_id}/subscriptions":{"get":{"tags":["tenant-info"],"summary":"List My Tenant Subscriptions","description":"DEPRECATED: Use /tenants/{tenant_id}/subscription-list for plan-based subscriptions.","operationId":"list_my_tenant_subscriptions_api_v1_tenants__tenant_id__subscriptions_get","parameters":[{"name":"tenant_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Tenant Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/tenants/{tenant_id}/subscriptions/{subscription_id}/change-plan":{"patch":{"tags":["tenant-info"],"summary":"Change Tenant Subscription Plan","description":"Change a tenant's subscription plan (tenant admin or super_admin).\n\nTenant admins can change plans for their own tenant or descendants.\nFor paid plan changes, returns a checkout_url for Dodo payment.\nFor free/free and Dodo-managed changes, updates immediately.","operationId":"change_tenant_subscription_plan_api_v1_tenants__tenant_id__subscriptions__subscription_id__change_plan_patch","parameters":[{"name":"tenant_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Tenant Id"}},{"name":"subscription_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Subscription Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TenantChangePlanRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChangePlanResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/partner/dashboard":{"get":{"tags":["partner"],"summary":"Get Dashboard","description":"Get the partner dashboard with balance, sub-tenant summaries, and recent activity.\n\nAuto-scoped to the authenticated user's tenant (no partner_id in URL).","operationId":"get_dashboard_api_v1_partner_dashboard_get","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerDashboardResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/partner/commissions":{"get":{"tags":["partner"],"summary":"List Commissions","description":"List commission accruals for the authenticated partner.\n\nSupports filtering by sub-tenant, status, and date range.","operationId":"list_commissions_api_v1_partner_commissions_get","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Page Size"}},{"name":"sub_tenant_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Sub Tenant Id"}},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}},{"name":"date_from","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Date From"}},{"name":"date_to","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Date To"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommissionListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/partner/transfers":{"get":{"tags":["partner"],"summary":"List Transfers","description":"List transfers received by the authenticated partner.","operationId":"list_transfers_api_v1_partner_transfers_get","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Page Size"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransferListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/partner/commissions/export":{"get":{"tags":["partner"],"summary":"Export Commissions","description":"Export commission history as CSV download.","operationId":"export_commissions_api_v1_partner_commissions_export_get","parameters":[{"name":"sub_tenant_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Sub Tenant Id"}},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}},{"name":"date_from","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Date From"}},{"name":"date_to","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Date To"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/provisioning/validate-token":{"post":{"tags":["provisioning"],"summary":"Validate Sso Token","description":"Validate an SSO token and return user info.\n\nCalled by downstream services (Lexxto, InsightPBX) when they receive a\nuser redirected from UUM with an sso_token query parameter.","operationId":"validate_sso_token_api_v1_provisioning_validate_token_post","parameters":[{"name":"X-API-Key","in":"header","required":true,"schema":{"type":"string","title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Validate Sso Token Api V1 Provisioning Validate Token Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/provisioning/services/{service_slug}/users":{"get":{"tags":["provisioning"],"summary":"List Service Users","description":"List users who have at least one role on this service.\n\nUsed by downstream services (Lexxto, InsightPBX) for periodic user sync.","operationId":"list_service_users_api_v1_provisioning_services__service_slug__users_get","parameters":[{"name":"service_slug","in":"path","required":true,"schema":{"type":"string","title":"Service Slug"}},{"name":"tenant_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"description":"Filter users by tenant","title":"Tenant Id"},"description":"Filter users by tenant"},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"description":"Page number","default":1,"title":"Page"},"description":"Page number"},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"description":"Items per page","default":50,"title":"Page Size"},"description":"Items per page"},{"name":"X-API-Key","in":"header","required":true,"schema":{"type":"string","title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProvisionedUserListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/provisioning/services/{service_slug}/users/{user_id}":{"get":{"tags":["provisioning"],"summary":"Get Service User Detail","description":"Get a single user's details and roles on this service.\n\nReturns 404 if the user is not found or has no roles on this service.","operationId":"get_service_user_detail_api_v1_provisioning_services__service_slug__users__user_id__get","parameters":[{"name":"service_slug","in":"path","required":true,"schema":{"type":"string","title":"Service Slug"}},{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}},{"name":"X-API-Key","in":"header","required":true,"schema":{"type":"string","title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProvisionedUserDetailResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/provisioning/services/{service_slug}/plans":{"post":{"tags":["provisioning"],"summary":"Create Service Plan","description":"Service syncs a plan to UUM. Auth: X-API-Key.\nCreates a corresponding Dodo Product.","operationId":"create_service_plan_api_v1_provisioning_services__service_slug__plans_post","parameters":[{"name":"service_slug","in":"path","required":true,"schema":{"type":"string","title":"Service Slug"}},{"name":"X-API-Key","in":"header","required":true,"schema":{"type":"string","title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlanCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlanResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/provisioning/services/{service_slug}/plans/{plan_slug}":{"patch":{"tags":["provisioning"],"summary":"Update Service Plan","description":"Service updates a plan. Propagates to Dodo Product.","operationId":"update_service_plan_api_v1_provisioning_services__service_slug__plans__plan_slug__patch","parameters":[{"name":"service_slug","in":"path","required":true,"schema":{"type":"string","title":"Service Slug"}},{"name":"plan_slug","in":"path","required":true,"schema":{"type":"string","title":"Plan Slug"}},{"name":"X-API-Key","in":"header","required":true,"schema":{"type":"string","title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlanUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlanResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/provisioning/services/{service_slug}/plans/sync":{"post":{"tags":["provisioning"],"summary":"Sync Service Plans","description":"Bulk sync plans for a service.\n\nReplaces or updates plans based on the payload. If replace_all=True,\nany existing plans not in the payload are deactivated (soft delete).\n\nAuth: X-API-Key header (must match the service_slug).","operationId":"sync_service_plans_api_v1_provisioning_services__service_slug__plans_sync_post","parameters":[{"name":"service_slug","in":"path","required":true,"schema":{"type":"string","title":"Service Slug"}},{"name":"X-API-Key","in":"header","required":true,"schema":{"type":"string","title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkPlanSyncRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/PlanResponse"},"title":"Response Sync Service Plans Api V1 Provisioning Services  Service Slug  Plans Sync Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/provisioning/services/{service_slug}/tenants/{tenant_id}":{"delete":{"tags":["provisioning"],"summary":"Delete Tenant Service","description":"External service confirms tenant data deletion.\n\nCalled by the external service after it has cleaned up all local data for\nthis tenant. UUM then hard-deletes TenantService + UserServiceRole records\nfor this tenant+service pair.\n\nAuth: X-API-Key header (must match the service_slug).","operationId":"delete_tenant_service_api_v1_provisioning_services__service_slug__tenants__tenant_id__delete","parameters":[{"name":"service_slug","in":"path","required":true,"schema":{"type":"string","title":"Service Slug"}},{"name":"tenant_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Tenant Id"}},{"name":"X-API-Key","in":"header","required":true,"schema":{"type":"string","title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Delete Tenant Service Api V1 Provisioning Services  Service Slug  Tenants  Tenant Id  Delete"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/provisioning/services/{service_slug}/tenants/{tenant_id}/subscription":{"get":{"tags":["provisioning"],"summary":"Get Tenant Subscription","description":"Return the tenant's current subscription for the calling service.\n\nUsed by downstream services (e.g. Yupana) to apply per-plan quotas when\nthey receive a request outside of any user session — a worker job, a\nscheduled task, or a quota-validation hook — without needing a user JWT.\n\nAuth: ``X-API-Key`` header. The API key must belong to the service whose\nslug is in the URL (matches the rest of the provisioning endpoints).\n\nScope: only subscriptions to plans **owned by the calling service** are\nvisible. A service cannot discover another service's plan or\nsubscription state.\n\nReturns 404 if the tenant has no active add-on to this service.","operationId":"get_tenant_subscription_api_v1_provisioning_services__service_slug__tenants__tenant_id__subscription_get","parameters":[{"name":"service_slug","in":"path","required":true,"schema":{"type":"string","title":"Service Slug"}},{"name":"tenant_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Tenant Id"}},{"name":"X-API-Key","in":"header","required":true,"schema":{"type":"string","title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TenantSubscriptionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/webhooks/dodo":{"post":{"tags":["webhooks"],"summary":"Dodo Webhook","description":"Receive and process Dodo Payments webhook events.\n\nIdempotent: duplicate events with same idempotency_key are skipped.\nHandles: subscription.created, subscription.updated, subscription.canceled,\n         payment.succeeded, payment.failed, recovery.* events.","operationId":"dodo_webhook_api_v1_webhooks_dodo_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Dodo Webhook Api V1 Webhooks Dodo Post"}}}}}}}},"components":{"schemas":{"ActivateRequest":{"properties":{"token":{"type":"string","title":"Token"},"password":{"type":"string","maxLength":128,"minLength":8,"title":"Password"},"auto_login":{"type":"boolean","title":"Auto Login","description":"Also start a session (refresh cookie + session in the response)","default":false},"language":{"anyOf":[{"type":"string","maxLength":10},{"type":"null"}],"title":"Language","description":"UI language used while activating"}},"type":"object","required":["token","password"],"title":"ActivateRequest","description":"POST /auth/activate request body."},"ActivateResponse":{"properties":{"message":{"type":"string","title":"Message"},"email":{"type":"string","format":"email","title":"Email"},"session":{"anyOf":[{"$ref":"#/components/schemas/LoginResponse"},{"type":"null"}]}},"type":"object","required":["message","email"],"title":"ActivateResponse","description":"POST /auth/activate response body."},"AdminPasswordResetRequest":{"properties":{"new_password":{"type":"string","maxLength":128,"minLength":8,"title":"New Password"}},"type":"object","required":["new_password"],"title":"AdminPasswordResetRequest","description":"PATCH /tenants/{tid}/users/{uid}/password request body."},"AdminSubscriptionsResponse":{"properties":{"tenant_id":{"type":"string","format":"uuid","title":"Tenant Id"},"subscriptions":{"items":{"$ref":"#/components/schemas/SubscriptionResponse"},"type":"array","title":"Subscriptions"},"total":{"type":"integer","title":"Total"},"page":{"type":"integer","title":"Page"},"page_size":{"type":"integer","title":"Page Size"}},"type":"object","required":["tenant_id","subscriptions","total","page","page_size"],"title":"AdminSubscriptionsResponse","description":"GET /admin/tenants/{tenant_id}/subscriptions response — paginated."},"ApiKeyResponse":{"properties":{"api_key":{"type":"string","title":"Api Key"},"message":{"type":"string","title":"Message","default":"Store this key securely. It will not be shown again."}},"type":"object","required":["api_key"],"title":"ApiKeyResponse","description":"Response after generating a new API key — raw key shown once."},"AuditLogListResponse":{"properties":{"items":{"items":{"$ref":"#/components/schemas/AuditLogResponse"},"type":"array","title":"Items"},"total":{"type":"integer","title":"Total"},"page":{"type":"integer","title":"Page"},"page_size":{"type":"integer","title":"Page Size"},"pages":{"type":"integer","title":"Pages"}},"type":"object","required":["items","total","page","page_size","pages"],"title":"AuditLogListResponse","description":"Paginated list of audit log entries."},"AuditLogResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"tenant_id":{"type":"string","format":"uuid","title":"Tenant Id"},"event_type":{"type":"string","title":"Event Type"},"actor_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Actor Id"},"actor_email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Actor Email"},"target_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Target Id"},"target_email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Target Email"},"details":{"additionalProperties":true,"type":"object","title":"Details"},"ip_address":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ip Address"},"user_agent":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"User Agent"},"session_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Session Id"},"accept_language":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Accept Language"},"content_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Content Type"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","tenant_id","event_type","details","created_at"],"title":"AuditLogResponse","description":"Single audit log entry."},"BillingServiceSummary":{"properties":{"plan_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Plan Id"},"slug":{"type":"string","title":"Slug"},"name":{"type":"string","title":"Name"},"plan_name":{"type":"string","title":"Plan Name"},"plan_slug":{"type":"string","title":"Plan Slug"},"price_amount":{"type":"integer","title":"Price Amount"},"price_currency":{"type":"string","title":"Price Currency"},"billing_interval":{"type":"string","title":"Billing Interval"},"logo_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Logo Url"},"added_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Added At"}},"type":"object","required":["slug","name","plan_name","plan_slug","price_amount","price_currency","billing_interval","logo_url","added_at"],"title":"BillingServiceSummary","description":"A single service's billing info within the unified subscription."},"BlockingService":{"properties":{"slug":{"type":"string","title":"Slug"},"name":{"type":"string","title":"Name"}},"type":"object","required":["slug","name"],"title":"BlockingService","description":"A service that blocks tenant deactivation."},"BulkPlanSyncRequest":{"properties":{"plans":{"items":{"$ref":"#/components/schemas/PlanCreate"},"type":"array","minItems":1,"title":"Plans"},"replace_all":{"type":"boolean","title":"Replace All","description":"If True, deactivate any existing plans not in the payload","default":false}},"type":"object","required":["plans"],"title":"BulkPlanSyncRequest","description":"Request payload for bulk plan synchronization."},"CancelSubscriptionResponse":{"properties":{"subscription_id":{"type":"string","format":"uuid","title":"Subscription Id"},"status":{"type":"string","title":"Status"},"cancel_at_period_end":{"type":"boolean","title":"Cancel At Period End"},"canceled_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Canceled At"},"canceled_at_period_end":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Canceled At Period End"},"message":{"type":"string","title":"Message"}},"type":"object","required":["subscription_id","status","cancel_at_period_end","canceled_at","message"],"title":"CancelSubscriptionResponse","description":"Response after canceling a subscription."},"CatalogEntry":{"properties":{"icon":{"type":"string","title":"Icon"},"title":{"type":"string","title":"Title"},"subtitle":{"type":"string","title":"Subtitle"},"description":{"type":"string","title":"Description"},"link":{"type":"string","title":"Link"},"logo_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Logo Url"},"landing_page":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Landing Page"}},"type":"object","required":["icon","title","subtitle","description","link"],"title":"CatalogEntry","description":"Single entry in the public service catalog."},"CatalogResponse":{"properties":{"services":{"items":{"$ref":"#/components/schemas/CatalogEntry"},"type":"array","title":"Services"}},"type":"object","required":["services"],"title":"CatalogResponse","description":"Public catalog — list of all discoverable services."},"ChangePasswordRequest":{"properties":{"current_password":{"type":"string","title":"Current Password"},"new_password":{"type":"string","maxLength":128,"minLength":8,"title":"New Password"}},"type":"object","required":["current_password","new_password"],"title":"ChangePasswordRequest"},"ChangePlanRequest":{"properties":{"new_plan_id":{"type":"string","format":"uuid","title":"New Plan Id"},"redirect_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Redirect Url","description":"Redirect URL after Dodo checkout completion. Required for paid plan changes."}},"type":"object","required":["new_plan_id"],"title":"ChangePlanRequest","description":"PATCH /me/subscriptions/{sid}/change-plan request body."},"ChangePlanResponse":{"properties":{"subscription_id":{"type":"string","format":"uuid","title":"Subscription Id"},"old_plan_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Old Plan Name"},"new_plan_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"New Plan Name"},"checkout_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Checkout Url","description":"Dodo checkout URL when changing to a paid plan. User must complete payment."},"message":{"type":"string","title":"Message"}},"type":"object","required":["subscription_id","old_plan_name","new_plan_name","message"],"title":"ChangePlanResponse","description":"PATCH /me/subscriptions/{sid}/change-plan response."},"CommissionListResponse":{"properties":{"items":{"items":{"$ref":"#/components/schemas/CommissionResponse"},"type":"array","title":"Items"},"total":{"type":"integer","title":"Total"},"page":{"type":"integer","title":"Page"},"page_size":{"type":"integer","title":"Page Size"},"pages":{"type":"integer","title":"Pages"}},"type":"object","required":["items","total","page","page_size","pages"],"title":"CommissionListResponse","description":"Paginated commission list."},"CommissionRateResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"name":{"type":"string","title":"Name"},"slug":{"type":"string","title":"Slug"},"commission_rate":{"type":"string","title":"Commission Rate"},"can_create_subtenants":{"type":"boolean","title":"Can Create Subtenants"}},"type":"object","required":["id","name","slug","commission_rate","can_create_subtenants"],"title":"CommissionRateResponse","description":"Response after updating commission rate."},"CommissionRateUpdateRequest":{"properties":{"commission_rate":{"anyOf":[{"type":"number","maximum":100.0,"minimum":0.0},{"type":"string"}],"title":"Commission Rate","description":"Commission rate as percentage (e.g. 15.00 = 15%)"}},"type":"object","required":["commission_rate"],"title":"CommissionRateUpdateRequest","description":"PATCH /admin/tenants/{tenant_id}/commission-rate request body."},"CommissionResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"partner_tenant_id":{"type":"string","format":"uuid","title":"Partner Tenant Id"},"partner_tenant_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Partner Tenant Name"},"sub_tenant_id":{"type":"string","format":"uuid","title":"Sub Tenant Id"},"sub_tenant_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Sub Tenant Name"},"dodo_payment_id":{"type":"string","title":"Dodo Payment Id"},"payment_amount":{"type":"string","title":"Payment Amount"},"commission_rate":{"type":"string","title":"Commission Rate"},"commission_amount":{"type":"string","title":"Commission Amount"},"currency":{"type":"string","title":"Currency"},"status":{"type":"string","title":"Status"},"accrued_at":{"type":"string","format":"date-time","title":"Accrued At"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","partner_tenant_id","sub_tenant_id","dodo_payment_id","payment_amount","commission_rate","commission_amount","currency","status","accrued_at","created_at"],"title":"CommissionResponse","description":"A single commission accrual record."},"CurrencyBalance":{"properties":{"currency":{"type":"string","title":"Currency"},"accrued":{"type":"string","title":"Accrued"},"transferred":{"type":"string","title":"Transferred"},"balance":{"type":"string","title":"Balance"}},"type":"object","required":["currency","accrued","transferred","balance"],"title":"CurrencyBalance","description":"Balance for a single currency."},"DiscountCreateRequest":{"properties":{"percentage":{"type":"integer","maximum":99.0,"minimum":1.0,"title":"Percentage","description":"Discount percentage. MSP: {25, 50, 75, 99}. Super admin: any."},"duration_months":{"type":"integer","minimum":1.0,"title":"Duration Months","description":"How many billing cycles the discount applies. MSP: {1, 2, 3}. Super admin: any."}},"type":"object","required":["percentage","duration_months"],"title":"DiscountCreateRequest","description":"Discount coupon request attached to a sub-tenant invitation.\n\nOnly available for paid plans. The MSP selects percentage + duration.\nThe coupon is created in Dodo via API with:\n- 15-day expiry\n- Usage limit: 1\n- subscription_cycles = duration_months"},"DiscountDetail":{"properties":{"discount_id":{"type":"string","title":"Discount Id"},"code":{"type":"string","title":"Code"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"type":{"type":"string","title":"Type"},"amount":{"type":"integer","title":"Amount"},"cycles_remaining":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Cycles Remaining"},"expires_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Expires At"}},"type":"object","required":["discount_id","code","type","amount"],"title":"DiscountDetail","description":"A single active discount applied to a subscription."},"DispatchTriggerResponse":{"properties":{"message":{"type":"string","title":"Message"},"tenants_processed":{"type":"integer","title":"Tenants Processed"},"invoices_sent":{"type":"integer","title":"Invoices Sent"},"invoices_skipped":{"type":"integer","title":"Invoices Skipped"},"errors":{"type":"integer","title":"Errors"}},"type":"object","required":["message","tenants_processed","invoices_sent","invoices_skipped","errors"],"title":"DispatchTriggerResponse"},"FinishImpersonationResponse":{"properties":{"access_token":{"type":"string","title":"Access Token"},"token_type":{"type":"string","title":"Token Type","default":"bearer"},"expires_in":{"type":"integer","title":"Expires In"},"user_id":{"type":"string","title":"User Id"},"email":{"type":"string","title":"Email"},"tenant_id":{"type":"string","title":"Tenant Id"}},"type":"object","required":["access_token","expires_in","user_id","email","tenant_id"],"title":"FinishImpersonationResponse","description":"POST /me/finish-impersonation response."},"ForceSubscribeRequest":{"properties":{"plan_id":{"type":"string","format":"uuid","title":"Plan Id"},"status":{"type":"string","title":"Status","description":"Desired subscription status after force-provisioning:\n- ``'active'`` (default) — activate immediately with a 1-year billing period. No Dodo checkout is created; the tenant gets immediate access.\n- ``'incomplete'`` — create a Dodo checkout requiring payment setup. The subscription remains in ``incomplete`` until the tenant completes checkout or the admin processes payment externally.\n","default":"active"}},"type":"object","required":["plan_id"],"title":"ForceSubscribeRequest","description":"POST /admin/tenants/{tenant_id}/plan-subscriptions/force request body.\n\nLike SubscribeRequest but with an extra ``status`` field that lets the\nsuper-admin decide the subscription's initial state when force-provisioning."},"GeneratedPassword":{"properties":{"email":{"type":"string","title":"Email"},"password":{"type":"string","title":"Password"}},"type":"object","required":["email","password"],"title":"GeneratedPassword","description":"A generated password returned after CSV import."},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ImpersonateResponse":{"properties":{"access_token":{"type":"string","title":"Access Token"},"token_type":{"type":"string","title":"Token Type","default":"bearer"},"expires_in":{"type":"integer","title":"Expires In","default":900},"impersonator_email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Impersonator Email"}},"type":"object","required":["access_token"],"title":"ImpersonateResponse","description":"POST /admin/tenants/{tid}/users/{uid}/impersonate response."},"ImportRequest":{"properties":{"csv":{"type":"string","minLength":1,"title":"Csv"}},"type":"object","required":["csv"],"title":"ImportRequest","description":"POST /admin/tenants/import request body — CSV blob."},"ImportResponse":{"properties":{"success":{"type":"boolean","title":"Success"},"created":{"additionalProperties":{"type":"integer"},"type":"object","title":"Created"},"updated":{"additionalProperties":{"type":"integer"},"type":"object","title":"Updated"},"errors":{"items":{"$ref":"#/components/schemas/ImportRowError"},"type":"array","title":"Errors"},"generated_passwords":{"items":{"$ref":"#/components/schemas/GeneratedPassword"},"type":"array","title":"Generated Passwords"}},"type":"object","required":["success","created","updated","errors","generated_passwords"],"title":"ImportResponse","description":"Response body for CSV import endpoints."},"ImportRowError":{"properties":{"line":{"type":"integer","title":"Line"},"reason":{"type":"string","title":"Reason"}},"type":"object","required":["line","reason"],"title":"ImportRowError","description":"A single validation error from CSV import."},"InvitationCreateRequest":{"properties":{"email":{"type":"string","format":"email","title":"Email"},"services":{"items":{"$ref":"#/components/schemas/ServiceAssignment"},"type":"array","title":"Services","description":"Service roles to assign when the invitation is accepted. If omitted, the user only gets 'user' on 'uum'."},"language":{"anyOf":[{"type":"string","maxLength":10},{"type":"null"}],"title":"Language","description":"Language of the invitation email (en, es, pt-BR). Defaults to the tenant's usual language."}},"type":"object","required":["email"],"title":"InvitationCreateRequest","description":"POST /tenants/{tid}/invitations request body."},"InvitationListResponse":{"properties":{"items":{"items":{"$ref":"#/components/schemas/InvitationResponse"},"type":"array","title":"Items"},"total":{"type":"integer","title":"Total"},"page":{"type":"integer","title":"Page"},"page_size":{"type":"integer","title":"Page Size"},"pages":{"type":"integer","title":"Pages"}},"type":"object","required":["items","total","page","page_size","pages"],"title":"InvitationListResponse","description":"Paginated invitation list."},"InvitationPreviewResponse":{"properties":{"status":{"type":"string","enum":["pending","accepted","expired","revoked","invalid"],"title":"Status"},"email_masked":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email Masked"},"tenant_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tenant Name"},"expires_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Expires At"},"services":{"items":{"type":"string"},"type":"array","title":"Services","default":[]}},"type":"object","required":["status"],"title":"InvitationPreviewResponse","description":"GET /auth/invitations/{token}/preview — what the activation page needs up front."},"InvitationResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"email":{"type":"string","format":"email","title":"Email"},"tenant_id":{"type":"string","format":"uuid","title":"Tenant Id"},"status":{"type":"string","title":"Status"},"expires_at":{"type":"string","format":"date-time","title":"Expires At"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"services":{"items":{"$ref":"#/components/schemas/ServiceAssignment"},"type":"array","title":"Services","description":"Service roles assigned to this invitation."},"discount_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Discount Code","description":"Dodo discount code attached to this invitation, if any"}},"type":"object","required":["id","email","tenant_id","status","expires_at","created_at"],"title":"InvitationResponse","description":"Invitation as returned by the API."},"InviteTenantRequest":{"properties":{"name":{"type":"string","maxLength":100,"minLength":2,"title":"Name","description":"Tenant name"},"admin_email":{"type":"string","format":"email","title":"Admin Email","description":"Email of the tenant admin to invite"},"slug":{"anyOf":[{"type":"string","maxLength":50,"minLength":2},{"type":"null"}],"title":"Slug","description":"Optional slug, auto-generated if omitted"}},"type":"object","required":["name","admin_email"],"title":"InviteTenantRequest","description":"POST /admin/tenants/invite request body.\n\nCreates a new tenant and sends an invitation to the tenant admin.\nThe invited admin will become a regular user in the new tenant (not admin).\nThe inviter receives a CC on the invitation email."},"InvoiceDeliveryItem":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"tenant_id":{"type":"string","format":"uuid","title":"Tenant Id"},"tenant_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tenant Name"},"subscription_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Subscription Id"},"dodo_payment_id":{"type":"string","title":"Dodo Payment Id"},"billing_email":{"type":"string","title":"Billing Email"},"amount":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Amount"},"currency":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Currency"},"status":{"type":"string","title":"Status"},"error_message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error Message"},"sent_at":{"type":"string","format":"date-time","title":"Sent At"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","tenant_id","dodo_payment_id","billing_email","status","sent_at","created_at"],"title":"InvoiceDeliveryItem"},"InvoiceDeliveryListResponse":{"properties":{"items":{"items":{"$ref":"#/components/schemas/InvoiceDeliveryItem"},"type":"array","title":"Items"},"total":{"type":"integer","title":"Total"}},"type":"object","required":["items","total"],"title":"InvoiceDeliveryListResponse"},"LoginRequest":{"properties":{"email":{"type":"string","format":"email","title":"Email"},"password":{"type":"string","title":"Password"}},"type":"object","required":["email","password"],"title":"LoginRequest","description":"POST /auth/login request body."},"LoginResponse":{"properties":{"access_token":{"type":"string","title":"Access Token"},"token_type":{"type":"string","title":"Token Type","default":"bearer"},"expires_in":{"type":"integer","title":"Expires In"},"user_id":{"type":"string","format":"uuid","title":"User Id"},"email":{"type":"string","format":"email","title":"Email"},"tenant_id":{"type":"string","format":"uuid","title":"Tenant Id"},"tenant_slug":{"type":"string","title":"Tenant Slug"},"current_tenant_id":{"type":"string","format":"uuid","title":"Current Tenant Id"},"current_tenant_name":{"type":"string","title":"Current Tenant Name"}},"type":"object","required":["access_token","expires_in","user_id","email","tenant_id","tenant_slug","current_tenant_id","current_tenant_name"],"title":"LoginResponse","description":"POST /auth/login response body."},"MeTenantsResponse":{"properties":{"current_tenant_id":{"type":"string","format":"uuid","title":"Current Tenant Id"},"home_tenant_id":{"type":"string","format":"uuid","title":"Home Tenant Id"},"tenants":{"items":{"$ref":"#/components/schemas/TenantSwitchInfo"},"type":"array","title":"Tenants"}},"type":"object","required":["current_tenant_id","home_tenant_id","tenants"],"title":"MeTenantsResponse","description":"GET /me/tenants response."},"PartnerBalanceResponse":{"properties":{"partner_id":{"type":"string","format":"uuid","title":"Partner Id"},"partner_name":{"type":"string","title":"Partner Name"},"commission_rate":{"type":"string","title":"Commission Rate"},"balances":{"items":{"$ref":"#/components/schemas/CurrencyBalance"},"type":"array","title":"Balances"},"last_accrual_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Accrual At"},"last_transfer_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Transfer At"}},"type":"object","required":["partner_id","partner_name","commission_rate","balances"],"title":"PartnerBalanceResponse","description":"Partner balance summary."},"PartnerDashboardResponse":{"properties":{"partner_tenant_id":{"type":"string","format":"uuid","title":"Partner Tenant Id"},"partner_name":{"type":"string","title":"Partner Name"},"commission_rate":{"type":"string","title":"Commission Rate"},"balances":{"items":{"$ref":"#/components/schemas/CurrencyBalance"},"type":"array","title":"Balances"},"sub_tenant_count":{"type":"integer","title":"Sub Tenant Count"},"sub_tenant_summaries":{"items":{"$ref":"#/components/schemas/SubTenantSummary"},"type":"array","title":"Sub Tenant Summaries"}},"type":"object","required":["partner_tenant_id","partner_name","commission_rate","balances","sub_tenant_count","sub_tenant_summaries"],"title":"PartnerDashboardResponse","description":"Full partner dashboard response."},"PartnerListItem":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"name":{"type":"string","title":"Name"},"slug":{"type":"string","title":"Slug"},"commission_rate":{"type":"string","title":"Commission Rate"},"sub_tenant_count":{"type":"integer","title":"Sub Tenant Count"},"is_active":{"type":"boolean","title":"Is Active"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","name","slug","commission_rate","sub_tenant_count","is_active","created_at"],"title":"PartnerListItem","description":"A partner as returned in the admin partner list."},"PartnerListResponse":{"properties":{"items":{"items":{"$ref":"#/components/schemas/PartnerListItem"},"type":"array","title":"Items"},"total":{"type":"integer","title":"Total"},"page":{"type":"integer","title":"Page"},"page_size":{"type":"integer","title":"Page Size"},"pages":{"type":"integer","title":"Pages"}},"type":"object","required":["items","total","page","page_size","pages"],"title":"PartnerListResponse","description":"Paginated partner list."},"PasswordResetConfirm":{"properties":{"token":{"type":"string","title":"Token"},"new_password":{"type":"string","maxLength":128,"minLength":8,"title":"New Password"}},"type":"object","required":["token","new_password"],"title":"PasswordResetConfirm","description":"Confirm password reset with the token from email."},"PasswordResetRequest":{"properties":{"email":{"type":"string","format":"email","title":"Email"}},"type":"object","required":["email"],"title":"PasswordResetRequest","description":"Request a password reset email.\n\nSe busca el usuario por email y se envía un enlace de recuperación.\nSi el email no existe, se responde OK por razones de seguridad (no enumeración de usuarios)."},"PaymentHistoryResponse":{"properties":{"subscription_id":{"type":"string","format":"uuid","title":"Subscription Id"},"payments":{"items":{"$ref":"#/components/schemas/PaymentItem"},"type":"array","title":"Payments"},"total":{"type":"integer","title":"Total"}},"type":"object","required":["subscription_id","payments","total"],"title":"PaymentHistoryResponse","description":"GET /me/subscriptions/{sid}/payments response."},"PaymentItem":{"properties":{"payment_id":{"type":"string","title":"Payment Id"},"amount":{"type":"integer","title":"Amount"},"currency":{"type":"string","title":"Currency"},"status":{"type":"string","title":"Status"},"created_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Created At"},"invoice_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Invoice Url"}},"type":"object","required":["payment_id","amount","currency","status","created_at","invoice_url"],"title":"PaymentItem","description":"A single payment record from Dodo."},"PaymentMethodInfo":{"properties":{"brand":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Brand"},"last4":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last4"},"exp_month":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Exp Month"},"exp_year":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Exp Year"}},"type":"object","title":"PaymentMethodInfo","description":"Stored/default payment method for a tenant."},"PaymentMethodResponse":{"properties":{"payment_method":{"anyOf":[{"$ref":"#/components/schemas/PaymentMethodInfo"},{"type":"null"}]}},"type":"object","title":"PaymentMethodResponse","description":"GET /me/billing/payment-method response."},"PendingDeletionItem":{"properties":{"tenant_id":{"type":"string","format":"uuid","title":"Tenant Id"},"tenant_slug":{"type":"string","title":"Tenant Slug"},"service_slug":{"type":"string","title":"Service Slug"},"deletion_scheduled_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Deletion Scheduled At"},"status":{"type":"string","title":"Status","default":"pending_deletion"}},"type":"object","required":["tenant_id","tenant_slug","service_slug"],"title":"PendingDeletionItem","description":"A tenant+service pair pending deletion."},"PlanCreate":{"properties":{"slug":{"type":"string","maxLength":50,"minLength":1,"pattern":"^[a-z0-9-]+$","title":"Slug"},"name":{"type":"string","maxLength":200,"minLength":1,"title":"Name"},"description":{"anyOf":[{"type":"string","maxLength":1000},{"type":"null"}],"title":"Description"},"features":{"items":{"type":"string"},"type":"array","title":"Features"},"price_amount":{"type":"integer","minimum":0.0,"title":"Price Amount","description":"Price in cents (0 = free)"},"price_currency":{"type":"string","maxLength":3,"minLength":3,"title":"Price Currency","default":"USD"},"billing_interval":{"type":"string","pattern":"^(monthly|yearly)$","title":"Billing Interval"},"trial_period_days":{"type":"integer","minimum":0.0,"title":"Trial Period Days","default":0},"is_active":{"type":"boolean","title":"Is Active","default":true},"metadata":{"additionalProperties":true,"type":"object","title":"Metadata"},"service_slug":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Service Slug","description":"Service slug (URL param or body)"},"dodo_addon_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Dodo Addon Id","description":"Existing Dodo Payments Add-on ID. Required for paid plans (price_amount > 0). The add-on must be created manually in Dodo Payments first."}},"type":"object","required":["slug","name","price_amount","billing_interval"],"title":"PlanCreate","description":"Create a plan — requires pre-existing dodo_addon_id for paid plans."},"PlanListResponse":{"properties":{"items":{"items":{"$ref":"#/components/schemas/PlanResponse"},"type":"array","title":"Items"},"total":{"type":"integer","title":"Total"},"page":{"type":"integer","title":"Page"},"page_size":{"type":"integer","title":"Page Size"}},"type":"object","required":["items","total","page","page_size"],"title":"PlanListResponse","description":"Paginated plan list."},"PlanPublicItem":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"slug":{"type":"string","title":"Slug"},"name":{"type":"string","title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"features":{"items":{"type":"string"},"type":"array","title":"Features"},"price_amount":{"type":"integer","title":"Price Amount"},"price_currency":{"type":"string","title":"Price Currency"},"billing_interval":{"type":"string","title":"Billing Interval"},"trial_period_days":{"type":"integer","title":"Trial Period Days"},"is_active":{"type":"boolean","title":"Is Active","default":true}},"type":"object","required":["id","slug","name","features","price_amount","price_currency","billing_interval","trial_period_days"],"title":"PlanPublicItem","description":"Public-facing plan item (no internal IDs, status, or dodo_addon_id)."},"PlanResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"service_id":{"type":"string","format":"uuid","title":"Service Id"},"service_slug":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Service Slug"},"service_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Service Name"},"slug":{"type":"string","title":"Slug"},"name":{"type":"string","title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"features":{"items":{"type":"string"},"type":"array","title":"Features"},"price_amount":{"type":"integer","title":"Price Amount"},"price_currency":{"type":"string","title":"Price Currency"},"billing_interval":{"type":"string","title":"Billing Interval"},"trial_period_days":{"type":"integer","title":"Trial Period Days"},"dodo_addon_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Dodo Addon Id"},"is_active":{"type":"boolean","title":"Is Active"},"metadata":{"additionalProperties":true,"type":"object","title":"Metadata"},"subscription_count":{"type":"integer","title":"Subscription Count","default":0},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["id","service_id","slug","name","features","price_amount","price_currency","billing_interval","trial_period_days","is_active","metadata","created_at","updated_at"],"title":"PlanResponse","description":"Plan returned to clients."},"PlanUpdate":{"properties":{"slug":{"anyOf":[{"type":"string","maxLength":50,"minLength":1,"pattern":"^[a-z0-9-]+$"},{"type":"null"}],"title":"Slug"},"name":{"anyOf":[{"type":"string","maxLength":200,"minLength":1},{"type":"null"}],"title":"Name"},"description":{"anyOf":[{"type":"string","maxLength":1000},{"type":"null"}],"title":"Description"},"features":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Features"},"price_amount":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Price Amount"},"price_currency":{"anyOf":[{"type":"string","maxLength":3,"minLength":3},{"type":"null"}],"title":"Price Currency"},"billing_interval":{"anyOf":[{"type":"string","pattern":"^(monthly|yearly)$"},{"type":"null"}],"title":"Billing Interval"},"trial_period_days":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Trial Period Days"},"is_active":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Active"},"metadata":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Metadata"},"dodo_addon_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Dodo Addon Id","description":"Dodo Payments Add-on ID reference"}},"type":"object","title":"PlanUpdate","description":"Update a plan — all fields optional."},"PortalBrandingResponse":{"properties":{"portal_name":{"type":"string","title":"Portal Name"},"portal_logo_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Portal Logo Url"},"source_tenant_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Source Tenant Id"},"source_tenant_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source Tenant Name"}},"type":"object","required":["portal_name","portal_logo_url"],"title":"PortalBrandingResponse","description":"Effective portal branding for a tenant, with cascade from parent chain.\n\nReturns the first portal_name / portal_logo_url found by walking up the\nparent chain. Falls back to default UUM branding if no ancestor has custom\nbranding configured."},"PortalBrandingUpdateRequest":{"properties":{"portal_name":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"title":"Portal Name"},"portal_logo_url":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Portal Logo Url"},"billing_email":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Billing Email"}},"type":"object","title":"PortalBrandingUpdateRequest","description":"PATCH /tenants/{tenant_id}/branding — restricted to portal branding fields only."},"PortalSessionResponse":{"properties":{"portal_url":{"type":"string","title":"Portal Url"}},"type":"object","required":["portal_url"],"title":"PortalSessionResponse","description":"Response with customer portal URL."},"ProvisionedUserDetailResponse":{"properties":{"user_id":{"type":"string","format":"uuid","title":"User Id"},"email":{"type":"string","title":"Email"},"tenant_id":{"type":"string","format":"uuid","title":"Tenant Id"},"is_active":{"type":"boolean","title":"Is Active"},"roles":{"items":{"type":"string"},"type":"array","title":"Roles"}},"type":"object","required":["user_id","email","tenant_id","is_active","roles"],"title":"ProvisionedUserDetailResponse","description":"Single user detail for provisioning (Section 10)."},"ProvisionedUserItem":{"properties":{"user_id":{"type":"string","format":"uuid","title":"User Id"},"email":{"type":"string","title":"Email"},"tenant_id":{"type":"string","format":"uuid","title":"Tenant Id"},"roles":{"items":{"type":"string"},"type":"array","title":"Roles"},"deletion_status":{"type":"string","title":"Deletion Status","default":"active"},"deletion_scheduled_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Deletion Scheduled At"}},"type":"object","required":["user_id","email","tenant_id","roles"],"title":"ProvisionedUserItem","description":"User summary in the provisioning list endpoint (Section 10)."},"ProvisionedUserListResponse":{"properties":{"items":{"items":{"$ref":"#/components/schemas/ProvisionedUserItem"},"type":"array","title":"Items"},"pending_deletions":{"items":{"$ref":"#/components/schemas/PendingDeletionItem"},"type":"array","title":"Pending Deletions","default":[]},"total":{"type":"integer","title":"Total"},"page":{"type":"integer","title":"Page"},"page_size":{"type":"integer","title":"Page Size"}},"type":"object","required":["items","total","page","page_size"],"title":"ProvisionedUserListResponse","description":"Paginated list of provisioned users (Section 10)."},"PublicPlansResponse":{"properties":{"service_slug":{"type":"string","title":"Service Slug"},"service_name":{"type":"string","title":"Service Name"},"plans":{"items":{"$ref":"#/components/schemas/PlanPublicItem"},"type":"array","title":"Plans"}},"type":"object","required":["service_slug","service_name","plans"],"title":"PublicPlansResponse","description":"Response for GET /public/services/{slug}/plans."},"PublicSignupRequest":{"properties":{"service_slug":{"type":"string","maxLength":50,"minLength":1,"title":"Service Slug"},"email":{"type":"string","format":"email","title":"Email"},"password":{"type":"string","maxLength":128,"minLength":8,"title":"Password"},"full_name":{"type":"string","maxLength":200,"minLength":1,"title":"Full Name"},"company_name":{"type":"string","maxLength":200,"minLength":1,"title":"Company Name"},"plan_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Plan Id","description":"Optional plan to subscribe to. Must belong to the service. Falls back to default_plan_id if omitted or invalid."},"plan_slug":{"anyOf":[{"type":"string","maxLength":50},{"type":"null"}],"title":"Plan Slug","description":"Optional plan slug (alternative to plan_id, easier for API clients). Ignored when plan_id is given."},"language":{"anyOf":[{"type":"string","maxLength":10},{"type":"null"}],"title":"Language","description":"UI language used to sign up (stored as preference)"}},"type":"object","required":["service_slug","email","password","full_name","company_name"],"title":"PublicSignupRequest","description":"Request for simplified public signup (no checkout/payment).","examples":[{"company_name":"Acme","email":"agent@example.com","full_name":"Ada Agent","language":"en","password":"a-long-random-password","plan_slug":"free","service_slug":"sandbox-labs-demo"}]},"PublicSignupResponse":{"properties":{"tenant_id":{"type":"string","format":"uuid","title":"Tenant Id"},"tenant_slug":{"type":"string","title":"Tenant Slug"},"user_id":{"type":"string","format":"uuid","title":"User Id"},"email":{"type":"string","title":"Email"},"subscription_id":{"type":"string","format":"uuid","title":"Subscription Id"},"checkout_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Checkout Url"},"status":{"type":"string","title":"Status","default":"active"},"session":{"anyOf":[{"$ref":"#/components/schemas/LoginResponse"},{"type":"null"}],"description":"Session started for the new user (refresh cookie is also set)"},"message":{"type":"string","title":"Message"}},"type":"object","required":["tenant_id","tenant_slug","user_id","email","subscription_id","message"],"title":"PublicSignupResponse","description":"Response after successful public signup.\n\nFor free plans (price_amount == 0): checkout_url is None, subscription active immediately.\nFor paid plans (price_amount > 0): checkout_url contains the Dodo Payments checkout link,\nand the subscription stays \"incomplete\" until payment is confirmed via webhook."},"RefreshCheckoutResponse":{"properties":{"subscription_id":{"type":"string","format":"uuid","title":"Subscription Id"},"checkout_url":{"type":"string","title":"Checkout Url"},"message":{"type":"string","title":"Message"}},"type":"object","required":["subscription_id","checkout_url","message"],"title":"RefreshCheckoutResponse","description":"POST /me/subscriptions/{sid}/refresh-checkout response."},"RefreshResponse":{"properties":{"access_token":{"type":"string","title":"Access Token"},"token_type":{"type":"string","title":"Token Type","default":"bearer"},"expires_in":{"type":"integer","title":"Expires In"},"current_tenant_id":{"type":"string","format":"uuid","title":"Current Tenant Id"}},"type":"object","required":["access_token","expires_in","current_tenant_id"],"title":"RefreshResponse","description":"POST /auth/refresh response body."},"RoleAssignment":{"properties":{"service_slug":{"type":"string","title":"Service Slug"},"role":{"type":"string","title":"Role"}},"type":"object","required":["service_slug","role"],"title":"RoleAssignment","description":"A single role assignment: service_slug + role name."},"RoleAssignmentRequest":{"properties":{"assignments":{"items":{"$ref":"#/components/schemas/RoleAssignment"},"type":"array","maxItems":50,"minItems":0,"title":"Assignments"}},"type":"object","required":["assignments"],"title":"RoleAssignmentRequest","description":"PUT /tenants/{tid}/users/{uid}/roles request body — atomic replace."},"RoleInfo":{"properties":{"service_slug":{"type":"string","title":"Service Slug"},"service_name":{"type":"string","title":"Service Name"},"role":{"type":"string","title":"Role"},"enabled":{"type":"boolean","title":"Enabled","default":true}},"type":"object","required":["service_slug","service_name","role"],"title":"RoleInfo","description":"Role assignment summary shown in user lists."},"RoleUpdateRequest":{"properties":{"role":{"type":"string","title":"Role"}},"type":"object","required":["role"],"title":"RoleUpdateRequest","description":"PATCH /tenants/{tid}/users/{uid}/roles/{service_slug} request body."},"SSORedirectRequest":{"properties":{"service_slug":{"type":"string","title":"Service Slug"}},"type":"object","required":["service_slug"],"title":"SSORedirectRequest","description":"POST /sso/redirect request body."},"SSOValidateExternalRequest":{"properties":{"user_email":{"type":"string","title":"User Email"},"service_slug":{"type":"string","title":"Service Slug"}},"type":"object","required":["user_email","service_slug"],"title":"SSOValidateExternalRequest","description":"POST /sso/validate-external request body.\n\nThe external service (Lexxto, InsightPBX) already authenticated its user\nand sends the user's email directly. UUM verifies the calling service\nvia X-API-Key header, looks up the user by email, and issues an SSO token\nif the user has a valid role on that service."},"ServiceAssignment":{"properties":{"service_slug":{"type":"string","title":"Service Slug","description":"The service slug, e.g. 'lexxto'"},"role":{"type":"string","title":"Role","description":"Role to assign, e.g. 'member', 'admin'"},"enabled":{"type":"boolean","title":"Enabled","description":"Whether the service assignment is active or temporarily disabled","default":true}},"type":"object","required":["service_slug","role"],"title":"ServiceAssignment","description":"A service + role pair assigned to an invitation."},"ServiceBranding":{"properties":{"background_color":{"anyOf":[{"type":"string","pattern":"^#[0-9A-Fa-f]{6}$"},{"type":"null"}],"title":"Background Color"},"primary_color":{"anyOf":[{"type":"string","pattern":"^#[0-9A-Fa-f]{6}$"},{"type":"null"}],"title":"Primary Color"},"secondary_color":{"anyOf":[{"type":"string","pattern":"^#[0-9A-Fa-f]{6}$"},{"type":"null"}],"title":"Secondary Color"}},"type":"object","title":"ServiceBranding","description":"Branding customization for login/signup pages."},"ServiceCreateRequest":{"properties":{"slug":{"type":"string","maxLength":50,"minLength":2,"pattern":"^[a-z0-9-]+$","title":"Slug"},"name":{"type":"string","maxLength":100,"minLength":1,"title":"Name"},"description":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Description"},"icon":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"title":"Icon"},"category":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"title":"Category"},"landing_page":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Landing Page"},"logo_url":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Logo Url"},"callback_url":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Callback Url"},"available_roles":{"items":{"type":"string"},"type":"array","maxItems":20,"minItems":1,"title":"Available Roles"},"allow_public_signup":{"type":"boolean","title":"Allow Public Signup","default":false},"is_internal":{"type":"boolean","title":"Is Internal","default":false},"default_plan_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Default Plan Id"},"default_role":{"anyOf":[{"type":"string","maxLength":50},{"type":"null"}],"title":"Default Role"},"catalog_url":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Catalog Url"},"branding":{"$ref":"#/components/schemas/ServiceBranding"},"webhook":{"anyOf":[{"$ref":"#/components/schemas/WebhookConfig"},{"type":"null"}],"description":"Outbound webhook configuration (optional)."}},"type":"object","required":["slug","name","available_roles"],"title":"ServiceCreateRequest","description":"POST /admin/services request body."},"ServiceResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"slug":{"type":"string","title":"Slug"},"name":{"type":"string","title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"icon":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Icon"},"category":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category"},"landing_page":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Landing Page"},"callback_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Callback Url"},"available_roles":{"items":{"type":"string"},"type":"array","title":"Available Roles"},"has_api_key":{"type":"boolean","title":"Has Api Key"},"is_active":{"type":"boolean","title":"Is Active"},"is_internal":{"type":"boolean","title":"Is Internal"},"allow_public_signup":{"type":"boolean","title":"Allow Public Signup"},"default_plan_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Default Plan Id"},"default_plan_slug":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Default Plan Slug"},"default_plan_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Default Plan Name"},"default_role":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Default Role"},"catalog_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Catalog Url"},"logo_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Logo Url"},"branding":{"$ref":"#/components/schemas/ServiceBranding"},"webhook_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Webhook Url"},"webhook_events":{"items":{"type":"string"},"type":"array","title":"Webhook Events"},"has_webhook_secret":{"type":"boolean","title":"Has Webhook Secret","default":false},"deleted_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Deleted At"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["id","slug","name","description","available_roles","has_api_key","is_active","is_internal","allow_public_signup","created_at","updated_at"],"title":"ServiceResponse","description":"Service as returned by the admin API."},"ServiceStatusToggleRequest":{"properties":{"enabled":{"type":"boolean","title":"Enabled"}},"type":"object","required":["enabled"],"title":"ServiceStatusToggleRequest","description":"PATCH /tenants/{tid}/users/{uid}/services/{service_slug}/status request body."},"ServiceUpdateRequest":{"properties":{"name":{"anyOf":[{"type":"string","maxLength":100,"minLength":1},{"type":"null"}],"title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"icon":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Icon"},"category":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category"},"landing_page":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Landing Page"},"logo_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Logo Url"},"callback_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Callback Url"},"available_roles":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Available Roles"},"is_active":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Active"},"is_internal":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Internal"},"allow_public_signup":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Allow Public Signup"},"default_plan_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Default Plan Id"},"default_role":{"anyOf":[{"type":"string","maxLength":50},{"type":"null"}],"title":"Default Role"},"catalog_url":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Catalog Url"},"branding":{"anyOf":[{"$ref":"#/components/schemas/ServiceBranding"},{"type":"null"}]},"webhook":{"anyOf":[{"$ref":"#/components/schemas/WebhookConfig"},{"type":"null"}],"description":"Webhook configuration. To disable webhooks, send {webhook: {webhook_url: null}} explicitly."}},"type":"object","title":"ServiceUpdateRequest","description":"PATCH /admin/services/{id} request body."},"SignupCheckoutRequest":{"properties":{"service_slug":{"type":"string","maxLength":50,"minLength":1,"title":"Service Slug"},"plan_slug":{"type":"string","maxLength":50,"minLength":1,"title":"Plan Slug"},"email":{"type":"string","format":"email","title":"Email"},"company_name":{"type":"string","maxLength":200,"minLength":1,"title":"Company Name"},"company_slug":{"type":"string","maxLength":50,"minLength":1,"pattern":"^[a-z0-9-]+$","title":"Company Slug"},"full_name":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Full Name"},"redirect_url":{"type":"string","title":"Redirect Url","description":"URL to redirect after Dodo checkout completes"}},"type":"object","required":["service_slug","plan_slug","email","company_name","company_slug","redirect_url"],"title":"SignupCheckoutRequest","description":"Request to initiate signup checkout."},"SignupCheckoutResponse":{"properties":{"tenant_id":{"type":"string","format":"uuid","title":"Tenant Id"},"tenant_slug":{"type":"string","title":"Tenant Slug"},"user_id":{"type":"string","format":"uuid","title":"User Id"},"email":{"type":"string","title":"Email"},"subscription_id":{"type":"string","format":"uuid","title":"Subscription Id"},"checkout_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Checkout Url"},"status":{"type":"string","title":"Status"},"trial_end":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Trial End"},"message":{"type":"string","title":"Message"}},"type":"object","required":["tenant_id","tenant_slug","user_id","email","subscription_id","status","message"],"title":"SignupCheckoutResponse","description":"Response after initiating signup checkout."},"SignupConfigResponse":{"properties":{"allow_public_signup":{"type":"boolean","title":"Allow Public Signup"},"service_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Service Name"},"logo_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Logo Url"},"landing_page":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Landing Page"},"icon":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Icon"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"default_plan":{"anyOf":[{"$ref":"#/components/schemas/SignupPlanInfo"},{"type":"null"}]},"plans":{"items":{"$ref":"#/components/schemas/SignupPlanInfo"},"type":"array","title":"Plans","description":"All active plans available for this service (for plan selector in signup form)."},"branding":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Branding"}},"type":"object","required":["allow_public_signup"],"title":"SignupConfigResponse","description":"Public signup config for a service."},"SignupPlanInfo":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"slug":{"type":"string","title":"Slug"},"name":{"type":"string","title":"Name"}},"type":"object","required":["id","slug","name"],"title":"SignupPlanInfo","description":"Minimal plan info returned in signup config."},"SignupServiceItem":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"slug":{"type":"string","title":"Slug"},"name":{"type":"string","title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"icon_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Icon Url"},"category":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category"},"allow_public_signup":{"type":"boolean","title":"Allow Public Signup","description":"True when POST /public/signup accepts this service_slug.","default":false}},"type":"object","required":["id","slug","name"],"title":"SignupServiceItem","description":"A service available for signup."},"SignupServicesResponse":{"properties":{"services":{"items":{"$ref":"#/components/schemas/SignupServiceItem"},"type":"array","title":"Services"}},"type":"object","required":["services"],"title":"SignupServicesResponse","description":"List of services available for signup."},"SubTenantCreateRequest":{"properties":{"name":{"type":"string","maxLength":100,"minLength":2,"title":"Name"},"slug":{"anyOf":[{"type":"string","maxLength":50,"minLength":2},{"type":"null"}],"title":"Slug"},"admin_email":{"anyOf":[{"type":"string","format":"email"},{"type":"null"}],"title":"Admin Email","description":"Email to send the admin invitation to"},"initial_services":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Initial Services","description":"Service slugs to subscribe the tenant to on creation"},"service_assignments":{"anyOf":[{"items":{"$ref":"#/components/schemas/ServiceAssignment"},"type":"array"},{"type":"null"}],"title":"Service Assignments","description":"Roles to assign the invited admin on each service"},"discount":{"anyOf":[{"$ref":"#/components/schemas/DiscountCreateRequest"},{"type":"null"}],"description":"Optional discount coupon to attach to the invitation"}},"type":"object","required":["name"],"title":"SubTenantCreateRequest","description":"POST /admin/tenants/{tenant_id}/subtenants request body.\n\nIf ``admin_email`` is provided, an invitation is sent to that address\nafter the sub-tenant is created, so the new tenant's admin can activate\ntheir account.\n\n``initial_services`` subscribes the new tenant to the default plan of each\nservice slug. ``service_assignments`` controls which roles the invited admin\nreceives (default: service.default_role if omitted)."},"SubTenantListItem":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"name":{"type":"string","title":"Name"},"slug":{"type":"string","title":"Slug"},"is_active":{"type":"boolean","title":"Is Active"},"can_create_subtenants":{"type":"boolean","title":"Can Create Subtenants","default":false},"created_at":{"type":"string","format":"date-time","title":"Created At"},"deleted_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Deleted At"},"user_count":{"type":"integer","title":"User Count"},"direct_children_count":{"type":"integer","title":"Direct Children Count"},"has_pending_invitation":{"type":"boolean","title":"Has Pending Invitation","default":false},"discount_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Discount Code"},"portal_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Portal Name"},"portal_logo_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Portal Logo Url"},"billing_email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Billing Email"}},"type":"object","required":["id","name","slug","is_active","created_at","user_count","direct_children_count"],"title":"SubTenantListItem","description":"Sub-tenant as returned in subtenant list."},"SubTenantListResponse":{"properties":{"tenant_id":{"type":"string","format":"uuid","title":"Tenant Id"},"tenant_name":{"type":"string","title":"Tenant Name"},"subtenants":{"items":{"$ref":"#/components/schemas/SubTenantListItem"},"type":"array","title":"Subtenants"}},"type":"object","required":["tenant_id","tenant_name","subtenants"],"title":"SubTenantListResponse","description":"GET /admin/tenants/{tenant_id}/subtenants response."},"SubTenantSummary":{"properties":{"sub_tenant_id":{"type":"string","format":"uuid","title":"Sub Tenant Id"},"sub_tenant_name":{"type":"string","title":"Sub Tenant Name"},"total_commission":{"type":"string","title":"Total Commission"},"currency":{"type":"string","title":"Currency"}},"type":"object","required":["sub_tenant_id","sub_tenant_name","total_commission","currency"],"title":"SubTenantSummary","description":"Commission summary for a single sub-tenant."},"SubTenantTreeResponse":{"properties":{"tenant":{"$ref":"#/components/schemas/TenantTreeNode"}},"type":"object","required":["tenant"],"title":"SubTenantTreeResponse","description":"GET /admin/tenants/{tenant_id}/tree response."},"SubscribeCheckoutResponse":{"properties":{"subscription_id":{"type":"string","format":"uuid","title":"Subscription Id"},"checkout_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Checkout Url"},"status":{"type":"string","title":"Status"},"trial_end":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Trial End"},"message":{"type":"string","title":"Message"}},"type":"object","required":["subscription_id","checkout_url","status","trial_end","message"],"title":"SubscribeCheckoutResponse","description":"Response after initiating a subscription — may include a checkout URL."},"SubscribeRequest":{"properties":{"plan_id":{"type":"string","format":"uuid","title":"Plan Id"},"redirect_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Redirect Url","description":"Redirect URL after checkout completion. Required for paid plans."}},"type":"object","required":["plan_id"],"title":"SubscribeRequest","description":"POST /admin/tenants/{tenant_id}/subscriptions request body (plan-based)."},"SubscribeServiceRequest":{"properties":{"plan_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Plan Id","description":"Plan ID to subscribe to. If omitted, uses the service's default_plan."},"redirect_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Redirect Url","description":"URL to redirect to after checkout (for paid plans)."}},"type":"object","title":"SubscribeServiceRequest","description":"Request body for self-service subscription."},"SubscriptionDiscountsResponse":{"properties":{"subscription_id":{"type":"string","format":"uuid","title":"Subscription Id"},"discounts":{"items":{"$ref":"#/components/schemas/DiscountDetail"},"type":"array","title":"Discounts"},"total":{"type":"integer","title":"Total"}},"type":"object","required":["subscription_id","discounts","total"],"title":"SubscriptionDiscountsResponse","description":"GET /me/subscriptions/{sid}/discounts response."},"SubscriptionRequest":{"properties":{"service_slug":{"type":"string","title":"Service Slug"}},"type":"object","required":["service_slug"],"title":"SubscriptionRequest","description":"POST /admin/tenants/{tid}/subscriptions request body."},"SubscriptionResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"tenant_id":{"type":"string","format":"uuid","title":"Tenant Id"},"plan_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Plan Id"},"plan_slug":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Plan Slug"},"plan_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Plan Name"},"service_slug":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Service Slug"},"service_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Service Name"},"plan_features":{"items":{"type":"string"},"type":"array","title":"Plan Features"},"price_amount":{"type":"integer","title":"Price Amount"},"price_currency":{"type":"string","title":"Price Currency"},"billing_interval":{"type":"string","title":"Billing Interval"},"status":{"type":"string","title":"Status"},"trial_start":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Trial Start"},"trial_end":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Trial End"},"current_period_start":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Current Period Start"},"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"},"dodo_subscription_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Dodo Subscription Id"},"dodo_customer_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Dodo Customer Id"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"metadata":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Metadata"}},"type":"object","required":["id","tenant_id","plan_id","plan_slug","plan_name","service_slug","service_name","plan_features","price_amount","price_currency","billing_interval","status","trial_start","trial_end","current_period_start","current_period_end","cancel_at_period_end","dodo_subscription_id","dodo_customer_id","created_at"],"title":"SubscriptionResponse","description":"Full subscription detail with plan + service information."},"SubscriptionStatusItem":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"plan_name":{"type":"string","title":"Plan Name"},"service_name":{"type":"string","title":"Service Name"},"status":{"type":"string","title":"Status"},"checkout_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Checkout Url"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","plan_name","service_name","status","created_at"],"title":"SubscriptionStatusItem","description":"Lightweight subscription status for the frontend banner."},"SubscriptionStatusResponse":{"properties":{"subscriptions":{"items":{"$ref":"#/components/schemas/SubscriptionStatusItem"},"type":"array","title":"Subscriptions"},"message":{"type":"string","title":"Message","default":"ok"}},"type":"object","required":["subscriptions"],"title":"SubscriptionStatusResponse","description":"Response for GET /me/subscriptions-status."},"SwitchTenantRequest":{"properties":{"tenant_id":{"type":"string","format":"uuid","title":"Tenant Id"}},"type":"object","required":["tenant_id"],"title":"SwitchTenantRequest","description":"POST /me/switch-tenant request body."},"SwitchTenantResponse":{"properties":{"access_token":{"type":"string","title":"Access Token"},"token_type":{"type":"string","title":"Token Type","default":"bearer"},"current_tenant_id":{"type":"string","format":"uuid","title":"Current Tenant Id"},"current_tenant_name":{"type":"string","title":"Current Tenant Name"}},"type":"object","required":["access_token","current_tenant_id","current_tenant_name"],"title":"SwitchTenantResponse","description":"POST /me/switch-tenant response."},"TenantChangePlanRequest":{"properties":{"new_plan_id":{"type":"string","format":"uuid","title":"New Plan Id"},"redirect_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Redirect Url","description":"Redirect URL after Dodo checkout completion. Required for paid plan changes."}},"type":"object","required":["new_plan_id"],"title":"TenantChangePlanRequest","description":"PATCH /tenants/{tid}/subscriptions/{sid}/change-plan request body."},"TenantCreateRequest":{"properties":{"name":{"type":"string","maxLength":100,"minLength":2,"title":"Name"},"slug":{"anyOf":[{"type":"string","maxLength":50,"minLength":2},{"type":"null"}],"title":"Slug"},"parent_tenant_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Parent Tenant Id"},"admin_email":{"anyOf":[{"type":"string","format":"email"},{"type":"null"}],"title":"Admin Email"},"initial_services":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Initial Services"},"can_create_subtenants":{"type":"boolean","title":"Can Create Subtenants","default":false}},"type":"object","required":["name"],"title":"TenantCreateRequest","description":"POST /admin/tenants request body."},"TenantDeactivateResponse":{"properties":{"tenant_id":{"type":"string","format":"uuid","title":"Tenant Id"},"deactivated_at":{"type":"string","format":"date-time","title":"Deactivated At"},"message":{"type":"string","title":"Message"}},"type":"object","required":["tenant_id","deactivated_at","message"],"title":"TenantDeactivateResponse","description":"Response for the tenant deactivation endpoint."},"TenantDeactivationCheck":{"properties":{"can_deactivate":{"type":"boolean","title":"Can Deactivate"},"has_active_users":{"type":"boolean","title":"Has Active Users"},"has_blocking_services":{"items":{"$ref":"#/components/schemas/BlockingService"},"type":"array","title":"Has Blocking Services"},"message":{"type":"string","title":"Message"}},"type":"object","required":["can_deactivate","has_active_users","has_blocking_services","message"],"title":"TenantDeactivationCheck","description":"Response for the deactivation status check endpoint."},"TenantListItem":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"name":{"type":"string","title":"Name"},"slug":{"type":"string","title":"Slug"},"parent_tenant_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Parent Tenant Id"},"parent_tenant_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Parent Tenant Name"},"is_active":{"type":"boolean","title":"Is Active"},"can_create_subtenants":{"type":"boolean","title":"Can Create Subtenants","default":false},"commission_rate":{"type":"string","title":"Commission Rate","default":"0"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"deleted_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Deleted At"},"user_count":{"type":"integer","title":"User Count"},"has_pending_invitation":{"type":"boolean","title":"Has Pending Invitation","default":false},"portal_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Portal Name"},"portal_logo_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Portal Logo Url"},"billing_email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Billing Email"}},"type":"object","required":["id","name","slug","parent_tenant_id","parent_tenant_name","is_active","created_at","user_count"],"title":"TenantListItem","description":"Tenant as returned in flat list."},"TenantListResponse":{"properties":{"items":{"items":{"$ref":"#/components/schemas/TenantListItem"},"type":"array","title":"Items"},"total":{"type":"integer","title":"Total"},"page":{"type":"integer","title":"Page"},"page_size":{"type":"integer","title":"Page Size"},"pages":{"type":"integer","title":"Pages"}},"type":"object","required":["items","total","page","page_size","pages"],"title":"TenantListResponse","description":"Paginated tenant list (flat format)."},"TenantPlanInfo":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"slug":{"type":"string","title":"Slug"},"name":{"type":"string","title":"Name"},"features":{"items":{"type":"string"},"type":"array","title":"Features"},"price_amount":{"type":"integer","title":"Price Amount"},"price_currency":{"type":"string","title":"Price Currency"},"billing_interval":{"type":"string","title":"Billing Interval"}},"type":"object","required":["id","slug","name","features","price_amount","price_currency","billing_interval"],"title":"TenantPlanInfo","description":"Plan details scoped to a tenant's active add-on.\n\nReturned to downstream services so they can apply plan-based quotas."},"TenantResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"name":{"type":"string","title":"Name"},"slug":{"type":"string","title":"Slug"},"parent_tenant_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Parent Tenant Id"},"parent_tenant_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Parent Tenant Name"},"is_active":{"type":"boolean","title":"Is Active"},"can_create_subtenants":{"type":"boolean","title":"Can Create Subtenants","default":false},"commission_rate":{"type":"string","title":"Commission Rate","default":"0"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"deleted_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Deleted At"},"user_count":{"type":"integer","title":"User Count"},"direct_children_count":{"type":"integer","title":"Direct Children Count"},"has_pending_invitation":{"type":"boolean","title":"Has Pending Invitation","default":false},"discount_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Discount Code"},"portal_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Portal Name"},"portal_logo_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Portal Logo Url"},"billing_email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Billing Email"}},"type":"object","required":["id","name","slug","parent_tenant_id","parent_tenant_name","is_active","created_at","user_count","direct_children_count"],"title":"TenantResponse","description":"Tenant as returned by a single-get or create."},"TenantServicesUpdateRequest":{"properties":{"services":{"items":{"type":"string","format":"uuid"},"type":"array","title":"Services"}},"type":"object","required":["services"],"title":"TenantServicesUpdateRequest","description":"PATCH /admin/tenants/{tenant_id}/services request body."},"TenantSubscriptionItem":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"status":{"type":"string","title":"Status"},"plan":{"$ref":"#/components/schemas/TenantPlanInfo"},"current_period_start":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Current Period Start"},"current_period_end":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Current Period End"},"trial_end":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Trial End"},"cancel_at_period_end":{"type":"boolean","title":"Cancel At Period End","default":false}},"type":"object","required":["id","status","plan"],"title":"TenantSubscriptionItem","description":"Subscription state for a tenant+service pair.\n\nCombines the per-service plan (the add-on) with the tenant's unified\nbilling-cycle state. Both views are needed: the plan tells a downstream\nservice which quotas to apply, and the subscription state tells them\nwhether the tenant is in good standing."},"TenantSubscriptionResponse":{"properties":{"tenant_id":{"type":"string","format":"uuid","title":"Tenant Id"},"subscription":{"$ref":"#/components/schemas/TenantSubscriptionItem"}},"type":"object","required":["tenant_id","subscription"],"title":"TenantSubscriptionResponse","description":"Response for GET /provisioning/services/{slug}/tenants/{tenant_id}/subscription."},"TenantSwitchInfo":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"name":{"type":"string","title":"Name"},"slug":{"type":"string","title":"Slug"},"is_home":{"type":"boolean","title":"Is Home"},"is_current":{"type":"boolean","title":"Is Current"},"can_manage":{"type":"boolean","title":"Can Manage"},"level":{"type":"integer","title":"Level"}},"type":"object","required":["id","name","slug","is_home","is_current","can_manage","level"],"title":"TenantSwitchInfo","description":"Tenant info in the switch list."},"TenantTreeNode":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"name":{"type":"string","title":"Name"},"slug":{"type":"string","title":"Slug"},"is_active":{"type":"boolean","title":"Is Active"},"can_create_subtenants":{"type":"boolean","title":"Can Create Subtenants","default":false},"created_at":{"type":"string","format":"date-time","title":"Created At"},"deleted_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Deleted At"},"user_count":{"type":"integer","title":"User Count"},"has_pending_invitation":{"type":"boolean","title":"Has Pending Invitation","default":false},"discount_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Discount Code"},"portal_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Portal Name"},"portal_logo_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Portal Logo Url"},"billing_email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Billing Email"},"children":{"items":{"$ref":"#/components/schemas/TenantTreeNode"},"type":"array","title":"Children"}},"type":"object","required":["id","name","slug","is_active","created_at","user_count","children"],"title":"TenantTreeNode","description":"A single node in the tenant tree response."},"TenantTreeResponse":{"properties":{"tenants":{"items":{"$ref":"#/components/schemas/TenantTreeNode"},"type":"array","title":"Tenants"}},"type":"object","required":["tenants"],"title":"TenantTreeResponse","description":"Tenant tree response (format=tree)."},"TenantUpdateRequest":{"properties":{"name":{"anyOf":[{"type":"string","maxLength":100,"minLength":2},{"type":"null"}],"title":"Name"},"slug":{"anyOf":[{"type":"string","maxLength":50,"minLength":2},{"type":"null"}],"title":"Slug"},"parent_tenant_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Parent Tenant Id"},"is_active":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Active"},"can_create_subtenants":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Can Create Subtenants"},"admin_email":{"anyOf":[{"type":"string","format":"email"},{"type":"null"}],"title":"Admin Email","description":"Email of the tenant admin to invite"},"services":{"anyOf":[{"items":{"type":"string","format":"uuid"},"type":"array"},{"type":"null"}],"title":"Services","description":"Replace tenant's subscribed services (service IDs)"},"portal_name":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"title":"Portal Name","description":"Custom portal display name"},"portal_logo_url":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Portal Logo Url","description":"Custom portal logo URL"},"billing_email":{"anyOf":[{"type":"string","maxLength":255,"format":"email"},{"type":"null"}],"title":"Billing Email","description":"Email address for billing/invoices"}},"type":"object","title":"TenantUpdateRequest","description":"PATCH /admin/tenants/{tenant_id} request body."},"TransactionItem":{"properties":{"id":{"type":"string","title":"Id"},"date":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Date"},"description":{"type":"string","title":"Description"},"amount":{"type":"integer","title":"Amount"},"currency":{"type":"string","title":"Currency"},"status":{"type":"string","title":"Status"},"invoice_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Invoice Url"}},"type":"object","required":["id","date","description","amount","currency","status"],"title":"TransactionItem","description":"A single payment transaction across all subscriptions."},"TransactionListResponse":{"properties":{"transactions":{"items":{"$ref":"#/components/schemas/TransactionItem"},"type":"array","title":"Transactions"},"total":{"type":"integer","title":"Total"}},"type":"object","required":["transactions","total"],"title":"TransactionListResponse","description":"GET /me/billing/transactions response — aggregated across all subscriptions."},"TransferListResponse":{"properties":{"items":{"items":{"$ref":"#/components/schemas/TransferResponse"},"type":"array","title":"Items"},"total":{"type":"integer","title":"Total"},"page":{"type":"integer","title":"Page"},"page_size":{"type":"integer","title":"Page Size"},"pages":{"type":"integer","title":"Pages"}},"type":"object","required":["items","total","page","page_size","pages"],"title":"TransferListResponse","description":"Paginated transfer list."},"TransferRequest":{"properties":{"amount":{"anyOf":[{"type":"number","exclusiveMinimum":0.0},{"type":"string"}],"title":"Amount","description":"Transfer amount"},"currency":{"type":"string","maxLength":3,"minLength":3,"title":"Currency","description":"Transfer currency (e.g. USD, EUR)"},"reference_number":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Reference Number","description":"Bank transfer reference / proof of payment"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes","description":"Optional admin notes about the transfer"},"transferred_at":{"type":"string","format":"date-time","title":"Transferred At","description":"When the transfer was made (external date)"}},"type":"object","required":["amount","currency","transferred_at"],"title":"TransferRequest","description":"POST /admin/partners/{partner_id}/transfers request body."},"TransferResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"partner_tenant_id":{"type":"string","format":"uuid","title":"Partner Tenant Id"},"partner_tenant_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Partner Tenant Name"},"amount":{"type":"string","title":"Amount"},"currency":{"type":"string","title":"Currency"},"reference_number":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reference Number"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"},"transferred_at":{"type":"string","format":"date-time","title":"Transferred At"},"created_by":{"type":"string","format":"uuid","title":"Created By"},"created_by_email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Created By Email"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","partner_tenant_id","amount","currency","transferred_at","created_by","created_at"],"title":"TransferResponse","description":"A single transfer record."},"UnifiedBillingResponse":{"properties":{"subscription_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Subscription Id"},"status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"},"services":{"items":{"$ref":"#/components/schemas/BillingServiceSummary"},"type":"array","title":"Services"},"total_monthly":{"type":"integer","title":"Total Monthly"},"total_monthly_formatted":{"type":"string","title":"Total Monthly Formatted"},"next_billing_date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Billing Date"},"has_payment_method":{"type":"boolean","title":"Has Payment Method"}},"type":"object","required":["subscription_id","status","services","total_monthly","total_monthly_formatted","next_billing_date","has_payment_method"],"title":"UnifiedBillingResponse","description":"GET /me/billing response — unified single-subscription billing summary."},"UpdateDodoIdRequest":{"properties":{"dodo_subscription_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Dodo Subscription Id"},"dodo_customer_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Dodo Customer Id"}},"type":"object","title":"UpdateDodoIdRequest","description":"PATCH /admin/tenants/{tenant_id}/subscriptions/{subscription_id}/dodo-id"},"UpdateLanguageRequest":{"properties":{"language":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Language","description":"Language code: 'en', 'es', 'pt-BR', or null to clear."}},"type":"object","title":"UpdateLanguageRequest","description":"PATCH /me/language request body."},"UpgradeUrlResponse":{"properties":{"redirect_url":{"type":"string","title":"Redirect Url"},"plan_slug":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Plan Slug"}},"type":"object","required":["redirect_url"],"title":"UpgradeUrlResponse","description":"Response for GET /me/services/{slug}/upgrade-url."},"UserCreateRequest":{"properties":{"email":{"type":"string","format":"email","title":"Email"},"password":{"type":"string","maxLength":128,"minLength":8,"title":"Password"},"is_active":{"type":"boolean","title":"Is Active","default":true}},"type":"object","required":["email","password"],"title":"UserCreateRequest","description":"POST /tenants/{tid}/users request body."},"UserInfoResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"email":{"type":"string","format":"email","title":"Email"},"tenant_id":{"type":"string","format":"uuid","title":"Tenant Id"},"tenant_slug":{"type":"string","title":"Tenant Slug"},"current_tenant_id":{"type":"string","format":"uuid","title":"Current Tenant Id"},"current_tenant_name":{"type":"string","title":"Current Tenant Name"},"is_active":{"type":"boolean","title":"Is Active"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"language":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Language"},"impersonator_email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Impersonator Email"},"email_verified":{"type":"boolean","title":"Email Verified","default":true}},"type":"object","required":["id","email","tenant_id","tenant_slug","current_tenant_id","current_tenant_name","is_active","created_at"],"title":"UserInfoResponse","description":"GET /me response."},"UserListResponse":{"properties":{"items":{"items":{"$ref":"#/components/schemas/UserResponse"},"type":"array","title":"Items"},"total":{"type":"integer","title":"Total"},"page":{"type":"integer","title":"Page"},"page_size":{"type":"integer","title":"Page Size"},"pages":{"type":"integer","title":"Pages"}},"type":"object","required":["items","total","page","page_size","pages"],"title":"UserListResponse","description":"Paginated user list."},"UserResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"email":{"type":"string","format":"email","title":"Email"},"tenant_id":{"type":"string","format":"uuid","title":"Tenant Id"},"tenant_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tenant Name"},"is_active":{"type":"boolean","title":"Is Active"},"deleted_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Deleted At"},"roles":{"items":{"$ref":"#/components/schemas/RoleInfo"},"type":"array","title":"Roles"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["id","email","tenant_id","is_active","created_at","updated_at"],"title":"UserResponse","description":"User as returned by the API."},"UserRolesResponse":{"properties":{"user_id":{"type":"string","format":"uuid","title":"User Id"},"roles":{"items":{"$ref":"#/components/schemas/RoleAssignment"},"type":"array","title":"Roles"}},"type":"object","required":["user_id","roles"],"title":"UserRolesResponse","description":"GET /tenants/{tid}/users/{uid}/roles response."},"UserSubscriptionsResponse":{"properties":{"tenant_id":{"type":"string","format":"uuid","title":"Tenant Id"},"tenant_name":{"type":"string","title":"Tenant Name"},"subscriptions":{"items":{"$ref":"#/components/schemas/SubscriptionResponse"},"type":"array","title":"Subscriptions"}},"type":"object","required":["tenant_id","tenant_name","subscriptions"],"title":"UserSubscriptionsResponse","description":"GET /me/subscriptions response — all subscriptions for current user's tenant."},"UserUpdateRequest":{"properties":{"email":{"anyOf":[{"type":"string","format":"email"},{"type":"null"}],"title":"Email"},"is_active":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Active"}},"type":"object","title":"UserUpdateRequest","description":"PATCH /tenants/{tid}/users/{uid} request body."},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"},"VerifyEmailRequest":{"properties":{"token":{"type":"string","maxLength":2000,"minLength":10,"title":"Token"}},"type":"object","required":["token"],"title":"VerifyEmailRequest","description":"POST /auth/verify-email request body."},"WebhookConfig":{"properties":{"webhook_url":{"anyOf":[{"type":"string","maxLength":2083,"minLength":1,"format":"uri"},{"type":"null"}],"title":"Webhook Url","description":"HTTPS endpoint to POST events to. Required to enable outbound webhooks."},"webhook_secret":{"anyOf":[{"type":"string","maxLength":128,"minLength":16},{"type":"null"}],"title":"Webhook Secret","description":"HMAC-SHA256 signing key. If omitted on create, UUM generates a 32-byte random secret and returns it in the response (shown once — store it securely)."},"webhook_events":{"items":{"type":"string"},"type":"array","title":"Webhook Events","description":"Event types to receive. Empty list = all events. Supported: subscription.created, subscription.updated, subscription.canceled, payment.failed."}},"type":"object","title":"WebhookConfig","description":"Outbound webhook configuration for a service.\n\n``webhook_url`` must be HTTPS (HMAC signatures are useless on plaintext\nchannels). ``webhook_secret`` is generated by UUM and shown to the\nsuper-admin once; the receiving service uses it to verify the\n``X-UUM-Webhook-Signature`` header. ``webhook_events`` is the allowlist\nof event types the service wants to receive; an empty list means\n\"all events\" (UUM's default for any new listener)."},"WebhookSecretResponse":{"properties":{"webhook_secret":{"type":"string","title":"Webhook Secret"},"webhook_url":{"anyOf":[{"type":"string","maxLength":2083,"minLength":1,"format":"uri"},{"type":"null"}],"title":"Webhook Url"},"webhook_events":{"items":{"type":"string"},"type":"array","title":"Webhook Events"},"message":{"type":"string","title":"Message","default":"Store this secret securely. It will not be shown again. Configure it on the receiving service to verify X-UUM-Webhook-Signature."}},"type":"object","required":["webhook_secret"],"title":"WebhookSecretResponse","description":"Response after rotating or generating a webhook secret — shown once."}}},"tags":[{"name":"public-agents","description":"Machine-readable onboarding guide for AI agents."},{"name":"public-signup","description":"Create an organization + admin user. No auth."},{"name":"public-signup-config","description":"Plans and branding of a service signup. No auth."},{"name":"auth","description":"Login, refresh, logout, invitations, password reset."},{"name":"me","description":"Current user, tenant, subscriptions and billing."}]}