/** * Consolidated event definitions coming from the frontend, including studio, www, and docs. * * Note that events are not emitted for users that have opted out of telemetry. * * ## Naming conventions * Event names and actions should use standardized past-tense verbs for data quality and consistency. * Only use verbs already established in this file or in https://github.com/supabase/platform/blob/develop/packages/api-core/src/shared/telemetry.ts * Adding new verbs requires @growth-eng review to prevent data pollution. * * @module telemetry-frontend */ import type { components } from 'api-types' export type TelemetryGroups = { project: string organization: string } export const TABLE_EVENT_ACTIONS = { TableCreated: 'table_created', TableDataAdded: 'table_data_added', TableRLSEnabled: 'table_rls_enabled', } as const satisfies { TableCreated: TableCreatedEvent['action'] TableDataAdded: TableDataAddedEvent['action'] TableRLSEnabled: TableRlsEnabledEvent['action'] } export type TableEventAction = (typeof TABLE_EVENT_ACTIONS)[keyof typeof TABLE_EVENT_ACTIONS] export const TABLE_EVENT_VALUES: TableEventAction[] = Object.values(TABLE_EVENT_ACTIONS) /** * Triggered when a user signs up. When signing up with Email and Password, this is only triggered once user confirms their email. * * @group Events * @source studio * @page /sign-up */ export interface SignUpEvent { action: 'sign_up' properties: { category: 'conversion' } } /** * Triggered when a user signs in with an OAuth provider, Email and Password, or SSO. * * Some unintuitive behavior: * - If signing up with GitHub the SignInEvent gets triggered first before the SignUpEvent. * - distinct_id often resolves to the anonymous cookie (races identify); not a person-level join key. * * @group Events * @source studio * @page /sign-in, /sign-in-mfa */ export interface SignInEvent { action: 'sign_in' properties: { category: 'account' /** * The method used to sign in, e.g. email, github, sso */ method: string } } /** * Triggered when a user initiates a sign-in (form submit including client-side validation * failures, OAuth or custom-provider click, partner token exchange), before auth resolves. * Pre-auth, so distinct_id is the anonymous cookie: not a person-level join key. * * @group Events * @source studio * @page /sign-in, /sign-in-sso, /sign-in-partner */ export interface SignInSubmittedEvent { action: 'sign_in_submitted' properties: { category: 'account' /** * Matches the sign_in event's method vocabulary, e.g. email (password path), github, sso */ method: string } } /** * User copied the database connection string. * * @group Events * @source studio */ export interface ConnectionStringCopiedEvent { action: 'connection_string_copied' properties: { /** * Method selected by user, e.g. URI, PSQL, SQLAlchemy, MCP URL, Framework snippet, Command Line, JSON, etc. * Required for Connection String, App Frameworks, and Mobile Frameworks tabs */ connectionType?: string /** * Language of the code block if selected, e.g. bash, go, http, typescript * Required for Connection String, App Frameworks, and Mobile Frameworks tabs */ lang?: string /** * Connection Method, e.g. direct, transaction_pooler, session_pooler * Only used for Connection String tab */ connectionMethod?: 'direct' | 'transaction_pooler' | 'session_pooler' /** * Tab from which the connection string was copied */ connectionTab: 'Connection String' | 'App Frameworks' | 'Mobile Frameworks' | 'ORMs' | 'MCP' /** * Selected framework, tool, or client (e.g., 'Next.js', 'Prisma', 'Cursor') */ selectedItem?: string /** * Source of the event, either 'studio' or 'docs' */ source?: 'studio' | 'docs' } groups: TelemetryGroups } /** * User clicked the MCP install button (one-click installation for Cursor or VS Code). * * @group Events * @source studio, docs */ export interface McpInstallButtonClickedEvent { action: 'mcp_install_button_clicked' properties: { /** * The MCP client that was selected (e.g., 'Cursor', 'VS Code') */ client: string /** * Source of the event, either 'studio' or 'docs' */ source?: 'studio' | 'docs' } groups: TelemetryGroups } /** * Cron job created. * * @group Events * @source studio * @page /dashboard/project/{ref}/integrations/cron/jobs?new=true */ export interface CronJobCreatedEvent { action: 'cron_job_created' properties: { /** * What the cron job executes, e.g. sql_function or sql_snippet */ type: 'sql_function' | 'sql_snippet' | 'edge_function' | 'http_request' /** * Schedule of the cron job in the format of * * * * * */ schedule: string } groups: TelemetryGroups } /** * Cron job updated. * * @group Events * @source studio * @page /dashboard/project/{ref}/integrations/cron/jobs?new=true */ export interface CronJobUpdatedEvent { action: 'cron_job_updated' properties: { /** * What the cron job executes, e.g. sql_function or sql_snippet */ type: 'sql_function' | 'sql_snippet' | 'edge_function' | 'http_request' /** * Schedule of the cron job in the format of * * * * * */ schedule: string } groups: TelemetryGroups } /** * Cron job removed. Previously: cron_job_deleted * * @group Events * @source studio * @page /dashboard/project/{ref}/integrations/cron/jobs */ export interface CronJobRemovedEvent { action: 'cron_job_removed' properties: { /** Cron job classification, parsed from the job's command at deletion time. */ type: 'sql_function' | 'sql_snippet' | 'edge_function' | 'http_request' } groups: TelemetryGroups } /** * Create job button clicked that opens the dialog. * * @group Events * @source studio * @page /dashboard/project/{ref}/integrations/cron/jobs */ export interface CronJobCreateClickedEvent { action: 'cron_job_create_clicked' groups: TelemetryGroups } /** * Edit cron job button (hidden in the dropdown) clicked that opens the dialog. * * @group Events * @source studio * @page /dashboard/project/{ref}/integrations/cron/jobs */ export interface CronJobUpdateClickedEvent { action: 'cron_job_update_clicked' groups: TelemetryGroups } /** * Delete cron job button (hidden in the dropdown) clicked that opens the deletion confirmation modal. * * @group Events * @source studio * @page /dashboard/project/{ref}/integrations/cron/jobs */ export interface CronJobDeleteClickedEvent { action: 'cron_job_delete_clicked' groups: TelemetryGroups } /** * User clicked the history button to see previous runs of the cron job * * @group Events * @source studio * @page /dashboard/project/{ref}/integrations/cron/jobs */ export interface CronJobHistoryClickedEvent { action: 'cron_job_history_clicked' groups: TelemetryGroups } /** * Fired when the user clicks the header 'Enable cleanup' button to open the * confirmation dialog. * * @group Events * @source studio * @page /dashboard/project/{ref}/integrations/cron/jobs */ export interface CronJobCleanupDialogOpenedEvent { action: 'cron_job_cleanup_dialog_opened' groups: TelemetryGroups } /** * Fired when the user confirms the cleanup dialog, initiating the request to * schedule the daily cleanup job (deletes old rows from cron.job_run_details). * Emitted on confirm, before the scheduling request resolves, so it does not * indicate the job was scheduled successfully. * * @group Events * @source studio * @page /dashboard/project/{ref}/integrations/cron/jobs */ export interface CronJobCleanupEnableButtonClickedEvent { action: 'cron_job_cleanup_enable_button_clicked' properties: { /** Retention period chosen for the cleanup job, e.g. 7 days. */ retentionInterval?: string } groups: TelemetryGroups } /** * A feature preview was enabled by the user through the FeaturePreviewModal. * * The FeaturePreviewModal can be opened clicking at the profile icon at the bottom left corner of the project sidebar. * * @group Events * @source studio */ export interface FeaturePreviewEnabledEvent { action: 'feature_preview_enabled' properties: { /** * Feature key of the preview that was enabled. e.g. supabase-ui-api-side-panel */ feature: string } groups: TelemetryGroups } /** * A feature preview was disabled by the user through the FeaturePreviewModal. * * The FeaturePreviewModal can be opened clicking at the profile icon at the bottom left corner of the project sidebar. * * @group Events * @source studio */ export interface FeaturePreviewDisabledEvent { action: 'feature_preview_disabled' properties: { /** * Feature key of the preview that was disabled. e.g. supabase-ui-api-side-panel */ feature: string } groups: TelemetryGroups } /** * The user picked a timezone in the dashboard timezone picker (in the user * avatar dropdown). Setting an explicit IANA value or returning to the auto * detected default both fire this event. * * @group Events * @source studio */ export interface TimezonePickerClickedEvent { action: 'timezone_picker_clicked' properties: { /** IANA name resolved before the change. */ previousTimezone: string /** IANA name resolved after the change. */ nextTimezone: string /** True when the user opted back into the browser-detected default. */ isAutoDetected: boolean /** Where the picker was rendered. */ source: 'user_dropdown' | 'account_preferences' } groups: TelemetryGroups } /** * Top-of-funnel event for the dataApiRevokeOnCreateDefault rollout. Fires once per * mount after the flag resolves so cohort attribution is clean — pair with * project_creation_simple_version_submitted to measure the flag's impact on * project creation completion rate. * * @group Events * @source studio * @page new/{slug} and /integrations/vercel/{slug}/deploy-button/new-project */ export interface ProjectCreationDefaultPrivilegesExposedEvent { action: 'project_creation_default_privileges_exposed' properties: { /** Where the checkbox was shown. */ surface: 'main' | 'vercel' /** * Current state of the "Automatically expose new tables" checkbox * (`dataApiDefaultPrivileges` form field) at exposure time. This is the * field the experiment actually controls. * true = default privileges granted (legacy behaviour) * false = revoke SQL runs on create (new behaviour, treatment default) */ dataApiDefaultPrivileges: boolean /** * Raw value of the dataApiRevokeOnCreateDefault PostHog flag at exposure time. * Accepts boolean (current rollout shape) or string (post-multivariate-migration * variant name, e.g. 'test' / 'control'). See GROWTH-877 for the migration plan. * true | 'test' = revoke cohort (checkbox defaulted to unchecked) * false = outside the rollout (checkbox defaulted to checked) * 'control' = in-experiment control arm (checkbox defaulted to checked) */ dataApiRevokeOnCreateDefaultEnabled: boolean | string } groups: Omit } /** * Project creation form was submitted and the project was created. Fires from both * the main project creation wizard and the Vercel deploy-button flow — disambiguate * by the `surface` property. * * @group Events * @source studio * @page new/{slug} and /integrations/vercel/{slug}/deploy-button/new-project */ export interface ProjectCreationSimpleVersionSubmittedEvent { action: 'project_creation_simple_version_submitted' properties: { /** * Which surface produced the submission. Omitted on events emitted before this * property was introduced; treat absent as 'main' for backfill. */ surface?: 'main' | 'vercel' /** * The instance size selected in the project creation form. */ instanceSize?: string /** * Whether the automatic RLS event trigger option was enabled */ enableRlsEventTrigger?: boolean /** * Experiment variant: 'control' (checkbox not shown) or 'test' (checkbox shown) */ rlsOptionVariant?: 'control' | 'test' /** * Whether Data API is enabled. * true = "Data API + Connection String" (default) * false = "Only Connection String" */ dataApiEnabled?: boolean /** * Data API schema configuration. Only relevant when dataApiEnabled is true. * true = "Use dedicated API schema for Data API" * false = "Use public schema for Data API" (default) */ useApiSchema?: boolean /** * Postgres engine type selection. * true = "Postgres with OrioleDB" (beta) * false = "Postgres" (default) */ useOrioleDb?: boolean /** * Raw checkbox state for "Automatically expose new tables and functions" at submission. * true = default privileges are granted on new entities (current behaviour) * false = revoke SQL ran; user must manually grant access per entity */ dataApiDefaultPrivilegesGranted?: boolean /** * Raw value of the dataApiRevokeOnCreateDefault PostHog flag at submission time. * Controls only the default checkbox state of "Automatically expose new tables and functions" * at project creation. Tracking it lets us correlate flag cohort with user choice. * Accepts boolean (current rollout shape) or string (post-multivariate-migration * variant name, e.g. 'test' / 'control'). See GROWTH-877 for the migration plan. * true | 'test' = user is in the treatment arm (checkbox defaulted to unchecked) * false = user is outside the rollout (checkbox defaulted to checked) * 'control' = in-experiment control arm (checkbox defaulted to checked) * omitted = PostHog flags had not loaded at the time of project creation */ dataApiRevokeOnCreateDefaultEnabled?: boolean | string /** * Which region option was submitted. Only present for the region-recommendation experiment's * eligible cohort (free plan + `project_creation:show_best_available_region` feature enabled — * see `shouldTrackRegionRecommendation` in ProjectCreationForm.tsx). This is cohort-level * eligibility, not "the option was shown" — it's present for both the PostHog flag's control * and test arms so the two can be compared; omitted entirely outside the cohort (e.g. paid * plans, or providers like AWS_NIMBUS where the feature is disabled). * 'best_available' = the "Best available region" shortcut was used * otherwise = the name of the region that was directly selected (e.g. 'Americas', 'ap-southeast-1') */ selectedRegionOption?: string /** * Which region list `selectedRegionOption` came from. Only present alongside `selectedRegionOption`. * 'general' = picked from the "General regions" (smart group) list, or the "Best available * region" shortcut was used (it always resolves to a general/smart region) * 'specific' = picked from the "Specific regions" list */ selectedRegionOptionType?: 'general' | 'specific' /** * The region that was recommended/defaulted to on initial render, before any user * interaction. Present under the same cohort gate as `selectedRegionOption`. Frozen the * first time it's known, so a later refetch (e.g. switching cloud provider or instance size) * doesn't overwrite what was actually shown to the user initially. * 'best_available' = the user was in the PostHog flag's test arm, so the form defaulted to * the "Best available region" shortcut * otherwise = the name of the smart-group region recommended by the `available-regions` * endpoint (e.g. 'Americas'), for users in the flag's control arm * undefined = no recommendation had loaded yet at submission time */ initialRecommendedRegion?: string } groups: TelemetryGroups } /** * User clicked to connect GitHub during project creation. * * @group Events * @source studio * @page new/{slug} */ export interface ProjectCreationGithubConnectClickedEvent { action: 'project_creation_github_connect_clicked' groups: Omit } /** * Existing project creation form confirm modal was triggered and opened. * * @group Events * @source studio * @page new/{slug} */ export interface ProjectCreationSimpleVersionConfirmModalOpenedEvent { action: 'project_creation_simple_version_confirm_modal_opened' /** * the instance size selected in the project creation form */ properties: { instanceSize?: string } groups: Omit } /** * Project creation form was rendered and shown to the user. Passive impression that * anchors the project-creation funnel (exposed -> completed). Fires once per form view, * after the org and create-project permission have resolved, so it tracks the form * actually being visible rather than the route loading. Disambiguate by `surface`. * Completion is measured by `project_creation_simple_version_submitted` (which fires * client-side on the create success callback). * * @group Events * @source studio * @page new/{slug} */ export interface ProjectCreationFormExposedEvent { action: 'project_creation_form_exposed' properties: { /** * Which surface rendered the form. 'main' is the standard project creation wizard. */ surface?: 'main' | 'vercel' } groups: Omit } /** * New-organization form was rendered and shown to the user. Passive impression that * anchors the organization-creation funnel (exposed -> completed). Fires once per form * view, after the user's profile has resolved (i.e. an authenticated session), so it * does not count pre-auth redirects. No organization group: the org does not exist yet * at this point in the flow. * * @group Events * @source studio * @page new */ export interface OrganizationCreationFormExposedEvent { action: 'organization_creation_form_exposed' } /** * Organization was created and the new org slug is available client-side. Fires from the * create success callback (both the free path and the paid path that confirms a pending * payment intent), so org-creation completion is measurable from frontend events without * relying on the backend `organization_created` event (which fires across all surfaces). * Closes the organization-creation funnel (exposed -> completed). * * @group Events * @source studio * @page new */ export interface OrganizationCreationCompletedEvent { action: 'organization_creation_completed' properties: { /** * Billing tier provisioned at creation. tier_payg is uncapped PRO. */ tier: 'tier_free' | 'tier_pro' | 'tier_payg' | 'tier_team' } groups: Omit } /** * User toggled Data API access on a table via the switch in the table editor side panel. * Only fires for new tables — editing existing tables links out to the settings page instead. * * @group Events * @source studio * @page /dashboard/project/{ref}/editor */ export interface TableApiAccessToggleClickedEvent { action: 'table_api_access_toggle_clicked' properties: { /** * The resulting state of the toggle after the click. */ newState: 'enabled' | 'disabled' /** * The schema containing the table being created. */ schemaName: string } groups: TelemetryGroups } /** * User clicked either "Listening to channel" or "Start listening" button after selecting a channel. * * @group Events * @source studio * @page /dashboard/project/{ref}/realtime/inspector */ export interface RealtimeInspectorListenChannelClickedEvent { action: 'realtime_inspector_listen_channel_clicked' groups: TelemetryGroups } /** * A broadcast message was sent from the SendMessageModal. * * @group Events * @source studio * @page /dashboard/project/{ref}/realtime/inspector */ export interface RealtimeInspectorBroadcastSentEvent { action: 'realtime_inspector_broadcast_sent' groups: TelemetryGroups } /** * User clicked a message in the RealtimeInspector, which opens a sidebar that shows the messsage details including metadata. * * @group Events * @source studio * @page /dashboard/project/{ref}/realtime/inspector */ export interface RealtimeInspectorMessageClickedEvent { action: 'realtime_inspector_message_clicked' groups: TelemetryGroups } /** * A message was copied from the RealtimeInspector. * * @group Events * @source studio * @page /dashboard/project/{ref}/realtime/inspector */ export interface RealtimeInspectorCopyMessageClickedEvent { action: 'realtime_inspector_copy_message_clicked' groups: TelemetryGroups } /** * Filters were applied in the RealtimeInspector. * * @group Events * @source studio * @page /dashboard/project/{ref}/realtime/inspector */ export interface RealtimeInspectorFiltersAppliedEvent { action: 'realtime_inspector_filters_applied' groups: TelemetryGroups } /** * Database role was updated in the RealtimeInspector. * * @group Events * @source studio * @page /dashboard/project/{ref}/realtime/inspector */ export interface RealtimeInspectorDatabaseRoleUpdatedEvent { action: 'realtime_inspector_database_role_updated' groups: TelemetryGroups } /** * User clicked to toggle realtime on a table. * * @group Events * @source studio * @page /dashboard/project/{ref}/editor */ export interface RealtimeToggleTableClickedEvent { action: 'realtime_toggle_table_clicked' properties: { /** * The state of the toggle. */ newState: 'enabled' | 'disabled' /** * Where the toggle was clicked from */ origin: 'tableSidePanel' | 'tableGridHeader' } groups: TelemetryGroups } /** * Realtime was enabled on a table. * * @group Events * @source studio * @page /dashboard/project/{ref}/editor */ export interface TableRealtimeEnabledEvent { action: 'table_realtime_enabled' properties: { /** * The method used to enable realtime */ method: 'ui' | 'sql_editor' | 'api' /** * Schema name */ schema_name: string /** * Table name */ table_name: string } groups: TelemetryGroups } /** * Realtime was disabled on a table. * * @group Events * @source studio * @page /dashboard/project/{ref}/editor */ export interface TableRealtimeDisabledEvent { action: 'table_realtime_disabled' properties: { /** * The method used to disable realtime */ method: 'ui' | 'sql_editor' | 'api' /** * Schema name */ schema_name: string /** * Table name */ table_name: string } groups: TelemetryGroups } /** * User clicked the quickstart card in the SQL editor. * * @group Events * @source studio * @page /dashboard/project/{ref}/sql */ export interface SqlEditorQuickstartClickedEvent { action: 'sql_editor_quickstart_clicked' properties: { /** * The title of the quickstart card clicked. */ quickstartName: string } groups: TelemetryGroups } /** * User clicked the template card in the SQL editor. * * @group Events * @source studio * @page /dashboard/project/{ref}/sql */ export interface SqlEditorTemplateClickedEvent { action: 'sql_editor_template_clicked' properties: { /** * The name of the template card clicked. */ templateName: string } groups: TelemetryGroups } /** * User clicked the "Disable" button next to the autosave status text in the * SQL Editor, to open the feature preview modal for manual snippet saving. * * @group Events * @source studio * @page /dashboard/project/{ref}/sql/{id} */ export interface SqlEditorAutosaveDisableClickedEvent { action: 'sql_editor_autosave_disable_clicked' groups: TelemetryGroups } /** * User clicked the "Result download CSV" button in the SQL editor. * * @group Events * @source studio * @page /dashboard/project/{ref}/sql */ export interface SqlEditorResultDownloadCsvClickedEvent { action: 'sql_editor_result_download_csv_clicked' groups: TelemetryGroups } /** * User clicked the "Result copy Markdown" button in the SQL editor. * * @group Events * @source studio * @page /dashboard/project/{ref}/sql */ export interface SqlEditorResultCopyMarkdownClickedEvent { action: 'sql_editor_result_copy_markdown_clicked' groups: TelemetryGroups } /** * User clicked the "Result copy JSON" button in the SQL editor * * @group Events * @source studio * @page /dashboard/project/{ref}/sql */ export interface SqlEditorResultCopyJsonClickedEvent { action: 'sql_editor_result_copy_json_clicked' groups: TelemetryGroups } /** * User clicked the "Result copy CSV" button in the SQL editor * * @group Events * @source studio * @page /dashboard/project/{ref}/sql */ export interface SqlEditorResultCopyCsvClickedEvent { action: 'sql_editor_result_copy_csv_clicked' groups: TelemetryGroups } /** * User submitted a prompt to the assistant sidebar. * * @group Events * @source studio */ export interface AssistantPromptSubmittedEvent { action: 'assistant_prompt_submitted' properties: { /** UUID of the chat session in which the prompt was submitted */ chatId?: string } groups: TelemetryGroups } /** * User submitted a debug request to the assistant sidebar or prompt submitted has Help me to debug. * * @group Events * @source studio */ export interface AssistantDebugSubmittedEvent { action: 'assistant_debug_submitted' properties: { /** UUID of the chat session in which the debug request was submitted */ chatId?: string } groups: TelemetryGroups } /** * User clicked the run query button in the suggestion provided in the assistant sidebar. * * @group Events * @source studio */ export interface AssistantSuggestionRunQueryClickedEvent { action: 'assistant_suggestion_run_query_clicked' properties: { /** * The type of suggestion that was run by the user. Mutate or Select query types only. */ queryType: string /** * For mutation queries only: the DDL subtype detected from the SQL. * 'functions' for CREATE FUNCTION / CREATE OR REPLACE FUNCTION, * 'rls-policies' for CREATE POLICY / ALTER POLICY, * 'unknown' for any other mutation. Omitted for non-mutation queries. */ mutationType?: 'functions' | 'rls-policies' | 'unknown' } groups: TelemetryGroups } /** * User accepted or rejected changes in sql ai diff handler. * They can accept change by clicking accept button or typing shortcut (CMD+Enter) or reject by clicking reject button or typing shortcut (Esc). * Handler only appears after clicking any dropdown option in Edit in Sql Editor in suggestion provided by the assistant. * The dropdown options only appear in any page with 'sql' in url. * * @group Events * @source studio * @page /dashboard/project/{ref}/sql */ export interface AssistantSqlDiffHandlerEvaluatedEvent { action: 'assistant_sql_diff_handler_evaluated' properties: { /** * Whether the user accepted or rejected the changes. */ handlerAccepted: boolean } groups: TelemetryGroups } /** * User clicked Edit in SQL Editor button in the assistant sidebar when user is in any page that does not have 'sql' in url or is in a new snippet. * * @group Events * @source studio */ export interface AssistantEditInSqlEditorClickedEvent { action: 'assistant_edit_in_sql_editor_clicked' properties: { /** * Whether the user is in the SQL editor page or in a new snippet. */ isInSQLEditor: boolean isInNewSnippet: boolean } groups: TelemetryGroups } /** * User clicked on Add block -> SQL Snippets -> a SQL snippet in a custom reports page. * * @group Events * @source studio * @page /dashboard/project/{ref}/reports/{id} */ export interface CustomReportAddSqlBlockClickedEvent { action: 'custom_report_add_sql_block_clicked' groups: TelemetryGroups } /** * User dragged and dropped a SQL block from the Assistant Panel into the custom report while on a custom report page. * * @group Events * @source studio * @page /dashboard/project/{ref}/reports/{id} */ export interface CustomReportAssistantSqlBlockAddedEvent { action: 'custom_report_assistant_sql_block_added' groups: TelemetryGroups } /** * User voted on the feedback button on a docs page. The feedback button is located at the sidebar of every docs page. * * @group Events * @source docs */ export interface DocsFeedbackClickedEvent { action: 'docs_feedback_clicked' properties: { /** * 'yes' means clicking on the tick button, 'no' means clicking on the cross button. */ response: 'yes' | 'no' } } export type MarkdownAffordancePageType = | 'blog' | 'customers' | 'events' | 'pricing' | 'changelog' | 'guide' /** * User clicked 'Copy as Markdown' on a page and the markdown was copied successfully. * Fires on success only; failed fetch/clipboard writes are not counted. * * @group Events * @source www, docs */ export interface CopyAsMarkdownClickedEvent { action: 'copy_as_markdown_clicked' properties: { /** * Page class the affordance sits on. */ pageType: MarkdownAffordancePageType } } /** * User clicked the sidebar link to set up an AI coding agent with Supabase. * * @group Events * @source docs */ export interface AgentSetupClickedEvent { action: 'agent_setup_clicked' } /** * User clicked "Ask..." to open a new window to consult an agent about the current page. * * @group Events * @source www, docs */ export interface AskAiClickedEvent { action: 'ask_ai_clicked' properties: { agent: 'chatgpt' | 'claude' /** * Page class the affordance sits on. */ pageType: MarkdownAffordancePageType } } /** * Surface that rendered the prompt panel a user copied from. */ export type DocsAiPromptSource = 'homepage' | 'guide' | 'agent_setup' /** * User copied the contents of a docs prompt panel - the homepage setup card or an * `AiPrompt` block - and the clipboard write succeeded. Fires on success only; * failed clipboard writes are not counted. * * Distinct from `ai_prompt_copied`, which belongs to Studio's AI assistant. * * @group Events * @source docs * @page /docs, /docs/guides */ export interface DocsAiPromptCopiedEvent { action: 'docs_ai_prompt_copied' properties: { /** * Surface the panel was rendered on. */ source: DocsAiPromptSource /** * `value` of the pane that was active when the copy happened. Known panes * are `prompt` and `cli`; other strings remain allowed for future panes. */ tab: 'prompt' | 'cli' | (string & {}) /** * Prompt identifier, set when the panel comes from an `AiPrompt` block. */ promptId?: string } } /** * User clicked a curated orientation link from a content listings MDX component. * * @group Events * @source docs */ export interface DocsContentListingClickedEvent { action: 'docs_content_listing_clicked' properties: { targetPath: string linkTitle: string groupTitle?: string listingId?: string } } /** * User clicked a recommended page card shown on a docs "not found" page. * * @group Events * @source docs */ export interface Docs404RecommendationClickedEvent { action: 'docs_404_recommendation_clicked' properties: { /** * The path of the recommended page that was clicked. */ destinationPath: string /** * The path of the "not found" page where the recommendation was shown. */ sourcePath: string } } /** * User clicked the copy button on a project config variable in the docs. * * @group Events * @source docs */ export interface DocsProjectConfigVariablesCopyButtonClickedEvent { action: 'docs_project_config_variables_copy_button_clicked' properties: { variable: 'url' | 'publishable' | 'anon' | 'sessionPooler' } } /** * User clicked the framework quickstart card on the homepage, leading to the specific framework documentation. * * @group Events * @source www * @page / */ export interface HomepageFrameworkQuickstartClickedEvent { action: 'homepage_framework_quickstart_clicked' properties: { /** * The name of the framework quickstart card clicked. */ frameworkName: string } } /** * User clicked on a product card in the homepage products section. * * @group Events * @source www * @page / */ export interface HomepageProductCardClickedEvent { action: 'homepage_product_card_clicked' properties: { product: string } } /** * User clicked on the CTA button on a plan in the pricing page. * * @group Events * @source www * @page /pricing */ export interface WwwPricingPlanCtaClickedEvent { action: 'www_pricing_plan_cta_clicked' properties: { /** * The plan type that was clicked. */ plan: string /** * Whether the upgrade now text is shown on the cta button. This is only shown when org is upgradeable and user is logged in. */ showUpgradeText: boolean /** * The section of the page where the plan was clicked. * Main means the big top section of the page, * comparison_table means the comparison table with all plans listed together below. */ section: 'main' | 'comparison_table' tableMode?: 'mobile' | 'desktop' } groups?: Partial } /** * User clicked the main CTA button in an event page. * * @group Events * @source www * @page /events/* */ export interface WwwEventPageCtaClickedEvent { action: 'www_event_page_cta_clicked' properties: { /** * The title of the event clicked. */ eventTitle: string } } /** * User successfully subscribed to subprocessor list update notifications. * * @group Events * @source www * @page /legal/customer-resources/subprocessor-list */ export interface WwwSubprocessorUpdatesSubscribedEvent { action: 'www_subprocessor_updates_subscribed' } /** * User clicked the GitHub button in the homepage header section. The button is hidden in mobile view. * * @group Events * @source www * @page / */ export interface HomepageGithubButtonClickedEvent { action: 'homepage_github_button_clicked' } /** * User clicked the Discord button in the homepage community section. * * @group Events * @source www * @page / */ export interface HomepageDiscordButtonClickedEvent { action: 'homepage_discord_button_clicked' } /** * User clicked a customer story card in the homepage. * * @group Events * @source www * @page / */ export interface HomepageCustomerStoryCardClickedEvent { action: 'homepage_customer_story_card_clicked' properties: { customer?: string /** * The size of the card clicked. */ cardType: 'expanded' | 'narrow' } } /** * User clicked the project template card in the homepage. * * @group Events * @source www * @page / */ export interface HomepageProjectTemplateCardClickedEvent { action: 'homepage_project_template_card_clicked' properties: { /** * The title of the project template card clicked. */ templateTitle: string } } /** * User clicked the open source repository card. * * @group Events * @source www * @page /open-source */ export interface OpenSourceRepoCardClickedEvent { action: 'open_source_repo_card_clicked' properties: { /** * The name of the open source repository clicked. */ repoName: string } } /** * User clicked the green "Start Project" button in various locations described in properties. * * @group Events * @source www */ export interface StartProjectButtonClickedEvent { action: 'start_project_button_clicked' properties: { /** * The source of the button click, e.g. homepage hero, product page header. */ buttonLocation: string } } /** * User clicked the "See Documentation" button usually next to the "Start Project" button in various locations described in properties. * * @group Events * @source www */ export interface SeeDocumentationButtonClickedEvent { action: 'see_documentation_button_clicked' properties: { /** * The source of the button click, e.g. homepage hero, product page header - product name. */ buttonLocation: string } } /** * User clicked the "Request a Demo" button in various locations described in properties. * * @group Events * @source www */ export interface RequestDemoButtonClickedEvent { action: 'request_demo_button_clicked' properties: { /** * The source of the button click, e.g. homepage hero, cta banner, product page header. * If it states it came from the request demo form, it can come from different pages so refer to path name to determine. */ buttonLocation: string } } /** * User clicked the sign-in button in various locations described in properties. * * @group Events * @source www */ export interface SignInButtonClickedEvent { action: 'sign_in_button_clicked' properties: { /** * The source of the button click, e.g. homepage hero, cta banner, product page header. */ buttonLocation: string } } /** * User clicked the "Help" button in the top right corner of the page header. * * @group Events * @source studio */ export interface HelpButtonClickedEvent { action: 'help_button_clicked' groups: Partial } /** * User clicked the "Send Feedback" button in the top right corner of the page header. * * @group Events * @source studio */ export interface SendFeedbackButtonClickedEvent { action: 'send_feedback_button_clicked' groups: Partial } /** * User clicked on an example project card. * * @group Events * @source studio * @page /project/{ref} */ export interface ExampleProjectCardClickedEvent { action: 'example_project_card_clicked' properties: { /** * The title of the example project card clicked. */ cardTitle: string } groups: TelemetryGroups } /** * User clicked the "Import Data" button. * * @group Events * @source studio * @page /dashboard/project/{ref}/editor */ export interface ImportDataButtonClickedEvent { action: 'import_data_button_clicked' properties: { /** * The type of table the data is imported to. * New Table means added when creating new table by clicking from New table sidebar, * Existing Table means added to an existing table by going to the table and clicking from the green Insert button.. */ tableType: 'New Table' | 'Existing Table' } groups: TelemetryGroups } /** * User added a file to the import data dropzone on an empty table. * * @group Events * @source studio * @page /dashboard/project/{ref}/editor */ export interface ImportDataDropzoneFileAddedEvent { action: 'import_data_dropzone_file_added' groups: TelemetryGroups } /** * User added data from the import data via CSV/spreadsheet successfully. * * @group Events * @source studio * @page /dashboard/project/{ref}/editor */ export interface ImportDataAddedEvent { action: 'import_data_added' groups: TelemetryGroups } /** * User clicked the run query button in the SQL editor. * * @group Events * @source studio * @page /dashboard/project/{ref}/sql/{id} */ export interface SqlEditorQueryRunButtonClickedEvent { action: 'sql_editor_query_run_button_clicked' properties: { /** Which backend the query ran against. */ source: 'database' | 'logs' } groups: TelemetryGroups } /** * User clicked on the "Cancel Subscription" Button on the billing settings page. * * @group Events * @source studio * @page /billing */ export interface StudioBillingCancelSubscriptionClickedEvent { action: 'studio_billing_cancel_subscription_clicked' properties: { /** * The plan type the org is currently on. */ currentPlan: string } groups: Omit } /** * User clicked on the CTA button on a plan in the pricing side panel in studio. * * @group Events * @source studio * @page /billing?panel=subscriptionPlan */ export interface StudioPricingPlanCtaClickedEvent { action: 'studio_pricing_plan_cta_clicked' properties: { /** * The plan type that was clicked. */ selectedPlan: string /** * The plan type the org is currently on. */ currentPlan?: string } groups: Omit } /** * User opened the pricing side panel in studio. * * @group Events * @source studio * @page /billing?panel=subscriptionPlan */ export interface StudioPricingSidePanelOpenedEvent { action: 'studio_pricing_side_panel_opened' properties: { currentPlan?: string /** * Tracks how user landed on the Pricing side panel, e.g. diskManagementPanelDiskSize, backupsRestoreToNewProject */ origin?: string } groups: Omit } /** * User clicks on grafana banner in studio Reports page. * * @group Events * @source studio * @page /reports/database */ export interface ReportsDatabaseGrafanaBannerClickedEvent { action: 'reports_database_grafana_banner_clicked' groups: TelemetryGroups } /** * The logs.all deprecation banner was rendered, fired once per mount. Acts as the * denominator for the dismiss rate. Migration outcome itself is measured via decay in * `/v1/projects/:ref/analytics/endpoints/logs.all` traffic in the warehouse, not from this event. * * @group Events * @source studio * @page /project/[ref]/logs/*, /project/[ref]/observability/* */ export interface LogsAllDeprecationBannerExposedEvent { action: 'logs_all_deprecation_banner_exposed' groups: TelemetryGroups } /** * User dismissed the logs.all deprecation banner. * * @group Events * @source studio * @page /project/[ref]/logs/*, /project/[ref]/observability/* */ export interface LogsAllDeprecationBannerDismissButtonClickedEvent { action: 'logs_all_deprecation_banner_dismiss_button_clicked' groups: TelemetryGroups } /** * User clicked the enable button for Index Advisor, either from the banner or the confirmation dialog. * * @group Events * @source studio * @page /observability/query-performance */ export interface IndexAdvisorEnableButtonClickedEvent { action: 'index_advisor_enable_button_clicked' properties: { origin: 'banner' | 'dialog' } groups: TelemetryGroups } /** * Index Advisor banner dimissed event. * * @group Events * @source studio * @page /observability/query-performance */ export interface IndexAdvisorBannerDismissButtonClickedEvent { action: 'index_advisor_banner_dismiss_button_clicked' groups: TelemetryGroups } /** * Index Advisor tab clicked event. * * @group Events * @source studio * @page /observability/query-performance */ export interface IndexAdvisorTabClickedEvent { action: 'index_advisor_tab_clicked' properties: { hasRecommendations: boolean isIndexAdvisorEnabled: boolean } groups: TelemetryGroups } /** * User toggled live mode on the Database Connections observability page. * * @group Events * @source studio * @page /dashboard/project/{ref}/observability/connections */ export interface DatabaseConnectionsLiveModeClickedEvent { action: 'database_connections_live_mode_clicked' properties: { newState: 'enabled' | 'disabled' } groups: TelemetryGroups } /** * The Explorer feature preview banner was rendered in studio project pages, fired at most once * per page load. Acts as the denominator for the banner's dismiss and CTA rates; dedupe per * session or per user at query time. * * @group Events * @source studio */ export interface ExplorerBannerExposedEvent { action: 'explorer_banner_exposed' groups: TelemetryGroups } /** * User clicked the dismiss button on the Explorer feature preview banner in studio project pages. * * @group Events * @source studio */ export interface ExplorerBannerDismissButtonClickedEvent { action: 'explorer_banner_dismiss_button_clicked' groups: TelemetryGroups } /** * User clicked the CTA button on the Explorer feature preview banner in studio project pages. * * @group Events * @source studio */ export interface ExplorerBannerCtaButtonClickedEvent { action: 'explorer_banner_cta_button_clicked' groups: TelemetryGroups } /** * User clicked the SQL Editor button in the Explorer sidebar footer to temporarily switch * to the SQL Editor for snippet access. * * @group Events * @source studio * @page /project/{ref}/explorer */ export interface ExplorerTempAccessSqlEditorClickedEvent { action: 'explorer_temp_access_sql_editor_clicked' groups: TelemetryGroups } /** * User clicked the Explorer sidebar nav item while on the SQL Editor page, navigating back * to Explorer. * * @group Events * @source studio * @page /project/{ref}/sql */ export interface SqlEditorBackExplorerClickedEvent { action: 'sql_editor_back_explorer_clicked' groups: TelemetryGroups } /** * User clicked a metric card PID in the Overview panel of the Database Connections observability page, selecting it in the activity table below. * * @group Events * @source studio * @page /dashboard/project/{ref}/observability/connections */ export interface DatabaseConnectionsOverviewMetricCardClickedEvent { action: 'database_connections_overview_metric_card_clicked' properties: { type: 'longest_blocked' | 'top_blocker' | 'longest_running' } groups: TelemetryGroups } /** * User updated a filter on the Sessions table of the Database Connections observability page. * * @group Events * @source studio * @page /dashboard/project/{ref}/observability/connections */ export interface DatabaseConnectionsFilterUpdatedEvent { action: 'database_connections_filter_updated' properties: { type: 'state' | 'roles' | 'application' | 'reset' } groups: TelemetryGroups } /** * User clicked the Root blockers filter button on the Database Connections activity table. * * @group Events * @source studio * @page /dashboard/project/{ref}/observability/connections */ export interface DatabaseConnectionsBlockerViewClickedEvent { action: 'database_connections_blocker_view_clicked' properties: { newState: 'enabled' | 'disabled' } groups: TelemetryGroups } type DatabaseActivityState = | 'idle' | 'active' | 'idle in transaction' | 'idle in transaction (aborted)' | 'fastpath function call' | 'disabled' | null /** * User clicked the Terminate menu item for a database session in the Database Connections activity table, opening the confirmation dialog. * * @group Events * @source studio * @page /dashboard/project/{ref}/observability/connections */ export interface SessionTerminateButtonClickedEvent { action: 'session_terminate_button_clicked' properties: { activityState: DatabaseActivityState /** * Whether the session being terminated was itself blocking one or more other sessions. */ isBlocking: boolean } groups: TelemetryGroups } /** * User confirmed terminating a database session in the Database Connections activity table. * * @group Events * @source studio * @page /dashboard/project/{ref}/observability/connections */ export interface SessionTerminateSubmittedEvent { action: 'session_terminate_submitted' properties: { activityState: DatabaseActivityState /** * Whether the terminated session was itself blocking one or more other sessions. */ isBlocking: boolean } groups: TelemetryGroups } /** * User clicked Cancel query for a database session in the Database Connections activity table, * either from the row's dropdown menu or from the terminate session confirmation dialog. * * @group Events * @source studio * @page /dashboard/project/{ref}/observability/connections */ export interface QueryCancelButtonClickedEvent { action: 'query_cancel_button_clicked' properties: { activityState: DatabaseActivityState /** * Whether the session whose query is being cancelled was itself blocking one or more other sessions. */ isBlocking: boolean /** * Which surface the cancel was triggered from. */ origin: 'dropdown_menu' | 'terminate_dialog' } groups: TelemetryGroups } /** * Index Advisor create indexes button clicked event. * * @group Events * @source studio * @page /observability/query-performance */ export interface IndexAdvisorCreateIndexesButtonClickedEvent { action: 'index_advisor_create_indexes_button_clicked' groups: TelemetryGroups } /** * User clicked the deploy button for an Edge Function. * * @group Events * @source studio * @page /dashboard/project/{ref}/functions/new */ export interface EdgeFunctionDeployButtonClickedEvent { action: 'edge_function_deploy_button_clicked' properties: { /** * Click on Deploy can either happen: * 1. in the functions editor page * 2. in the chat button in the functions editor */ origin: 'functions_editor' | 'functions_ai_assistant' } groups: TelemetryGroups } /** * User clicked the confirm deploy updates button for an Edge Function in the code page within the warning model. * * @group Events * @source studio * @page /dashboard/project/{ref}/functions/{id}/code */ export interface EdgeFunctionDeployUpdatesConfirmClickedEvent { action: 'edge_function_deploy_updates_confirm_clicked' groups: TelemetryGroups } /** * User clicked the AI Assistant button to create an Edge Function. * * @group Events * @source studio * @page /dashboard/project/{ref}/functions */ export interface EdgeFunctionAiAssistantButtonClickedEvent { action: 'edge_function_ai_assistant_button_clicked' properties: { /** * Click on AI Assistant can either happen: * 1. on the main block when there are no functions * 2. in the secondary action section of the page * 3. on the chat button in the functions editor */ origin: 'no_functions_block' | 'secondary_action' | 'functions_editor_chat' } groups: TelemetryGroups } /** * User clicked the button to go to the functions editor page to create an edge function. * * @group Events * @source studio * @page /dashboard/project/{ref}/functions */ export interface EdgeFunctionViaEditorButtonClickedEvent { action: 'edge_function_via_editor_button_clicked' properties: { /** * Click on Via Editor can either happen: * 1. on the main block when there are no functions * 2. in the secondary action section of the page */ origin: 'no_functions_block' | 'secondary_action' } groups: TelemetryGroups } /** * User clicked on an Edge Function template. * * @group Events * @source studio * @page /dashboard/project/{ref}/functions */ export interface EdgeFunctionTemplateClickedEvent { action: 'edge_function_template_clicked' properties: { templateName: string /** * Where the edge function template was clicked from: * 1. functions page * 2. editor page */ origin: 'functions_page' | 'editor_page' } groups: TelemetryGroups } /** * User clicked the button to create an edge function via CLI. * * @group Events * @source studio * @page /dashboard/project/{ref}/functions */ export interface EdgeFunctionViaCliButtonClickedEvent { action: 'edge_function_via_cli_button_clicked' properties: { /** * Click on Via CLI can either happen: * 1. on the main block when there are no functions * 2. in the secondary action section of the page */ origin: 'no_functions_block' | 'secondary_action' } groups: TelemetryGroups } /** * User clicked the deploy updates button for an edge function. * * @group Events * @source studio * @page /dashboard/project/{ref}/functions/{id}/code */ export interface EdgeFunctionDeployUpdatesButtonClickedEvent { action: 'edge_function_deploy_updates_button_clicked' groups: TelemetryGroups } /** * User clicked the Send Request button for testing an Edge Function. * * @group Events * @source studio * @page /dashboard/project/{ref}/functions/{id} */ export interface EdgeFunctionTestSendButtonClickedEvent { action: 'edge_function_test_send_button_clicked' properties: { /** * The HTTP method used for the test request, e.g., GET, POST. */ httpMethod: string } groups: TelemetryGroups } /** * User opened the side panel for testing an edge function. * * @group Events * @source studio * @page /dashboard/project/{ref}/functions/{id} */ export interface EdgeFunctionTestSidePanelOpenedEvent { action: 'edge_function_test_side_panel_opened' groups: TelemetryGroups } /** * User submitted a support ticket. Project and organization are optional because the ticket might be about user account issues. * * @group Events * @source studio * @page /dashboard/support/new */ export interface SupportTicketSubmittedEvent { action: 'support_ticket_submitted' properties: { ticketCategory: string } groups: Partial } /** * User clicked the AI Assistant card on top of the support ticket form. * This event is specifically when the user goes back to the AI Assistant in the Studio. * * @group Events * @source studio * @page /dashboard/support/new */ export interface AiAssistantInSupportFormClickedEvent { action: 'ai_assistant_in_support_form_clicked' groups: Partial } /** * User clicked the Assistant follow-up card after submitting a support ticket. * * @group Events * @source studio * @page /dashboard/support/new */ export interface SupportAssistantFollowUpCardClickedEvent { action: 'support_assistant_follow_up_card_clicked' properties: { ticketCategory: string } groups: Partial } /** * User rated an AI assistant message with thumbs up or thumbs down. * * @group Events * @source studio */ export interface AssistantMessageRatingSubmittedEvent { action: 'assistant_message_rating_submitted' properties: { /** * The rating given by the user: positive (thumbs up) or negative (thumbs down) */ rating: 'positive' | 'negative' /** * The category of the conversation */ category: | 'sql_generation' | 'schema_design' | 'rls_policies' | 'edge_functions' | 'database_optimization' | 'debugging' | 'general_help' | 'other' /** Optional reason provided by the user when rating negatively */ reason?: string /** UUID of the chat session in which the message was rated */ chatId?: string } groups: TelemetryGroups } /** * User copied the command for a Supabase UI component. * * @group Events * @source supabase-ui * @page /library/docs/{framework}/{templateTitle} */ export interface SupabaseUiCommandCopyButtonClickedEvent { action: 'supabase_ui_command_copy_button_clicked' properties: { templateTitle: string command: string framework: 'nextjs' | 'react-router' | 'tanstack' | 'react' | 'vue' | 'nuxtjs' packageManager: 'npm' | 'pnpm' | 'yarn' | 'bun' } } /** * Triggered when the organization MFA enforcement setting is updated. * * @group Events * @source studio * @page /dashboard/org/{slug}/security */ export interface OrganizationMfaEnforcementUpdatedEvent { action: 'organization_mfa_enforcement_updated' properties: { mfaEnforced: boolean } groups: Omit } /** * Triggered when a new foreign data wrapper is created in a project. * * @group Events * @source studio * @page /dashboard/project/{ref}/database/integrations */ export interface ForeignDataWrapperCreatedEvent { action: 'foreign_data_wrapper_created' properties: { /** * The type of the foreign data wrapper, e.g. postgres_fdw, mysql_fdw, etc. */ wrapperType: string } groups: TelemetryGroups } /** * Triggered when a new storage bucket is created in a project. * * @group Events * @source studio * @page /dashboard/project/{ref}/storage/buckets */ export interface StorageBucketCreatedEvent { action: 'storage_bucket_created' properties: { /** * The type of the bucket created. E.g. standard or analytics iceberg. */ bucketType?: string } groups: TelemetryGroups } /** * Triggered when a new branch is created. * * @group Events * @source studio * @page /dashboard/project/{ref}/branches */ export interface BranchCreateButtonClickedEvent { action: 'branch_create_button_clicked' properties: { /** * The type of branch created, e.g. preview, persistent */ branchType: 'preview' | 'persistent' /** * Whether the branch was created with a git branch association */ gitlessBranching: boolean } groups: TelemetryGroups } /** * Triggered when a branch delete button is clicked. * * @group Events * @source studio * @page /dashboard/project/{ref}/branches, /dashboard/project/{ref}/merge or /dashboard/project/{ref}/settings/general */ export interface BranchDeleteButtonClickedEvent { action: 'branch_delete_button_clicked' properties: { /** * The type of branch being deleted, e.g. preview, persistent */ branchType?: 'preview' | 'persistent' /** * Where the delete action was initiated from */ origin: 'branches_page' | 'merge_page' | 'settings_page' } groups: TelemetryGroups } /** * Triggered when a create merge request is clicked for a branch. * * @group Events * @source studio * @page /dashboard/project/{ref}/branches */ export interface BranchCreateMergeRequestButtonClickedEvent { action: 'branch_create_merge_request_button_clicked' properties: { /** * The type of branch being merged, e.g. preview, persistent */ branchType: 'preview' | 'persistent' origin: 'header' | 'merge_page' | 'branch_selector' } groups: TelemetryGroups } /** * Triggered when a merge request is closed. * * @group Events * @source studio * @page /dashboard/project/{ref}/branches/merge-requests */ export interface BranchCloseMergeRequestButtonClickedEvent { action: 'branch_close_merge_request_button_clicked' groups: TelemetryGroups } /** * Triggered when a user clicks the merge button successfully to attempt merging a branch. * * @group Events * @source studio * @page /dashboard/project/{ref}/merge */ export interface BranchMergeSubmittedEvent { action: 'branch_merge_submitted' groups: TelemetryGroups } /** * Triggered when a branch merge completes successfully. Previously: branch_merge_succeeded * * @group Events * @source studio * @page /dashboard/project/{ref}/merge */ export interface BranchMergeCompletedEvent { action: 'branch_merge_completed' properties: { /** * The type of branch being merged, e.g. preview, persistent */ branchType: 'preview' | 'persistent' } groups: TelemetryGroups } /** * Triggered when a branch merge fails. * * @group Events * @source studio * @page /dashboard/project/{ref}/merge */ export interface BranchMergeFailedEvent { action: 'branch_merge_failed' properties: { /** * The type of branch being merged, e.g. preview, persistent */ branchType: 'preview' | 'persistent' /** * The error message or reason for failure */ error?: string } groups: TelemetryGroups } /** * Triggered when a branch is updated on push with latest changes from production. * Does not include renaming and linking to GitHub branch. * * @group Events * @source studio * @page /dashboard/project/{ref}/merge */ export interface BranchUpdatedEvent { action: 'branch_updated' properties: { /** * The source of the update action */ source: 'merge_page' | 'out_of_date_notice' modifiedEdgeFunctions?: boolean } groups: TelemetryGroups } /** * Triggered when a user clicks the review with assistant button for a merge. * * @group Events * @source studio * @page /dashboard/project/{ref}/merge */ export interface BranchReviewWithAssistantClickedEvent { action: 'branch_review_with_assistant_clicked' groups: TelemetryGroups } /** * Triggered when a user selects a branch from the branch selector dropdown. * * @group Events * @source studio * @page branch selector (header / sheet / popover) */ export interface BranchSelectorBranchClickedEvent { action: 'branch_selector_branch_clicked' properties: { branchId: string branchName: string } groups: TelemetryGroups } /** * Triggered when a user clicks "Create branch" in the branch selector dropdown. * * @group Events * @source studio * @page branch selector (header / sheet / popover) */ export interface BranchSelectorCreateClickedEvent { action: 'branch_selector_create_clicked' groups: TelemetryGroups } /** * Triggered when a user clicks "Manage branches" in the branch selector dropdown. * * @group Events * @source studio * @page branch selector (header / sheet / popover) */ export interface BranchSelectorManageClickedEvent { action: 'branch_selector_manage_clicked' groups: TelemetryGroups } /** * User clicked on an activity stat in HomeV2. * * @group Events * @source studio * @page /project/{ref} */ export interface HomeActivityStatClickedEvent { action: 'home_activity_stat_clicked' properties: { /** * The type of activity stat clicked */ stat_type: 'migrations' | 'backups' | 'branches' /** * The current value of the stat */ stat_value: number } groups: TelemetryGroups } /** * User clicked on a service title in Project Usage section of HomeV2. * * @group Events * @source studio * @page /project/{ref} */ export interface HomeProjectUsageServiceClickedEvent { action: 'home_project_usage_service_clicked' properties: { /** * The service that was clicked */ service_type: 'db' | 'functions' | 'auth' | 'storage' | 'realtime' | 'data_api' /** * Total requests for this service */ total_requests: number /** * Number of errors for this service (optional, only sent when error data is available) */ error_count?: number } groups: TelemetryGroups } /** * User clicked on a bar in the usage chart in HomeV2. * * @group Events * @source studio * @page /project/{ref} */ export interface HomeProjectUsageChartClickedEvent { action: 'home_project_usage_chart_clicked' properties: { /** * The service type for this chart */ service_type: 'db' | 'functions' | 'auth' | 'storage' | 'realtime' | 'data_api' /** * Timestamp of the bar clicked */ bar_timestamp: string } groups: TelemetryGroups } /** * User added a block to the custom report in HomeV2. * * @group Events * @source studio * @page /project/{ref} */ export interface HomeCustomReportBlockAddedEvent { action: 'home_custom_report_block_added' properties: { /** * ID of the snippet/block added */ block_id: string /** * If position is 0 it is equivalent to 'Add your first chart'. */ position: number } groups: TelemetryGroups } /** * User removed a block from the custom report in HomeV2. * * @group Events * @source studio * @page /project/{ref} */ export interface HomeCustomReportBlockRemovedEvent { action: 'home_custom_report_block_removed' properties: { /** * ID of the block removed */ block_id: string } groups: TelemetryGroups } /** * Connect section was shown to the user on the project homepage. * * @group Events * @source studio * @page /project/{ref} */ export interface HomeConnectSectionExposedEvent { action: 'home_connect_section_exposed' groups: TelemetryGroups } /** * User clicked a connect action tile in the Connect section on the project homepage. * * @group Events * @source studio * @page /project/{ref} */ export interface HomeConnectActionClickedEvent { action: 'home_connect_action_clicked' properties: { /** * The connect action/tile that was clicked */ mode: 'framework' | 'direct' | 'orm' | 'mcp' | 'server' | 'warehouse' | 'api_keys' } groups: TelemetryGroups } export type ConnectSheetSource = 'header_button' | 'connect_section' | 'keyboard_shortcut' /** * User opened the ConnectSheet panel. * * @group Events * @source studio * @page /project/{ref} */ export interface ConnectSheetOpenedEvent { action: 'connect_sheet_opened' properties: { /** * Where the sheet was opened from */ source: ConnectSheetSource } groups: TelemetryGroups } /** * User reordered sections in HomeV2 using drag and drop. * * @group Events * @source studio * @page /project/{ref} */ export interface HomeSectionRowsMovedEvent { action: 'home_section_rows_moved' properties: { /** * The section that was moved */ section_moved: string /** * The old position of the section (0-based index) */ old_position: number /** * The new position of the section (0-based index) */ new_position: number } groups: TelemetryGroups } /** * User clicked a document view/download button to access a document. * * @group Events * @source studio * @page /dashboard/org/{slug}/documents */ export interface DocumentViewButtonClickedEvent { action: 'document_view_button_clicked' properties: { /** * The name of the document being viewed, e.g. TIA, SOC2, Standard Security Questionnaire */ documentName: 'TIA' | 'SOC2' | 'ISO27001' | 'Standard Security Questionnaire' | 'DPA' } groups: Omit } /** * User clicked the Request HIPAA button to open the HIPAA request form. * * @group Events * @source studio * @page /dashboard/org/{slug}/documents */ export interface HipaaRequestButtonClickedEvent { action: 'hipaa_request_button_clicked' groups: Omit } /** * User successfully created a table in the project. * * @group Events * @source studio * @page /dashboard/project/{ref}/editor or /dashboard/project/{ref}/sql */ export interface TableCreatedEvent { action: 'table_created' properties: { /** * Method used to create the table */ method: 'sql_editor' | 'table_editor' /** * Schema where table was created */ schema_name?: string /** * Name of the table created */ table_name?: string /** * Whether RLS policies were generated and saved with the table */ has_generated_policies?: boolean } groups: Partial } /** * User successfully added data to a table. * * @group Events * @source studio * @page /dashboard/project/{ref}/editor or /dashboard/project/{ref}/sql */ export interface TableDataAddedEvent { action: 'table_data_added' properties: { /** * Method used to insert data */ method: 'sql_editor' | 'table_editor' | 'spreadsheet_import' /** * Schema of the table */ schema_name?: string /** * Name of the table */ table_name?: string } groups: Partial } /** * User successfully enabled RLS on a table. * * @group Events * @source studio * @page /dashboard/project/{ref}/editor or /dashboard/project/{ref}/sql */ export interface TableRlsEnabledEvent { action: 'table_rls_enabled' properties: { /** * Method used to enable RLS */ method: 'sql_editor' | 'table_editor' /** * Schema of the table */ schema_name?: string /** * Name of the table */ table_name?: string } groups: Partial } /** * User clicked the generate policies button in the table editor. * * @group Events * @source studio * @page /dashboard/project/{ref}/editor */ export interface RlsGeneratePoliciesClickedEvent { action: 'rls_generate_policies_clicked' groups: TelemetryGroups } /** * User removed a generated policy from the table editor. * * @group Events * @source studio * @page /dashboard/project/{ref}/editor */ export interface RlsGeneratedPolicyRemovedEvent { action: 'rls_generated_policy_removed' groups: TelemetryGroups } /** * User successfully created generated RLS policies for a table. * * @group Events * @source studio * @page /dashboard/project/{ref}/editor */ export interface RlsGeneratedPoliciesCreatedEvent { action: 'rls_generated_policies_created' groups: TelemetryGroups } /** * User opened API docs panel. * * @group Events * @source studio * @page Various pages with API docs button */ export interface ApiDocsOpenedEvent { action: 'api_docs_opened' properties: { /** * Source of the API docs button click, e.g. table_editor, sidebar */ source: string } groups: Partial } /** * User clicked copy button in API docs panel. * * @group Events * @source studio * @page API docs panel */ export interface ApiDocsCodeCopyButtonClickedEvent { action: 'api_docs_code_copy_button_clicked' properties: { /** * Title of the content being copied */ title?: string /** * Selected programming language, e.g. js, bash */ selectedLanguage?: string } groups: Partial } /** * User performed a search via the Auth Users page. * * @group Events * @source studio * @page /dashboard/project/{ref}/auth/users */ export interface AuthUsersSearchSubmittedEvent { action: 'auth_users_search_submitted' properties: { /** * The trigger that initiated the search */ trigger: | 'search_input' | 'refresh_button' | 'sort_change' | 'provider_filter' | 'user_type_filter' /** * The column being sorted on, e.g. email, phone, created_at, last_sign_in_at */ sort_column: string /** * The sort order, either ascending or descending */ sort_order: string /** * The authentication provider(s) being filtered on, e.g. email, phone, google, github */ providers?: string[] /** * The user role(s) being filtered on, e.g. verified, unverified, anonymous */ user_type?: string /** * The keywords being searched for */ keywords?: string /** * The column being filtered on, e.g. email, phone * (only included if filtering by a specific column and not all columns) */ filter_column?: string } groups: TelemetryGroups } /** * User opened the command menu. * * @group Events * @source studio, docs, www * @page any */ export interface CommandMenuOpenedEvent { action: 'command_menu_opened' properties: { /** * The trigger that opened the command menu */ trigger_type: 'keyboard_shortcut' | 'search_input' /** * The location where the command menu was opened */ trigger_location?: string /** * In which app the command input was typed */ app: 'studio' | 'docs' | 'www' } groups: Partial } /** * User typed a search term in the command menu input. * * @group Events * @source studio, docs, www * @page any */ export interface CommandMenuSearchSubmittedEvent { action: 'command_menu_search_submitted' properties: { /** * Search term typed into the command menu input */ value: string /** * In which app the command input was typed */ app: 'studio' | 'docs' | 'www' } groups: Partial } /** * User clicked a command from the command menu. * * @group Events * @source studio, docs, www * @page any */ export interface CommandMenuCommandClickedEvent { action: 'command_menu_command_clicked' properties: { /** * The clicked command */ command_name: string command_value?: string command_type: 'action' | 'route' /** * The search query that was active when the command was clicked */ search_query?: string /** * The path or URL the clicked item leads to (only present for route commands) */ result_path?: string /** * In which app the command input was typed */ app: 'studio' | 'docs' | 'www' } groups: Partial } /** * User closed the command menu. * * @group Events * @source studio, docs, www * @page any */ export interface CommandMenuClosedEvent { action: 'command_menu_closed' properties: { /** * In which app the command menu was closed */ app: 'studio' | 'docs' | 'www' } groups: Partial } /** * User opened a sidebar panel. * * @group Events * @source studio * @page Various pages with sidebar buttons */ export interface SidebarOpenedEvent { action: 'sidebar_opened' properties: { /** * The sidebar panel that was opened, e.g. ai-assistant, editor-panel, advisor-panel */ sidebar: 'ai-assistant' | 'editor-panel' | 'advisor-panel' | 'help-panel' } groups: TelemetryGroups } /** * User opened an org menu submenu in the mobile navigation sheet. * * @group Events * @source studio * @page Organization pages (mobile) */ export interface OrgSubmenuOpenedEvent { action: 'org_submenu_opened' properties: { /** The key of the submenu item that was opened */ itemKey: string /** The display label of the submenu item */ itemLabel: string } groups: TelemetryGroups } /** * User clicked the back button in the mobile org menu to return to the top-level menu. * * @group Events * @source studio * @page Organization pages (mobile) */ export interface OrgMenuBackClickedEvent { action: 'org_menu_back_clicked' groups: TelemetryGroups } /** * User clicked a menu item in the mobile org navigation sheet. * * @group Events * @source studio * @page Organization pages (mobile) */ export interface OrgMenuItemClickedEvent { action: 'org_menu_item_clicked' properties: { /** The key identifying the menu item */ itemKey: string /** The navigation href of the menu item */ itemHref: string } groups: TelemetryGroups } /** * User toggled the inline editor setting in account preferences. * * @group Events * @source studio * @page /dashboard/account/preferences */ export interface InlineEditorSettingClickedEvent { action: 'inline_editor_setting_clicked' properties: { /** * Whether the inline editor was enabled or disabled */ enabled: boolean } groups: Partial } /** * User toggled the queue table operations setting in account preferences. * * @group Events * @source studio * @page /dashboard/account/preferences */ export interface QueueOperationsSettingClickedEvent { action: 'queue_operations_setting_clicked' properties: { /** * Whether the queue operations was enabled or disabled */ enabled: boolean } groups: Partial } /** * User clicked the save destination button in add log drains sheet. * * @group Events * @source studio * @page /dashboard/project/{ref}/settings/log-drains (LogDrainDestinationSheetForm) */ export interface LogDrainSaveButtonClickedEvent { action: 'log_drain_save_button_clicked' properties: { /** * Type of the destination saved */ destination: | 'postgres' | 'bigquery' | 'clickhouse' | 'webhook' | 'datadog' | 'loki' | 'sentry' | 's3' | 'axiom' | 'last9' | 'otlp' | 'syslog' } groups: TelemetryGroups } /** * User confirmed removal of a log drain destination in the delete-confirm modal. * * @group Events * @source studio * @page /dashboard/project/{ref}/settings/log-drains */ export interface LogDrainRemovedEvent { action: 'log_drain_removed' properties: { /** * Type of the destination removed */ destination: | 'postgres' | 'bigquery' | 'clickhouse' | 'webhook' | 'datadog' | 'loki' | 'sentry' | 's3' | 'axiom' | 'last9' | 'otlp' | 'syslog' } groups: TelemetryGroups } /** * User clicked the save destination button in the add audit log drain sheet. * * @group Events * @source studio * @page /dashboard/org/{slug}/audit-log-drains (LogDrainDestinationSheetForm) */ export interface AuditLogDrainSaveButtonClickedEvent { action: 'audit_log_drain_save_button_clicked' properties: { /** * Type of the destination saved */ destination: | 'postgres' | 'bigquery' | 'clickhouse' | 'webhook' | 'datadog' | 'loki' | 'sentry' | 's3' | 'axiom' | 'last9' | 'otlp' | 'syslog' } groups: Omit } /** * User confirmed removal of an audit log drain destination in the delete-confirm modal. * * @group Events * @source studio * @page /dashboard/org/{slug}/audit-log-drains */ export interface AuditLogDrainRemovedEvent { action: 'audit_log_drain_removed' properties: { /** * Type of the destination removed */ destination: | 'postgres' | 'bigquery' | 'clickhouse' | 'webhook' | 'datadog' | 'loki' | 'sentry' | 's3' | 'axiom' | 'last9' | 'otlp' | 'syslog' } groups: Omit } type AdvisorCategory = components['schemas']['GetProjectLintsResponse_Output'][number]['categories'][number] type AdvisorLevel = 'ERROR' | 'WARN' | 'INFO' /** * User opened an advisor detail page to view a specific advisor (lint, notification, or signal). * This tracks when users engage with advisor recommendations. * * @group Events * @source studio * @page /dashboard/project/{ref}/advisors/security or home page or advisor panel sidebar */ export interface AdvisorDetailOpenedEvent { action: 'advisor_detail_opened' properties: { /** * Where the advisor was viewed from */ origin: 'homepage' | 'advisor_panel' | 'advisors_page' /** * Source of the advisor */ advisorSource: 'lint' | 'notification' | 'signal' /** * Category of the advisor */ advisorCategory?: AdvisorCategory /** * Specific advisor type/name, e.g. missing_index, no_rls_policy */ advisorType?: string /** * Severity level of the advisor (only for lints) */ advisorLevel?: AdvisorLevel } groups: TelemetryGroups } /** * User clicked the Assistant button to get AI help with an advisor issue. * This opens the AI Assistant sidebar with a pre-filled prompt about the issue. * * @group Events * @source studio * @page /dashboard/project/{ref} (homepage), /dashboard/project/{ref}/advisors/security or /dashboard/project/{ref}/advisors/performance (lint detail panel) */ export interface AdvisorAssistantButtonClickedEvent { action: 'advisor_assistant_button_clicked' properties: { /** * Where the button was clicked */ origin: 'homepage' | 'lint_detail' /** * Category of the advisor */ advisorCategory?: AdvisorCategory /** * Specific advisor type/name */ advisorType?: string /** * Severity level of the advisor (only for lints) */ advisorLevel?: AdvisorLevel /** * Number of issues found (only included when origin is 'homepage') */ issuesCount?: number } groups: TelemetryGroups } /** * User clicked on "Explain with AI" button in Query Performance detail panel * * @group Events * @source studio * @page /dashboard/project/{ref}/observability/query-performance */ export interface QueryPerformanceExplainWithAiButtonClickedEvent { action: 'query_performance_explain_with_ai_button_clicked' groups: TelemetryGroups } /** * Source/location where AI assistant actions originate from. */ export type AiAssistantSource = | 'explain_visualizer' | 'query_performance' | 'sql_debug' | 'lint_detail' | 'advisor_section' | 'advisor_widget' | 'branch_review' | 'log_explorer' | 'error_code' | 'advisor_signal_detail' | 'database_connections' /** * User copied an AI prompt to clipboard instead of using the built-in assistant. * This allows users to paste the prompt into external AI tools (Cursor, Claude, etc.) * * @group Events * @source studio */ export interface AiPromptCopiedEvent { action: 'ai_prompt_copied' properties: { /** * Source/location where the prompt was copied from */ source: AiAssistantSource } groups: TelemetryGroups } /** * User clicked the main AI assistant button in the dropdown. * * @group Events * @source studio */ export interface AiAssistantDropdownButtonClickedEvent { action: 'ai_assistant_dropdown_button_clicked' properties: { /** * Source/location where the button was clicked */ source: AiAssistantSource } groups: TelemetryGroups } /** * User clicked an external AI tool link (ChatGPT or Claude) in the dropdown. * * @group Events * @source studio */ export interface AiExternalToolClickedEvent { action: 'ai_external_tool_clicked' properties: { /** * Source/location where the link was clicked */ source: AiAssistantSource /** * Which external AI tool was selected */ tool: 'chatgpt' | 'claude' } groups: TelemetryGroups } /** * User clicked a CTA in the project security gate. * * @group Events * @source studio */ export interface ProjectSecurityCtaClickedEvent { action: 'project_security_cta_clicked' properties: { type: 'ask_assistant' | 'copy_prompt' | 'skip_to_home' | 'view_policies' schema?: string tableName?: string } groups: TelemetryGroups } /** * User opened the request upgrade modal (for users without billing permissions). * * @group Events * @source studio */ export interface RequestUpgradeModalOpenedEvent { action: 'request_upgrade_modal_opened' properties: { /** Target plan being requested */ requestedPlan: 'Pro' | 'Team' | 'Enterprise' /** Addon being requested, if applicable */ addon?: 'pitr' | 'customDomain' | 'ipv4' | 'spendCap' | 'computeSize' /** Current organization plan */ currentPlan?: string /** Feature context driving the upgrade request */ featureProposition?: string } groups: Omit } /** * User submitted a request upgrade form to billing owners. * * @group Events * @source studio */ export interface RequestUpgradeSubmittedEvent { action: 'request_upgrade_submitted' properties: { /** Target plan being requested */ requestedPlan: 'Pro' | 'Team' | 'Enterprise' /** Addon being requested, if applicable */ addon?: 'pitr' | 'customDomain' | 'ipv4' | 'spendCap' | 'computeSize' /** Current organization plan */ currentPlan?: string } groups: Omit } /** * Triggered when a Studio error UI element is displayed (mounted). * This includes error Admonitions, Toast notifications, and ErrorDisplay components. * * @group Events * @source studio */ export interface DashboardErrorCreatedEvent { action: 'dashboard_error_created' properties: { /** * Source of the error */ source?: 'admonition' | 'toast' | 'error_display' | 'form' /** * Type of error matched (for error_display source) */ errorType?: string /** * Whether troubleshooting steps are available (for error_display source) */ hasTroubleshooting?: boolean /** * Funnel the error occurred in (set only for instrumented funnel errors) */ origin?: 'signup' | 'signin' | 'project_creation' | 'org_creation' /** * Coarse classification of the funnel error */ errorCategory?: 'validation' | 'api' | 'network' | 'payment' | 'unknown' /** * Controlled-vocabulary slug describing the reason (no free text, no PII). * * Typed `string` rather than a literal union on purpose: the source-of-truth * union `FunnelErrorReason` lives in `apps/studio/lib/telemetry/funnel-errors.ts`, * and this `common` package cannot import from an app. The constraint is enforced * at the only emit site instead: `useTrackFunnelError` accepts a classified * `FunnelErrorReason`, so free text never reaches this field. Do not widen usage by * setting `errorReason` from a raw error message. */ errorReason?: string /** * HTTP status code for api/network errors (absent for validation/payment) */ errorCode?: number } groups: TelemetryGroups } /** * Triggered when the inline error troubleshooter is shown to the user. * * @group Events * @source studio */ export interface InlineErrorTroubleshooterExposedEvent { action: 'inline_error_troubleshooter_exposed' properties: { /** ID of the matched error mapping */ errorType: string } groups: TelemetryGroups } /** * Triggered when a user opens or closes a troubleshooting accordion step. * * @group Events * @source studio */ export interface InlineErrorTroubleshooterStepClickedEvent { action: 'inline_error_troubleshooter_step_clicked' properties: { /** ID of the matched error mapping */ errorType: string /** Step number that was clicked (1, 2, 3, ...) — null when a step is collapsed */ step: number | null /** Title of the step that was clicked */ stepTitle?: string /** Whether the step was opened (true) or closed (false) */ expanded: boolean } groups: TelemetryGroups } /** * Triggered when a user clicks an action within the inline error troubleshooter. * Covers all CTAs including the contact support link. * * @group Events * @source studio */ export interface InlineErrorTroubleshooterActionClickedEvent { action: 'inline_error_troubleshooter_action_clicked' properties: { /** ID of the matched error mapping */ errorType: string /** Which CTA was clicked */ ctaType: 'restart_db' | 'troubleshooting_guide' | 'ask_ai' | 'contact_support' } groups: TelemetryGroups } /** * User successfully completed installing an integration via the integrations marketplace in the dashboard. * Note: This excludes Wrappers and Postgres Extensions. Previously: integration_installed * * @group Events * @source studio * @page /dashboard/project/{ref}/integrations/{integration_slug} */ export interface IntegrationInstallCompletedEvent { action: 'integration_install_completed' properties: { /** * The name of the integration installed */ integrationName: string } groups: TelemetryGroups } /** * User submitted an integration install via the integrations marketplace. Previously: integration_install_started * * @group Events * @source studio * @page /dashboard/project/{ref}/integrations/{integration_slug} */ export interface IntegrationInstallSubmittedEvent { action: 'integration_install_submitted' properties: { /** The name of the integration being installed */ integrationName: string /** The integration method (will be 'template' for frontend-driven integrations.) */ method: string } groups: TelemetryGroups } /** * User submitted an integration uninstall via the integrations marketplace. Previously: integration_uninstall_started * * @group Events * @source studio * @page /dashboard/project/{ref}/integrations/{integration_slug} */ export interface IntegrationUninstallSubmittedEvent { action: 'integration_uninstall_submitted' properties: { /** * The name of the integration being uninstalled */ integrationName: string } groups: TelemetryGroups } /** * Installation failed for an integration. * * @group Events * @source studio * @page /dashboard/project/{ref}/integrations/{integration_slug} */ export interface IntegrationInstallFailedEvent { action: 'integration_install_failed' properties: { /** * The name of the integration whose installation failed */ integrationName: string } groups: TelemetryGroups } /** * User successfully completed uninstalling an integration via the integrations marketplace in the dashboard. * Note: This excludes Wrappers and Postgres Extensions. Previously: integration_uninstalled * * @group Events * @source studio * @page /dashboard/project/{ref}/integrations/{integration_slug} */ export interface IntegrationUninstallCompletedEvent { action: 'integration_uninstall_completed' properties: { /** * The name of the integration installed */ integrationName: string } groups: TelemetryGroups } /** * User clicked the enable Create rls_ensure trigger button in the RLS Event Trigger banner. * * @group Events * @source studio * @page /project/{ref}/database/policies */ export interface RlsEventTriggerBannerCreateButtonClickedEvent { action: 'rls_event_trigger_banner_create_button_clicked' groups: TelemetryGroups } /** * User clicked the Run button in the log explorer. * * @group Events * @source studio * @page /project/{ref}/logs/explorer */ export interface LogExplorerQueryRunButtonClickedEvent { action: 'log_explorer_query_run_button_clicked' properties: { /** * Whether the user is editing a saved query */ is_saved_query: boolean } groups: TelemetryGroups } export type ExplorerQueryLocation = | { surface: 'query_tab'; queryId: string; notebookId?: never; cellId?: never } | { surface: 'notebook_cell'; notebookId: string; cellId: string; queryId?: never } export type ExplorerQueryRunProperties = ExplorerQueryLocation & { runId: string source: 'database' | 'logs' } type ExplorerGroups = Pick & Partial> /** * User started an Explorer query run. * * @group Events * @source studio * @page /project/{ref}/explorer */ export interface ExplorerQuerySubmittedEvent { action: 'explorer_query_submitted' properties: ExplorerQueryRunProperties groups: ExplorerGroups } /** * An Explorer query run completed successfully. * * @group Events * @source studio * @page /project/{ref}/explorer */ export interface ExplorerQueryCompletedEvent { action: 'explorer_query_completed' properties: ExplorerQueryRunProperties groups: ExplorerGroups } /** * An Explorer query run failed. * * @group Events * @source studio * @page /project/{ref}/explorer */ export interface ExplorerQueryFailedEvent { action: 'explorer_query_failed' properties: ExplorerQueryRunProperties & { failureReason: 'logs_unavailable' | 'connection_unavailable' | 'execution_error' } groups: ExplorerGroups } /** * An Explorer notebook was saved for the first time. * * @group Events * @source studio * @page /project/{ref}/explorer */ export interface ExplorerNotebookCreatedEvent { action: 'explorer_notebook_created' properties: { notebookId: string } groups: ExplorerGroups } /** * An Explorer notebook was saved after creation. * * @group Events * @source studio * @page /project/{ref}/explorer */ export interface ExplorerNotebookUpdatedEvent { action: 'explorer_notebook_updated' properties: { notebookId: string } groups: ExplorerGroups } /** * User clicked an upgrade CTA inside the compute badge hover card. * * @group Events * @source studio */ export interface ComputeBadgeUpgradeClickedEvent { action: 'compute_badge_upgrade_clicked' properties: { computeSize: string planId: string upgradeType: 'free_micro_upgrade' | 'compute_upgrade' } groups: TelemetryGroups } /** * User dismissed the free Micro upgrade banner. * * @group Events * @source studio */ export interface FreeMicroUpgradeBannerDismissedEvent { action: 'free_micro_upgrade_banner_dismissed' groups: TelemetryGroups } /** * User clicked the CTA on the free Micro upgrade banner. * * @group Events * @source studio */ export interface FreeMicroUpgradeBannerCtaClickedEvent { action: 'free_micro_upgrade_banner_cta_clicked' groups: TelemetryGroups } /** * User clicked the Navigate action in the storage explorer header. * * @group Events * @source studio * @page /project/{ref}/storage/files/buckets/{bucketId} */ export interface StorageExplorerNavigateClickedEvent { action: 'storage_explorer_navigate_clicked' groups: TelemetryGroups } /** * User submitted a folder path from the storage explorer Navigate action. * * @group Events * @source studio * @page /project/{ref}/storage/files/buckets/{bucketId} */ export interface StorageExplorerNavigateSubmittedEvent { action: 'storage_explorer_navigate_submitted' groups: TelemetryGroups } /** * User clicked the Remove policy button on the public bucket SELECT policy warning. * * @group Events * @source studio * @page /project/{ref}/storage/files/buckets/{bucketId} */ export interface StoragePublicBucketSelectPolicyRemovedEvent { action: 'storage_public_bucket_select_policy_removed' properties: { /** The ID of the bucket whose SELECT policy was removed */ bucketId: string } groups: TelemetryGroups } /** * User dismissed the public bucket SELECT policy warning banner. * * @group Events * @source studio * @page /project/{ref}/storage/files/buckets/{bucketId} */ export interface StoragePublicBucketSelectPolicyWarningDismissButtonClickedEvent { action: 'storage_public_bucket_select_policy_warning_dismiss_button_clicked' properties: { /** The ID of the bucket whose warning was dismissed */ bucketId: string } groups: TelemetryGroups } /** * Triggered when an access token is successfully created. * * @group Events * @source studio * @page /account/tokens */ export interface AccessTokenCreatedEvent { action: 'access_token_created' properties: { tokenType: 'classic' | 'scoped' expiryPreset: string resourceAccess?: 'project' | 'organization' | 'account' permissionCount?: number } groups: Omit } /** * Triggered when the access token creation sheet is closed before a token was created, either by * the user (Escape, outside click, or Cancel) or because the permissions map failed to load and * forced the sheet shut. The token created step blocks non-safe closes, so this event never fires * for a completed creation. * * @group Events * @source studio * @page /account/tokens */ export interface AccessTokenCreationSheetDismissedEvent { action: 'access_token_creation_sheet_dismissed' properties: { resourceAccess: 'project' | 'organization' | 'account' formStep: 'form' | 'review' isFormTouched: boolean trigger: 'user' | 'permissions_load_error' } groups: Omit } /** * Triggered when an access token is successfully deleted. * * @group Events * @source studio * @page /account/tokens */ export interface AccessTokenRemovedEvent { action: 'access_token_removed' properties: { tokenType: 'classic' | 'scoped' } groups: Omit } /** * Triggered when the copy button is used on the token value shown after creation. The value is * only ever displayed once, so this measures how many users leave with a usable token. * * @group Events * @source studio * @page /account/tokens (token created step of the generate token sheet) */ export interface AccessTokenCopiedEvent { action: 'access_token_copied' properties: { tokenType: 'classic' | 'scoped' } groups: Omit } /** * Triggered when the "I have copied the key and stored it securely" checkbox is toggled on the * token created step. `isChecked` is the resulting state, so unticking is tracked too. * * @group Events * @source studio * @page /account/tokens (token created step of the generate token sheet) */ export interface AccessTokenStoredCheckboxClickedEvent { action: 'access_token_stored_checkbox_clicked' properties: { tokenType: 'classic' | 'scoped' /** The state the checkbox was toggled into */ isChecked: boolean } groups: Omit } /** * Triggered when the "Done" button dismisses the token created step, completing the creation flow. * * @group Events * @source studio * @page /account/tokens (token created step of the generate token sheet) */ export interface AccessTokenDoneButtonClickedEvent { action: 'access_token_done_button_clicked' properties: { tokenType: 'classic' | 'scoped' /** Whether the copy button was used before finishing, as opposed to copying the value manually */ hasCopiedToken: boolean } groups: Omit } /** * User clicked the "Upgrade to Pro" CTA. Fired from each CTA placement surface, with * `placement` identifying which one (the user dropdown or the org project-list usage card). * * @group Events * @source studio */ export interface UpgradeCtaClickedEvent { action: 'upgrade_cta_clicked' properties: { placement: 'user_dropdown' | 'org_projects_list' } groups: Omit } /** * User was exposed to the plan-change panel presentation experiment. * Fires once per session per enrolled user in any variant (including control), so the * conversion analysis has a baseline cohort. Conversion itself is tracked server-side. * GROWTH experiment: `pricingPanelPlanPresentation`. * * @group Events * @page /org/[slug]/billing (plan-change side panel) * @source studio */ export interface PricingPanelPlanPresentationExperimentExposedEvent { action: 'pricing_panel_plan_presentation_experiment_exposed' properties: { /** The experiment variant the user is enrolled in */ variant: 'control' | 'parity' | 'gaps' | 'fullscreen' | 'fullscreen-gaps' } groups: Omit } /** * User clicked the primary CTA on a resource exhaustion warning banner. * * @group Events * @source studio */ export interface ResourceExhaustionBannerUpgradeClickedEvent { action: 'resource_exhaustion_banner_upgrade_clicked' groups: TelemetryGroups properties: { warningTypes: string[] destination: string } } /** * User clicked "Ask AI Assistant" on a resource exhaustion warning banner. * * @group Events * @source studio */ export interface ResourceExhaustionBannerAiAssistantClickedEvent { action: 'resource_exhaustion_banner_ai_assistant_clicked' groups: TelemetryGroups properties: { warningTypes: string[] } } /** * User clicked a metrics or documentation link on a resource exhaustion warning banner (Troubleshoot menu item or single-action button). * * @group Events * @source studio */ export interface ResourceExhaustionBannerTroubleshootClickedEvent { action: 'resource_exhaustion_banner_troubleshoot_clicked' groups: TelemetryGroups properties: { troubleshootAction: 'metrics' | 'docs' warningType: string warningTypes: string[] destination: string } } /** * User clicked a row in the Unified Logs interface. * * @group Events * @source studio */ export interface UnifiedLogsRowClickedEvent { action: 'unified_logs_row_clicked' properties: { /** * Service that produced the log row. Mirrors `LOG_TYPES` in UnifiedLogs.constants.tsx. * Server values are validated against this set by zod (UnifiedLogs.schema.ts) before * reaching the table; anything else is rejected upstream so the union here is exhaustive. */ logType: | 'edge' | 'postgres' | 'postgrest' | 'auth' | 'storage' | 'edge function' | 'realtime' | 'supavisor' | 'pgbouncer' | 'multigres' | 'compute' } groups: TelemetryGroups } /** * User clicked the Supabase logo in the top-left corner of the page header. * * @group Events * @source studio */ export interface HeaderHomeLogoClickedEvent { action: 'header_home_logo_clicked' groups: Partial } /** * User clicked the mobile back-to-dashboard chevron in the page header. * * @group Events * @source studio */ export interface HeaderBackToDashboardClickedEvent { action: 'header_back_to_dashboard_clicked' groups: Partial } /** * User clicked the "Exceeding usage limits" badge in the page header. * * @group Events * @source studio */ export interface HeaderExceedingUsageBadgeClickedEvent { action: 'header_exceeding_usage_badge_clicked' groups: Partial } /** * User opened the organization dropdown in the page header. * * @group Events * @source studio */ export interface HeaderOrganizationDropdownOpenedEvent { action: 'header_organization_dropdown_opened' groups: Partial } /** * User opened the project dropdown in the page header. * * @group Events * @source studio */ export interface HeaderProjectDropdownOpenedEvent { action: 'header_project_dropdown_opened' groups: Partial } /** * User opened the branch dropdown in the page header. * * @group Events * @source studio */ export interface HeaderBranchDropdownOpenedEvent { action: 'header_branch_dropdown_opened' groups: Partial } /** * User clicked the merge-request trigger button in the page header. * Fires on click; the existing branch_create_merge_request_button_clicked * fires only on successful merge-request creation. * * @group Events * @source studio */ export interface HeaderMergeRequestButtonClickedEvent { action: 'header_merge_request_button_clicked' properties: { /** Whether a review has already been requested for this branch. */ hasReviewRequested: boolean } groups: TelemetryGroups } /** * User clicked the "Connect" button in the page header. * * @group Events * @source studio */ export interface HeaderConnectButtonClickedEvent { action: 'header_connect_button_clicked' groups: TelemetryGroups } /** * User opened the feedback dropdown in the page header. * * @group Events * @source studio */ export interface HeaderFeedbackDropdownOpenedEvent { action: 'header_feedback_dropdown_opened' groups: Partial } /** * User clicked the Advisor Center toggle button in the page header. * * @group Events * @source studio */ export interface HeaderAdvisorButtonClickedEvent { action: 'header_advisor_button_clicked' groups: Partial } /** * User clicked the Inline SQL Editor toggle button in the page header. * * @group Events * @source studio */ export interface HeaderInlineEditorButtonClickedEvent { action: 'header_inline_editor_button_clicked' groups: Partial } /** * User clicked the AI Assistant toggle button in the page header. * * @group Events * @source studio */ export interface HeaderAssistantButtonClickedEvent { action: 'header_assistant_button_clicked' groups: Partial } /** * User opened the user/account dropdown in the page header. * * @group Events * @source studio */ export interface HeaderUserDropdownOpenedEvent { action: 'header_user_dropdown_opened' groups: Partial } /** * User opened the local-development settings dropdown in the page header. * * @group Events * @source studio */ export interface HeaderLocalDropdownOpenedEvent { action: 'header_local_dropdown_opened' groups: Partial } /** * User opened the local CLI version popover in the page header. * * @group Events * @source studio */ export interface HeaderLocalVersionPopoverOpenedEvent { action: 'header_local_version_popover_opened' groups: Partial } /** * User enabled Warehouse by submitting a schema and table selection. * * @group Events * @source studio * @page /dashboard/project/{ref}/integrations/warehouse/overview */ export interface WarehouseEnabledEvent { action: 'warehouse_enabled' properties: { /** Where the user initiated Warehouse setup. */ source: 'integrations_overview' /** Number of schemas replicated in full. */ schemaTargetCount: number /** Number of tables replicated individually. */ tableTargetCount: number } groups: TelemetryGroups } /** * User disabled Warehouse for a project. * * @group Events * @source studio * @page /dashboard/project/{ref}/integrations/warehouse/overview */ export interface WarehouseDisabledEvent { action: 'warehouse_disabled' properties: { /** Number of schemas that were replicated in full. Omitted when the replicated tables have not resolved. */ schemaTargetCount?: number /** Number of tables that were replicated individually. Omitted when the replicated tables have not resolved. */ tableTargetCount?: number } groups: TelemetryGroups } /** * @hidden */ export type TelemetryEvent = | ExplorerQuerySubmittedEvent | ExplorerQueryCompletedEvent | ExplorerQueryFailedEvent | ExplorerNotebookCreatedEvent | ExplorerNotebookUpdatedEvent | SignUpEvent | SignInEvent | SignInSubmittedEvent | ConnectionStringCopiedEvent | McpInstallButtonClickedEvent | ApiDocsOpenedEvent | ApiDocsCodeCopyButtonClickedEvent | CronJobCreatedEvent | CronJobUpdatedEvent | CronJobRemovedEvent | CronJobCreateClickedEvent | CronJobUpdateClickedEvent | CronJobDeleteClickedEvent | CronJobHistoryClickedEvent | CronJobCleanupDialogOpenedEvent | CronJobCleanupEnableButtonClickedEvent | FeaturePreviewEnabledEvent | FeaturePreviewDisabledEvent | TimezonePickerClickedEvent | ProjectCreationDefaultPrivilegesExposedEvent | ProjectCreationGithubConnectClickedEvent | ProjectCreationSimpleVersionSubmittedEvent | ProjectCreationSimpleVersionConfirmModalOpenedEvent | ProjectCreationFormExposedEvent | OrganizationCreationFormExposedEvent | OrganizationCreationCompletedEvent | TableApiAccessToggleClickedEvent | RealtimeInspectorListenChannelClickedEvent | RealtimeInspectorBroadcastSentEvent | RealtimeInspectorMessageClickedEvent | RealtimeInspectorCopyMessageClickedEvent | RealtimeInspectorFiltersAppliedEvent | RealtimeInspectorDatabaseRoleUpdatedEvent | RealtimeToggleTableClickedEvent | TableRealtimeEnabledEvent | TableRealtimeDisabledEvent | SqlEditorQuickstartClickedEvent | SqlEditorTemplateClickedEvent | SqlEditorAutosaveDisableClickedEvent | SqlEditorResultDownloadCsvClickedEvent | SqlEditorResultCopyMarkdownClickedEvent | SqlEditorResultCopyJsonClickedEvent | SqlEditorResultCopyCsvClickedEvent | AssistantPromptSubmittedEvent | AssistantDebugSubmittedEvent | AssistantSuggestionRunQueryClickedEvent | AssistantSqlDiffHandlerEvaluatedEvent | AssistantEditInSqlEditorClickedEvent | AssistantMessageRatingSubmittedEvent | DocsFeedbackClickedEvent | CopyAsMarkdownClickedEvent | AgentSetupClickedEvent | AskAiClickedEvent | DocsAiPromptCopiedEvent | DocsContentListingClickedEvent | Docs404RecommendationClickedEvent | DocsProjectConfigVariablesCopyButtonClickedEvent | HomepageFrameworkQuickstartClickedEvent | HomepageProductCardClickedEvent | WwwPricingPlanCtaClickedEvent | WwwEventPageCtaClickedEvent | WwwSubprocessorUpdatesSubscribedEvent | HomepageGithubButtonClickedEvent | HomepageDiscordButtonClickedEvent | HomepageCustomerStoryCardClickedEvent | HomepageProjectTemplateCardClickedEvent | CustomReportAddSqlBlockClickedEvent | CustomReportAssistantSqlBlockAddedEvent | OpenSourceRepoCardClickedEvent | StartProjectButtonClickedEvent | SeeDocumentationButtonClickedEvent | RequestDemoButtonClickedEvent | SignInButtonClickedEvent | HelpButtonClickedEvent | ExampleProjectCardClickedEvent | ImportDataButtonClickedEvent | ImportDataDropzoneFileAddedEvent | ImportDataAddedEvent | SendFeedbackButtonClickedEvent | SqlEditorQueryRunButtonClickedEvent | LogExplorerQueryRunButtonClickedEvent | StorageExplorerNavigateClickedEvent | StorageExplorerNavigateSubmittedEvent | StoragePublicBucketSelectPolicyRemovedEvent | StoragePublicBucketSelectPolicyWarningDismissButtonClickedEvent | StudioPricingPlanCtaClickedEvent | StudioBillingCancelSubscriptionClickedEvent | StudioPricingSidePanelOpenedEvent | ReportsDatabaseGrafanaBannerClickedEvent | LogsAllDeprecationBannerExposedEvent | LogsAllDeprecationBannerDismissButtonClickedEvent | IndexAdvisorEnableButtonClickedEvent | IndexAdvisorBannerDismissButtonClickedEvent | IndexAdvisorTabClickedEvent | DatabaseConnectionsLiveModeClickedEvent | DatabaseConnectionsOverviewMetricCardClickedEvent | DatabaseConnectionsFilterUpdatedEvent | DatabaseConnectionsBlockerViewClickedEvent | ExplorerBannerExposedEvent | ExplorerBannerDismissButtonClickedEvent | ExplorerBannerCtaButtonClickedEvent | ExplorerTempAccessSqlEditorClickedEvent | SqlEditorBackExplorerClickedEvent | SessionTerminateButtonClickedEvent | SessionTerminateSubmittedEvent | QueryCancelButtonClickedEvent | IndexAdvisorCreateIndexesButtonClickedEvent | EdgeFunctionDeployButtonClickedEvent | EdgeFunctionDeployUpdatesConfirmClickedEvent | EdgeFunctionAiAssistantButtonClickedEvent | EdgeFunctionViaEditorButtonClickedEvent | EdgeFunctionTemplateClickedEvent | EdgeFunctionViaCliButtonClickedEvent | EdgeFunctionDeployUpdatesButtonClickedEvent | EdgeFunctionTestSendButtonClickedEvent | EdgeFunctionTestSidePanelOpenedEvent | SupabaseUiCommandCopyButtonClickedEvent | SupportTicketSubmittedEvent | AiAssistantInSupportFormClickedEvent | SupportAssistantFollowUpCardClickedEvent | OrganizationMfaEnforcementUpdatedEvent | ForeignDataWrapperCreatedEvent | StorageBucketCreatedEvent | BranchCreateButtonClickedEvent | BranchDeleteButtonClickedEvent | BranchCreateMergeRequestButtonClickedEvent | BranchCloseMergeRequestButtonClickedEvent | BranchMergeSubmittedEvent | BranchMergeCompletedEvent | BranchMergeFailedEvent | BranchUpdatedEvent | BranchReviewWithAssistantClickedEvent | BranchSelectorBranchClickedEvent | BranchSelectorCreateClickedEvent | BranchSelectorManageClickedEvent | HomeConnectSectionExposedEvent | HomeConnectActionClickedEvent | ConnectSheetOpenedEvent | HomeSectionRowsMovedEvent | HomeActivityStatClickedEvent | HomeProjectUsageServiceClickedEvent | HomeProjectUsageChartClickedEvent | HomeCustomReportBlockAddedEvent | HomeCustomReportBlockRemovedEvent | DocumentViewButtonClickedEvent | HipaaRequestButtonClickedEvent | TableCreatedEvent | TableDataAddedEvent | TableRlsEnabledEvent | RlsGeneratePoliciesClickedEvent | RlsGeneratedPolicyRemovedEvent | RlsGeneratedPoliciesCreatedEvent | AuthUsersSearchSubmittedEvent | CommandMenuOpenedEvent | CommandMenuClosedEvent | CommandMenuSearchSubmittedEvent | CommandMenuCommandClickedEvent | InlineEditorSettingClickedEvent | QueueOperationsSettingClickedEvent | SidebarOpenedEvent | LogDrainSaveButtonClickedEvent | LogDrainRemovedEvent | AuditLogDrainSaveButtonClickedEvent | AuditLogDrainRemovedEvent | AdvisorDetailOpenedEvent | AdvisorAssistantButtonClickedEvent | QueryPerformanceExplainWithAiButtonClickedEvent | AiPromptCopiedEvent | AiAssistantDropdownButtonClickedEvent | AiExternalToolClickedEvent | ProjectSecurityCtaClickedEvent | RequestUpgradeModalOpenedEvent | RequestUpgradeSubmittedEvent | DashboardErrorCreatedEvent | InlineErrorTroubleshooterExposedEvent | InlineErrorTroubleshooterStepClickedEvent | InlineErrorTroubleshooterActionClickedEvent | IntegrationInstallCompletedEvent | IntegrationInstallSubmittedEvent | IntegrationUninstallSubmittedEvent | IntegrationInstallFailedEvent | IntegrationUninstallCompletedEvent | RlsEventTriggerBannerCreateButtonClickedEvent | OrgSubmenuOpenedEvent | OrgMenuBackClickedEvent | OrgMenuItemClickedEvent | ComputeBadgeUpgradeClickedEvent | FreeMicroUpgradeBannerDismissedEvent | FreeMicroUpgradeBannerCtaClickedEvent | UpgradeCtaClickedEvent | PricingPanelPlanPresentationExperimentExposedEvent | AccessTokenCreatedEvent | AccessTokenCreationSheetDismissedEvent | AccessTokenRemovedEvent | AccessTokenCopiedEvent | AccessTokenStoredCheckboxClickedEvent | AccessTokenDoneButtonClickedEvent | ResourceExhaustionBannerUpgradeClickedEvent | ResourceExhaustionBannerAiAssistantClickedEvent | ResourceExhaustionBannerTroubleshootClickedEvent | UnifiedLogsRowClickedEvent | HeaderHomeLogoClickedEvent | HeaderBackToDashboardClickedEvent | HeaderExceedingUsageBadgeClickedEvent | HeaderOrganizationDropdownOpenedEvent | HeaderProjectDropdownOpenedEvent | HeaderBranchDropdownOpenedEvent | HeaderMergeRequestButtonClickedEvent | HeaderConnectButtonClickedEvent | HeaderFeedbackDropdownOpenedEvent | HeaderAdvisorButtonClickedEvent | HeaderInlineEditorButtonClickedEvent | HeaderAssistantButtonClickedEvent | HeaderUserDropdownOpenedEvent | HeaderLocalDropdownOpenedEvent | HeaderLocalVersionPopoverOpenedEvent | WarehouseEnabledEvent | WarehouseDisabledEvent