diff --git a/apps/studio/components/interfaces/Explorer/QueryCell/DisplaySettingsButton.tsx b/apps/studio/components/interfaces/Explorer/QueryCell/DisplaySettingsButton.tsx
index 96460ec03ec24..29a8ee384277d 100644
--- a/apps/studio/components/interfaces/Explorer/QueryCell/DisplaySettingsButton.tsx
+++ b/apps/studio/components/interfaces/Explorer/QueryCell/DisplaySettingsButton.tsx
@@ -1,4 +1,5 @@
import { BarChart2, Settings2, Table } from 'lucide-react'
+import { useEffect, useEffectEvent, useMemo } from 'react'
import {
Checkbox,
Popover,
@@ -12,23 +13,34 @@ import {
SelectValue,
ToggleGroup,
ToggleGroupItem,
+ Tooltip,
+ TooltipContent,
+ TooltipTrigger,
} from 'ui'
import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout'
import { type Snapshot } from 'valtio'
import { ExplorerToolbarAction } from '../ExplorerToolbar'
+import { type QueryResult } from '../types'
+import { checkHasNonPositiveValues } from '@/components/ui/QueryBlock/QueryBlock.utils'
import { type DatabaseCell as DatabaseCellSchema } from '@/data/content/notebooks/notebook-schema'
import { useCurrentNotebook, useNotebooksStateSnapshot } from '@/state/notebooks/notebooks-state'
interface DisplaySettingsButtonProps {
cell: Snapshot
+ result?: QueryResult
columns: string[]
disabled: boolean
}
// [Joshen] TODO support multiple y axis charts
-export const DisplaySettingsButton = ({ cell, columns, disabled }: DisplaySettingsButtonProps) => {
+export const DisplaySettingsButton = ({
+ cell,
+ result,
+ columns,
+ disabled,
+}: DisplaySettingsButtonProps) => {
const snap = useNotebooksStateSnapshot()
const currentNotebook = useCurrentNotebook()
const cells = currentNotebook?.notebook.content?.cells ?? []
@@ -37,12 +49,22 @@ export const DisplaySettingsButton = ({ cell, columns, disabled }: DisplaySettin
const {
type = 'bar',
x_column,
- y_columns,
+ y_columns = [],
cumulative = false,
show_labels = false,
scale = 'linear',
} = chart ?? {}
+ const hasNonPositiveValues = useMemo(
+ () => checkHasNonPositiveValues(result?.rows ?? [], y_columns[0]),
+ [result, y_columns]
+ )
+
+ const canToggleLogScale = useMemo(() => {
+ if (y_columns.length === 0 || !result || (result.rows ?? []).length === 0) return false
+ return !hasNonPositiveValues
+ }, [hasNonPositiveValues, result, y_columns.length])
+
const onChangeView = (view: 'table' | 'chart') => {
const notebookId = currentNotebook?.notebook.id
if (!notebookId) return
@@ -84,12 +106,22 @@ export const DisplaySettingsButton = ({ cell, columns, disabled }: DisplaySettin
snap.updateCells({ id: notebookId, cells: nextCells })
}
+ const resetToLinearScale = useEffectEvent(() => {
+ onUpdateChartConfig({ scale: 'linear' })
+ })
+
+ useEffect(() => {
+ if (hasNonPositiveValues && scale === 'log') {
+ resetToLinearScale()
+ }
+ }, [hasNonPositiveValues, scale])
+
return (
} tooltip="Result settings" />
-
+
Result display settings
@@ -187,7 +219,24 @@ export const DisplaySettingsButton = ({ cell, columns, disabled }: DisplaySettin
Linear
- Logarithmic
+
+
+
+ Logarithmic
+
+
+ {!canToggleLogScale && (
+
+ {y_columns.length === 0
+ ? 'Select a column for the Y axis first'
+ : 'Data contains zero or negative values'}
+
+ )}
+
diff --git a/apps/studio/components/interfaces/Explorer/QueryCell/QueryResultChart.tsx b/apps/studio/components/interfaces/Explorer/QueryCell/QueryResultChart.tsx
index 8f6db1ffc8c47..ddee91b17b7f5 100644
--- a/apps/studio/components/interfaces/Explorer/QueryCell/QueryResultChart.tsx
+++ b/apps/studio/components/interfaces/Explorer/QueryCell/QueryResultChart.tsx
@@ -4,7 +4,7 @@ import { type Snapshot } from 'valtio'
import { type QueryResult } from '../types'
import NoDataPlaceholder from '@/components/ui/Charts/NoDataPlaceholder'
-import { getCumulativeResults } from '@/components/ui/QueryBlock/QueryBlock.utils'
+import { formatLogTick, getCumulativeResults } from '@/components/ui/QueryBlock/QueryBlock.utils'
import { type DatabaseCell as DatabaseCellSchema } from '@/data/content/notebooks/notebook-schema'
interface QueryResultChartProps {
@@ -23,7 +23,7 @@ const toChartValue = (value: unknown): string | number => {
export const QueryResultChart = ({ cell, result }: QueryResultChartProps) => {
const { chart } = cell
- const { type, x_column, y_columns = [], cumulative, show_labels } = chart ?? {}
+ const { type, x_column, y_columns = [], cumulative, show_labels, scale } = chart ?? {}
const hasConfig = !!x_column && y_columns.length > 0
const chartRows = useMemo(() => {
@@ -76,6 +76,11 @@ export const QueryResultChart = ({ cell, result }: QueryResultChartProps) => {
showXAxis={show_labels}
showYAxis={show_labels}
data={resultToRender}
+ YAxisProps={{
+ scale: scale === 'log' ? 'log' : 'auto',
+ domain: scale === 'log' ? [1, 'auto'] : undefined,
+ tickFormatter: scale === 'log' ? formatLogTick : undefined,
+ }}
/>
)}
{type === 'line' && (
@@ -86,6 +91,11 @@ export const QueryResultChart = ({ cell, result }: QueryResultChartProps) => {
showXAxis={show_labels}
showYAxis={show_labels}
data={resultToRender}
+ YAxisProps={{
+ scale: scale === 'log' ? 'log' : 'auto',
+ domain: scale === 'log' ? [1, 'auto'] : undefined,
+ tickFormatter: scale === 'log' ? formatLogTick : undefined,
+ }}
/>
)}
diff --git a/apps/studio/components/interfaces/Explorer/QueryCell/index.tsx b/apps/studio/components/interfaces/Explorer/QueryCell/index.tsx
index bf225ba54c55a..2a2a6a8ff1f6f 100644
--- a/apps/studio/components/interfaces/Explorer/QueryCell/index.tsx
+++ b/apps/studio/components/interfaces/Explorer/QueryCell/index.tsx
@@ -120,6 +120,7 @@ export const QueryCell = ({ cell }: QueryCellProps) => {
diff --git a/apps/studio/components/interfaces/Organization/BillingSettings/Subscription/DowngradeModal.tsx b/apps/studio/components/interfaces/Organization/BillingSettings/Subscription/DowngradeModal.tsx
index 5b4dd4f5ed970..13160f9235c62 100644
--- a/apps/studio/components/interfaces/Organization/BillingSettings/Subscription/DowngradeModal.tsx
+++ b/apps/studio/components/interfaces/Organization/BillingSettings/Subscription/DowngradeModal.tsx
@@ -170,12 +170,6 @@ export const DowngradeModal = ({
-
- {subscription?.billing_via_partner === true && subscription.billing_partner === 'fly' && (
-
- Your organization will be downgraded at the end of your current billing cycle.
-
- )}
- {billingViaPartner &&
- billingPartner === 'fly' &&
- subscriptionPreview?.plan_change_type === 'downgrade' && (
-
- Your organization will be downgraded at the end of your current billing
- cycle.
-
- )}
)}
diff --git a/apps/studio/components/interfaces/SQLEditor/UtilityPanel/QuerySourceMenu/DatabaseSubMenu.tsx b/apps/studio/components/interfaces/QuerySources/DatabaseParametersSubMenu.tsx
similarity index 74%
rename from apps/studio/components/interfaces/SQLEditor/UtilityPanel/QuerySourceMenu/DatabaseSubMenu.tsx
rename to apps/studio/components/interfaces/QuerySources/DatabaseParametersSubMenu.tsx
index 59458d69a99b6..f946f4e03f848 100644
--- a/apps/studio/components/interfaces/SQLEditor/UtilityPanel/QuerySourceMenu/DatabaseSubMenu.tsx
+++ b/apps/studio/components/interfaces/QuerySources/DatabaseParametersSubMenu.tsx
@@ -1,4 +1,4 @@
-import { LOCAL_STORAGE_KEYS, useParams } from 'common'
+import { useParams } from 'common'
import { Check, Plus } from 'lucide-react'
import Link from 'next/link'
import {
@@ -12,9 +12,6 @@ import {
import { useReadReplicasQuery } from '@/data/read-replicas/replicas-query'
import { formatDatabaseID, formatDatabaseRegion } from '@/data/read-replicas/replicas.utils'
import { useIsFeatureEnabled } from '@/hooks/misc/useIsFeatureEnabled'
-import { useLocalStorageQuery } from '@/hooks/misc/useLocalStorage'
-import { useDatabaseSelectorStateSnapshot } from '@/state/database-selector'
-import { useSqlEditorSessionSnapshot } from '@/state/sql-editor/sql-editor-session-state'
/** The label a database row/summary shows: the primary, or a replica by region + id. */
function databaseLabel(identifier: string, region: string, projectRef: string | undefined) {
@@ -22,35 +19,27 @@ function databaseLabel(identifier: string, region: string, projectRef: string |
return `Read replica (${formatDatabaseRegion(region)} - ${formatDatabaseID(identifier)})`
}
-export const DatabaseSubMenu = ({ id }: { id: string }) => {
+export const DatabaseParametersSubMenu = ({
+ identifier,
+ onIdentifierChange,
+}: {
+ identifier?: string
+ onIdentifierChange: (identifier: string) => void
+}) => {
const { ref: projectRef } = useParams()
- const sessionSnap = useSqlEditorSessionSnapshot()
- const dbSelector = useDatabaseSelectorStateSnapshot()
const { infrastructureReadReplicas } = useIsFeatureEnabled(['infrastructure:read_replicas'])
- const [lastSelectedDb, setLastSelectedDb] = useLocalStorageQuery(
- LOCAL_STORAGE_KEYS.SQL_EDITOR_LAST_SELECTED_DB(projectRef ?? ''),
- ''
- )
-
const { data } = useReadReplicasQuery({ projectRef })
const databases = (data ?? [])
.slice()
.sort((a, b) => (a.inserted_at > b.inserted_at ? 1 : 0))
.sort((database) => (database.identifier === projectRef ? -1 : 0))
- const selectedDatabaseId =
- lastSelectedDb.length > 0 ? lastSelectedDb : (dbSelector.selectedDatabaseId ?? projectRef)
+ const selectedDatabaseId = identifier ?? projectRef
const selectedDatabase = databases.find((db) => db.identifier === selectedDatabaseId)
const newReplicaURL = `/project/${projectRef}/database/replication?destinationType=Read+Replica`
- const handleSelect = (databaseId: string) => {
- dbSelector.setSelectedDatabaseId(databaseId)
- setLastSelectedDb(databaseId)
- sessionSnap.resetResult(id)
- }
-
return (
@@ -71,7 +60,7 @@ export const DatabaseSubMenu = ({ id }: { id: string }) => {
key={database.identifier}
className="justify-between"
disabled={isUnhealthy}
- onClick={() => handleSelect(database.identifier)}
+ onClick={() => onIdentifierChange(database.identifier)}
>
{databaseLabel(database.identifier, database.region, projectRef)}
{database.identifier === selectedDatabaseId && }
diff --git a/apps/studio/components/interfaces/QuerySources/LogTimeRange.utils.test.ts b/apps/studio/components/interfaces/QuerySources/LogTimeRange.utils.test.ts
new file mode 100644
index 0000000000000..f12ec9cef6624
--- /dev/null
+++ b/apps/studio/components/interfaces/QuerySources/LogTimeRange.utils.test.ts
@@ -0,0 +1,114 @@
+import dayjs from 'dayjs'
+import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
+
+import {
+ customDateRangeToLogTimeRange,
+ datePickerValueToLogTimeRange,
+ logTimeRangesEqual,
+ logTimeRangeToDatePickerValue,
+ resolveLogTimeRange,
+} from './LogTimeRange.utils'
+import { generateDynamicHelper } from '@/components/interfaces/Settings/Logs/Logs.datePickerHelpers'
+import {
+ DEFAULT_LOG_TIME_RANGE,
+ type LogTimeRange,
+} from '@/data/query-sources/query-source-registry'
+
+describe('LogTimeRange.utils', () => {
+ beforeEach(() => {
+ vi.useFakeTimers()
+ vi.setSystemTime(new Date('2025-01-08T12:00:00.000Z'))
+ })
+
+ afterEach(() => vi.useRealTimers())
+
+ it.each([
+ ['30m', 30, 'minute'],
+ ['2h', 2, 'hour'],
+ ['7d', 7, 'day'],
+ ] as const)('round-trips the picker helper for %s', (_, amount, unit) => {
+ const helper = generateDynamicHelper(amount, unit)
+ const pickerValue = {
+ from: helper.calcFrom(),
+ to: helper.calcTo(),
+ isHelper: true,
+ text: helper.text,
+ }
+ const range: LogTimeRange = { type: 'relative', amount, unit }
+
+ expect(datePickerValueToLogTimeRange(pickerValue)).toEqual(range)
+ expect(logTimeRangeToDatePickerValue(range)).toEqual(pickerValue)
+ })
+
+ it('falls back to the default when a custom value has no valid start', () => {
+ expect(datePickerValueToLogTimeRange({ from: '', to: '', isHelper: false })).toEqual(
+ DEFAULT_LOG_TIME_RANGE
+ )
+ })
+
+ it('uses now when an absolute helper has an empty end', () => {
+ expect(
+ datePickerValueToLogTimeRange({
+ from: '2025-01-01T00:00:00.000Z',
+ to: '',
+ isHelper: true,
+ text: 'Custom',
+ })
+ ).toEqual({
+ type: 'absolute',
+ from: '2025-01-01T00:00:00.000Z',
+ to: '2025-01-08T12:00:00.000Z',
+ })
+ })
+
+ it('compares relative and absolute ranges structurally', () => {
+ expect(
+ logTimeRangesEqual(
+ { type: 'relative', amount: 1, unit: 'hour' },
+ { type: 'relative', amount: 1, unit: 'hour' }
+ )
+ ).toBe(true)
+ expect(
+ logTimeRangesEqual(
+ { type: 'relative', amount: 1, unit: 'hour' },
+ { type: 'relative', amount: 1, unit: 'day' }
+ )
+ ).toBe(false)
+ expect(
+ logTimeRangesEqual(
+ { type: 'absolute', from: '2025-01-01T00:00:00.000Z', to: '2025-01-02T00:00:00.000Z' },
+ { type: 'absolute', from: '2025-01-01T00:00:00.000Z', to: '2025-01-02T00:00:00.000Z' }
+ )
+ ).toBe(true)
+ })
+
+ it('resolves a relative range against the current time', () => {
+ expect(resolveLogTimeRange({ type: 'relative', amount: 2, unit: 'day' })).toEqual({
+ from: dayjs().subtract(2, 'day').toISOString(),
+ to: dayjs().toISOString(),
+ })
+ })
+
+ it('passes an absolute range through unchanged', () => {
+ const range: LogTimeRange = {
+ type: 'absolute',
+ from: '2025-01-01T00:00:00.000Z',
+ to: '2025-01-02T00:00:00.000Z',
+ }
+ expect(resolveLogTimeRange(range)).toEqual({ from: range.from, to: range.to })
+ })
+
+ it('clamps a custom range ending today to now', () => {
+ const from = new Date('2025-01-07T09:00:00.000Z')
+ expect(
+ customDateRangeToLogTimeRange({
+ from,
+ to: new Date('2025-01-08T09:00:00.000Z'),
+ })
+ ).toEqual({
+ type: 'absolute',
+ from: dayjs(from).startOf('day').toISOString(),
+ to: '2025-01-08T12:00:00.000Z',
+ })
+ })
+})
diff --git a/apps/studio/components/interfaces/QuerySources/LogTimeRange.utils.ts b/apps/studio/components/interfaces/QuerySources/LogTimeRange.utils.ts
new file mode 100644
index 0000000000000..4dd9f9ff10078
--- /dev/null
+++ b/apps/studio/components/interfaces/QuerySources/LogTimeRange.utils.ts
@@ -0,0 +1,97 @@
+import dayjs from 'dayjs'
+
+import { generateDynamicHelper } from '@/components/interfaces/Settings/Logs/Logs.datePickerHelpers'
+import type { DatePickerValue } from '@/components/interfaces/Settings/Logs/Logs.DatePickers'
+import type { ResolvedLogDateRange } from '@/components/interfaces/Settings/Logs/logsDateRange'
+import {
+ DEFAULT_LOG_TIME_RANGE,
+ type LogTimeRange,
+} from '@/data/query-sources/query-source-registry'
+import { isoDateTimeString, type IsoDateTimeString } from '@/lib/iso-datetime'
+
+export type RelativeTimeUnit = Extract['unit']
+
+const nowIsoDateTime = (): IsoDateTimeString => dayjs().toISOString() as IsoDateTimeString
+
+function parseRelativeHelperLabel(
+ text: string | undefined
+): { amount: number; unit: RelativeTimeUnit } | null {
+ if (!text) return null
+ const match = text
+ .trim()
+ .toLowerCase()
+ .match(/^last\s+(?:(\d+)\s+)?(minute|hour|day)s?$/)
+ if (!match) return null
+
+ const amount = match[1] ? parseInt(match[1], 10) : 1
+ if (!Number.isFinite(amount) || amount <= 0) return null
+
+ const unit = match[2]
+ if (unit !== 'minute' && unit !== 'hour' && unit !== 'day') return null
+ return { amount, unit }
+}
+
+export function datePickerValueToLogTimeRange(value: DatePickerValue): LogTimeRange {
+ if (value.isHelper) {
+ const relative = parseRelativeHelperLabel(value.text)
+ if (relative) return { type: 'relative', ...relative }
+ }
+
+ const from = isoDateTimeString(value.from)
+ if (from === null) return DEFAULT_LOG_TIME_RANGE
+ const to = isoDateTimeString(value.to) ?? nowIsoDateTime()
+ return { type: 'absolute', from, to }
+}
+
+export function logTimeRangeToDatePickerValue(range: LogTimeRange): DatePickerValue {
+ if (range.type === 'relative') {
+ const helper = generateDynamicHelper(range.amount, range.unit)
+ return {
+ from: helper.calcFrom(),
+ to: helper.calcTo(),
+ isHelper: true,
+ text: helper.text,
+ }
+ }
+ return { from: range.from, to: range.to, isHelper: false }
+}
+
+export function customDateRangeToLogTimeRange({
+ from,
+ to,
+ now = new Date(),
+}: {
+ from: Date
+ to: Date
+ now?: Date
+}): Extract {
+ const nowValue = dayjs(now)
+ const requestedTo = dayjs(to).endOf('day')
+
+ return {
+ type: 'absolute',
+ from: dayjs(from).startOf('day').toISOString(),
+ to: requestedTo.isAfter(nowValue) ? nowValue.toISOString() : requestedTo.toISOString(),
+ }
+}
+
+export function logTimeRangesEqual(a: LogTimeRange, b: LogTimeRange): boolean {
+ if (a.type === 'relative' && b.type === 'relative') {
+ return a.amount === b.amount && a.unit === b.unit
+ }
+ if (a.type === 'absolute' && b.type === 'absolute') {
+ return a.from === b.from && a.to === b.to
+ }
+ return false
+}
+
+export function resolveLogTimeRange(range: LogTimeRange): ResolvedLogDateRange {
+ if (range.type === 'relative') {
+ const now = dayjs()
+ return {
+ from: now.subtract(range.amount, range.unit).toISOString(),
+ to: now.toISOString(),
+ }
+ }
+ return { from: range.from, to: range.to }
+}
diff --git a/apps/studio/components/interfaces/SQLEditor/UtilityPanel/QuerySourceMenu/LogsCustomRangeDialog.tsx b/apps/studio/components/interfaces/QuerySources/LogsCustomRangeDialog.tsx
similarity index 100%
rename from apps/studio/components/interfaces/SQLEditor/UtilityPanel/QuerySourceMenu/LogsCustomRangeDialog.tsx
rename to apps/studio/components/interfaces/QuerySources/LogsCustomRangeDialog.tsx
diff --git a/apps/studio/components/interfaces/QuerySources/LogsTimeRangeSubMenu.test.tsx b/apps/studio/components/interfaces/QuerySources/LogsTimeRangeSubMenu.test.tsx
new file mode 100644
index 0000000000000..80d4c0fac1c4a
--- /dev/null
+++ b/apps/studio/components/interfaces/QuerySources/LogsTimeRangeSubMenu.test.tsx
@@ -0,0 +1,57 @@
+import { screen } from '@testing-library/react'
+import userEvent from '@testing-library/user-event'
+import { mockAnimationsApi } from 'jsdom-testing-mocks'
+import { DropdownMenu, DropdownMenuContent, DropdownMenuTrigger } from 'ui'
+import { describe, expect, it, vi } from 'vitest'
+
+import { LogsTimeRangeSubMenu } from './LogsTimeRangeSubMenu'
+import { customRender } from '@/tests/lib/custom-render'
+
+mockAnimationsApi()
+
+vi.mock('@/hooks/misc/useCheckEntitlements', () => ({
+ useCheckEntitlements: () => ({ getEntitlementNumericValue: () => 1 }),
+}))
+
+const renderSubMenu = ({
+ onRangeChange = vi.fn(),
+ onOpenCustomRange = vi.fn(),
+ onShowUpgrade = vi.fn(),
+} = {}) => {
+ customRender(
+
+ Open
+
+
+
+
+ )
+
+ return { onRangeChange, onOpenCustomRange, onShowUpgrade }
+}
+
+describe('LogsTimeRangeSubMenu', () => {
+ it('opens the upgrade prompt instead of applying a range beyond retention', async () => {
+ const { onRangeChange, onShowUpgrade } = renderSubMenu()
+
+ await userEvent.hover(await screen.findByText('Time range'))
+ await userEvent.click(await screen.findByText('Last 7 days'))
+
+ expect(onShowUpgrade).toHaveBeenCalledOnce()
+ expect(onRangeChange).not.toHaveBeenCalled()
+ })
+
+ it('exposes the custom-range action', async () => {
+ const { onOpenCustomRange } = renderSubMenu()
+
+ await userEvent.hover(await screen.findByText('Time range'))
+ await userEvent.click(await screen.findByText('Custom range…'))
+
+ expect(onOpenCustomRange).toHaveBeenCalledOnce()
+ })
+})
diff --git a/apps/studio/components/interfaces/SQLEditor/UtilityPanel/QuerySourceMenu/TimeRangeSubMenu.tsx b/apps/studio/components/interfaces/QuerySources/LogsTimeRangeSubMenu.tsx
similarity index 80%
rename from apps/studio/components/interfaces/SQLEditor/UtilityPanel/QuerySourceMenu/TimeRangeSubMenu.tsx
rename to apps/studio/components/interfaces/QuerySources/LogsTimeRangeSubMenu.tsx
index f633d4a8a58be..9830e206a14c4 100644
--- a/apps/studio/components/interfaces/SQLEditor/UtilityPanel/QuerySourceMenu/TimeRangeSubMenu.tsx
+++ b/apps/studio/components/interfaces/QuerySources/LogsTimeRangeSubMenu.tsx
@@ -8,42 +8,37 @@ import {
DropdownMenuSubTrigger,
} from 'ui'
-import {
- datePickerValueToLogDateRange,
- logDateRangesEqual,
- type LogDateRange,
-} from '../../querySource'
+import { datePickerValueToLogTimeRange, logTimeRangesEqual } from './LogTimeRange.utils'
import { EXPLORER_DATEPICKER_HELPERS } from '@/components/interfaces/Settings/Logs/Logs.constants'
import { maybeShowUpgradePromptIfNotEntitled } from '@/components/interfaces/Settings/Logs/Logs.utils'
+import type { LogTimeRange } from '@/data/query-sources/query-source-registry'
import { useCheckEntitlements } from '@/hooks/misc/useCheckEntitlements'
-import { useSqlEditorSessionSnapshot } from '@/state/sql-editor/sql-editor-session-state'
-export const TimeRangeSubMenu = ({
- id,
+export const LogsTimeRangeSubMenu = ({
range,
+ onRangeChange,
onOpenCustomRange,
onShowUpgrade,
}: {
- id: string
- range: LogDateRange
+ range: LogTimeRange
+ onRangeChange: (range: LogTimeRange) => void
onOpenCustomRange: () => void
onShowUpgrade: () => void
}) => {
- const sessionSnap = useSqlEditorSessionSnapshot()
const { getEntitlementNumericValue } = useCheckEntitlements('log.retention_days')
const entitledToLogDays = getEntitlementNumericValue()
- const isCustomRange = range.kind === 'absolute'
+ const isCustomRange = range.type === 'absolute'
const presets = EXPLORER_DATEPICKER_HELPERS.map((helper) => ({
helper,
- range: datePickerValueToLogDateRange({
+ range: datePickerValueToLogTimeRange({
from: helper.calcFrom(),
to: helper.calcTo(),
isHelper: true,
text: helper.text,
}),
}))
- const selectedPreset = presets.find((preset) => logDateRangesEqual(range, preset.range))
+ const selectedPreset = presets.find((preset) => logTimeRangesEqual(range, preset.range))
return (
@@ -59,7 +54,7 @@ export const TimeRangeSubMenu = ({
{presets.map(({ helper, range: presetRange }) => {
- const isSelected = !isCustomRange && logDateRangesEqual(range, presetRange)
+ const isSelected = !isCustomRange && logTimeRangesEqual(range, presetRange)
const isLocked = maybeShowUpgradePromptIfNotEntitled(helper.calcFrom(), entitledToLogDays)
return (
@@ -68,7 +63,7 @@ export const TimeRangeSubMenu = ({
className="justify-between"
onClick={() => {
if (isLocked) return onShowUpgrade()
- sessionSnap.setLogRange(id, presetRange)
+ onRangeChange(presetRange)
}}
>
{helper.text}
diff --git a/apps/studio/components/interfaces/QuerySources/QuerySourceIcon.tsx b/apps/studio/components/interfaces/QuerySources/QuerySourceIcon.tsx
new file mode 100644
index 0000000000000..a1d635866ba00
--- /dev/null
+++ b/apps/studio/components/interfaces/QuerySources/QuerySourceIcon.tsx
@@ -0,0 +1,15 @@
+import { Database, ScrollText } from 'lucide-react'
+
+import type { QuerySourceId } from '@/data/query-sources/query-source-registry'
+
+export const QuerySourceIcon = ({
+ source,
+ className,
+}: {
+ source: QuerySourceId
+ className?: string
+}) => {
+ const props = { className, size: 16, strokeWidth: 2 }
+
+ return source === 'logs' ? :
+}
diff --git a/apps/studio/components/interfaces/QuerySources/useLogsCustomRange.ts b/apps/studio/components/interfaces/QuerySources/useLogsCustomRange.ts
new file mode 100644
index 0000000000000..43e103d82c262
--- /dev/null
+++ b/apps/studio/components/interfaces/QuerySources/useLogsCustomRange.ts
@@ -0,0 +1,35 @@
+import { useState } from 'react'
+
+import { customDateRangeToLogTimeRange } from './LogTimeRange.utils'
+import { maybeShowUpgradePromptIfNotEntitled } from '@/components/interfaces/Settings/Logs/Logs.utils'
+import type { LogTimeRange } from '@/data/query-sources/query-source-registry'
+import { useCheckEntitlements } from '@/hooks/misc/useCheckEntitlements'
+
+export function useLogsCustomRange({
+ onRangeChange,
+}: {
+ onRangeChange: (range: LogTimeRange) => void
+}) {
+ const [isCustomRangeOpen, setIsCustomRangeOpen] = useState(false)
+ const [showUpgradePrompt, setShowUpgradePrompt] = useState(false)
+ const { getEntitlementNumericValue } = useCheckEntitlements('log.retention_days')
+ const entitledToLogDays = getEntitlementNumericValue()
+
+ const handleApplyCustomRange = ({ from, to }: { from: Date; to: Date }) => {
+ const range = customDateRangeToLogTimeRange({ from, to })
+ if (maybeShowUpgradePromptIfNotEntitled(range.from, entitledToLogDays)) {
+ setShowUpgradePrompt(true)
+ return
+ }
+
+ onRangeChange(range)
+ }
+
+ return {
+ isCustomRangeOpen,
+ setIsCustomRangeOpen,
+ showUpgradePrompt,
+ setShowUpgradePrompt,
+ handleApplyCustomRange,
+ }
+}
diff --git a/apps/studio/components/interfaces/SQLEditor/UtilityPanel/QuerySourceMenu/QuerySourceMenu.tsx b/apps/studio/components/interfaces/SQLEditor/UtilityPanel/QuerySourceMenu/QuerySourceMenu.tsx
index 9e08a904d5059..d741dc3535e7f 100644
--- a/apps/studio/components/interfaces/SQLEditor/UtilityPanel/QuerySourceMenu/QuerySourceMenu.tsx
+++ b/apps/studio/components/interfaces/SQLEditor/UtilityPanel/QuerySourceMenu/QuerySourceMenu.tsx
@@ -1,8 +1,6 @@
-import { useParams } from 'common'
-import dayjs from 'dayjs'
-import { Check, ChevronDown, Database, ScrollText } from 'lucide-react'
+import { LOCAL_STORAGE_KEYS, useParams } from 'common'
+import { Check, ChevronDown } from 'lucide-react'
import { useRouter } from 'next/router'
-import { useState } from 'react'
import {
Button,
DropdownMenu,
@@ -12,32 +10,23 @@ import {
DropdownMenuTrigger,
} from 'ui'
-import {
- datePickerValueToLogDateRange,
- type QuerySource,
- type SqlSnippetSource,
-} from '../../querySource'
-import { DatabaseSubMenu } from './DatabaseSubMenu'
-import { LogsCustomRangeDialog } from './LogsCustomRangeDialog'
+import { type QuerySource, type SqlSnippetSource } from '../../querySource'
import { resolveSourceSwitch } from './QuerySourceMenu.utils'
import { RowLimitSubMenu } from './RowLimitSubMenu'
import { RunAsSubMenu } from './RunAsSubMenu'
-import { TimeRangeSubMenu } from './TimeRangeSubMenu'
-import { maybeShowUpgradePromptIfNotEntitled } from '@/components/interfaces/Settings/Logs/Logs.utils'
+import { DatabaseParametersSubMenu } from '@/components/interfaces/QuerySources/DatabaseParametersSubMenu'
+import { LogsCustomRangeDialog } from '@/components/interfaces/QuerySources/LogsCustomRangeDialog'
+import { LogsTimeRangeSubMenu } from '@/components/interfaces/QuerySources/LogsTimeRangeSubMenu'
+import { QuerySourceIcon } from '@/components/interfaces/QuerySources/QuerySourceIcon'
+import { useLogsCustomRange } from '@/components/interfaces/QuerySources/useLogsCustomRange'
import UpgradePrompt from '@/components/interfaces/Settings/Logs/UpgradePrompt'
-import { useCheckEntitlements } from '@/hooks/misc/useCheckEntitlements'
+import { QUERY_SOURCE_LABELS, QUERY_SOURCES } from '@/data/query-sources/query-source-registry'
+import { useLocalStorageQuery } from '@/hooks/misc/useLocalStorage'
import { IS_PLATFORM } from '@/lib/constants'
+import { useDatabaseSelectorStateSnapshot } from '@/state/database-selector'
import { useSqlEditorSessionSnapshot } from '@/state/sql-editor/sql-editor-session-state'
import { useSqlEditorV2StateSnapshot } from '@/state/sql-editor/sql-editor-state'
-const SOURCE_LABEL: Record = {
- database: 'Database',
- logs: 'Logs',
-}
-
-const SourceIcon = ({ source, ...props }: { source: SqlSnippetSource; className?: string }) =>
- source === 'logs' ? :
-
type QuerySourceMenuProps = {
id: string
runSource: QuerySource
@@ -67,18 +56,33 @@ export const QuerySourceMenu = ({ id, runSource, canCreateLogsSnippet }: QuerySo
const router = useRouter()
const snapV2 = useSqlEditorV2StateSnapshot()
const sessionSnap = useSqlEditorSessionSnapshot()
+ const databaseSelector = useDatabaseSelectorStateSnapshot()
+ const [lastSelectedDatabase, setLastSelectedDatabase] = useLocalStorageQuery(
+ LOCAL_STORAGE_KEYS.SQL_EDITOR_LAST_SELECTED_DB(ref ?? ''),
+ ''
+ )
- const [isCustomRangeOpen, setIsCustomRangeOpen] = useState(false)
- const [showUpgradePrompt, setShowUpgradePrompt] = useState(false)
-
- const { getEntitlementNumericValue } = useCheckEntitlements('log.retention_days')
- const entitledToLogDays = getEntitlementNumericValue()
+ const {
+ isCustomRangeOpen,
+ setIsCustomRangeOpen,
+ showUpgradePrompt,
+ setShowUpgradePrompt,
+ handleApplyCustomRange,
+ } = useLogsCustomRange({ onRangeChange: (range) => sessionSnap.setLogRange(id, range) })
const currentSource = runSource.type
const isLogs = currentSource === 'logs'
// A snippet materializes in the store on its first keystroke; until then a
// `/sql/new` tab is a blank scaffold with nothing to preserve.
const isBlankNewTab = snapV2.snippets[id] === undefined
+ const databaseIdentifier =
+ lastSelectedDatabase.length > 0
+ ? lastSelectedDatabase
+ : (databaseSelector.selectedDatabaseId ?? ref)
+
+ const selectableSources = QUERY_SOURCES.filter(
+ (source) => source.type !== 'logs' || canCreateLogsSnippet || isLogs
+ )
const switchSource = (target: SqlSnippetSource) => {
const next = resolveSourceSwitch({ ref, target, currentSource, isBlankNewTab })
@@ -86,20 +90,10 @@ export const QuerySourceMenu = ({ id, runSource, canCreateLogsSnippet }: QuerySo
router[next.method](next.url)
}
- const applyCustomRange = ({ from, to }: { from: Date; to: Date }) => {
- const fromIso = dayjs(from).startOf('day').toISOString()
- if (maybeShowUpgradePromptIfNotEntitled(fromIso, entitledToLogDays)) {
- setShowUpgradePrompt(true)
- return
- }
- sessionSnap.setLogRange(
- id,
- datePickerValueToLogDateRange({
- from: fromIso,
- to: dayjs(to).endOf('day').toISOString(),
- isHelper: false,
- })
- )
+ const updateDatabaseIdentifier = (identifier: string) => {
+ databaseSelector.setSelectedDatabaseId(identifier)
+ setLastSelectedDatabase(identifier)
+ sessionSnap.resetResult(id)
}
return (
@@ -108,55 +102,48 @@ export const QuerySourceMenu = ({ id, runSource, canCreateLogsSnippet }: QuerySo
}
+ aria-label={`Query source: ${QUERY_SOURCE_LABELS[currentSource]}`}
+ icon={}
iconRight={}
>
- {SOURCE_LABEL[currentSource]}
+ {QUERY_SOURCE_LABELS[currentSource]}
- {
- e.preventDefault()
- switchSource('database')
- }}
- >
-
-
- Database
-
- {!isLogs && }
-
- {(canCreateLogsSnippet || isLogs) && (
+ {selectableSources.map((source) => (
{
e.preventDefault()
- switchSource('logs')
+ switchSource(source.id)
}}
>
-
- Logs
+
+ {QUERY_SOURCE_LABELS[source.id]}
- {isLogs && }
+ {currentSource === source.id && }
- )}
+ ))}
{runSource.type === 'logs' ? (
- sessionSnap.setLogRange(id, range)}
onOpenCustomRange={() => setIsCustomRangeOpen(true)}
onShowUpgrade={() => setShowUpgradePrompt(true)}
/>
) : (
<>
- {IS_PLATFORM && }
+ {IS_PLATFORM && (
+
+ )}
>
@@ -169,7 +156,7 @@ export const QuerySourceMenu = ({ id, runSource, canCreateLogsSnippet }: QuerySo
>
diff --git a/apps/studio/components/interfaces/SQLEditor/querySource.test.ts b/apps/studio/components/interfaces/SQLEditor/querySource.test.ts
index 6c68f56e2db46..93f38dcfa7278 100644
--- a/apps/studio/components/interfaces/SQLEditor/querySource.test.ts
+++ b/apps/studio/components/interfaces/SQLEditor/querySource.test.ts
@@ -1,43 +1,11 @@
-import dayjs from 'dayjs'
-import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
+import { describe, expect, it } from 'vitest'
import {
- datePickerValueToLogDateRange,
- DEFAULT_LOG_DATE_RANGE,
getSnippetSource,
isLogsSource,
- logDateRangesEqual,
- logDateRangeToDatePickerValue,
- resolveLogRunRange,
resolveSnippetSource,
sqlSourceToFenceLanguage,
- type LogDateRange,
} from './querySource'
-import {
- EXPLORER_DATEPICKER_HELPERS,
- getDefaultHelper,
-} from '@/components/interfaces/Settings/Logs/Logs.constants'
-import { generateHelpersFromInput } from '@/components/interfaces/Settings/Logs/Logs.datePickerHelpers'
-import type { DatePickerValue } from '@/components/interfaces/Settings/Logs/Logs.DatePickers'
-import type { DatetimeHelper } from '@/components/interfaces/Settings/Logs/Logs.types'
-import { isoDateTimeString } from '@/lib/iso-datetime'
-
-/** Build the `DatePickerValue` the Logs picker submits when a helper is selected. */
-const valueFromHelper = (helper: DatetimeHelper): DatePickerValue => ({
- from: helper.calcFrom(),
- to: helper.calcTo(),
- isHelper: true,
- text: helper.text,
-})
-
-/** The single dynamic helper produced from typed input like "2h" / "30m". */
-const dynamicHelper = (input: string): DatetimeHelper => {
- const generated = generateHelpersFromInput(input)
- if (!generated || generated.length !== 1) {
- throw new Error(`Expected a single dynamic helper for "${input}"`)
- }
- return generated[0]
-}
describe('querySource.ts:getSnippetSource', () => {
it('maps log_sql to the logs source', () => {
@@ -91,221 +59,3 @@ describe('querySource.ts:resolveSnippetSource', () => {
expect(resolveSnippetSource(undefined, 'nonsense')).toBe('database')
})
})
-
-describe('querySource.ts:datePickerValueToLogDateRange', () => {
- it('parses every static preset into a relative range', () => {
- const cases: Array<[string, { amount: number; unit: 'minute' | 'hour' | 'day' }]> = [
- ['Last hour', { amount: 1, unit: 'hour' }],
- ['Last 3 hours', { amount: 3, unit: 'hour' }],
- ['Last 24 hours', { amount: 24, unit: 'hour' }],
- ['Last 3 days', { amount: 3, unit: 'day' }],
- ['Last 7 days', { amount: 7, unit: 'day' }],
- ]
-
- for (const [text, last] of cases) {
- const helper = EXPLORER_DATEPICKER_HELPERS.find((h) => h.text === text)
- expect(helper, `preset "${text}" exists`).toBeDefined()
- expect(datePickerValueToLogDateRange(valueFromHelper(helper!))).toEqual({
- kind: 'relative',
- last,
- })
- }
- })
-
- it('parses dynamic helpers ("2h", "30m", "7d") into relative ranges', () => {
- expect(datePickerValueToLogDateRange(valueFromHelper(dynamicHelper('2h')))).toEqual({
- kind: 'relative',
- last: { amount: 2, unit: 'hour' },
- })
- expect(datePickerValueToLogDateRange(valueFromHelper(dynamicHelper('30m')))).toEqual({
- kind: 'relative',
- last: { amount: 30, unit: 'minute' },
- })
- expect(datePickerValueToLogDateRange(valueFromHelper(dynamicHelper('7d')))).toEqual({
- kind: 'relative',
- last: { amount: 7, unit: 'day' },
- })
- })
-
- it('treats a preset (calcTo() === "") as relative — the empty end means "now"', () => {
- const lastHour = getDefaultHelper(EXPLORER_DATEPICKER_HELPERS)
- const value = valueFromHelper(lastHour)
- expect(value.to).toBe('')
- expect(datePickerValueToLogDateRange(value)).toEqual({
- kind: 'relative',
- last: { amount: 1, unit: 'hour' },
- })
- })
-
- it('degrades an unparseable helper to an absolute range using from/now (never empty)', () => {
- vi.useFakeTimers()
- const now = new Date('2025-01-01T12:00:00.000Z')
- vi.setSystemTime(now)
-
- const from = '2024-12-31T00:00:00.000Z'
- const result = datePickerValueToLogDateRange({
- from,
- to: '',
- isHelper: true,
- text: 'Some custom label',
- })
-
- expect(result).toEqual({
- kind: 'absolute',
- from,
- to: dayjs(now).toISOString(),
- })
- })
-
- it('maps a custom (non-helper) pick to an absolute range with both endpoints', () => {
- const from = '2025-01-01T00:00:00.000Z'
- const to = '2025-01-02T00:00:00.000Z'
- expect(datePickerValueToLogDateRange({ from, to, isHelper: false })).toEqual({
- kind: 'absolute',
- from,
- to,
- })
- })
-
- it('falls back to the default range when the value has no usable from', () => {
- expect(datePickerValueToLogDateRange({ from: '', to: '', isHelper: false })).toEqual(
- DEFAULT_LOG_DATE_RANGE
- )
- })
-})
-
-describe('querySource.ts:logDateRangeToDatePickerValue', () => {
- beforeEach(() => {
- vi.useFakeTimers()
- vi.setSystemTime(new Date('2025-01-01T12:00:00.000Z'))
- })
-
- it('renders a relative range exactly as the picker would emit the helper', () => {
- const value = logDateRangeToDatePickerValue({
- kind: 'relative',
- last: { amount: 1, unit: 'hour' },
- })
- expect(value).toEqual({
- from: dayjs().subtract(1, 'hour').toISOString(),
- to: dayjs().toISOString(),
- isHelper: true,
- text: 'Last 1 hour',
- })
- })
-
- it('pluralizes the label for amounts greater than one', () => {
- expect(
- logDateRangeToDatePickerValue({ kind: 'relative', last: { amount: 3, unit: 'day' } }).text
- ).toBe('Last 3 days')
- })
-
- it('round-trips through datePickerValueToLogDateRange', () => {
- const range: LogDateRange = { kind: 'relative', last: { amount: 30, unit: 'minute' } }
- expect(datePickerValueToLogDateRange(logDateRangeToDatePickerValue(range))).toEqual(range)
- })
-
- it('passes an absolute range through as a non-helper value', () => {
- const range: LogDateRange = {
- kind: 'absolute',
- from: isoDateTimeString('2025-01-01T00:00:00.000Z')!,
- to: isoDateTimeString('2025-01-02T00:00:00.000Z')!,
- }
- expect(logDateRangeToDatePickerValue(range)).toEqual({
- from: '2025-01-01T00:00:00.000Z',
- to: '2025-01-02T00:00:00.000Z',
- isHelper: false,
- })
- })
-})
-
-describe('querySource.ts:resolveLogRunRange', () => {
- afterEach(() => {
- vi.useRealTimers()
- })
-
- it('re-resolves a relative range against the current time', () => {
- vi.useFakeTimers()
- const now = new Date('2025-06-15T08:30:00.000Z')
- vi.setSystemTime(now)
-
- expect(resolveLogRunRange({ kind: 'relative', last: { amount: 2, unit: 'hour' } })).toEqual({
- from: dayjs(now).subtract(2, 'hour').toISOString(),
- to: dayjs(now).toISOString(),
- })
- })
-
- it('re-resolves the same relative range differently as time advances', () => {
- vi.useFakeTimers()
- vi.setSystemTime(new Date('2025-06-15T08:00:00.000Z'))
- const first = resolveLogRunRange({ kind: 'relative', last: { amount: 1, unit: 'hour' } })
-
- vi.setSystemTime(new Date('2025-06-15T10:00:00.000Z'))
- const second = resolveLogRunRange({ kind: 'relative', last: { amount: 1, unit: 'hour' } })
-
- expect(first).not.toEqual(second)
- expect(second.to).toBe(dayjs('2025-06-15T10:00:00.000Z').toISOString())
- })
-
- it('passes an absolute range through unchanged', () => {
- const from = isoDateTimeString('2025-01-01T00:00:00.000Z')!
- const to = isoDateTimeString('2025-01-02T00:00:00.000Z')!
- expect(resolveLogRunRange({ kind: 'absolute', from, to })).toEqual({
- from: '2025-01-01T00:00:00.000Z',
- to: '2025-01-02T00:00:00.000Z',
- })
- })
-})
-
-describe('querySource.ts:logDateRangesEqual', () => {
- it('matches relative ranges on amount + unit regardless of label formatting', () => {
- const lastHourPreset = EXPLORER_DATEPICKER_HELPERS.find((h) => h.text === 'Last hour')!
- const presetRange = datePickerValueToLogDateRange({
- from: lastHourPreset.calcFrom(),
- to: lastHourPreset.calcTo(),
- isHelper: true,
- text: lastHourPreset.text,
- })
-
- expect(
- logDateRangesEqual(presetRange, { kind: 'relative', last: { amount: 1, unit: 'hour' } })
- ).toBe(true)
- })
-
- it('does not match relative ranges with a different amount or unit', () => {
- expect(
- logDateRangesEqual(
- { kind: 'relative', last: { amount: 1, unit: 'hour' } },
- { kind: 'relative', last: { amount: 3, unit: 'hour' } }
- )
- ).toBe(false)
- expect(
- logDateRangesEqual(
- { kind: 'relative', last: { amount: 1, unit: 'hour' } },
- { kind: 'relative', last: { amount: 1, unit: 'day' } }
- )
- ).toBe(false)
- })
-
- it('matches absolute ranges on their ISO endpoints', () => {
- const from = isoDateTimeString('2025-01-01T00:00:00.000Z')!
- const to = isoDateTimeString('2025-01-02T00:00:00.000Z')!
- expect(logDateRangesEqual({ kind: 'absolute', from, to }, { kind: 'absolute', from, to })).toBe(
- true
- )
- })
-
- it('never matches a relative range against an absolute one', () => {
- const from = isoDateTimeString('2025-01-01T00:00:00.000Z')!
- const to = isoDateTimeString('2025-01-02T00:00:00.000Z')!
- expect(
- logDateRangesEqual(
- { kind: 'relative', last: { amount: 1, unit: 'hour' } },
- {
- kind: 'absolute',
- from,
- to,
- }
- )
- ).toBe(false)
- })
-})
diff --git a/apps/studio/components/interfaces/SQLEditor/querySource.ts b/apps/studio/components/interfaces/SQLEditor/querySource.ts
index 4a1174f837537..49f57612446ce 100644
--- a/apps/studio/components/interfaces/SQLEditor/querySource.ts
+++ b/apps/studio/components/interfaces/SQLEditor/querySource.ts
@@ -1,11 +1,5 @@
-import dayjs from 'dayjs'
-
-import type { Unit } from '@/components/interfaces/Settings/Logs/Logs.datePickerHelpers'
-import { generateDynamicHelper } from '@/components/interfaces/Settings/Logs/Logs.datePickerHelpers'
-import type { DatePickerValue } from '@/components/interfaces/Settings/Logs/Logs.DatePickers'
-import type { ResolvedLogDateRange } from '@/components/interfaces/Settings/Logs/logsDateRange'
import type { Snippet } from '@/data/content/sql-folders-query'
-import { isoDateTimeString, type IsoDateTimeString } from '@/lib/iso-datetime'
+import { type LogTimeRange, type QuerySourceId } from '@/data/query-sources/query-source-registry'
/**
* Domain view of where a snippet's query runs. Derived from the content TYPE:
@@ -14,7 +8,7 @@ import { isoDateTimeString, type IsoDateTimeString } from '@/lib/iso-datetime'
* immutable — switching backends means creating a new snippet, not toggling this
* value.
*/
-export type SqlSnippetSource = 'database' | 'logs'
+export type SqlSnippetSource = QuerySourceId
/**
* The single reader every surface (AI, reports, tabs, nav, execution) uses to
@@ -61,128 +55,10 @@ export function resolveSnippetSource(
return snippet !== undefined ? getSnippetSource(snippet) : parseSqlSnippetSource(sourceParam)
}
-/** `now` as a branded ISO datetime — `toISOString()` is always valid ISO-8601. */
-function nowIsoDateTime(): IsoDateTimeString {
- return dayjs().toISOString() as IsoDateTimeString
-}
-
-/**
- * The units a relative log range is expressed in. Aliases the Logs date picker's
- * `Unit` so the two stay in lockstep rather than drifting as parallel unions.
- */
-export type RelativeTimeUnit = Unit
-
-/**
- * A log query's time range. Relative ranges are structural (amount + unit) and
- * re-resolve against `now` at every run — so a saved "last hour" always means the
- * hour before the run, not the hour before the snippet was opened. Absolute ranges
- * carry validated ISO datetimes and pass through unchanged.
- */
-export type LogDateRange =
- | { kind: 'relative'; last: { amount: number; unit: RelativeTimeUnit } }
- | { kind: 'absolute'; from: IsoDateTimeString; to: IsoDateTimeString }
-
-/** The range a freshly opened logs snippet starts with: the last hour. */
-export const DEFAULT_LOG_DATE_RANGE: LogDateRange = {
- kind: 'relative',
- last: { amount: 1, unit: 'hour' },
-}
-
/**
* The runtime query source for a snippet, pairing the database/logs discriminant
* with the extra state each backend needs to run. A logs run carries the active
* time range (session state, re-resolved at every run); a database run needs
* nothing beyond the connection the execution pipeline already resolves.
*/
-export type QuerySource = { type: 'database' } | { type: 'logs'; dateRange: LogDateRange }
-
-/**
- * Parse a date-picker helper's label (e.g. "Last hour", "Last 3 hours", "Last 30
- * minutes") into a relative amount/unit. Covers both the static presets in
- * `EXPLORER_DATEPICKER_HELPERS` and the dynamic helpers `generateHelpersFromInput`
- * produces from typed input like "2h"/"30m". A label with no number means one unit
- * ("Last hour"). Returns null for any other label.
- */
-function parseRelativeHelperLabel(
- text: string | undefined
-): { amount: number; unit: RelativeTimeUnit } | null {
- if (!text) return null
- const match = text
- .trim()
- .toLowerCase()
- .match(/^last\s+(?:(\d+)\s+)?(minute|hour|day)s?$/)
- if (!match) return null
- const amount = match[1] ? parseInt(match[1], 10) : 1
- if (!Number.isFinite(amount) || amount <= 0) return null
- const unit = match[2]
- if (unit !== 'minute' && unit !== 'hour' && unit !== 'day') return null
- return { amount, unit }
-}
-
-/**
- * Convert a Logs date-picker value into a `LogDateRange`. Helper picks (presets and
- * dynamic "2h"/"30m" helpers) become relative ranges by parsing the helper label;
- * a preset's `calcTo()` resolves to `''` (meaning "now"), which the relative variant
- * models implicitly. Everything else — custom calendar picks, or a helper whose label
- * we can't parse — becomes an absolute range with validated ISO datetimes, degrading
- * via `from`/now rather than rejecting an empty string. A value with no usable `from`
- * falls back to the default range.
- */
-export function datePickerValueToLogDateRange(value: DatePickerValue): LogDateRange {
- if (value.isHelper) {
- const relative = parseRelativeHelperLabel(value.text)
- if (relative) return { kind: 'relative', last: relative }
- }
-
- const from = isoDateTimeString(value.from)
- if (from === null) return DEFAULT_LOG_DATE_RANGE
- const to = isoDateTimeString(value.to) ?? nowIsoDateTime()
- return { kind: 'absolute', from, to }
-}
-
-/**
- * Render a `LogDateRange` back into a Logs date-picker value for display. Relative
- * ranges reuse the picker's own `generateDynamicHelper` to derive the resolved
- * `from`/`to` and matching "Last N unit(s)" label, so the value is byte-for-byte
- * what the picker itself would emit for that helper. Absolute ranges pass their
- * datetimes through.
- */
-export function logDateRangeToDatePickerValue(range: LogDateRange): DatePickerValue {
- if (range.kind === 'relative') {
- const helper = generateDynamicHelper(range.last.amount, range.last.unit)
- return { from: helper.calcFrom(), to: helper.calcTo(), isHelper: true, text: helper.text }
- }
- return { from: range.from, to: range.to, isHelper: false }
-}
-
-/**
- * Structural equality for two log date ranges. Relative ranges match on amount +
- * unit, NOT display text — "Last hour" and "Last 1 hour" render differently but
- * are the same range, so comparing labels is unreliable. Absolute ranges match on
- * their (validated) ISO endpoints.
- */
-export function logDateRangesEqual(a: LogDateRange, b: LogDateRange): boolean {
- if (a.kind === 'relative' && b.kind === 'relative') {
- return a.last.amount === b.last.amount && a.last.unit === b.last.unit
- }
- if (a.kind === 'absolute' && b.kind === 'absolute') {
- return a.from === b.from && a.to === b.to
- }
- return false
-}
-
-/**
- * Resolve a `LogDateRange` to concrete ISO endpoints for a run. Relative ranges
- * re-resolve against `now` (so "last hour" is always the hour before the run);
- * absolute ranges pass through. Reuses the Logs `ResolvedLogDateRange` shape.
- */
-export function resolveLogRunRange(range: LogDateRange): ResolvedLogDateRange {
- if (range.kind === 'relative') {
- const now = dayjs()
- return {
- from: now.subtract(range.last.amount, range.last.unit).toISOString(),
- to: now.toISOString(),
- }
- }
- return { from: range.from, to: range.to }
-}
+export type QuerySource = { type: 'database' } | { type: 'logs'; dateRange: LogTimeRange }
diff --git a/apps/studio/components/interfaces/SQLEditor/useLogsSqlExecution.test.tsx b/apps/studio/components/interfaces/SQLEditor/useLogsSqlExecution.test.tsx
index 38e3fb8634b26..97bd6bdd789ee 100644
--- a/apps/studio/components/interfaces/SQLEditor/useLogsSqlExecution.test.tsx
+++ b/apps/studio/components/interfaces/SQLEditor/useLogsSqlExecution.test.tsx
@@ -99,8 +99,9 @@ describe('useLogsSqlExecution', () => {
it('resolves a relative session range to a from/to window around now', async () => {
const captured = mockLogsAllOtel([])
sqlEditorSessionState.setLogRange(SNIPPET_ID, {
- kind: 'relative',
- last: { amount: 2, unit: 'hour' },
+ type: 'relative',
+ amount: 2,
+ unit: 'hour',
})
const { result } = renderLogsExecution()
diff --git a/apps/studio/components/interfaces/SQLEditor/useLogsSqlExecution.ts b/apps/studio/components/interfaces/SQLEditor/useLogsSqlExecution.ts
index 4c1c006bfd7b0..ddbd7fd3175b7 100644
--- a/apps/studio/components/interfaces/SQLEditor/useLogsSqlExecution.ts
+++ b/apps/studio/components/interfaces/SQLEditor/useLogsSqlExecution.ts
@@ -1,10 +1,13 @@
import { useFlag, useParams } from 'common'
import { useCallback } from 'react'
-import { DEFAULT_LOG_DATE_RANGE, resolveLogRunRange } from './querySource'
+import { resolveLogTimeRange } from '@/components/interfaces/QuerySources/LogTimeRange.utils'
import { useExecuteLogsSqlMutation } from '@/data/logs/execute-logs-sql-mutation'
-import { logsAllEndpointUrl } from '@/data/logs/logs-endpoint'
import { type SafeLogSqlFragment } from '@/data/logs/safe-analytics-sql'
+import {
+ DEFAULT_LOG_TIME_RANGE,
+ QUERY_SOURCE_REGISTRY,
+} from '@/data/query-sources/query-source-registry'
import { useTrack } from '@/lib/telemetry/track'
import {
getSqlEditorSessionSnapshot,
@@ -46,11 +49,11 @@ export function useLogsSqlExecution({ id }: UseLogsSqlExecutionArgs) {
// Re-read imperatively so a range picked immediately before the run is
// honored; relative ranges re-resolve against `now` here.
- const range = resolveLogRunRange(
- getSqlEditorSessionSnapshot().logRange[id] ?? DEFAULT_LOG_DATE_RANGE
+ const range = resolveLogTimeRange(
+ getSqlEditorSessionSnapshot().logRange[id] ?? DEFAULT_LOG_TIME_RANGE
)
- mutate({ projectRef, sql, range, endpoint: logsAllEndpointUrl(true) })
+ mutate({ projectRef, sql, range, endpoint: QUERY_SOURCE_REGISTRY.logs.endpoint })
track('sql_editor_query_run_button_clicked', { source: 'logs' })
},
diff --git a/apps/studio/components/interfaces/SQLEditor/useRunSource.test.tsx b/apps/studio/components/interfaces/SQLEditor/useRunSource.test.tsx
index 820caa97c00f9..3d63dece309ac 100644
--- a/apps/studio/components/interfaces/SQLEditor/useRunSource.test.tsx
+++ b/apps/studio/components/interfaces/SQLEditor/useRunSource.test.tsx
@@ -1,7 +1,7 @@
import { beforeEach, describe, expect, it } from 'vitest'
-import { DEFAULT_LOG_DATE_RANGE } from './querySource'
import { useRunSource } from './useRunSource'
+import { DEFAULT_LOG_TIME_RANGE } from '@/data/query-sources/query-source-registry'
import { sqlEditorSessionState } from '@/state/sql-editor/sql-editor-session-state'
import {
renderSqlEditorHook,
@@ -31,22 +31,23 @@ describe('useRunSource', () => {
const { result } = renderSqlEditorHook(() => useRunSource(id))
- expect(result.current).toEqual({ type: 'logs', dateRange: DEFAULT_LOG_DATE_RANGE })
+ expect(result.current).toEqual({ type: 'logs', dateRange: DEFAULT_LOG_TIME_RANGE })
})
it('resolves a logs snippet to its session-stored range when one is set', () => {
const id = 'logs-snippet-custom-range'
seedSnippet({ id, source: 'logs' })
sqlEditorSessionState.setLogRange(id, {
- kind: 'relative',
- last: { amount: 2, unit: 'hour' },
+ type: 'relative',
+ amount: 2,
+ unit: 'hour',
})
const { result } = renderSqlEditorHook(() => useRunSource(id))
expect(result.current).toEqual({
type: 'logs',
- dateRange: { kind: 'relative', last: { amount: 2, unit: 'hour' } },
+ dateRange: { type: 'relative', amount: 2, unit: 'hour' },
})
})
})
diff --git a/apps/studio/components/interfaces/SQLEditor/useRunSource.ts b/apps/studio/components/interfaces/SQLEditor/useRunSource.ts
index 95c83d782a597..b9362d4827950 100644
--- a/apps/studio/components/interfaces/SQLEditor/useRunSource.ts
+++ b/apps/studio/components/interfaces/SQLEditor/useRunSource.ts
@@ -1,12 +1,8 @@
import { useParams } from 'common'
import { useMemo } from 'react'
-import {
- DEFAULT_LOG_DATE_RANGE,
- isLogsSource,
- resolveSnippetSource,
- type QuerySource,
-} from './querySource'
+import { isLogsSource, resolveSnippetSource, type QuerySource } from './querySource'
+import { DEFAULT_LOG_TIME_RANGE } from '@/data/query-sources/query-source-registry'
import { useSqlEditorSessionSnapshot } from '@/state/sql-editor/sql-editor-session-state'
import { useSqlEditorV2StateSnapshot } from '@/state/sql-editor/sql-editor-state'
@@ -33,7 +29,7 @@ export function useRunSource(id: string): QuerySource {
return useMemo(() => {
if (isLogsSource(source)) {
- return { type: 'logs', dateRange: logRange ?? DEFAULT_LOG_DATE_RANGE }
+ return { type: 'logs', dateRange: logRange ?? DEFAULT_LOG_TIME_RANGE }
}
return { type: 'database' }
}, [source, logRange])
diff --git a/apps/studio/components/interfaces/Settings/Database/JitDatabaseAccess/JitDbAccess.utils.test.ts b/apps/studio/components/interfaces/Settings/Database/JitDatabaseAccess/JitDbAccess.utils.test.ts
index edcdee317cdc9..9857f1069a661 100644
--- a/apps/studio/components/interfaces/Settings/Database/JitDatabaseAccess/JitDbAccess.utils.test.ts
+++ b/apps/studio/components/interfaces/Settings/Database/JitDatabaseAccess/JitDbAccess.utils.test.ts
@@ -121,6 +121,7 @@ describe('getJitMemberOptions', () => {
const organizationMembers: OrganizationMembersData = [
{
gotrue_id: 'de305d54-75b4-431b-adb2-eb6b9e546014',
+ avatar_url: null,
primary_email: 'active@example.com',
username: 'Active User',
is_sso_user: false,
@@ -130,6 +131,7 @@ describe('getJitMemberOptions', () => {
},
{
gotrue_id: '',
+ avatar_url: null,
invited_id: 123,
invited_at: '2026-03-01T00:00:00.000Z',
primary_email: 'expired-invite@example.com',
diff --git a/apps/studio/components/interfaces/Settings/Database/JitDatabaseAccess/JitDbAccessConfiguration.tsx b/apps/studio/components/interfaces/Settings/Database/JitDatabaseAccess/JitDbAccessConfiguration.tsx
index f6dd58a29073a..dab3b686cd3cd 100644
--- a/apps/studio/components/interfaces/Settings/Database/JitDatabaseAccess/JitDbAccessConfiguration.tsx
+++ b/apps/studio/components/interfaces/Settings/Database/JitDatabaseAccess/JitDbAccessConfiguration.tsx
@@ -318,19 +318,15 @@ export const JitDbAccessConfiguration = () => {
const unavailableTitle =
unavailableReason === 'postgres_upgrade_required'
? 'Postgres upgrade required'
- : unavailableReason === 'manual_migration_required'
- ? 'Migration required'
- : unavailableReason === 'ssl_enforcement_required'
- ? 'SSL enforcement required'
- : 'Temporary access unavailable'
+ : unavailableReason === 'ssl_enforcement_required'
+ ? 'SSL enforcement required'
+ : 'Temporary access unavailable'
const unavailableDescription =
unavailableReason === 'postgres_upgrade_required'
? 'must be upgraded to Postgres 17 or later before temporary access can be enabled.'
- : unavailableReason === 'manual_migration_required'
- ? 'must be migrated before temporary access can be enabled. Contact support to migrate this project.'
- : unavailableReason === 'ssl_enforcement_required'
- ? 'must have SSL enforcement enabled before temporary access can be enabled.'
- : 'This feature is currently unavailable for this project. Contact support if you need help enabling it.'
+ : unavailableReason === 'ssl_enforcement_required'
+ ? 'must have SSL enforcement enabled before temporary access can be enabled.'
+ : 'This feature is currently unavailable for this project. Contact support if you need help enabling it.'
useEffect(() => {
if (!isLoadingConfiguration && jitDbAccessConfiguration) {
@@ -386,12 +382,13 @@ export const JitDbAccessConfiguration = () => {
layout="responsive"
title={unavailableTitle}
description={
- unavailableReason === 'temporarily_unavailable' ? (
- unavailableDescription
- ) : (
+ unavailableReason === 'postgres_upgrade_required' ||
+ unavailableReason === 'ssl_enforcement_required' ? (
<>
{projectReference} {unavailableDescription}
>
+ ) : (
+ unavailableDescription
)
}
actions={
diff --git a/apps/studio/components/ui/AIAssistantPanel/AIAssistant.tsx b/apps/studio/components/ui/AIAssistantPanel/AIAssistant.tsx
index 02c2844a13950..8b2b0b1776f81 100644
--- a/apps/studio/components/ui/AIAssistantPanel/AIAssistant.tsx
+++ b/apps/studio/components/ui/AIAssistantPanel/AIAssistant.tsx
@@ -1,59 +1,14 @@
import type { UIMessage as MessageType } from '@ai-sdk/react'
-import { useChat } from '@ai-sdk/react'
-import { lastAssistantMessageIsCompleteWithApprovalResponses } from 'ai'
-import { LOCAL_STORAGE_KEYS, useFlag } from 'common'
-import { useParams, useSearchParamsShallow } from 'common/hooks'
-import { AnimatePresence, motion } from 'framer-motion'
-import { Eraser, Pencil, X } from 'lucide-react'
+import { useParams } from 'common/hooks'
import { useRouter } from 'next/router'
-import { Fragment, useCallback, useEffect, useMemo, useRef, useState } from 'react'
-import { Button, cn, KeyboardShortcut } from 'ui'
-import { Admonition } from 'ui-patterns/Admonition'
+import { useEffect } from 'react'
-import { AlertError } from '../AlertError'
-import { ButtonTooltip } from '../ButtonTooltip'
-import { ErrorBoundary } from '../ErrorBoundary/ErrorBoundary'
-import { InlineLinkClassName } from '../InlineLink'
-import { ASSISTANT_ERRORS } from './AiAssistant.constants'
-import {
- containsLogsSnippets,
- hasPendingToolApproval,
- onErrorChat,
- resolvePendingToolApprovalsAsDenied,
-} from './AIAssistant.utils'
import { AIAssistantHeader } from './AIAssistantHeader'
-import { AIOnboarding } from './AIOnboarding'
-import { AssistantChatForm } from './AssistantChatForm'
-import {
- Conversation,
- ConversationContent,
- ConversationScrollButton,
-} from './elements/Conversation'
-import { Message } from './Message'
-import { Markdown } from '@/components/interfaces/Markdown'
+import { AssistantChat } from './AssistantChat'
import { resolveSnippetSource } from '@/components/interfaces/SQLEditor/querySource'
import { SIDEBAR_KEYS } from '@/components/layouts/ProjectLayout/LayoutSidebar/LayoutSidebarProvider'
-import { useCheckOpenAIKeyQuery } from '@/data/ai/check-api-key-query'
-import { useRateMessageMutation } from '@/data/ai/rate-message-mutation'
-import { useTablesQuery } from '@/data/tables/tables-query'
-import { useCheckEntitlements } from '@/hooks/misc/useCheckEntitlements'
-import { useLocalStorageQuery } from '@/hooks/misc/useLocalStorage'
-import { useOrgAiOptInLevel } from '@/hooks/misc/useOrgOptedIntoAi'
-import { useSelectedOrganizationQuery } from '@/hooks/misc/useSelectedOrganization'
-import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject'
-import type { AssistantMessageMetadata } from '@/lib/ai/assistant-message-metadata'
-import { getParallelApprovalIdsToReject } from '@/lib/ai/message-utils'
-import {
- DEFAULT_ASSISTANT_BASE_MODEL_ID,
- defaultAssistantModelId,
- isAssistantBaseModelId,
- isKnownAssistantModelId,
-} from '@/lib/ai/model.utils'
-import { IS_PLATFORM } from '@/lib/constants'
-import { uuidv4 } from '@/lib/helpers'
-import { useTrack } from '@/lib/telemetry/track'
-import type { AssistantModel, SqlSnippet } from '@/state/ai-assistant-state'
import { useAiAssistantState, useAiAssistantStateSnapshot } from '@/state/ai-assistant-state'
+import type { SqlSnippet } from '@/state/ai-assistant-state'
import { SHORTCUT_IDS } from '@/state/shortcuts/registry'
import { useShortcut } from '@/state/shortcuts/useShortcut'
import { useSidebarManagerSnapshot } from '@/state/sidebar-manager-state'
@@ -64,646 +19,89 @@ interface AIAssistantProps {
className?: string
}
+type CurrentQuerySnippet = Exclude
+
+const isSameSnippet = (snippet: SqlSnippet, currentQuery: CurrentQuerySnippet) =>
+ typeof snippet !== 'string' &&
+ snippet.label === currentQuery.label &&
+ snippet.content === currentQuery.content &&
+ snippet.source === currentQuery.source
+
export const AIAssistant = ({ className }: AIAssistantProps) => {
const router = useRouter()
const { id: entityId, source: sourceParam } = useParams()
- const { data: project } = useSelectedProjectQuery()
- const searchParams = useSearchParamsShallow()
-
- const { data: selectedOrganization, isPending: isLoadingOrganization } =
- useSelectedOrganizationQuery()
-
- useShortcut(SHORTCUT_IDS.AI_ASSISTANT_CANCEL_EDIT, () => cancelEdit())
- useShortcut(SHORTCUT_IDS.AI_ASSISTANT_NEW_CHAT, () => snap.newChat())
-
- const disablePrompts = useFlag('disableAssistantPrompts')
- const { snippets } = useSqlEditorV2StateSnapshot()
const snap = useAiAssistantStateSnapshot()
const state = useAiAssistantState()
+ const { snippets } = useSqlEditorV2StateSnapshot()
const { activeSidebar, closeSidebar } = useSidebarManagerSnapshot()
+ const shortcutsEnabled = activeSidebar?.id === SIDEBAR_KEYS.AI_ASSISTANT
- const { hasAccess: hasAccessToAdvanceModel, isLoading: isLoadingEntitlements } =
- useCheckEntitlements('assistant.advance_model')
-
- const selectedModel = useMemo(() => {
- // While entitlements are loading, use the stored model without enforcing access
- if (isLoadingEntitlements) {
- return snap.model ?? DEFAULT_ASSISTANT_BASE_MODEL_ID
- }
-
- const defaultModel = defaultAssistantModelId(hasAccessToAdvanceModel)
- const model = snap.model ?? defaultModel
-
- if (!isKnownAssistantModelId(model)) return defaultModel
- if (!hasAccessToAdvanceModel && !isAssistantBaseModelId(model)) {
- return DEFAULT_ASSISTANT_BASE_MODEL_ID
- }
-
- return model
- }, [isLoadingEntitlements, hasAccessToAdvanceModel, snap.model])
-
- const [updatedOptInSinceMCP] = useLocalStorageQuery(
- LOCAL_STORAGE_KEYS.AI_ASSISTANT_MCP_OPT_IN,
- false
- )
-
- const inputRef = useRef(null)
-
- const { aiOptInLevel, isHipaaProjectDisallowed } = useOrgAiOptInLevel()
- // Whether attached queries are sent at all. One definition, shared by the chat form
- // (which folds them into the message text) and the message metadata (which states
- // whether any of them was a logs query), so the two can't disagree.
- const includeSnippetsInMessage = aiOptInLevel !== 'disabled'
- const showMetadataWarning =
- IS_PLATFORM &&
- !!selectedOrganization &&
- (aiOptInLevel === 'disabled' || aiOptInLevel === 'schema')
-
- // Add a ref to store the last user message
- const lastUserMessageRef = useRef(null)
-
- // Keep latest selected organization to avoid stale values in useChat transport
- const selectedOrganizationRef = useRef(selectedOrganization)
- useEffect(() => {
- selectedOrganizationRef.current = selectedOrganization
- }, [selectedOrganization])
-
- const [value, setValue] = useState(snap.initialInput || '')
- const [editingMessageId, setEditingMessageId] = useState(null)
- const [isResubmitting, setIsResubmitting] = useState(false)
- const [messageRatings, setMessageRatings] = useState>({})
+ const handleNewChat = () => state.newChat()
- const { data: check, isSuccess } = useCheckOpenAIKeyQuery()
- const isApiKeySet = !!check?.hasKey
-
- const { mutateAsync: rateMessage } = useRateMessageMutation()
+ useShortcut(SHORTCUT_IDS.AI_ASSISTANT_NEW_CHAT, handleNewChat, {
+ enabled: shortcutsEnabled,
+ })
const isInSQLEditor = router.pathname.includes('/sql/[id]')
const snippet = snippets[entityId ?? '']
const snippetContent = snippet?.snippet?.content?.unchecked_sql
-
const openSnippetSource = isInSQLEditor
? resolveSnippetSource(snippet?.snippet, sourceParam)
: undefined
- const { data: tables } = useTablesQuery(
- {
- projectRef: project?.ref,
- connectionString: project?.connectionString,
- schema: 'public',
- },
- { enabled: isApiKeySet }
- )
-
- const currentTable = tables?.find((t) => t.id.toString() === entityId)
- const currentSchema = searchParams?.get('schema') ?? 'public'
-
- // Update context in state
useEffect(() => {
- state.setContext({
- projectRef: project?.ref,
- orgSlug: selectedOrganizationRef.current?.slug,
- connectionString: project?.connectionString ?? '',
- })
- }, [project?.ref, project?.connectionString, selectedOrganizationRef.current?.slug, state])
-
- const track = useTrack()
-
- const {
- messages: chatMessages,
- status: chatStatus,
- error,
- sendMessage,
- setMessages,
- addToolApprovalResponse,
- stop,
- regenerate,
- } = useChat({
- id: snap.activeChatId,
- ...(snap.activeChatId && snap.chatInstances[snap.activeChatId]
- ? { chat: snap.chatInstances[snap.activeChatId] }
- : {}),
- sendAutomaticallyWhen: lastAssistantMessageIsCompleteWithApprovalResponses,
- onError: onErrorChat,
- })
-
- const isChatLoading = chatStatus === 'submitted' || chatStatus === 'streaming'
- const hasPendingApproval = hasPendingToolApproval(chatMessages)
- const supportMetadata = snap.activeChat?.supportMetadata
- const isSupportChat = !!supportMetadata?.isSupportChat
- const isSupportChatClosed = isSupportChat && supportMetadata.lifecycleStatus !== 'bot_active'
- const activeChatId = snap.activeChatId
- const supportConversationId = supportMetadata?.frontConversationId
- const isChatInputDisabled =
- !isApiKeySet || disablePrompts || isLoadingOrganization || isSupportChatClosed
-
- const branchedFrom = snap.activeChat?.branchedFrom
- const branchedConversation = branchedFrom ? snap.chats[branchedFrom.chatId] : undefined
-
- const deleteMessageFromHere = useCallback(
- (messageId: string) => {
- // Find the message index in current chatMessages
- const messageIndex = chatMessages.findIndex((msg) => msg.id === messageId)
- if (messageIndex === -1) return
-
- if (isChatLoading) stop()
-
- snap.deleteMessagesAfter(messageId, { includeSelf: true })
-
- const updatedMessages = chatMessages.slice(0, messageIndex)
- setMessages(updatedMessages)
- },
- [snap, setMessages, chatMessages, isChatLoading, stop]
- )
-
- const editMessage = useCallback(
- (messageId: string) => {
- const messageIndex = chatMessages.findIndex((msg) => msg.id === messageId)
- if (messageIndex === -1) return
-
- // Target message
- const messageToEdit = chatMessages[messageIndex]
-
- // Activate editing mode
- setEditingMessageId(messageId)
- const textContent =
- messageToEdit.parts
- ?.filter((part) => part.type === 'text')
- .map((part) => part.text)
- .join('') ?? ''
- setValue(textContent)
-
- setTimeout(() => {
- if (inputRef.current) {
- inputRef?.current?.focus()
+ if (!shortcutsEnabled || !isInSQLEditor || !snippetContent) return
- // [Joshen] This is just to make the cursor go to the end of the text when focusing
- const val = inputRef.current.value
- inputRef.current.value = ''
- inputRef.current.value = val
- }
- }, 100)
- },
- [chatMessages, setValue]
- )
-
- const cancelEdit = useCallback(() => {
- setEditingMessageId(null)
- setValue('')
- }, [setValue])
-
- const handleRateMessage = useCallback(
- async (messageId: string, rating: 'positive' | 'negative', reason?: string) => {
- if (!project?.ref || !selectedOrganization?.slug) return
-
- // Optimistically update UI
- setMessageRatings((prev) => ({ ...prev, [messageId]: rating }))
-
- try {
- const result = await rateMessage({
- rating,
- messages: chatMessages,
- messageId,
- projectRef: project.ref,
- orgSlug: selectedOrganization.slug,
- reason,
- spanId: state.messageSpanIds[messageId],
- })
-
- track('assistant_message_rating_submitted', {
- rating,
- category: result.category,
- ...(reason && { reason }),
- chatId: state.activeChatId,
- })
- } catch (error) {
- console.error('Failed to rate message:', error)
- // Rollback on error
- setMessageRatings((prev) => {
- const { [messageId]: _, ...rest } = prev
- return rest
- })
- }
- },
- [chatMessages, project?.ref, selectedOrganization?.slug, rateMessage, track, state]
- )
-
- const isContextExceededError =
- error &&
- (error.message?.includes('context_length_exceeded') ||
- error.message?.includes('exceeds the context window'))
-
- const renderedMessages = useMemo(
- () =>
- chatMessages.map((message, index) => {
- const isBeingEdited = editingMessageId === message.id
- const isAfterEditedMessage = editingMessageId
- ? chatMessages.findIndex((m) => m.id === editingMessageId) < index
- : false
- const isLastMessage = index === chatMessages.length - 1
-
- return (
-
-
- {branchedConversation && branchedFrom?.messageId === message.id && (
-
-
-
- Branched from
-
-
-
-
- )}
-
- )
- }),
- [
- chatMessages,
- deleteMessageFromHere,
- editMessage,
- cancelEdit,
- editingMessageId,
- chatStatus,
- addToolApprovalResponse,
- handleRateMessage,
- messageRatings,
- branchedConversation,
- branchedFrom,
- snap,
- ]
- )
-
- const hasMessages = chatMessages.length > 0
-
- const sendMessageToAssistant = (finalContent: string) => {
- if (editingMessageId) {
- // Handling when the user is in edit mode
- // delete the message(s) from the chat just like the delete button
- setIsResubmitting(true)
- deleteMessageFromHere(editingMessageId)
- setEditingMessageId(null)
- }
-
- // Read off the attachments this message actually carries, so detaching the
- // "Current Query" chip also drops the claim. Gated on the same condition that
- // decides whether attachments make it into the text at all: with AI opt-in
- // disabled the chip is shown but no query is sent, and claiming otherwise would
- // have the server prepend ClickHouse context for a message holding no query.
- // Rides on the message rather than the request, so a Retry reproduces the context
- // the message was asked in.
- const metadata: AssistantMessageMetadata = {
- containsLogsSnippets: includeSnippetsInMessage && containsLogsSnippets(snap.sqlSnippets),
- }
-
- const payload = {
- role: 'user',
- createdAt: new Date(),
- parts: [{ type: 'text', text: finalContent }],
- id: uuidv4(),
- metadata,
- } as MessageType
-
- snap.clearSqlSnippets()
- lastUserMessageRef.current = payload
- if (hasPendingApproval && !editingMessageId) {
- setMessages(resolvePendingToolApprovalsAsDenied(chatMessages))
- }
- sendMessage(payload, {
- body: {
- schema: currentSchema,
- table: currentTable?.name,
- },
- })
- setValue('')
-
- if (finalContent.includes('Help me to debug')) {
- track('assistant_debug_submitted', { chatId: snap.activeChatId })
- } else {
- track('assistant_prompt_submitted', { chatId: snap.activeChatId })
- }
- }
-
- const handleClearMessages = () => {
- if (isChatLoading) stop()
- snap.clearMessages()
- setMessages([])
- lastUserMessageRef.current = null
- setEditingMessageId(null)
- }
-
- useEffect(() => {
- // Keep "Thinking" visible while stopping and resubmitting during edit
- // Only clear once the new response actually starts streaming (or errors)
- if (isResubmitting && (chatStatus === 'streaming' || !!error)) {
- setIsResubmitting(false)
+ const currentQuery = {
+ label: 'Current Query',
+ content: snippetContent,
+ source: openSnippetSource,
}
- }, [isResubmitting, chatStatus, error])
+ state.setSqlSnippets([currentQuery])
- useEffect(() => {
- // Approval-required tools can't run in parallel. Auto-deny extras so the model reissues them sequentially.
- for (const id of getParallelApprovalIdsToReject(chatMessages)) {
- addToolApprovalResponse?.({
- id,
- approved: false,
- reason:
- 'Only one approval-required tool call is allowed per turn. Please reissue this tool call after the current one completes.',
- })
- }
- }, [chatMessages, addToolApprovalResponse])
+ return () => {
+ const currentSnippets = state.sqlSnippets
+ const remainingSnippets = currentSnippets?.filter(
+ (snippet) => !isSameSnippet(snippet, currentQuery)
+ )
- useEffect(() => {
- setValue(snap.initialInput || '')
- if (inputRef.current && snap.initialInput) {
- inputRef.current.focus()
- inputRef.current.setSelectionRange(snap.initialInput.length, snap.initialInput.length)
+ if (currentSnippets && remainingSnippets?.length !== currentSnippets.length) {
+ state.setSqlSnippets(remainingSnippets ?? [])
+ }
}
- }, [snap.initialInput])
+ }, [shortcutsEnabled, isInSQLEditor, snippetContent, openSnippetSource, state])
- useEffect(() => {
- const isOpen = activeSidebar?.id === SIDEBAR_KEYS.AI_ASSISTANT
- if (isOpen && isInSQLEditor && !!snippetContent) {
- snap.setSqlSnippets([
- { label: 'Current Query', content: snippetContent, source: openSnippetSource },
- ])
- }
- // eslint-disable-next-line react-hooks/exhaustive-deps
- }, [activeSidebar?.id, isInSQLEditor, snippetContent, openSnippetSource])
+ if (!snap.activeChatId) return null
return (
- state.selectChat(chatId)}
+ onBranchChat={(messageId) => state.branchChat(messageId)}
+ composerContext={{
+ initialInput: snap.initialInput,
+ sqlSnippets: snap.sqlSnippets as SqlSnippet[] | undefined,
+ suggestions: snap.suggestions
+ ? {
+ title: snap.suggestions.title,
+ prompts: snap.suggestions.prompts?.map((prompt) => ({ ...prompt })),
+ }
+ : undefined,
+ onSetSqlSnippets: state.setSqlSnippets,
+ onClearSqlSnippets: state.clearSqlSnippets,
}}
- actions={[
- {
- label: 'Clear messages and refresh',
- onClick: () => {
- handleClearMessages()
- window.location.reload()
- },
- },
- ]}
- >
-
+ renderHeader={(props) => (
closeSidebar(SIDEBAR_KEYS.AI_ASSISTANT)}
- showMetadataWarning={showMetadataWarning}
- updatedOptInSinceMCP={updatedOptInSinceMCP}
- isHipaaProjectDisallowed={isHipaaProjectDisallowed}
- aiOptInLevel={aiOptInLevel}
/>
- {hasMessages ? (
-
-
- {renderedMessages}
- {error && (
- <>
-
- {isContextExceededError ? (
-
- ) : (
- <>
-
- }
- tooltip={{ content: { side: 'bottom', text: 'Clear messages' } }}
- />
- >
- )}
-
- }
- />
- >
- )}
- {isChatLoading && (
-
- )}
-
-
- The Assistant can make mistakes. Double check responses.
-
-
-
-
- ) : (
- setValue(val)}
- onFocusInput={() => inputRef.current?.focus()}
- />
- )}
-
-
- {editingMessageId && (
-
-
-
-
-
-
}
- onClick={cancelEdit}
- className="w-6 h-6 p-0"
- title="Cancel editing"
- aria-label="Cancel editing"
- tooltip={{
- content: { side: 'top', text:
},
- }}
- />
-
-
-
-
- )}
-
-
-
- {isSupportChat && !isSupportChatClosed && (
-
-
-
-
-
-
-
- )}
-
- {disablePrompts && (
-
- )}
-
- {isSuccess && !isApiKeySet && (
-
- }
- />
- )}
-
-
form>textarea]:text-base [&>form>textarea]:md:text-sm [&>form>textarea]:border',
- '[&>form>textarea]:rounded-md [&>form>textarea]:outline-hidden!',
- '[&>form>textarea]:ring-offset-0! [&>form>textarea]:ring-0!'
- )}
- loading={isChatLoading}
- isEditing={!!editingMessageId}
- disabled={isChatInputDisabled}
- placeholder={
- hasMessages
- ? isSupportChat
- ? 'Share details so the assistant can help with your support request...'
- : 'Ask a follow up question...'
- : (snap.sqlSnippets ?? [])?.length > 0
- ? 'Ask a question or make a change...'
- : isSupportChat
- ? 'Describe your support issue...'
- : 'Chat to Postgres...'
- }
- value={value}
- onValueChange={(e) => setValue(e.target.value)}
- onSubmit={(finalMessage) => {
- sendMessageToAssistant(finalMessage)
- }}
- onStop={() => {
- stop()
- // to save partial responses from the AI
- const lastMessage = chatMessages[chatMessages.length - 1]
- if (lastMessage && lastMessage.role === 'assistant') {
- state.updateMessage(lastMessage)
- }
- }}
- sqlSnippets={snap.sqlSnippets as SqlSnippet[] | undefined}
- onRemoveSnippet={(index) => {
- const newSnippets = [...(snap.sqlSnippets ?? [])]
- newSnippets.splice(index, 1)
- snap.setSqlSnippets(newSnippets)
- }}
- includeSnippetsInMessage={includeSnippetsInMessage}
- selectedModel={selectedModel}
- onSelectModel={(model) => snap.setModel(model)}
- />
-
-
-
+ )}
+ />
)
}
diff --git a/apps/studio/components/ui/AIAssistantPanel/AIAssistantChatSelector.tsx b/apps/studio/components/ui/AIAssistantPanel/AIAssistantChatSelector.tsx
index e5631c81b38d0..11b87ad765386 100644
--- a/apps/studio/components/ui/AIAssistantPanel/AIAssistantChatSelector.tsx
+++ b/apps/studio/components/ui/AIAssistantPanel/AIAssistantChatSelector.tsx
@@ -24,9 +24,13 @@ import { useShortcut } from '@/state/shortcuts/useShortcut'
interface AIAssistantChatSelectorProps {
disabled?: boolean
+ shortcutsEnabled?: boolean
}
-export const AIAssistantChatSelector = ({ disabled = false }: AIAssistantChatSelectorProps) => {
+export const AIAssistantChatSelector = ({
+ disabled = false,
+ shortcutsEnabled = true,
+}: AIAssistantChatSelectorProps) => {
const snap = useAiAssistantStateSnapshot()
const [chatSelectorOpen, setChatSelectorOpen] = useState(false)
@@ -35,7 +39,13 @@ export const AIAssistantChatSelector = ({ disabled = false }: AIAssistantChatSel
const chats = Object.entries(snap.chats)
- useShortcut(SHORTCUT_IDS.AI_ASSISTANT_TOGGLE_HISTORY, () => setChatSelectorOpen((prev) => !prev))
+ useShortcut(
+ SHORTCUT_IDS.AI_ASSISTANT_TOGGLE_HISTORY,
+ () => setChatSelectorOpen((prev) => !prev),
+ {
+ enabled: shortcutsEnabled,
+ }
+ )
const handleSelectChat = (id: string) => {
snap.selectChat(id)
diff --git a/apps/studio/components/ui/AIAssistantPanel/AIAssistantHeader.tsx b/apps/studio/components/ui/AIAssistantPanel/AIAssistantHeader.tsx
index 49351c8a205b4..c2f7294590ac5 100644
--- a/apps/studio/components/ui/AIAssistantPanel/AIAssistantHeader.tsx
+++ b/apps/studio/components/ui/AIAssistantPanel/AIAssistantHeader.tsx
@@ -33,6 +33,7 @@ import { useSidebarManagerSnapshot } from '@/state/sidebar-manager-state'
interface AIAssistantHeaderProps {
isChatLoading: boolean
+ shortcutsEnabled?: boolean
onNewChat: () => void
onCloseAssistant: () => void
showMetadataWarning: boolean
@@ -43,6 +44,7 @@ interface AIAssistantHeaderProps {
export const AIAssistantHeader = ({
isChatLoading,
+ shortcutsEnabled = true,
onNewChat,
onCloseAssistant,
showMetadataWarning,
@@ -87,15 +89,15 @@ export const AIAssistantHeader = ({
}
useShortcut(SHORTCUT_IDS.AI_ASSISTANT_COPY_CHAT_ID, handleCopyChatId, {
- enabled: !isChatLoading,
+ enabled: shortcutsEnabled && !isChatLoading,
})
useShortcut(SHORTCUT_IDS.AI_ASSISTANT_OPEN_PERMISSIONS, () => setIsOptInModalOpen(true), {
- enabled: !isChatLoading,
+ enabled: shortcutsEnabled && !isChatLoading,
})
useShortcut(SHORTCUT_IDS.AI_ASSISTANT_MAXIMIZE, toggleMaximise, {
- enabled: !isChatLoading,
+ enabled: shortcutsEnabled && !isChatLoading,
})
return (
@@ -128,7 +130,7 @@ export const AIAssistantHeader = ({
-
+
void
+ onClearSqlSnippets?: () => void
+}
+
+interface AssistantChatProps {
+ className?: string
+ chatId: string
+ shortcutsEnabled?: boolean
+ onNewChat: () => void
+ onSelectChat: (chatId: string) => void
+ onBranchChat: (messageId: string) => void
+ composerContext?: AssistantChatComposerContext
+ renderHeader?: (props: AssistantChatHeaderProps) => ReactNode
+}
+
+export const AssistantChat = ({
+ className,
+ chatId,
+ shortcutsEnabled = true,
+ onNewChat,
+ onSelectChat,
+ onBranchChat,
+ composerContext,
+ renderHeader,
+}: AssistantChatProps) => {
+ const { id: entityId } = useParams()
+ const { data: project } = useSelectedProjectQuery()
+ const searchParams = useSearchParamsShallow()
+
+ const { data: selectedOrganization, isPending: isLoadingOrganization } =
+ useSelectedOrganizationQuery()
+
+ const disablePrompts = useFlag('disableAssistantPrompts')
+ const snap = useAiAssistantStateSnapshot()
+ const state = useAiAssistantState()
+ const currentChat = snap.chats[chatId]
+
+ useShortcut(SHORTCUT_IDS.AI_ASSISTANT_CANCEL_EDIT, () => cancelEdit(), {
+ enabled: shortcutsEnabled,
+ })
+
+ const { hasAccess: hasAccessToAdvanceModel, isLoading: isLoadingEntitlements } =
+ useCheckEntitlements('assistant.advance_model')
+
+ const selectedModel = useMemo(() => {
+ // While entitlements are loading, use the stored model without enforcing access
+ if (isLoadingEntitlements) {
+ return snap.model ?? DEFAULT_ASSISTANT_BASE_MODEL_ID
+ }
+
+ const defaultModel = defaultAssistantModelId(hasAccessToAdvanceModel)
+ const model = snap.model ?? defaultModel
+
+ if (!isKnownAssistantModelId(model)) return defaultModel
+ if (!hasAccessToAdvanceModel && !isAssistantBaseModelId(model)) {
+ return DEFAULT_ASSISTANT_BASE_MODEL_ID
+ }
+
+ return model
+ }, [isLoadingEntitlements, hasAccessToAdvanceModel, snap.model])
+
+ const [updatedOptInSinceMCP] = useLocalStorageQuery(
+ LOCAL_STORAGE_KEYS.AI_ASSISTANT_MCP_OPT_IN,
+ false
+ )
+
+ const inputRef = useRef(null)
+
+ const { aiOptInLevel, isHipaaProjectDisallowed } = useOrgAiOptInLevel()
+ // Whether attached queries are sent at all. One definition, shared by the chat form
+ // (which folds them into the message text) and the message metadata (which states
+ // whether any of them was a logs query), so the two can't disagree.
+ const includeSnippetsInMessage = aiOptInLevel !== 'disabled'
+ const showMetadataWarning =
+ IS_PLATFORM &&
+ !!selectedOrganization &&
+ (aiOptInLevel === 'disabled' || aiOptInLevel === 'schema')
+
+ // Add a ref to store the last user message
+ const lastUserMessageRef = useRef(null)
+
+ const [value, setValue] = useState(composerContext?.initialInput || '')
+ const [editingMessageId, setEditingMessageId] = useState(null)
+ const [isResubmitting, setIsResubmitting] = useState(false)
+ const [messageRatings, setMessageRatings] = useState>({})
+
+ const { data: check, isSuccess } = useCheckOpenAIKeyQuery()
+ const isApiKeySet = !!check?.hasKey
+
+ const { mutateAsync: rateMessage } = useRateMessageMutation()
+
+ const { data: tables } = useTablesQuery(
+ {
+ projectRef: project?.ref,
+ connectionString: project?.connectionString,
+ schema: 'public',
+ },
+ { enabled: isApiKeySet }
+ )
+
+ const currentTable = tables?.find((t) => t.id.toString() === entityId)
+ const currentSchema = searchParams?.get('schema') ?? 'public'
+
+ // Update context in state
+ useEffect(() => {
+ state.setContext({
+ projectRef: project?.ref,
+ orgSlug: selectedOrganization?.slug,
+ connectionString: project?.connectionString ?? '',
+ })
+ }, [project?.ref, project?.connectionString, selectedOrganization?.slug, state])
+
+ const track = useTrack()
+
+ useEffect(() => {
+ state.ensureChatInstance(chatId)
+ }, [chatId, state])
+
+ const chatInstance = snap.chatInstances[chatId]
+
+ const {
+ messages: chatMessages,
+ status: chatStatus,
+ error,
+ sendMessage,
+ setMessages,
+ addToolApprovalResponse,
+ stop,
+ regenerate,
+ } = useChat({
+ id: chatId,
+ ...(chatInstance ? { chat: chatInstance } : {}),
+ sendAutomaticallyWhen: lastAssistantMessageIsCompleteWithApprovalResponses,
+ onError: onErrorChat,
+ })
+
+ const isChatLoading = chatStatus === 'submitted' || chatStatus === 'streaming'
+ const hasPendingApproval = hasPendingToolApproval(chatMessages)
+ const supportMetadata = currentChat?.supportMetadata
+ const isSupportChat = !!supportMetadata?.isSupportChat
+ const isSupportChatClosed = isSupportChat && supportMetadata.lifecycleStatus !== 'bot_active'
+ const supportConversationId = supportMetadata?.frontConversationId
+ const isChatInputDisabled =
+ !isApiKeySet || disablePrompts || isLoadingOrganization || isSupportChatClosed
+
+ const branchedFrom = currentChat?.branchedFrom
+ const branchedConversation = branchedFrom ? snap.chats[branchedFrom.chatId] : undefined
+
+ const deleteMessageFromHere = useCallback(
+ (messageId: string) => {
+ // Find the message index in current chatMessages
+ const messageIndex = chatMessages.findIndex((msg) => msg.id === messageId)
+ if (messageIndex === -1) return
+
+ if (isChatLoading) stop()
+
+ snap.deleteMessagesAfter(messageId, { includeSelf: true, chatId })
+
+ const updatedMessages = chatMessages.slice(0, messageIndex)
+ setMessages(updatedMessages)
+ },
+ [snap, setMessages, chatMessages, isChatLoading, stop, chatId]
+ )
+
+ const editMessage = useCallback(
+ (messageId: string) => {
+ const messageIndex = chatMessages.findIndex((msg) => msg.id === messageId)
+ if (messageIndex === -1) return
+
+ // Target message
+ const messageToEdit = chatMessages[messageIndex]
+
+ // Activate editing mode
+ setEditingMessageId(messageId)
+ const textContent =
+ messageToEdit.parts
+ ?.filter((part) => part.type === 'text')
+ .map((part) => part.text)
+ .join('') ?? ''
+ setValue(textContent)
+
+ setTimeout(() => {
+ if (inputRef.current) {
+ inputRef?.current?.focus()
+
+ // [Joshen] This is just to make the cursor go to the end of the text when focusing
+ const val = inputRef.current.value
+ inputRef.current.value = ''
+ inputRef.current.value = val
+ }
+ }, 100)
+ },
+ [chatMessages, setValue]
+ )
+
+ const cancelEdit = useCallback(() => {
+ setEditingMessageId(null)
+ setValue('')
+ }, [setValue])
+
+ const handleRateMessage = useCallback(
+ async (messageId: string, rating: 'positive' | 'negative', reason?: string) => {
+ if (!project?.ref || !selectedOrganization?.slug) return
+
+ // Optimistically update UI
+ setMessageRatings((prev) => ({ ...prev, [messageId]: rating }))
+
+ try {
+ const result = await rateMessage({
+ rating,
+ messages: chatMessages,
+ messageId,
+ projectRef: project.ref,
+ orgSlug: selectedOrganization.slug,
+ reason,
+ spanId: state.messageSpanIds[messageId],
+ })
+
+ track('assistant_message_rating_submitted', {
+ rating,
+ category: result.category,
+ ...(reason && { reason }),
+ chatId,
+ })
+ } catch (error) {
+ console.error('Failed to rate message:', error)
+ // Rollback on error
+ setMessageRatings((prev) => {
+ const { [messageId]: _, ...rest } = prev
+ return rest
+ })
+ }
+ },
+ [chatMessages, project?.ref, selectedOrganization?.slug, rateMessage, track, state, chatId]
+ )
+
+ const isContextExceededError =
+ error &&
+ (error.message?.includes('context_length_exceeded') ||
+ error.message?.includes('exceeds the context window'))
+
+ const renderedMessages = useMemo(
+ () =>
+ chatMessages.map((message, index) => {
+ const isBeingEdited = editingMessageId === message.id
+ const isAfterEditedMessage = editingMessageId
+ ? chatMessages.findIndex((m) => m.id === editingMessageId) < index
+ : false
+ const isLastMessage = index === chatMessages.length - 1
+
+ return (
+
+
+ {branchedConversation && branchedFrom?.messageId === message.id && (
+
+
+
+ Branched from
+
+
+
+
+ )}
+
+ )
+ }),
+ [
+ chatMessages,
+ deleteMessageFromHere,
+ editMessage,
+ cancelEdit,
+ editingMessageId,
+ chatStatus,
+ addToolApprovalResponse,
+ handleRateMessage,
+ messageRatings,
+ branchedConversation,
+ branchedFrom,
+ onSelectChat,
+ onBranchChat,
+ ]
+ )
+
+ const hasMessages = chatMessages.length > 0
+
+ const sendMessageToAssistant = (finalContent: string) => {
+ if (editingMessageId) {
+ // Handling when the user is in edit mode
+ // delete the message(s) from the chat just like the delete button
+ setIsResubmitting(true)
+ deleteMessageFromHere(editingMessageId)
+ setEditingMessageId(null)
+ }
+
+ // Read off the attachments this message actually carries, so detaching the
+ // "Current Query" chip also drops the claim. Gated on the same condition that
+ // decides whether attachments make it into the text at all: with AI opt-in
+ // disabled the chip is shown but no query is sent, and claiming otherwise would
+ // have the server prepend ClickHouse context for a message holding no query.
+ // Rides on the message rather than the request, so a Retry reproduces the context
+ // the message was asked in.
+ const metadata: AssistantMessageMetadata = {
+ containsLogsSnippets:
+ includeSnippetsInMessage && containsLogsSnippets(composerContext?.sqlSnippets),
+ }
+
+ const payload = {
+ role: 'user',
+ createdAt: new Date(),
+ parts: [{ type: 'text', text: finalContent }],
+ id: uuidv4(),
+ metadata,
+ } as MessageType
+
+ composerContext?.onClearSqlSnippets?.()
+ lastUserMessageRef.current = payload
+ if (hasPendingApproval && !editingMessageId) {
+ setMessages(resolvePendingToolApprovalsAsDenied(chatMessages))
+ }
+ sendMessage(payload, {
+ body: {
+ schema: currentSchema,
+ table: currentTable?.name,
+ },
+ })
+ setValue('')
+
+ if (finalContent.includes('Help me to debug')) {
+ track('assistant_debug_submitted', { chatId })
+ } else {
+ track('assistant_prompt_submitted', { chatId })
+ }
+ }
+
+ const handleClearMessages = () => {
+ if (isChatLoading) stop()
+ snap.clearMessages(chatId)
+ setMessages([])
+ lastUserMessageRef.current = null
+ setEditingMessageId(null)
+ }
+
+ useEffect(() => {
+ // Keep "Thinking" visible while stopping and resubmitting during edit
+ // Only clear once the new response actually starts streaming (or errors)
+ if (isResubmitting && (chatStatus === 'streaming' || !!error)) {
+ setIsResubmitting(false)
+ }
+ }, [isResubmitting, chatStatus, error])
+
+ useEffect(() => {
+ // Approval-required tools can't run in parallel. Auto-deny extras so the model reissues them sequentially.
+ for (const id of getParallelApprovalIdsToReject(chatMessages)) {
+ addToolApprovalResponse?.({
+ id,
+ approved: false,
+ reason:
+ 'Only one approval-required tool call is allowed per turn. Please reissue this tool call after the current one completes.',
+ })
+ }
+ }, [chatMessages, addToolApprovalResponse])
+
+ useEffect(() => {
+ setValue(composerContext?.initialInput || '')
+ if (inputRef.current && composerContext?.initialInput) {
+ inputRef.current.focus()
+ inputRef.current.setSelectionRange(
+ composerContext.initialInput.length,
+ composerContext.initialInput.length
+ )
+ }
+ }, [composerContext?.initialInput])
+
+ return (
+ {
+ handleClearMessages()
+ window.location.reload()
+ },
+ },
+ ]}
+ >
+
+ {renderHeader?.({
+ isChatLoading,
+ showMetadataWarning,
+ updatedOptInSinceMCP,
+ isHipaaProjectDisallowed,
+ aiOptInLevel,
+ })}
+ {hasMessages ? (
+
+
+ {renderedMessages}
+ {error && (
+ <>
+
+ {isContextExceededError ? (
+
+ ) : (
+ <>
+
+ }
+ tooltip={{ content: { side: 'bottom', text: 'Clear messages' } }}
+ />
+ >
+ )}
+
+ }
+ />
+ >
+ )}
+ {isChatLoading && (
+
+ )}
+
+
+ The Assistant can make mistakes. Double check responses.
+
+
+
+
+ ) : (
+ setValue(val)}
+ onFocusInput={() => inputRef.current?.focus()}
+ />
+ )}
+
+
+ {editingMessageId && (
+
+
+
+
+
+
}
+ onClick={cancelEdit}
+ className="w-6 h-6 p-0"
+ title="Cancel editing"
+ aria-label="Cancel editing"
+ tooltip={{
+ content: { side: 'top', text:
},
+ }}
+ />
+
+
+
+
+ )}
+
+
+
+ {isSupportChat && !isSupportChatClosed && (
+
+
+
+
+
+
+
+ )}
+
+ {disablePrompts && (
+
+ )}
+
+ {isSuccess && !isApiKeySet && (
+
+ }
+ />
+ )}
+
+
form>textarea]:text-base [&>form>textarea]:md:text-sm [&>form>textarea]:border',
+ '[&>form>textarea]:rounded-md [&>form>textarea]:outline-hidden!',
+ '[&>form>textarea]:ring-offset-0! [&>form>textarea]:ring-0!'
+ )}
+ loading={isChatLoading}
+ isEditing={!!editingMessageId}
+ disabled={isChatInputDisabled}
+ placeholder={
+ hasMessages
+ ? isSupportChat
+ ? 'Share details so the assistant can help with your support request...'
+ : 'Ask a follow up question...'
+ : (composerContext?.sqlSnippets ?? []).length > 0
+ ? 'Ask a question or make a change...'
+ : isSupportChat
+ ? 'Describe your support issue...'
+ : 'Chat to Postgres...'
+ }
+ value={value}
+ onValueChange={(e) => setValue(e.target.value)}
+ onSubmit={(finalMessage) => {
+ sendMessageToAssistant(finalMessage)
+ }}
+ onStop={() => {
+ stop()
+ // to save partial responses from the AI
+ const lastMessage = chatMessages[chatMessages.length - 1]
+ if (lastMessage && lastMessage.role === 'assistant') {
+ state.updateMessage(lastMessage, chatId)
+ }
+ }}
+ sqlSnippets={composerContext?.sqlSnippets}
+ onRemoveSnippet={(index) => {
+ const newSnippets = [...(composerContext?.sqlSnippets ?? [])]
+ newSnippets.splice(index, 1)
+ composerContext?.onSetSqlSnippets?.(newSnippets)
+ }}
+ includeSnippetsInMessage={includeSnippetsInMessage}
+ selectedModel={selectedModel}
+ onSelectModel={(model) => snap.setModel(model)}
+ />
+
+
+
+ )
+}
diff --git a/apps/studio/components/ui/AIAssistantPanel/Message.Context.tsx b/apps/studio/components/ui/AIAssistantPanel/Message.Context.tsx
index 3ce0cb1dd57cf..d39824361ee19 100644
--- a/apps/studio/components/ui/AIAssistantPanel/Message.Context.tsx
+++ b/apps/studio/components/ui/AIAssistantPanel/Message.Context.tsx
@@ -26,6 +26,7 @@ export interface MessageActions {
onDelete: (id: string) => void
onEdit: (id: string) => void
+ onBranch: (id: string) => void
onCancelEdit: () => void
onRate?: (id: string, rating: 'positive' | 'negative', reason?: string) => void
}
diff --git a/apps/studio/components/ui/AIAssistantPanel/Message.tsx b/apps/studio/components/ui/AIAssistantPanel/Message.tsx
index c9a5ef5e6e530..6ec5780bec6c6 100644
--- a/apps/studio/components/ui/AIAssistantPanel/Message.tsx
+++ b/apps/studio/components/ui/AIAssistantPanel/Message.tsx
@@ -8,11 +8,9 @@ import { MessageActions } from './Message.Actions'
import type { AddToolApprovalResponse, MessageInfo } from './Message.Context'
import { MessageProvider, useMessageActionsContext, useMessageInfoContext } from './Message.Context'
import { MessageDisplay } from './Message.Display'
-import { useAiAssistantStateSnapshot } from '@/state/ai-assistant-state'
function AssistantMessage({ message }: { message: VercelMessage }) {
- const snap = useAiAssistantStateSnapshot()
- const { onCancelEdit, onRate } = useMessageActionsContext()
+ const { onBranch, onCancelEdit, onRate } = useMessageActionsContext()
const { id, variant, state, isLastMessage, readOnly, rating, isLoading } = useMessageInfoContext()
const handleRate = (newRating: 'positive' | 'negative', reason?: string) => {
@@ -51,7 +49,7 @@ function AssistantMessage({ message }: { message: VercelMessage }) {
isActive={rating === 'negative'}
disabled={!!rating}
/>
-
snap.branchChat(id)} />
+ onBranch(id)} />
)}
@@ -107,6 +105,7 @@ interface MessageProps {
addToolApprovalResponse?: AddToolApprovalResponse
onDelete: (id: string) => void
onEdit: (id: string) => void
+ onBranch: (id: string) => void
isAfterEditedMessage: boolean
isBeingEdited: boolean
onCancelEdit: () => void
@@ -139,6 +138,7 @@ export function Message(props: MessageProps) {
addToolApprovalResponse: props.addToolApprovalResponse,
onDelete: props.onDelete,
onEdit: props.onEdit,
+ onBranch: props.onBranch,
onCancelEdit: props.onCancelEdit,
onRate: props.onRate,
}
diff --git a/apps/studio/data/api-keys/api-key-create-mutation.ts b/apps/studio/data/api-keys/api-key-create-mutation.ts
index 1aa32df38b210..3e07cfe8020af 100644
--- a/apps/studio/data/api-keys/api-key-create-mutation.ts
+++ b/apps/studio/data/api-keys/api-key-create-mutation.ts
@@ -18,7 +18,7 @@ export async function createAPIKey(payload: APIKeyCreateVariables) {
params: {
path: { ref: payload.projectRef },
query: {
- reveal: false,
+ reveal: 'false',
},
},
body: {
@@ -29,7 +29,7 @@ export async function createAPIKey(payload: APIKeyCreateVariables) {
role: 'service_role',
},
}
- : name),
+ : {}),
type: payload.type,
name: payload.name,
diff --git a/apps/studio/data/api-keys/api-key-delete-mutation.ts b/apps/studio/data/api-keys/api-key-delete-mutation.ts
index 18d0e767c4f1e..10fb0eabff918 100644
--- a/apps/studio/data/api-keys/api-key-delete-mutation.ts
+++ b/apps/studio/data/api-keys/api-key-delete-mutation.ts
@@ -16,7 +16,7 @@ export async function deleteAPIKey(payload: APIKeyDeleteVariables) {
const { data, error } = await del('/v1/projects/{ref}/api-keys/{id}', {
params: {
path: { ref: payload.projectRef, id: payload.id },
- query: { reveal: false },
+ query: { reveal: 'false' },
},
})
diff --git a/apps/studio/data/api-keys/api-key-id-query.ts b/apps/studio/data/api-keys/api-key-id-query.ts
index 9149361f40194..7340bafe0695d 100644
--- a/apps/studio/data/api-keys/api-key-id-query.ts
+++ b/apps/studio/data/api-keys/api-key-id-query.ts
@@ -16,7 +16,7 @@ export async function getAPIKeysById(
const { data, error } = await get('/v1/projects/{ref}/api-keys/{id}', {
params: {
path: { ref: projectRef, id },
- query: { reveal },
+ query: { reveal: reveal ? 'true' : 'false' },
},
signal,
})
diff --git a/apps/studio/data/api-keys/api-keys-query.ts b/apps/studio/data/api-keys/api-keys-query.ts
index a9f87625e3878..5ce1f14441741 100644
--- a/apps/studio/data/api-keys/api-keys-query.ts
+++ b/apps/studio/data/api-keys/api-keys-query.ts
@@ -55,7 +55,7 @@ async function getAPIKeys({ projectRef, reveal }: APIKeysVariables, signal?: Abo
if (!projectRef) throw new Error('projectRef is required')
const { data, error } = await get(`/v1/projects/{ref}/api-keys`, {
- params: { path: { ref: projectRef }, query: { reveal } },
+ params: { path: { ref: projectRef }, query: { reveal: reveal ? 'true' : 'false' } },
signal,
})
diff --git a/apps/studio/data/api-keys/legacy-api-key-toggle-mutation.ts b/apps/studio/data/api-keys/legacy-api-key-toggle-mutation.ts
index 72799e7686afc..cc4c0849c7124 100644
--- a/apps/studio/data/api-keys/legacy-api-key-toggle-mutation.ts
+++ b/apps/studio/data/api-keys/legacy-api-key-toggle-mutation.ts
@@ -16,7 +16,7 @@ export async function toggleLegacyAPIKeys(payload: ToggleLegacyAPIKeysVariables)
const { data, error } = await put('/v1/projects/{ref}/api-keys/legacy', {
params: {
path: { ref: payload.projectRef },
- query: { enabled: payload.enabled },
+ query: { enabled: payload.enabled ? 'true' : 'false' },
},
})
diff --git a/apps/studio/data/branches/branch-diff-query.ts b/apps/studio/data/branches/branch-diff-query.ts
index a858a48a3a4d8..4719993ac9cbe 100644
--- a/apps/studio/data/branches/branch-diff-query.ts
+++ b/apps/studio/data/branches/branch-diff-query.ts
@@ -24,10 +24,7 @@ export async function getBranchDiff({
const { data: diffData, error } = await get('/v1/branches/{branch_id_or_ref}/diff', {
params: {
path: { branch_id_or_ref: branchRef },
- query:
- Object.keys(query).length > 0
- ? (query as { included_schemas?: string; pgdelta?: boolean })
- : undefined,
+ query: Object.keys(query).length > 0 ? query : undefined,
},
headers: {
Accept: 'text/plain',
diff --git a/apps/studio/data/content/sql-snippets-query.ts b/apps/studio/data/content/sql-snippets-query.ts
index ec554a92b0c43..dbc4643479dad 100644
--- a/apps/studio/data/content/sql-snippets-query.ts
+++ b/apps/studio/data/content/sql-snippets-query.ts
@@ -40,7 +40,7 @@ export async function getSqlSnippets(
type,
cursor,
visibility,
- favorite,
+ favorite: favorite?.toString(),
name,
limit: SNIPPET_PAGE_LIMIT.toString(),
sort_by: sort,
diff --git a/apps/studio/data/custom-domains/custom-domains-delete-mutation.ts b/apps/studio/data/custom-domains/custom-domains-delete-mutation.ts
index 9d88c477b7f9d..56da08a1e1595 100644
--- a/apps/studio/data/custom-domains/custom-domains-delete-mutation.ts
+++ b/apps/studio/data/custom-domains/custom-domains-delete-mutation.ts
@@ -18,7 +18,7 @@ export async function deleteCustomDomain({
const { data, error } = await del(`/v1/projects/{ref}/custom-hostname`, {
params: {
path: { ref: projectRef },
- query: { remove_addon: removeAddon },
+ query: { remove_addon: removeAddon ? 'true' : 'false' },
},
})
diff --git a/apps/studio/data/organizations/organization-available-regions-query.ts b/apps/studio/data/organizations/organization-available-regions-query.ts
index 0c7ec9ec51b8d..2dbb1a9154213 100644
--- a/apps/studio/data/organizations/organization-available-regions-query.ts
+++ b/apps/studio/data/organizations/organization-available-regions-query.ts
@@ -10,7 +10,7 @@ export type DesiredInstanceSizeForAvailableRegions =
export type OrganizationAvailableRegionsVariables = {
slug?: string
- cloudProvider: 'AWS' | 'FLY' | 'AWS_K8S' | 'AWS_NIMBUS'
+ cloudProvider: 'AWS' | 'AWS_K8S' | 'AWS_NIMBUS'
desiredInstanceSize?: DesiredInstanceSizeForAvailableRegions
}
diff --git a/apps/studio/data/query-sources/query-source-registry.test.ts b/apps/studio/data/query-sources/query-source-registry.test.ts
new file mode 100644
index 0000000000000..03c2045655bcf
--- /dev/null
+++ b/apps/studio/data/query-sources/query-source-registry.test.ts
@@ -0,0 +1,116 @@
+import { describe, expect, it } from 'vitest'
+
+import {
+ cellSourceSchema,
+ createDefaultCellSource,
+ getQuerySource,
+ logTimeRangeSchema,
+ QUERY_SOURCES,
+} from './query-source-registry'
+
+describe('query source registry', () => {
+ it('registers database and logs sources with their execution endpoints', () => {
+ expect(QUERY_SOURCES.map(({ id }) => id)).toEqual(['database', 'logs'])
+ expect(getQuerySource('database').endpoint).toBe('/platform/pg-meta/{ref}/query')
+ expect(getQuerySource('logs').endpoint).toBe(
+ '/platform/projects/{ref}/analytics/endpoints/logs.all.otel'
+ )
+ })
+
+ it('creates independent, valid default cell bindings', () => {
+ const first = createDefaultCellSource('logs')
+ const second = createDefaultCellSource('logs')
+
+ expect(cellSourceSchema.parse(first)).toEqual({
+ id: 'logs',
+ type: 'logs',
+ parameters: {
+ time_range: { type: 'relative', amount: 1, unit: 'hour' },
+ },
+ })
+ expect(first.parameters.time_range).not.toBe(second.parameters.time_range)
+ expect(cellSourceSchema.parse(createDefaultCellSource('database'))).toEqual({
+ id: 'database',
+ type: 'database',
+ parameters: {},
+ })
+ })
+
+ it('rejects parameters that do not match the selected source type', () => {
+ expect(() =>
+ cellSourceSchema.parse({
+ id: 'logs',
+ type: 'logs',
+ parameters: { identifier: 'replica-1' },
+ })
+ ).toThrow()
+
+ expect(() =>
+ cellSourceSchema.parse({
+ id: 'database',
+ type: 'database',
+ parameters: { time_range: { type: 'relative', amount: 1, unit: 'hour' } },
+ })
+ ).toThrow()
+
+ expect(() =>
+ cellSourceSchema.parse({
+ id: 'logs',
+ type: 'logs',
+ parameters: { time_range: { type: 'relative', amount: 2, unit: 'week' } },
+ })
+ ).toThrow()
+ })
+
+ it('rejects absolute ranges that do not move forward in time', () => {
+ expect(
+ logTimeRangeSchema.safeParse({
+ type: 'absolute',
+ from: '2025-01-01T00:00:00.000Z',
+ to: '2025-01-02T00:00:00.000Z',
+ }).success
+ ).toBe(true)
+
+ const equal = logTimeRangeSchema.safeParse({
+ type: 'absolute',
+ from: '2025-01-01T00:00:00.000Z',
+ to: '2025-01-01T00:00:00.000Z',
+ })
+ expect(equal.success).toBe(false)
+ expect(equal.error?.issues[0].path).toEqual(['to'])
+
+ expect(
+ logTimeRangeSchema.safeParse({
+ type: 'absolute',
+ from: '2025-01-02T00:00:00.000Z',
+ to: '2025-01-01T00:00:00.000Z',
+ }).success
+ ).toBe(false)
+
+ expect(() =>
+ cellSourceSchema.parse({
+ id: 'logs',
+ type: 'logs',
+ parameters: {
+ time_range: {
+ type: 'absolute',
+ from: '2025-01-02T00:00:00.000Z',
+ to: '2025-01-01T00:00:00.000Z',
+ },
+ },
+ })
+ ).toThrow()
+ })
+
+ it('reports an invalid endpoint against its own field rather than the ordering rule', () => {
+ const result = logTimeRangeSchema.safeParse({
+ type: 'absolute',
+ from: 'not-a-date',
+ to: '2025-01-01T00:00:00.000Z',
+ })
+
+ expect(result.success).toBe(false)
+ expect(result.error?.issues).toHaveLength(1)
+ expect(result.error?.issues[0].path).toEqual(['from'])
+ })
+})
diff --git a/apps/studio/data/query-sources/query-source-registry.ts b/apps/studio/data/query-sources/query-source-registry.ts
new file mode 100644
index 0000000000000..eb8124a4f5830
--- /dev/null
+++ b/apps/studio/data/query-sources/query-source-registry.ts
@@ -0,0 +1,152 @@
+import dayjs from 'dayjs'
+import * as z from 'zod'
+
+import { logsAllEndpointUrl } from '@/data/logs/logs-endpoint'
+import { isoDateTimeString } from '@/lib/iso-datetime'
+
+export type LogTimeRange =
+ | {
+ type: 'relative'
+ amount: number
+ unit: 'minute' | 'hour' | 'day'
+ }
+ | {
+ type: 'absolute'
+ from: string
+ to: string
+ }
+
+export type DatabaseSource = {
+ id: 'database'
+ type: 'database'
+ endpoint: '/platform/pg-meta/{ref}/query'
+ parameters: {
+ /**
+ * Query-owned database selection. The SQL editor still adapts its legacy
+ * global/local-storage selector into this shape; new consumers persist the
+ * identifier directly with their query.
+ */
+ identifier?: string
+ }
+}
+
+export type LogsSource = {
+ id: 'logs'
+ type: 'logs'
+ endpoint: ReturnType
+ parameters: {
+ time_range: LogTimeRange
+ }
+}
+
+/** Sources are registered by Studio; query surfaces only store a source binding. */
+export type Source = DatabaseSource | LogsSource
+
+export type CellSourceOf = Pick
+
+export type CellSource = CellSourceOf | CellSourceOf
+
+export const DEFAULT_LOG_TIME_RANGE: LogTimeRange = {
+ type: 'relative',
+ amount: 1,
+ unit: 'hour',
+}
+
+export const QUERY_SOURCE_REGISTRY = {
+ database: {
+ id: 'database',
+ type: 'database',
+ endpoint: '/platform/pg-meta/{ref}/query',
+ parameters: {},
+ },
+ logs: {
+ id: 'logs',
+ type: 'logs',
+ endpoint: logsAllEndpointUrl(true),
+ parameters: { time_range: DEFAULT_LOG_TIME_RANGE },
+ },
+} as const satisfies Record
+
+export type QuerySourceId = keyof typeof QUERY_SOURCE_REGISTRY
+
+export const QUERY_SOURCES = Object.values(QUERY_SOURCE_REGISTRY) satisfies Source[]
+
+export const QUERY_SOURCE_LABELS: Record = {
+ database: 'Database',
+ logs: 'Logs',
+}
+
+const isoDateTimeSchema = z.string().refine((value) => isoDateTimeString(value) !== null, {
+ message: 'must be a valid ISO-8601 datetime',
+})
+
+export const logTimeRangeSchema = z
+ .discriminatedUnion('type', [
+ z
+ .object({
+ type: z.literal('relative'),
+ amount: z.number().int().positive(),
+ unit: z.enum(['minute', 'hour', 'day']),
+ })
+ .strict(),
+ z
+ .object({
+ type: z.literal('absolute'),
+ from: isoDateTimeSchema,
+ to: isoDateTimeSchema,
+ })
+ .strict(),
+ ])
+ .refine(
+ (range) => {
+ if (range.type !== 'absolute') return true
+
+ const from = dayjs(range.from)
+ const to = dayjs(range.to)
+ // An unparseable endpoint is already reported against its own field; the
+ // ordering rule stays quiet so it doesn't add a second, misleading issue.
+ if (!from.isValid() || !to.isValid()) return true
+
+ return to.isAfter(from)
+ },
+ {
+ message: 'must be later than the start of the range',
+ path: ['to'],
+ }
+ )
+
+export const cellSourceSchema = z.discriminatedUnion('type', [
+ z
+ .object({
+ id: z.literal('database'),
+ type: z.literal('database'),
+ parameters: z.object({ identifier: z.string().optional() }).strict(),
+ })
+ .strict(),
+ z
+ .object({
+ id: z.literal('logs'),
+ type: z.literal('logs'),
+ parameters: z.object({ time_range: logTimeRangeSchema }).strict(),
+ })
+ .strict(),
+])
+
+export function createDefaultCellSource(id: 'database'): CellSourceOf
+export function createDefaultCellSource(id: 'logs'): CellSourceOf
+export function createDefaultCellSource(id: QuerySourceId): CellSource
+export function createDefaultCellSource(id: QuerySourceId): CellSource {
+ const source = QUERY_SOURCE_REGISTRY[id]
+
+ if (source.type === 'logs') {
+ return {
+ id: source.id,
+ type: source.type,
+ parameters: { time_range: { ...source.parameters.time_range } },
+ }
+ }
+
+ return { id: source.id, type: source.type, parameters: { ...source.parameters } }
+}
+
+export const getQuerySource = (id: QuerySourceId): Source => QUERY_SOURCE_REGISTRY[id]
diff --git a/apps/studio/data/sql/execute-sql-mutation.ts b/apps/studio/data/sql/execute-sql-mutation.ts
index 3718fac1f5996..d1c2122cbf6af 100644
--- a/apps/studio/data/sql/execute-sql-mutation.ts
+++ b/apps/studio/data/sql/execute-sql-mutation.ts
@@ -12,6 +12,7 @@ import {
createNodeTree,
} from '@/components/interfaces/ExplainVisualizer/ExplainVisualizer.parser'
import { handleError as handleErrorFetchers, post } from '@/data/fetchers'
+import { QUERY_SOURCE_REGISTRY } from '@/data/query-sources/query-source-registry'
import { MB } from '@/lib/constants'
import { sqlEventParser } from '@/lib/sql-event-parser'
import { useTrack } from '@/lib/telemetry/track'
@@ -159,7 +160,7 @@ export async function executeSql(
const key =
queryKey?.filter((seg) => typeof seg === 'string' || typeof seg === 'number').join('-') ?? ''
- const result = await post('/platform/pg-meta/{ref}/query', {
+ const result = await post(QUERY_SOURCE_REGISTRY.database.endpoint, {
...options,
body: { query: sql, disable_statement_timeout: isStatementTimeoutDisabled },
params: {
diff --git a/apps/studio/data/storage/iceberg-namespace-table-delete-mutation.ts b/apps/studio/data/storage/iceberg-namespace-table-delete-mutation.ts
index d14f52fca5c3e..d78bd1d7678a0 100644
--- a/apps/studio/data/storage/iceberg-namespace-table-delete-mutation.ts
+++ b/apps/studio/data/storage/iceberg-namespace-table-delete-mutation.ts
@@ -25,7 +25,7 @@ async function deleteIcebergNamespaceTable({
{
params: {
path: { ref: projectRef, id: warehouse, namespace, table },
- query: { purge: true },
+ query: { purge: 'true' },
},
}
)
diff --git a/apps/studio/lib/api/self-hosted/signing-keys.test.ts b/apps/studio/lib/api/self-hosted/signing-keys.test.ts
index 69493f6509f7c..8e06231cb9068 100644
--- a/apps/studio/lib/api/self-hosted/signing-keys.test.ts
+++ b/apps/studio/lib/api/self-hosted/signing-keys.test.ts
@@ -30,6 +30,7 @@ describe('api/self-hosted/signing-keys', () => {
expect(key).toEqual({
id: '00000000-0000-0000-0000-000000000000',
algorithm: 'HS256',
+ public_jwk: '',
status: 'in_use',
created_at: '1970-01-01T00:00:00.000Z',
updated_at: '1970-01-01T00:00:00.000Z',
diff --git a/apps/studio/lib/api/self-hosted/signing-keys.ts b/apps/studio/lib/api/self-hosted/signing-keys.ts
index 86eb60d58f323..3541f2e8e7128 100644
--- a/apps/studio/lib/api/self-hosted/signing-keys.ts
+++ b/apps/studio/lib/api/self-hosted/signing-keys.ts
@@ -24,6 +24,7 @@ export function getLegacySigningKey(): SigningKeyResponse {
return {
id: LEGACY_KEY_ID,
algorithm: 'HS256',
+ public_jwk: '',
status: 'in_use',
created_at: LEGACY_KEY_CREATED_AT,
updated_at: LEGACY_KEY_CREATED_AT,
diff --git a/apps/studio/pages/api/platform/organizations/[slug]/billing/subscription.ts b/apps/studio/pages/api/platform/organizations/[slug]/billing/subscription.ts
index f585fc29b4e55..d7cee03359e45 100644
--- a/apps/studio/pages/api/platform/organizations/[slug]/billing/subscription.ts
+++ b/apps/studio/pages/api/platform/organizations/[slug]/billing/subscription.ts
@@ -35,7 +35,7 @@ const handleGet = async (_req: NextApiRequest, res: NextApiResponse {
// FE-3954: syncing the live array into valtio corrupted it with Proxies, breaking structuredClone in addToolApprovalResponse
@@ -44,3 +44,82 @@ describe('AI assistant chat message sync', () => {
expect(() => structuredClone(replacedMessage)).not.toThrow()
})
})
+
+describe('AI assistant chat surface isolation', () => {
+ it('creates chats without changing the sidebar selection', () => {
+ const state = createAiAssistantState()
+ const sidebarChatId = state.newChat({ name: 'Sidebar chat' })
+
+ const explorerChatId = state.createChat({ name: 'Explorer chat' })
+
+ expect(explorerChatId).not.toBe(sidebarChatId)
+ expect(state.activeChatId).toBe(sidebarChatId)
+ expect(state.chats[explorerChatId]?.name).toBe('Explorer chat')
+ })
+
+ it('branches a specified chat without changing the sidebar selection', () => {
+ const state = createAiAssistantState()
+ const sidebarChatId = state.newChat({ name: 'Sidebar chat' })
+ const explorerChatId = state.createChat({ name: 'Explorer chat' })
+ state.chats[explorerChatId].messages = [
+ { id: 'message-1', role: 'user', parts: [{ type: 'text', text: 'Hello' }] },
+ ]
+
+ const branchId = state.createBranch(explorerChatId, 'message-1')
+
+ expect(branchId).toBeDefined()
+ expect(state.activeChatId).toBe(sidebarChatId)
+ expect(state.chats[branchId!]?.branchedFrom).toEqual({
+ chatId: explorerChatId,
+ messageId: 'message-1',
+ })
+ })
+
+ it('mutates an explicit chat without changing or clearing the sidebar chat', () => {
+ const state = createAiAssistantState()
+ const sidebarChatId = state.newChat({ name: 'Sidebar chat' })
+ const explorerChatId = state.createChat({ name: 'Explorer chat' })
+ state.chats[sidebarChatId].messages = [
+ { id: 'sidebar-message', role: 'user', parts: [{ type: 'text', text: 'Keep me' }] },
+ ]
+ state.chats[explorerChatId].messages = [
+ { id: 'explorer-message', role: 'user', parts: [{ type: 'text', text: 'Clear me' }] },
+ ]
+ state.chatInstances[explorerChatId].messages = [
+ { id: 'explorer-message', role: 'user', parts: [{ type: 'text', text: 'Clear me' }] },
+ ]
+
+ state.clearMessages(explorerChatId)
+
+ expect(state.activeChatId).toBe(sidebarChatId)
+ expect(state.chats[sidebarChatId].messages).toHaveLength(1)
+ expect(state.chats[explorerChatId].messages).toHaveLength(0)
+ expect(state.chatInstances[explorerChatId].messages).toHaveLength(0)
+ })
+
+ it('keeps explicit chat message edits synchronized with the live chat instance', () => {
+ const state = createAiAssistantState()
+ const chatId = state.createChat({ name: 'Explorer chat' })
+ const messages = [
+ { id: 'message-1', role: 'user' as const, parts: [{ type: 'text' as const, text: 'First' }] },
+ {
+ id: 'message-2',
+ role: 'user' as const,
+ parts: [{ type: 'text' as const, text: 'Second' }],
+ },
+ ]
+ state.chats[chatId].messages = messages
+ state.chatInstances[chatId].messages = messages
+
+ state.deleteMessagesAfter('message-2', { chatId })
+ state.updateMessage(
+ { id: 'message-1', role: 'user', parts: [{ type: 'text', text: 'Updated' }] },
+ chatId
+ )
+
+ expect(state.chats[chatId].messages).toEqual([
+ { id: 'message-1', role: 'user', parts: [{ type: 'text', text: 'Updated' }] },
+ ])
+ expect(state.chatInstances[chatId].messages).toEqual(state.chats[chatId].messages)
+ })
+})
diff --git a/apps/studio/state/ai-assistant-state.tsx b/apps/studio/state/ai-assistant-state.tsx
index 5355074cf655c..8e0413bbc46a6 100644
--- a/apps/studio/state/ai-assistant-state.tsx
+++ b/apps/studio/state/ai-assistant-state.tsx
@@ -60,7 +60,7 @@ export type SupportChatMetadata = {
isLifecycleSyncing: boolean
}
-type ChatSession = {
+export type ChatSession = {
id: string
name: string
messages: AssistantMessageType[]
@@ -87,6 +87,10 @@ type AiAssistantData = {
context: AiAssistantContext
}
+type CreateChatOptions = { name?: string; initialMessage?: string }
+type NewChatOptions = CreateChatOptions &
+ Partial>
+
// Data structure stored in IndexedDB
type StoredAiAssistantState = {
projectRef: string
@@ -389,11 +393,7 @@ export const createAiAssistantState = (): AiAssistantState => {
return state.activeChatId ? state.chats[state.activeChatId] : undefined
},
- newChat: (
- options?: { name?: string; initialMessage?: string } & Partial<
- Pick
- >
- ) => {
+ createChat: (options?: CreateChatOptions) => {
const chatId = uuidv4()
const newChat: ChatSession = {
id: chatId,
@@ -407,21 +407,23 @@ export const createAiAssistantState = (): AiAssistantState => {
...state.chats,
[chatId]: newChat,
}
- state.activeChatId = chatId
- // Create new chat instance
const chatInstance = createChatInstance(state, { id: chatId, initialMessages: [] })
-
state.chatInstances[chatId] = ref(chatInstance)
- // If initialMessage is provided, append it to the chat instance
if (options?.initialMessage) {
chatInstance.sendMessage({
text: options.initialMessage,
})
}
- // Update non-chat related state based on options, falling back to current state, then initial
+ return chatId
+ },
+
+ newChat: (options?: NewChatOptions) => {
+ const chatId = state.createChat(options)
+ state.selectChat(chatId)
+
const initialAiAssistantData = createInitialAiAssistantData()
state.initialInput = options?.initialInput ?? initialAiAssistantData.initialInput
state.sqlSnippets = options?.sqlSnippets ?? initialAiAssistantData.sqlSnippets
@@ -431,8 +433,8 @@ export const createAiAssistantState = (): AiAssistantState => {
return chatId
},
- branchChat: (messageId: string) => {
- const sourceChat = state.activeChat
+ createBranch: (sourceChatId: string, messageId: string) => {
+ const sourceChat = state.chats[sourceChatId]
if (!sourceChat) return
const messageIndex = sourceChat.messages.findIndex((msg) => msg.id === messageId)
@@ -456,12 +458,22 @@ export const createAiAssistantState = (): AiAssistantState => {
...state.chats,
[chatId]: newChat,
}
- state.activeChatId = chatId
state.chatInstances[chatId] = ref(
createChatInstance(state, { id: chatId, initialMessages: branchedMessages })
)
+ return chatId
+ },
+
+ branchChat: (messageId: string) => {
+ if (!state.activeChatId) return
+
+ const chatId = state.createBranch(state.activeChatId, messageId)
+ if (!chatId) return
+
+ state.selectChat(chatId)
+
const initialAiAssistantData = createInitialAiAssistantData()
state.initialInput = initialAiAssistantData.initialInput
state.sqlSnippets = initialAiAssistantData.sqlSnippets
@@ -493,35 +505,33 @@ export const createAiAssistantState = (): AiAssistantState => {
})
},
- selectChat: (id: string) => {
- if (id !== state.activeChatId) {
- state.activeChatId = id
- const chat = state.chats[id]
- if (chat) {
- if (!state.chatInstances[id]) {
- state.chatInstances[id] = ref(
- createChatInstance(state, { id, initialMessages: chat.messages })
- )
- }
- }
+ ensureChatInstance: (id: string) => {
+ const chat = state.chats[id]
+ if (chat && !state.chatInstances[id]) {
+ state.chatInstances[id] = ref(
+ createChatInstance(state, { id, initialMessages: chat.messages })
+ )
}
},
+ selectChat: (id: string) => {
+ if (!state.chats[id]) return
+
+ state.activeChatId = id
+ state.ensureChatInstance(id)
+ },
+
deleteChat: (id: string) => {
const { [id]: _, ...remainingChats } = state.chats
state.chats = remainingChats
+ delete state.chatInstances[id]
if (id === state.activeChatId) {
const remainingChatIds = Object.keys(remainingChats)
state.activeChatId = remainingChatIds.length > 0 ? remainingChatIds[0] : undefined
if (state.activeChatId) {
- const chat = state.chats[state.activeChatId]
- if (!state.chatInstances[state.activeChatId]) {
- state.chatInstances[state.activeChatId] = ref(
- createChatInstance(state, { id: state.activeChatId, initialMessages: chat.messages })
- )
- }
+ state.ensureChatInstance(state.activeChatId)
}
}
},
@@ -534,19 +544,27 @@ export const createAiAssistantState = (): AiAssistantState => {
}
},
- clearMessages: () => {
- const chat = state.activeChat
+ clearMessages: (chatId = state.activeChatId) => {
+ if (!chatId) return
+
+ const chat = state.chats[chatId]
if (chat) {
chat.messages = []
+ const chatInstance = state.chatInstances[chatId]
+ if (chatInstance) chatInstance.messages = []
chat.updatedAt = new Date()
- state.suggestions = undefined
- state.sqlSnippets = []
- state.initialInput = ''
+ if (chatId === state.activeChatId) {
+ state.suggestions = undefined
+ state.sqlSnippets = []
+ state.initialInput = ''
+ }
}
},
- deleteMessagesAfter: (id: string, { includeSelf = true } = {}) => {
- const chat = state.activeChat
+ deleteMessagesAfter: (id: string, { includeSelf = true, chatId = state.activeChatId } = {}) => {
+ if (!chatId) return
+
+ const chat = state.chats[chatId]
if (!chat) return
const messageIndex = chat.messages.findIndex((msg) => msg.id === id)
@@ -555,17 +573,37 @@ export const createAiAssistantState = (): AiAssistantState => {
// Delete all messages from the target message (optionally including) to the end
const startIndex = includeSelf ? messageIndex : messageIndex + 1
chat.messages.splice(startIndex)
+ const chatInstance = state.chatInstances[chatId]
+ const instanceMessageIndex = chatInstance?.messages.findIndex((message) => message.id === id)
+ if (chatInstance && instanceMessageIndex !== undefined && instanceMessageIndex !== -1) {
+ chatInstance.messages = chatInstance.messages.slice(
+ 0,
+ includeSelf ? instanceMessageIndex : instanceMessageIndex + 1
+ )
+ }
chat.updatedAt = new Date()
},
- updateMessage: (updatedMessage: MessageType) => {
- const chat = state.activeChat
+ updateMessage: (updatedMessage: MessageType, chatId = state.activeChatId) => {
+ if (!chatId) return
+
+ const chat = state.chats[chatId]
if (!chat) return
const messageIndex = chat.messages.findIndex((msg) => msg.id === updatedMessage.id)
if (messageIndex !== -1) {
// Clone first — valtio's proxy() mutates nested properties in place and would corrupt the SDK's live array
- chat.messages[messageIndex] = sanitizeForCloning(updatedMessage)
+ const clonedMessage = sanitizeForCloning(updatedMessage)
+ chat.messages[messageIndex] = clonedMessage
+ const chatInstance = state.chatInstances[chatId]
+ const instanceMessageIndex = chatInstance?.messages.findIndex(
+ (message) => message.id === updatedMessage.id
+ )
+ if (chatInstance && instanceMessageIndex !== undefined && instanceMessageIndex !== -1) {
+ chatInstance.messages = chatInstance.messages.map((message, index) =>
+ index === instanceMessageIndex ? sanitizeForCloning(updatedMessage) : message
+ )
+ }
chat.updatedAt = new Date()
}
},
@@ -620,18 +658,7 @@ export const createAiAssistantState = (): AiAssistantState => {
}
// Initialize chat instance for the active chat
- if (
- state.activeChatId &&
- state.chats[state.activeChatId] &&
- !state.chatInstances[state.activeChatId]
- ) {
- state.chatInstances[state.activeChatId] = ref(
- createChatInstance(state, {
- id: state.activeChatId,
- initialMessages: state.chats[state.activeChatId].messages,
- })
- )
- }
+ if (state.activeChatId) state.ensureChatInstance(state.activeChatId)
},
clearStorage: async () => {
@@ -650,19 +677,18 @@ export type AiAssistantState = AiAssistantData & {
messageSpanIds: Record
setContext: (context: Partial) => void
setModel: (model: AssistantModel) => void
- newChat: (
- options?: { name?: string; initialMessage?: string } & Partial<
- Pick
- >
- ) => string
+ createChat: (options?: CreateChatOptions) => string
+ newChat: (options?: NewChatOptions) => string
+ createBranch: (sourceChatId: string, messageId: string) => string | undefined
branchChat: (messageId: string) => string | undefined
setSupportLifecycleStatus: (chatId: string, status: AiSupportStatus) => void
+ ensureChatInstance: (id: string) => void
selectChat: (id: string) => void
deleteChat: (id: string) => void
renameChat: (id: string, name: string) => void
- clearMessages: () => void
- deleteMessagesAfter: (id: string, options?: { includeSelf?: boolean }) => void
- updateMessage: (message: MessageType) => void
+ clearMessages: (chatId?: string) => void
+ deleteMessagesAfter: (id: string, options?: { includeSelf?: boolean; chatId?: string }) => void
+ updateMessage: (message: MessageType, chatId?: string) => void
setSqlSnippets: (snippets: SqlSnippet[]) => void
clearSqlSnippets: () => void
loadPersistedState: (persistedState: StoredAiAssistantState) => void
diff --git a/apps/studio/state/sql-editor/sql-editor-session-state.ts b/apps/studio/state/sql-editor/sql-editor-session-state.ts
index 38aeafc030c19..b7813f58333ab 100644
--- a/apps/studio/state/sql-editor/sql-editor-session-state.ts
+++ b/apps/studio/state/sql-editor/sql-editor-session-state.ts
@@ -1,6 +1,6 @@
import { proxy, ref, snapshot, useSnapshot } from 'valtio'
-import type { LogDateRange } from '@/components/interfaces/SQLEditor/querySource'
+import type { LogTimeRange } from '@/data/query-sources/query-source-registry'
/**
* Ephemeral, per-session SQL editor state that is NOT persisted: query results,
@@ -35,11 +35,11 @@ export const sqlEditorSessionState = proxy({
* The logs time range for a logs snippet, keyed by snippet id. Session state —
* never written to snippet content — so it works on read-only shared snippets
* and resets on reload. An unset snippet has no entry; read sites fall back to
- * `DEFAULT_LOG_DATE_RANGE`.
+ * `DEFAULT_LOG_TIME_RANGE`.
*/
- logRange: {} as { [snippetId: string]: LogDateRange },
+ logRange: {} as { [snippetId: string]: LogTimeRange },
- setLogRange: (id: string, range: LogDateRange) => {
+ setLogRange: (id: string, range: LogTimeRange) => {
sqlEditorSessionState.logRange[id] = range
},
diff --git a/apps/studio/tests/components/Organization/TeamSettings/InviteMemberButton.network.test.tsx b/apps/studio/tests/components/Organization/TeamSettings/InviteMemberButton.network.test.tsx
index c8138d6dc595e..1ab2641ffaede 100644
--- a/apps/studio/tests/components/Organization/TeamSettings/InviteMemberButton.network.test.tsx
+++ b/apps/studio/tests/components/Organization/TeamSettings/InviteMemberButton.network.test.tsx
@@ -67,6 +67,7 @@ const buildRole = (id: number, name: string): OrganizationRoleResponse['org_scop
const buildMember = (overrides: Partial): Member => ({
gotrue_id: 'gotrue-test',
+ avatar_url: null,
is_sso_user: false,
metadata: {},
mfa_enabled: false,
diff --git a/apps/studio/tests/components/Organization/TeamSettings/UpdateRolesPanel.network.test.tsx b/apps/studio/tests/components/Organization/TeamSettings/UpdateRolesPanel.network.test.tsx
index c8c4ca7bbabae..0ab629a98b246 100644
--- a/apps/studio/tests/components/Organization/TeamSettings/UpdateRolesPanel.network.test.tsx
+++ b/apps/studio/tests/components/Organization/TeamSettings/UpdateRolesPanel.network.test.tsx
@@ -83,6 +83,7 @@ const buildPermission = (resource: string): AccessControlPermission => ({
const MEMBER: OrganizationMember = {
gotrue_id: 'gotrue-member',
+ avatar_url: null,
is_sso_user: false,
metadata: {},
mfa_enabled: false,
diff --git a/apps/studio/tests/components/SQLEditor/QuerySourceMenu.test.tsx b/apps/studio/tests/components/SQLEditor/QuerySourceMenu.test.tsx
index 6985f0ad82202..d1ef963eb6342 100644
--- a/apps/studio/tests/components/SQLEditor/QuerySourceMenu.test.tsx
+++ b/apps/studio/tests/components/SQLEditor/QuerySourceMenu.test.tsx
@@ -1,42 +1,58 @@
import { screen } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import { mockAnimationsApi } from 'jsdom-testing-mocks'
-import { describe, expect, it } from 'vitest'
+import { beforeEach, describe, expect, it } from 'vitest'
-import { DEFAULT_LOG_DATE_RANGE } from '@/components/interfaces/SQLEditor/querySource'
import { QuerySourceMenu } from '@/components/interfaces/SQLEditor/UtilityPanel/QuerySourceMenu/QuerySourceMenu'
+import { DEFAULT_LOG_TIME_RANGE } from '@/data/query-sources/query-source-registry'
import { customRender } from '@/tests/lib/custom-render'
import { addAPIMock } from '@/tests/lib/msw'
// QuerySourceMenu renders a Radix dropdown (+ nested dialog), both of which use Web Animations.
mockAnimationsApi()
-addAPIMock({
- method: 'get',
- path: '/platform/projects/:ref',
- response: {
- id: 1,
- ref: 'default',
- organization_id: 1,
- name: 'Test Project',
- status: 'ACTIVE_HEALTHY',
- cloud_provider: 'AWS',
- region: 'us-east-1',
- db_host: 'db.default.supabase.co',
- restUrl: 'https://default.supabase.co/rest/v1/',
- inserted_at: '2024-01-01T00:00:00Z',
- updated_at: '2024-01-01T00:00:00Z',
- subscription_id: 'sub_123',
- is_branch_enabled: false,
- is_physical_backups_enabled: false,
- high_availability: false,
- integration_source: null,
- connectionString: 'postgresql://postgres@localhost:5432/postgres',
- is_hibernating: false,
- },
+beforeEach(() => {
+ addAPIMock({
+ method: 'get',
+ path: '/platform/projects/:ref',
+ response: {
+ id: 1,
+ ref: 'default',
+ organization_id: 1,
+ name: 'Test Project',
+ status: 'ACTIVE_HEALTHY',
+ cloud_provider: 'AWS',
+ region: 'us-east-1',
+ db_host: 'db.default.supabase.co',
+ restUrl: 'https://default.supabase.co/rest/v1/',
+ inserted_at: '2024-01-01T00:00:00Z',
+ updated_at: '2024-01-01T00:00:00Z',
+ subscription_id: 'sub_123',
+ is_branch_enabled: false,
+ is_physical_backups_enabled: false,
+ high_availability: false,
+ integration_source: null,
+ connectionString: 'postgresql://postgres@localhost:5432/postgres',
+ is_hibernating: false,
+ },
+ })
})
describe('QuerySourceMenu', () => {
+ it('hides logs when creating logs queries is unavailable', async () => {
+ customRender(
+
+ )
+
+ await userEvent.click(screen.getByRole('button', { name: 'Query source: Database' }))
+
+ expect(screen.queryByText('Logs')).not.toBeInTheDocument()
+ })
+
it('keeps the dropdown open across a source switch, so the new source’s controls appear without reopening it', async () => {
// Selecting a source doesn't mutate `runSource` in place — it navigates to a
// fresh tab, and the parent re-renders this component with the new source once
@@ -57,7 +73,7 @@ describe('QuerySourceMenu', () => {
rerender(
)
diff --git a/apps/studio/tests/features/logs/Logs.Datepickers.test.tsx b/apps/studio/tests/features/logs/Logs.Datepickers.test.tsx
index 09e328d5f4ec5..c9bff95574f13 100644
--- a/apps/studio/tests/features/logs/Logs.Datepickers.test.tsx
+++ b/apps/studio/tests/features/logs/Logs.Datepickers.test.tsx
@@ -96,7 +96,7 @@ describe('generateDynamicHelper', () => {
})
describe('generateDynamicHelpers', () => {
- test('generates 3 helpers for minutes, hours, days', () => {
+ test('generates helpers for every supported relative unit', () => {
const helpers = generateDynamicHelpers(5)
expect(helpers).toHaveLength(3)
expect(helpers[0].text).toBe('Last 5 minutes')
@@ -112,7 +112,7 @@ describe('generateHelpersFromInput', () => {
expect(generateHelpersFromInput('2yoie')).toBeNull()
})
- test('returns 3 helpers for number only input', () => {
+ test('returns a helper for every unit for number only input', () => {
const helpers = generateHelpersFromInput('25')
expect(helpers).toHaveLength(3)
expect(helpers![0].text).toBe('Last 25 minutes')
diff --git a/apps/www/data/PricingFAQ.json b/apps/www/data/PricingFAQ.json
index 222e0620e9ef6..4a268d4c1804a 100644
--- a/apps/www/data/PricingFAQ.json
+++ b/apps/www/data/PricingFAQ.json
@@ -17,19 +17,19 @@
},
{
"question": "Are you going to change your pricing in the future?",
- "answer": "Our pricing is in Beta. You can read more about our decisions in our [pricing blog post](/blog/2021/03/29/pricing). Pricing may change in the future, however as a team of developers we are committed to pricing being as developer friendly as possible."
+ "answer": "Pricing may change in the future. As a team of developers, we are committed to keeping our pricing as developer friendly as possible."
},
{
"question": "What happens if I cancel my subscription?",
"answer": "The organization is allocated credits for unused time during the billing month. Those credits can be used for other projects."
},
{
- "question": "Do I get a notification if I am approaching my usage limits?",
- "answer": "Yes, we will email you when you are within 20% of your Plan limits."
+ "question": "How can I track my usage?",
+ "answer": "You can track your organization's usage at any time on the [usage page](https://supabase.com/dashboard/org/_/usage) in the dashboard, which shows how each project is tracking against your plan's limits. Your upcoming invoice on the [billing page](https://supabase.com/dashboard/org/_/billing) updates as you go, and organizations on the Pro Plan or above can use the [Spend cap](https://supabase.com/docs/guides/platform/cost-control) to control costs."
},
{
"question": "What if I need one project for development and one for production?",
- "answer": "We are working on multi-environment projects. For now, you can create a project for your development backend and production backend. We give you 2 free projects as part of our Free Plan. This means you could have a development and a production server as part of your Free Plan."
+ "answer": "You can create two projects, one for development and one for production — the Free Plan includes two free projects. You can also use [Branching](https://supabase.com/docs/guides/deployment/branching), available on the Pro Plan and above, to run a separate development environment off your production project."
},
{
"question": "Can I self-host Supabase for free?",
diff --git a/packages/api-types/index.ts b/packages/api-types/index.ts
index 4870d902de659..9c89e97947a55 100644
--- a/packages/api-types/index.ts
+++ b/packages/api-types/index.ts
@@ -1,25 +1,38 @@
import type {
- components as apiComponents,
- operations as apiOperations,
- paths as apiPaths,
-} from './types/api'
+ components as apiV1Components,
+ operations as apiV1Operations,
+ paths as apiV1Paths,
+} from './types/api-v1'
+import type {
+ components as apiV2Components,
+ operations as apiV2Operations,
+ paths as apiV2Paths,
+} from './types/api-v2'
import type {
components as platformComponents,
operations as platformOperations,
paths as platformPaths,
} from './types/platform'
-export type { webhooks, $defs } from './types/api'
+export type { webhooks, $defs } from './types/api-v2'
-export interface paths extends apiPaths, platformPaths {}
-export interface operations extends apiOperations, platformOperations {}
+export interface paths extends apiV2Paths, apiV1Paths, platformPaths {}
+export interface operations extends apiV2Operations, apiV1Operations, platformOperations {}
export interface components {
- schemas: apiComponents['schemas'] & platformComponents['schemas']
- responses: apiComponents['responses'] & platformComponents['responses']
- parameters: apiComponents['parameters'] & platformComponents['parameters']
- requestBodies: apiComponents['requestBodies'] & platformComponents['requestBodies']
- headers: apiComponents['headers'] & platformComponents['headers']
- pathItems: apiComponents['pathItems'] & platformComponents['pathItems']
+ schemas: apiV2Components['schemas'] & apiV1Components['schemas'] & platformComponents['schemas']
+ responses: apiV2Components['responses'] &
+ apiV1Components['responses'] &
+ platformComponents['responses']
+ parameters: apiV2Components['parameters'] &
+ apiV1Components['parameters'] &
+ platformComponents['parameters']
+ requestBodies: apiV2Components['requestBodies'] &
+ apiV1Components['requestBodies'] &
+ platformComponents['requestBodies']
+ headers: apiV2Components['headers'] & apiV1Components['headers'] & platformComponents['headers']
+ pathItems: apiV2Components['pathItems'] &
+ apiV1Components['pathItems'] &
+ platformComponents['pathItems']
}
-export type { platformComponents, apiComponents }
+export type { platformComponents, apiV1Components, apiV2Components }
diff --git a/packages/api-types/redocly.yaml b/packages/api-types/redocly.yaml
index 59023bf6afc39..1d34a034cef1a 100644
--- a/packages/api-types/redocly.yaml
+++ b/packages/api-types/redocly.yaml
@@ -1,9 +1,13 @@
apis:
- api:
+ api-v2:
+ root: http://localhost:8080/api/v2-json
+ x-openapi-ts:
+ output: ./types/api-v2.d.ts
+ api-v1:
root: http://localhost:8080/api/v1-json
x-openapi-ts:
- output: ./types/api.d.ts
+ output: ./types/api-v1.d.ts
platform:
root: http://localhost:8080/api/platform-json
x-openapi-ts:
- output: ./types/platform.d.ts
\ No newline at end of file
+ output: ./types/platform.d.ts
diff --git a/packages/api-types/types/api.d.ts b/packages/api-types/types/api-v1.d.ts
similarity index 94%
rename from packages/api-types/types/api.d.ts
rename to packages/api-types/types/api-v1.d.ts
index eef705e690efe..182549218cac2 100644
--- a/packages/api-types/types/api.d.ts
+++ b/packages/api-types/types/api-v1.d.ts
@@ -521,6 +521,35 @@ export interface paths {
patch?: never
trace?: never
}
+ '/v1/projects/{ref}/analytics/endpoints/logs': {
+ parameters: {
+ query?: never
+ header?: never
+ path?: never
+ cookie?: never
+ }
+ /**
+ * Gets all project's logs in a single log stream
+ * @description Executes an SQL or LQL query on the project's unified logs stream.
+ *
+ * Either the `iso_timestamp_start` and `iso_timestamp_end` parameters must be provided.
+ * If both are not provided, only the last 1 minute of logs will be queried.
+ * The timestamp range must be no more than 24 hours and is rounded to the nearest minute. If the range is more than 24 hours, a validation error will be thrown.
+ *
+ * Filter by the `source` column to specify specific log sources, such as edge_logs, postgres_logs, etc.
+ *
+ * Note: SQL must be written in **ClickHouse SQL dialect**.
+ *
+ */
+ get: operations['v1-get-project-logs']
+ put?: never
+ post?: never
+ delete?: never
+ options?: never
+ head?: never
+ patch?: never
+ trace?: never
+ }
'/v1/projects/{ref}/analytics/endpoints/logs.all': {
parameters: {
query?: never
@@ -530,6 +559,7 @@ export interface paths {
}
/**
* Gets project's logs
+ * @deprecated
* @description Executes a SQL query on the project's logs.
*
* Either the `iso_timestamp_start` and `iso_timestamp_end` parameters must be provided.
@@ -539,7 +569,27 @@ export interface paths {
* Note: Unless the `sql` parameter is provided, only edge_logs will be queried. See the [log query docs](/docs/guides/telemetry/logs?queryGroups=product&product=postgres&queryGroups=source&source=edge_logs#querying-with-the-logs-explorer:~:text=logs%20from%20the-,Sources,-drop%2Ddown%3A) for all available sources.
*
*/
- get: operations['v1-get-project-logs']
+ get: operations['v1-get-project-logs-all']
+ put?: never
+ post?: never
+ delete?: never
+ options?: never
+ head?: never
+ patch?: never
+ trace?: never
+ }
+ '/v1/projects/{ref}/analytics/endpoints/metrics': {
+ parameters: {
+ query?: never
+ header?: never
+ path?: never
+ cookie?: never
+ }
+ /**
+ * Scrape a project's metrics
+ * @description Prometheus scrape endpoint. Returns metrics of a customer project in the Prometheus open exposition format.
+ */
+ get: operations['v1-scrape-project-metrics']
put?: never
post?: never
delete?: never
@@ -1315,6 +1365,66 @@ export interface paths {
patch?: never
trace?: never
}
+ '/v1/projects/{ref}/database/jit/invite': {
+ parameters: {
+ query?: never
+ header?: never
+ path?: never
+ cookie?: never
+ }
+ get?: never
+ put?: never
+ /**
+ * Invites an external user to a database for JIT access
+ * @description Invites the external user and sets initial roles that can be assumed and for how long
+ */
+ post: operations['v1-invite-external-jit-access']
+ delete?: never
+ options?: never
+ head?: never
+ patch?: never
+ trace?: never
+ }
+ '/v1/projects/{ref}/database/jit/invite/{invite_id}': {
+ parameters: {
+ query?: never
+ header?: never
+ path?: never
+ cookie?: never
+ }
+ get?: never
+ put?: never
+ post?: never
+ /**
+ * Deletes the invite for an external user to a database for JIT access
+ * @description Revokes and deletes the invitation
+ */
+ delete: operations['v1-delete-invite-external-jit-access']
+ options?: never
+ head?: never
+ patch?: never
+ trace?: never
+ }
+ '/v1/projects/{ref}/database/jit/invite/accept': {
+ parameters: {
+ query?: never
+ header?: never
+ path?: never
+ cookie?: never
+ }
+ get?: never
+ put?: never
+ /**
+ * Accepts invitation for JIT database access
+ * @description Accepts the invitation to JIT database access
+ */
+ post: operations['v1-accept-invite-external-jit-access']
+ delete?: never
+ options?: never
+ head?: never
+ patch?: never
+ trace?: never
+ }
'/v1/projects/{ref}/database/jit/list': {
parameters: {
query?: never
@@ -1342,25 +1452,13 @@ export interface paths {
path?: never
cookie?: never
}
- /**
- * List applied migration versions
- * @description Only available to selected partner OAuth apps
- */
+ /** List applied migration versions */
get: operations['v1-list-migration-history']
- /**
- * Upsert a database migration without applying
- * @description Only available to selected partner OAuth apps
- */
+ /** Upsert a database migration without applying */
put: operations['v1-upsert-a-migration']
- /**
- * Apply a database migration
- * @description Only available to selected partner OAuth apps
- */
+ /** Apply a database migration */
post: operations['v1-apply-a-migration']
- /**
- * Rollback database migrations and remove them from history table
- * @description Only available to selected partner OAuth apps
- */
+ /** Rollback database migrations and remove them from history table */
delete: operations['v1-rollback-migrations']
options?: never
head?: never
@@ -1374,20 +1472,14 @@ export interface paths {
path?: never
cookie?: never
}
- /**
- * Fetch an existing entry from migration history
- * @description Only available to selected partner OAuth apps
- */
+ /** Fetch an existing entry from migration history */
get: operations['v1-get-a-migration']
put?: never
post?: never
delete?: never
options?: never
head?: never
- /**
- * Patch an existing entry in migration history
- * @description Only available to selected partner OAuth apps
- */
+ /** Patch an existing entry in migration history */
patch: operations['v1-patch-a-migration']
trace?: never
}
@@ -2114,6 +2206,15 @@ export interface paths {
export type webhooks = Record
export interface components {
schemas: {
+ /** @example {
+ * "email": "external-user@somedomain.xyz",
+ * "token": ""
+ * } */
+ AcceptInviteExternalUserJitAccessBody: {
+ /** Format: email */
+ email: string
+ token: string
+ }
ActionRunResponse: {
branch_id: string
check_run_id: number | null
@@ -2749,7 +2850,6 @@ export interface components {
domains?: {
created_at?: string
domain?: string
- id: string
updated_at?: string
}[]
id: string
@@ -2765,7 +2865,6 @@ export interface components {
}
}
entity_id: string
- id: string
metadata_url?: string
metadata_xml?: string
/** @enum {string} */
@@ -2932,7 +3031,6 @@ export interface components {
domains?: {
created_at?: string
domain?: string
- id: string
updated_at?: string
}[]
id: string
@@ -2948,7 +3046,6 @@ export interface components {
}
}
entity_id: string
- id: string
metadata_url?: string
metadata_xml?: string
/** @enum {string} */
@@ -3053,7 +3150,7 @@ export interface components {
* }
* } */
FunctionDeployBody: {
- file?: string[]
+ file: string[]
metadata: {
entrypoint_path: string
import_map_path?: string
@@ -3122,7 +3219,6 @@ export interface components {
domains?: {
created_at?: string
domain?: string
- id: string
updated_at?: string
}[]
id: string
@@ -3138,7 +3234,6 @@ export interface components {
}
}
entity_id: string
- id: string
metadata_url?: string
metadata_xml?: string
/** @enum {string} */
@@ -3150,6 +3245,63 @@ export interface components {
}
updated_at?: string
}
+ /** @example {
+ * "email": "external-user@somedomain.xyz",
+ * "roles": [
+ * {
+ * "role": "postgres",
+ * "expires_at": 1740787200,
+ * "allowed_networks": {
+ * "allowed_cidrs": [
+ * {
+ * "cidr": "203.0.113.0/24"
+ * }
+ * ]
+ * },
+ * "branches_only": false
+ * }
+ * ]
+ * } */
+ InviteExternalUserJitAccessBody: {
+ /** Format: email */
+ email: string
+ roles: {
+ allowed_networks?: {
+ allowed_cidrs?: {
+ /** Format: cidrv4 */
+ cidr: string
+ }[]
+ allowed_cidrs_v6?: {
+ /** Format: cidrv6 */
+ cidr: string
+ }[]
+ }
+ branches_only?: boolean
+ expires_at?: number
+ role: string
+ }[]
+ }
+ InviteExternalUserJitResponse: {
+ /** Format: email */
+ email: string
+ /** Format: uuid */
+ invite_id: string
+ user_roles: {
+ allowed_networks?: {
+ allowed_cidrs?: {
+ /** Format: cidrv4 */
+ cidr: string
+ }[]
+ allowed_cidrs_v6?: {
+ /** Format: cidrv6 */
+ cidr: string
+ }[]
+ }
+ branches_only?: boolean
+ expires_at?: number
+ role: string
+ }[]
+ }
/** @example {
* "state": "enabled"
* } */
@@ -3159,13 +3311,15 @@ export interface components {
}
JitAccessResponse: {
/** Format: uuid */
- user_id: string
+ user_id?: string
user_roles: {
allowed_networks?: {
allowed_cidrs?: {
+ /** Format: cidrv4 */
cidr: string
}[]
allowed_cidrs_v6?: {
+ /** Format: cidrv6 */
cidr: string
}[]
}
@@ -3180,9 +3334,11 @@ export interface components {
user_role: {
allowed_networks?: {
allowed_cidrs?: {
+ /** Format: cidrv4 */
cidr: string
}[]
allowed_cidrs_v6?: {
+ /** Format: cidrv6 */
cidr: string
}[]
}
@@ -3193,14 +3349,19 @@ export interface components {
}
JitListAccessResponse: {
items: {
+ expires_at: null
+ invite_id: null
+ primary_email: string | null
/** Format: uuid */
user_id: string
user_roles: {
allowed_networks?: {
allowed_cidrs?: {
+ /** Format: cidrv4 */
cidr: string
}[]
allowed_cidrs_v6?: {
+ /** Format: cidrv6 */
cidr: string
}[]
}
@@ -3210,22 +3371,6 @@ export interface components {
}[]
}[]
}
- JitStateResponse:
- | {
- appliedSuccessfully?: boolean
- /** @enum {string} */
- state: 'enabled' | 'disabled'
- }
- | {
- /** @enum {string} */
- state: 'unavailable'
- /** @enum {string} */
- unavailableReason:
- | 'manual_migration_required'
- | 'postgres_upgrade_required'
- | 'ssl_enforcement_required'
- | 'temporarily_unavailable'
- }
LegacyApiKeysResponse: {
enabled: boolean
}
@@ -3288,8 +3433,7 @@ export interface components {
| 'auth_mfa_web_authn_default'
| 'log_drain_default'
| 'etl_pipeline_default'
- /** @description Any JSON-serializable value */
- meta?: unknown
+ meta?: components['schemas']['ListProjectAddonsResponseJsonValue']
name: string
price: {
amount: number
@@ -3341,8 +3485,7 @@ export interface components {
| 'auth_mfa_web_authn_default'
| 'log_drain_default'
| 'etl_pipeline_default'
- /** @description Any JSON-serializable value */
- meta?: unknown
+ meta?: components['schemas']['ListProjectAddonsResponseJsonValue']
name: string
price: {
amount: number
@@ -3355,13 +3498,19 @@ export interface components {
}
}[]
}
+ /** @description Any JSON-serializable value */
+ ListProjectAddonsResponseJsonValue:
+ | ((string | number | boolean) | null)
+ | components['schemas']['ListProjectAddonsResponseJsonValue'][]
+ | {
+ [key: string]: components['schemas']['ListProjectAddonsResponseJsonValue']
+ }
ListProvidersResponse: {
items: {
created_at?: string
domains?: {
created_at?: string
domain?: string
- id: string
updated_at?: string
}[]
id: string
@@ -3377,7 +3526,6 @@ export interface components {
}
}
entity_id: string
- id: string
metadata_url?: string
metadata_xml?: string
/** @enum {string} */
@@ -3437,7 +3585,17 @@ export interface components {
NetworkRestrictionsResponse: {
/** Format: date-time */
applied_at?: string
- /** @description At any given point in time, this is the config that the user has requested be applied to their project. The `status` field indicates if it has been applied to the project, or is pending. When an updated config is received, the applied config is moved to `old_config`. */
+ /**
+ * @description At any given point in time, this is the config that the user has requested be applied to their project. The `status` field indicates if it has been applied to the project, or is pending. When an updated config is received, the applied config is moved to `old_config`.
+ * @example {
+ * "dbAllowedCidrs": [
+ * "203.0.113.0/24"
+ * ],
+ * "dbAllowedCidrsV6": [
+ * "2001:db8::/32"
+ * ]
+ * }
+ */
config: {
dbAllowedCidrs?: string[]
dbAllowedCidrsV6?: string[]
@@ -3669,9 +3827,29 @@ export interface components {
*/
slug: string
}
+ /** @example {
+ * "root_key": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
+ * } */
PgsodiumConfigResponse: {
+ /** @description The pgsodium root key: 32 bytes, hex-encoded (64 characters). */
root_key: string
}
+ PlanGateErrorBody: {
+ /** @description Present on entitlement denials. Other errors with this status code (validation, billing state) carry only message. */
+ error?: {
+ /**
+ * @description Machine-readable marker for plan-gated denials
+ * @enum {string}
+ */
+ code: 'entitlement_required'
+ /** @description Entitlement feature key that failed the check */
+ feature: string
+ /** @description Billing page URL for the organization, present when the org is resolvable */
+ upgrade_url?: string
+ }
+ /** @description Human-readable explanation of the plan gate */
+ message: string
+ }
PostgresConfigResponse: {
/** @description Default unit: s */
checkpoint_timeout?: string
@@ -3694,6 +3872,7 @@ export interface components {
maintenance_work_mem?: string
max_connections?: number
max_locks_per_transaction?: number
+ max_logical_replication_workers?: number
max_parallel_maintenance_workers?: number
max_parallel_workers?: number
max_parallel_workers_per_gather?: number
@@ -3701,6 +3880,7 @@ export interface components {
max_slot_wal_keep_size?: string
max_standby_archive_delay?: string
max_standby_streaming_delay?: string
+ max_sync_workers_per_subscription?: number
max_wal_senders?: number
max_wal_size?: string
max_worker_processes?: number
@@ -3720,6 +3900,8 @@ export interface components {
db_extra_search_path: string
/** @description If `null`, the value is automatically configured based on compute size. */
db_pool: number | null
+ /** @description If `null`, the value is automatically configured to 10. */
+ db_pool_acquisition_timeout: number | null
db_schema: string
jwt_secret?: string
max_rows: number
@@ -3807,7 +3989,6 @@ export interface components {
}
| {
obj_name: string
- /** @enum {string} */
obj_type: 'table' | 'function'
schema_name: string
/** @enum {string} */
@@ -3906,7 +4087,7 @@ export interface components {
| 'sa-east-1'
name: string
/** @enum {string} */
- provider: 'AWS' | 'FLY' | 'AWS_K8S' | 'AWS_NIMBUS'
+ provider: 'AWS' | 'AWS_K8S' | 'AWS_NIMBUS'
/** @enum {string} */
status?: 'capacity' | 'other'
/** @enum {string} */
@@ -3944,7 +4125,7 @@ export interface components {
| 'sa-east-1'
name: string
/** @enum {string} */
- provider: 'AWS' | 'FLY' | 'AWS_K8S' | 'AWS_NIMBUS'
+ provider: 'AWS' | 'AWS_K8S' | 'AWS_NIMBUS'
/** @enum {string} */
status?: 'capacity' | 'other'
/** @enum {string} */
@@ -4014,7 +4195,7 @@ export interface components {
created_at: string
/** Format: uuid */
id: string
- public_jwk?: unknown
+ public_jwk: unknown
/** @enum {string} */
status: 'in_use' | 'previously_used' | 'revoked' | 'standby'
/** Format: date-time */
@@ -4028,7 +4209,7 @@ export interface components {
created_at: string
/** Format: uuid */
id: string
- public_jwk?: unknown
+ public_jwk: unknown
/** @enum {string} */
status: 'in_use' | 'previously_used' | 'revoked' | 'standby'
/** Format: date-time */
@@ -4131,6 +4312,9 @@ export interface components {
imageTransformation: {
enabled: boolean
}
+ purgeCache: {
+ enabled: boolean
+ }
s3Protocol: {
enabled: boolean
}
@@ -4483,8 +4667,8 @@ export interface components {
UpdateCustomHostnameResponse: {
custom_hostname: string
data: {
- errors: unknown[]
- messages: unknown[]
+ errors: components['schemas']['UpdateCustomHostnameResponseJsonValue'][]
+ messages: components['schemas']['UpdateCustomHostnameResponseJsonValue'][]
result: {
custom_origin_server: string
hostname: string
@@ -4517,6 +4701,13 @@ export interface components {
| '4_origin_setup_completed'
| '5_services_reconfigured'
}
+ /** @description Any JSON-serializable value */
+ UpdateCustomHostnameResponseJsonValue:
+ | ((string | number | boolean) | null)
+ | components['schemas']['UpdateCustomHostnameResponseJsonValue'][]
+ | {
+ [key: string]: components['schemas']['UpdateCustomHostnameResponseJsonValue']
+ }
/** @example {
* "user_id": "55555555-5555-4555-8555-555555555555",
* "roles": [
@@ -4538,9 +4729,11 @@ export interface components {
roles: {
allowed_networks?: {
allowed_cidrs?: {
+ /** Format: cidrv4 */
cidr: string
}[]
allowed_cidrs_v6?: {
+ /** Format: cidrv6 */
cidr: string
}[]
}
@@ -4552,9 +4745,10 @@ export interface components {
user_id: string
}
/** @example {
- * "root_key": "MDEyMzQ1Njc4OWFiY2RlZjAxMjM0NTY3ODlhYmNkZWY="
+ * "root_key": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
* } */
UpdatePgsodiumConfigBody: {
+ /** @description The pgsodium root key: 32 bytes, hex-encoded (64 characters). */
root_key: string
}
/** @example {
@@ -4585,6 +4779,7 @@ export interface components {
maintenance_work_mem?: string
max_connections?: number
max_locks_per_transaction?: number
+ max_logical_replication_workers?: number
max_parallel_maintenance_workers?: number
max_parallel_workers?: number
max_parallel_workers_per_gather?: number
@@ -4592,6 +4787,7 @@ export interface components {
max_slot_wal_keep_size?: string
max_standby_archive_delay?: string
max_standby_streaming_delay?: string
+ max_sync_workers_per_subscription?: number
max_wal_senders?: number
max_wal_size?: string
max_worker_processes?: number
@@ -4641,7 +4837,6 @@ export interface components {
domains?: {
created_at?: string
domain?: string
- id: string
updated_at?: string
}[]
id: string
@@ -4657,7 +4852,6 @@ export interface components {
}
}
entity_id: string
- id: string
metadata_url?: string
metadata_xml?: string
/** @enum {string} */
@@ -4754,6 +4948,9 @@ export interface components {
imageTransformation?: {
enabled: boolean
}
+ purgeCache?: {
+ enabled: boolean
+ }
s3Protocol?: {
enabled: boolean
}
@@ -4875,6 +5072,8 @@ export interface components {
| '48xlarge_optimized_memory'
| '48xlarge_optimized_cpu'
| '48xlarge_high_memory'
+ /** @description [Experimental] Whether to enable high availability for the project. */
+ high_availability?: boolean
/**
* @deprecated
* @description This field is deprecated and is ignored in this request
@@ -4898,6 +5097,8 @@ export interface components {
* @enum {string}
*/
plan?: 'free' | 'pro'
+ /** @deprecated */
+ postgres_engine?: null
/**
* @deprecated
* @description Region you want your server to reside in. Use region_selection instead.
@@ -4960,6 +5161,8 @@ export interface components {
/** @enum {string} */
type: 'smartGroup'
}
+ /** @deprecated */
+ release_channel?: null
/**
* Format: uri
* @description Template URL used to create the project from the CLI.
@@ -5047,6 +5250,7 @@ export interface components {
| 'storage.image_transformations'
| 'storage.vector_buckets'
| 'storage.iceberg_catalog'
+ | 'storage.purge_cache'
| 'security.audit_logs_days'
| 'security.questionnaire'
| 'security.soc2_report'
@@ -5096,6 +5300,8 @@ export interface components {
| 'integrations.github_connections'
| 'dedicated_pooler'
| 'observability.dashboard_advanced_metrics'
+ | 'api.members.invitations'
+ | 'api.members.roles'
/** @enum {string} */
type: 'boolean' | 'numeric' | 'set'
}
@@ -5109,6 +5315,7 @@ export interface components {
version: string
}[]
V1OrganizationMemberResponse: {
+ avatar_url: string | null
email?: string
mfa_enabled: boolean
role_name: string
@@ -5151,6 +5358,8 @@ export interface components {
db_extra_search_path: string
/** @description If `null`, the value is automatically configured based on compute size. */
db_pool: number | null
+ /** @description If `null`, the value is automatically configured to 10. */
+ db_pool_acquisition_timeout: number | null
db_schema: string
max_rows: number
}
@@ -5451,6 +5660,7 @@ export interface components {
V1UpdatePostgrestConfigBody: {
db_extra_search_path?: string
db_pool?: number
+ db_pool_acquisition_timeout?: number
db_schema?: string
max_rows?: number
}
@@ -5523,7 +5733,7 @@ export interface operations {
parameters: {
query?: {
/** @description If set to false, schedule deletion with 1-hour grace period (only when soft deletion is enabled). */
- force?: boolean
+ force?: string
}
header?: never
path: {
@@ -5588,8 +5798,13 @@ export interface operations {
parameters: {
query?: {
included_schemas?: string
- /** @description Use pg-delta instead of Migra for diffing when true */
- pgdelta?: boolean
+ /** @description Use pg-delta instead of Migra for diffing when true.
+ * Boolean string.
+ *
+ * Truthy values: `true`, `1`, `yes`, `on`, `y`, `enabled`
+ *
+ * Falsy values: `false`, `0`, `no`, `off`, `n`, `disabled` */
+ pgdelta?: string
}
header?: never
path: {
@@ -5760,6 +5975,7 @@ export interface operations {
response_type: 'code' | 'token' | 'id_token token'
scope?: string
state?: string
+ target_flow?: string
}
header?: never
path?: never
@@ -6908,6 +7124,68 @@ export interface operations {
}
content?: never
}
+ /** @description Usage exceeded. Enable additional usage to continue querying */
+ 402: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ /** @description Forbidden action */
+ 403: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ /** @description Rate limit exceeded */
+ 429: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ }
+ }
+ 'v1-get-project-logs-all': {
+ parameters: {
+ query?: {
+ iso_timestamp_end?: string
+ iso_timestamp_start?: string
+ /** @description Custom SQL query to execute on the logs. See [querying logs](/docs/guides/telemetry/logs?queryGroups=product&product=postgres&queryGroups=source&source=edge_logs#querying-with-the-logs-explorer) for more details. */
+ sql?: string
+ }
+ header?: never
+ path: {
+ /** @description Project ref */
+ ref: string
+ }
+ cookie?: never
+ }
+ requestBody?: never
+ responses: {
+ 200: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['AnalyticsResponse']
+ }
+ }
+ /** @description Unauthorized */
+ 401: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ /** @description Usage exceeded. Enable additional usage to continue querying */
+ 402: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
/** @description Forbidden action */
403: {
headers: {
@@ -6924,6 +7202,58 @@ export interface operations {
}
}
}
+ 'v1-scrape-project-metrics': {
+ parameters: {
+ query?: never
+ header?: never
+ path: {
+ /** @description Project ref */
+ ref: string
+ }
+ cookie?: never
+ }
+ requestBody?: never
+ responses: {
+ /** @description Prometheus / OpenMetrics text exposition */
+ 200: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/openmetrics-text': string
+ 'text/plain': string
+ }
+ }
+ /** @description Unauthorized */
+ 401: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ /** @description Forbidden action */
+ 403: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ /** @description Rate limit exceeded */
+ 429: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ /** @description Failed to fetch project's metrics */
+ 500: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ }
+ }
'v1-get-project-usage-api-count': {
parameters: {
query?: {
@@ -7029,8 +7359,12 @@ export interface operations {
'v1-get-project-api-keys': {
parameters: {
query?: {
- /** @description Boolean string, true or false */
- reveal?: boolean
+ /** @description Boolean string.
+ *
+ * Truthy values: `true`, `1`, `yes`, `on`, `y`, `enabled`
+ *
+ * Falsy values: `false`, `0`, `no`, `off`, `n`, `disabled` */
+ reveal?: string
}
header?: never
path: {
@@ -7075,8 +7409,12 @@ export interface operations {
'v1-create-project-api-key': {
parameters: {
query?: {
- /** @description Boolean string, true or false */
- reveal?: boolean
+ /** @description Boolean string.
+ *
+ * Truthy values: `true`, `1`, `yes`, `on`, `y`, `enabled`
+ *
+ * Falsy values: `false`, `0`, `no`, `off`, `n`, `disabled` */
+ reveal?: string
}
header?: never
path: {
@@ -7125,8 +7463,12 @@ export interface operations {
'v1-get-project-api-key': {
parameters: {
query?: {
- /** @description Boolean string, true or false */
- reveal?: boolean
+ /** @description Boolean string.
+ *
+ * Truthy values: `true`, `1`, `yes`, `on`, `y`, `enabled`
+ *
+ * Falsy values: `false`, `0`, `no`, `off`, `n`, `disabled` */
+ reveal?: string
}
header?: never
path: {
@@ -7174,9 +7516,9 @@ export interface operations {
query?: {
reason?: string
/** @description Boolean string, true or false */
- reveal?: boolean
+ reveal?: string
/** @description Boolean string, true or false */
- was_compromised?: boolean
+ was_compromised?: string
}
header?: never
path: {
@@ -7222,8 +7564,12 @@ export interface operations {
'v1-update-project-api-key': {
parameters: {
query?: {
- /** @description Boolean string, true or false */
- reveal?: boolean
+ /** @description Boolean string.
+ *
+ * Truthy values: `true`, `1`, `yes`, `on`, `y`, `enabled`
+ *
+ * Falsy values: `false`, `0`, `no`, `off`, `n`, `disabled` */
+ reveal?: string
}
header?: never
path: {
@@ -7316,8 +7662,12 @@ export interface operations {
'v1-update-project-legacy-api-keys': {
parameters: {
query: {
- /** @description Boolean string, true or false */
- enabled: boolean
+ /** @description Boolean string.
+ *
+ * Truthy values: `true`, `1`, `yes`, `on`, `y`, `enabled`
+ *
+ * Falsy values: `false`, `0`, `no`, `off`, `n`, `disabled` */
+ enabled: string
}
header?: never
path: {
@@ -9513,7 +9863,7 @@ export interface operations {
parameters: {
query?: {
/** @description If true, also removes the custom domain add-on from the project subscription. */
- remove_addon?: boolean
+ remove_addon?: string
}
header?: never
path: {
@@ -9985,7 +10335,9 @@ export interface operations {
headers: {
[name: string]: unknown
}
- content?: never
+ content: {
+ 'application/json': components['schemas']['PlanGateErrorBody']
+ }
}
/** @description Forbidden action */
403: {
@@ -10060,7 +10412,9 @@ export interface operations {
headers: {
[name: string]: unknown
}
- content?: never
+ content: {
+ 'application/json': components['schemas']['PlanGateErrorBody']
+ }
}
/** @description Forbidden action */
403: {
@@ -10275,7 +10629,7 @@ export interface operations {
}
content?: never
}
- /** @description Failed to upsert database migration */
+ /** @description Failed to update JIT access */
500: {
headers: {
[name: string]: unknown
@@ -10387,6 +10741,142 @@ export interface operations {
}
}
}
+ 'v1-invite-external-jit-access': {
+ parameters: {
+ query?: never
+ header?: never
+ path: {
+ /** @description Project ref */
+ ref: string
+ }
+ cookie?: never
+ }
+ requestBody: {
+ content: {
+ 'application/json': components['schemas']['InviteExternalUserJitAccessBody']
+ }
+ }
+ responses: {
+ 200: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['InviteExternalUserJitResponse']
+ }
+ }
+ /** @description Unauthorized */
+ 401: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ /** @description Forbidden action */
+ 403: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ /** @description Rate limit exceeded */
+ 429: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ /** @description Failed to invite external user */
+ 500: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ }
+ }
+ 'v1-delete-invite-external-jit-access': {
+ parameters: {
+ query?: never
+ header?: never
+ path: {
+ invite_id: string
+ /** @description Project ref */
+ ref: string
+ }
+ cookie?: never
+ }
+ requestBody?: never
+ responses: {
+ 200: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ /** @description Unauthorized */
+ 401: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ /** @description Forbidden action */
+ 403: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ /** @description Rate limit exceeded */
+ 429: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ /** @description Failed to revoke invite for external user */
+ 500: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ }
+ }
+ 'v1-accept-invite-external-jit-access': {
+ parameters: {
+ query?: never
+ header?: never
+ path: {
+ /** @description Project ref */
+ ref: string
+ }
+ cookie?: never
+ }
+ requestBody: {
+ content: {
+ 'application/json': components['schemas']['AcceptInviteExternalUserJitAccessBody']
+ }
+ }
+ responses: {
+ 200: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['JitAccessResponse']
+ }
+ }
+ /** @description Failed to accept invitation */
+ 500: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ }
+ }
'v1-list-jit-access': {
parameters: {
query?: never
@@ -11127,13 +11617,11 @@ export interface operations {
query?: {
entrypoint_path?: string
ezbr_sha256?: string
- /** @description Boolean string, true or false */
- import_map?: boolean
+ import_map?: string
import_map_path?: string
name?: string
slug?: string
- /** @description Boolean string, true or false */
- verify_jwt?: boolean
+ verify_jwt?: string
}
header?: never
path: {
@@ -11301,13 +11789,11 @@ export interface operations {
query?: {
entrypoint_path?: string
ezbr_sha256?: string
- /** @description Boolean string, true or false */
- import_map?: boolean
+ import_map?: string
import_map_path?: string
name?: string
slug?: string
- /** @description Boolean string, true or false */
- verify_jwt?: boolean
+ verify_jwt?: string
}
header?: never
path: {
@@ -11418,8 +11904,7 @@ export interface operations {
'v1-deploy-a-function': {
parameters: {
query?: {
- /** @description Boolean string, true or false */
- bundleOnly?: boolean
+ bundleOnly?: string
slug?: string
}
header?: never
@@ -11483,16 +11968,19 @@ export interface operations {
'v1-get-services-health': {
parameters: {
query: {
- services: (
- | 'auth'
- | 'db'
- | 'db_postgres_user'
- | 'pooler'
- | 'realtime'
- | 'rest'
- | 'storage'
- | 'pg_bouncer'
- )[]
+ /** @description Comma-separated list of enums or array of enums. */
+ services:
+ | string
+ | (
+ | 'auth'
+ | 'db'
+ | 'db_postgres_user'
+ | 'pooler'
+ | 'realtime'
+ | 'rest'
+ | 'storage'
+ | 'pg_bouncer'
+ )[]
timeout_ms?: number
}
header?: never
@@ -11559,7 +12047,21 @@ export interface operations {
[name: string]: unknown
}
content: {
- 'application/json': components['schemas']['JitStateResponse']
+ 'application/json':
+ | {
+ appliedSuccessfully?: boolean
+ /** @enum {string} */
+ state: 'enabled' | 'disabled'
+ }
+ | {
+ /** @constant */
+ state: 'unavailable'
+ /** @enum {string} */
+ unavailableReason:
+ | 'postgres_upgrade_required'
+ | 'ssl_enforcement_required'
+ | 'temporarily_unavailable'
+ }
}
}
/** @description Unauthorized */
@@ -11613,7 +12115,21 @@ export interface operations {
[name: string]: unknown
}
content: {
- 'application/json': components['schemas']['JitStateResponse']
+ 'application/json':
+ | {
+ appliedSuccessfully?: boolean
+ /** @enum {string} */
+ state: 'enabled' | 'disabled'
+ }
+ | {
+ /** @constant */
+ state: 'unavailable'
+ /** @enum {string} */
+ unavailableReason:
+ | 'postgres_upgrade_required'
+ | 'ssl_enforcement_required'
+ | 'temporarily_unavailable'
+ }
}
}
/** @description Unauthorized */
@@ -12291,7 +12807,9 @@ export interface operations {
headers: {
[name: string]: unknown
}
- content?: never
+ content: {
+ 'application/json': components['schemas']['PlanGateErrorBody']
+ }
}
/** @description Forbidden action */
403: {
@@ -13121,7 +13639,9 @@ export interface operations {
headers: {
[name: string]: unknown
}
- content?: never
+ content: {
+ 'application/json': components['schemas']['PlanGateErrorBody']
+ }
}
/** @description Unauthorized */
401: {
@@ -13230,7 +13750,9 @@ export interface operations {
headers: {
[name: string]: unknown
}
- content?: never
+ content: {
+ 'application/json': components['schemas']['PlanGateErrorBody']
+ }
}
/** @description Unauthorized */
401: {
@@ -13291,7 +13813,9 @@ export interface operations {
headers: {
[name: string]: unknown
}
- content?: never
+ content: {
+ 'application/json': components['schemas']['PlanGateErrorBody']
+ }
}
/** @description Unauthorized */
401: {
diff --git a/packages/api-types/types/api-v2.d.ts b/packages/api-types/types/api-v2.d.ts
new file mode 100644
index 0000000000000..0824bc203aad8
--- /dev/null
+++ b/packages/api-types/types/api-v2.d.ts
@@ -0,0 +1,12062 @@
+/**
+ * This file was auto-generated by openapi-typescript.
+ * Do not make direct changes to the file.
+ */
+
+export interface paths {
+ '/v1/webhooks/events': {
+ parameters: {
+ query?: never
+ header?: never
+ path?: never
+ cookie?: never
+ }
+ get?: never
+ put?: never
+ /**
+ * Publish event
+ * @description Ingests and schedules a new webhook event to be published out to all subscribed endpoints.
+ *
+ * In case of non-successful response status codes, early termination, networking issues,
+ * requests to this endpoint should be retried until it succeeds, otherwise there is a risk of
+ * loosing events.
+ *
+ * `meta.idempotency_key` is used to ensure idempotency when retrying the requests and so it
+ * must always be provided.
+ */
+ post: operations['postV1WebhooksEvents']
+ delete?: never
+ options?: never
+ head?: never
+ patch?: never
+ trace?: never
+ }
+ '/v2/organizations/{slug}/integrations/github/connections': {
+ parameters: {
+ query?: never
+ header?: never
+ path?: never
+ cookie?: never
+ }
+ /**
+ * List GitHub connections of an organization
+ * @description Returns a cursor-paginated list of the GitHub connections of the organization's projects.
+ *
+ * Use `page[after]` and `page[before]` to navigate pages and `page[size]` to control the page size.
+ * Paging walks the organization projects, so a page holds at most `page[size]` connections and can hold fewer (or none) when some of its projects are not connected.
+ * Follow `links.next` until it is `null` rather than stopping on a short page.
+ *
+ * Use `filter[project_ref]` to narrow the list down to a single project.
+ */
+ get: operations['v2-list-organization-github-connections']
+ put?: never
+ post?: never
+ delete?: never
+ options?: never
+ head?: never
+ patch?: never
+ trace?: never
+ }
+ '/v2/organizations/{slug}/members': {
+ parameters: {
+ query?: never
+ header?: never
+ path?: never
+ cookie?: never
+ }
+ /**
+ * List members of an organization
+ * @description Returns a cursor-paginated list of organization members including their roles and project-scoped permissions.
+ */
+ get: operations['v2-list-organization-members']
+ put?: never
+ post?: never
+ delete?: never
+ options?: never
+ head?: never
+ patch?: never
+ trace?: never
+ }
+ '/v2/organizations/{slug}/members/{user_id}/roles': {
+ parameters: {
+ query?: never
+ header?: never
+ path?: never
+ cookie?: never
+ }
+ get?: never
+ put?: never
+ post?: never
+ delete?: never
+ options?: never
+ head?: never
+ /**
+ * Assign or change an organization member role
+ * @description Assigns an org-wide role when projects is omitted, or creates a project-scoped assignment when projects is provided. Uses an org-level role template id from GET /v2/organizations/{slug}/roles. Stale role assignments are automatically cleaned up: if a role no longer has any projects, it is deleted; overlapping project assignments in other roles are automatically removed to avoid duplication.
+ */
+ patch: operations['v2-assign-organization-member-role']
+ trace?: never
+ }
+ '/v2/organizations/{slug}/members/invitations': {
+ parameters: {
+ query?: never
+ header?: never
+ path?: never
+ cookie?: never
+ }
+ get?: never
+ put?: never
+ /**
+ * Creates organization invitations
+ * @description Creates member invitations for an organization. Each invitation can have different role and project scope settings.
+ */
+ post: operations['v2-create-organization-invitations']
+ /**
+ * Deletes organization invitations by email
+ * @description Bulk delete member invitations for an organization by email address.
+ */
+ delete: operations['v2-delete-organization-invitations']
+ options?: never
+ head?: never
+ patch?: never
+ trace?: never
+ }
+ '/v2/organizations/{slug}/projects': {
+ parameters: {
+ query?: never
+ header?: never
+ path?: never
+ cookie?: never
+ }
+ /**
+ * List projects of an organization
+ * @description Returns a cursor-paginated list of projects for the specified organization, including their databases.
+ *
+ * Use `page[after]` and `page[before]` to navigate pages and `page[size]` to control the number of projects returned per page.
+ */
+ get: operations['v2-list-organization-projects']
+ put?: never
+ post?: never
+ delete?: never
+ options?: never
+ head?: never
+ patch?: never
+ trace?: never
+ }
+ '/v2/organizations/{slug}/roles': {
+ parameters: {
+ query?: never
+ header?: never
+ path?: never
+ cookie?: never
+ }
+ /**
+ * List roles of an organization
+ * @description Returns a list of org-level roles for the organization.
+ */
+ get: operations['v2-list-organization-roles']
+ put?: never
+ post?: never
+ delete?: never
+ options?: never
+ head?: never
+ patch?: never
+ trace?: never
+ }
+ '/v2/organizations/{slug}/webhooks/deliveries/{id}': {
+ parameters: {
+ query?: never
+ header?: never
+ path?: never
+ cookie?: never
+ }
+ /**
+ * Get delivery
+ * @description Get details of a specific delivery attempt.
+ */
+ get: operations['allV2OrganizationsBySlugWebhooks']
+ put?: never
+ post?: never
+ delete?: never
+ options?: never
+ head?: never
+ patch?: never
+ trace?: never
+ }
+ '/v2/organizations/{slug}/webhooks/deliveries/{id}/retry': {
+ parameters: {
+ query?: never
+ header?: never
+ path?: never
+ cookie?: never
+ }
+ get?: never
+ put?: never
+ /**
+ * Retry delivery
+ * @description Retry delivering the same event again.
+ *
+ * Automatic retries are not applicable to manual retries - if the delivery fails, there won't be any automatic retries attempted.
+ *
+ * This endpoint is heavy rate-limited to allow for 10 request within 60 seconds.
+ */
+ post: operations['allV2OrganizationsBySlugWebhooks']
+ delete?: never
+ options?: never
+ head?: never
+ patch?: never
+ trace?: never
+ }
+ '/v2/organizations/{slug}/webhooks/endpoints': {
+ parameters: {
+ query?: never
+ header?: never
+ path?: never
+ cookie?: never
+ }
+ /**
+ * List endpoints
+ * @description List all Webhook endpoints based on a project's ref or an organization's slug.
+ */
+ get: operations['allV2OrganizationsBySlugWebhooks']
+ put?: never
+ /**
+ * Create endpoint
+ * @description Create new endpoint configuration to subscribe to specific webhook events.
+ */
+ post: operations['allV2OrganizationsBySlugWebhooks']
+ /**
+ * Delete all endpoints
+ * @description Delete all endpoints including all events and deliveries.
+ *
+ * Any in-flight webhooks will result in a no-op.
+ */
+ delete: operations['allV2OrganizationsBySlugWebhooks']
+ options?: never
+ head?: never
+ patch?: never
+ trace?: never
+ }
+ '/v2/organizations/{slug}/webhooks/endpoints/{id}': {
+ parameters: {
+ query?: never
+ header?: never
+ path?: never
+ cookie?: never
+ }
+ /**
+ * Get endpoint
+ * @description Get details of a specific endpoint.
+ */
+ get: operations['allV2OrganizationsBySlugWebhooks']
+ put?: never
+ post?: never
+ /**
+ * Delete endpoint
+ * @description Delete the endpoint including all events and deliveries
+ *
+ * Any in-flight webhooks will result in a no-op.
+ */
+ delete: operations['allV2OrganizationsBySlugWebhooks']
+ options?: never
+ head?: never
+ /**
+ * Update endpoint
+ * @description Update endpoint's configuration.
+ */
+ patch: operations['allV2OrganizationsBySlugWebhooks']
+ trace?: never
+ }
+ '/v2/organizations/{slug}/webhooks/endpoints/{id}/deliveries': {
+ parameters: {
+ query?: never
+ header?: never
+ path?: never
+ cookie?: never
+ }
+ /**
+ * List deliveries
+ * @description List all deliveries for a specific endpoint in descending order (newest first).
+ *
+ * Deliveries which has expired are no longer available and will not be listed.
+ */
+ get: operations['allV2OrganizationsBySlugWebhooks']
+ put?: never
+ post?: never
+ delete?: never
+ options?: never
+ head?: never
+ patch?: never
+ trace?: never
+ }
+ '/v2/organizations/{slug}/webhooks/endpoints/{id}/test': {
+ parameters: {
+ query?: never
+ header?: never
+ path?: never
+ cookie?: never
+ }
+ get?: never
+ put?: never
+ /**
+ * Send test event
+ * @description Ingests and schedules a test webhook event to be published out this endpoints.
+ *
+ * Which event type to use can be specified in the request body, otherwise
+ * it will use any matching type the endpoint is listening for.
+ *
+ * The event will contain `is_test: true` in it's payload.
+ *
+ * This endpoint is heavy rate-limited to allow for 10 request within 60 seconds.
+ */
+ post: operations['allV2OrganizationsBySlugWebhooks']
+ delete?: never
+ options?: never
+ head?: never
+ patch?: never
+ trace?: never
+ }
+ '/v2/projects/{ref}/analytics/log-drains': {
+ parameters: {
+ query?: never
+ header?: never
+ path?: never
+ cookie?: never
+ }
+ /** List project log drains */
+ get: operations['v2-list-log-drains']
+ put?: never
+ /** Create a log drain for a project */
+ post: operations['v2-create-log-drain']
+ delete?: never
+ options?: never
+ head?: never
+ patch?: never
+ trace?: never
+ }
+ '/v2/projects/{ref}/analytics/log-drains/{id}': {
+ parameters: {
+ query?: never
+ header?: never
+ path?: never
+ cookie?: never
+ }
+ get?: never
+ /** Update a project log drain */
+ put: operations['v2-update-log-drain']
+ post?: never
+ /** Delete a project log drain */
+ delete: operations['v2-delete-log-drain']
+ options?: never
+ head?: never
+ patch?: never
+ trace?: never
+ }
+ '/v2/projects/{ref}/config': {
+ parameters: {
+ query?: never
+ header?: never
+ path?: never
+ cookie?: never
+ }
+ /**
+ * [Alpha] Get a project's service configuration
+ * @description Returns the project's database, pooler, Auth, Data API, Realtime and Storage configuration — the same configuration a branch inherits from its base project. Each is the effective config, so a setting the project has never overridden is reported at its platform default rather than as null. Auth secrets are returned as an HMAC of their value. `storage` is read live from the storage service; the rest come from this platform's own records.
+ */
+ get: operations['v2-get-project-config']
+ put?: never
+ post?: never
+ delete?: never
+ options?: never
+ head?: never
+ patch?: never
+ trace?: never
+ }
+ '/v2/projects/{ref}/private-link/associations': {
+ parameters: {
+ query?: never
+ header?: never
+ path?: never
+ cookie?: never
+ }
+ /** List AWS accounts attached to the project PrivateLink share */
+ get: operations['v2-list-private-link-associations']
+ put?: never
+ /**
+ * Add an AWS account to the project PrivateLink share
+ * @description Adds an AWS account to the project's PrivateLink configuration and schedules the AWS resources to be created.
+ */
+ post: operations['v2-create-private-link-association']
+ delete?: never
+ options?: never
+ head?: never
+ patch?: never
+ trace?: never
+ }
+ '/v2/projects/{ref}/private-link/associations/aws-account/{aws_account_id}': {
+ parameters: {
+ query?: never
+ header?: never
+ path?: never
+ cookie?: never
+ }
+ get?: never
+ put?: never
+ post?: never
+ /**
+ * Remove an AWS account from the project PrivateLink share
+ * @description Removes an AWS account from the project's PrivateLink configuration (targeting the primary database). Cleans up the associated AWS resources.
+ */
+ delete: operations['v2-delete-private-link-association']
+ options?: never
+ head?: never
+ patch?: never
+ trace?: never
+ }
+ '/v2/projects/{ref}/private-link/associations/aws-account/{aws_account_id}/database/{database_identifier}': {
+ parameters: {
+ query?: never
+ header?: never
+ path?: never
+ cookie?: never
+ }
+ get?: never
+ put?: never
+ post?: never
+ /**
+ * Remove an AWS account from a specific database PrivateLink share
+ * @description Removes an AWS account from the project's PrivateLink configuration for the given read replica. Cleans up the associated AWS resources.
+ */
+ delete: operations['v2-delete-private-link-association-for-database']
+ options?: never
+ head?: never
+ patch?: never
+ trace?: never
+ }
+ '/v2/projects/{ref}/transfers': {
+ parameters: {
+ query?: never
+ header?: never
+ path?: never
+ cookie?: never
+ }
+ get?: never
+ put?: never
+ /** Transfers a project to a different organization */
+ post: operations['v2-transfer-a-project']
+ delete?: never
+ options?: never
+ head?: never
+ patch?: never
+ trace?: never
+ }
+ '/v2/projects/{ref}/transfers/previews': {
+ parameters: {
+ query?: never
+ header?: never
+ path?: never
+ cookie?: never
+ }
+ get?: never
+ put?: never
+ /** Previews transferring a project to a different organizations, shows eligibility and impact */
+ post: operations['v2-preview-a-project-transfer']
+ delete?: never
+ options?: never
+ head?: never
+ patch?: never
+ trace?: never
+ }
+ '/v2/projects/{ref}/webhooks/deliveries/{id}': {
+ parameters: {
+ query?: never
+ header?: never
+ path?: never
+ cookie?: never
+ }
+ /**
+ * Get delivery
+ * @description Get details of a specific delivery attempt.
+ */
+ get: operations['allV2ProjectsByRefWebhooks']
+ put?: never
+ post?: never
+ delete?: never
+ options?: never
+ head?: never
+ patch?: never
+ trace?: never
+ }
+ '/v2/projects/{ref}/webhooks/deliveries/{id}/retry': {
+ parameters: {
+ query?: never
+ header?: never
+ path?: never
+ cookie?: never
+ }
+ get?: never
+ put?: never
+ /**
+ * Retry delivery
+ * @description Retry delivering the same event again.
+ *
+ * Automatic retries are not applicable to manual retries - if the delivery fails, there won't be any automatic retries attempted.
+ *
+ * This endpoint is heavy rate-limited to allow for 10 request within 60 seconds.
+ */
+ post: operations['allV2ProjectsByRefWebhooks']
+ delete?: never
+ options?: never
+ head?: never
+ patch?: never
+ trace?: never
+ }
+ '/v2/projects/{ref}/webhooks/endpoints': {
+ parameters: {
+ query?: never
+ header?: never
+ path?: never
+ cookie?: never
+ }
+ /**
+ * List endpoints
+ * @description List all Webhook endpoints based on a project's ref or an organization's slug.
+ */
+ get: operations['allV2ProjectsByRefWebhooks']
+ put?: never
+ /**
+ * Create endpoint
+ * @description Create new endpoint configuration to subscribe to specific webhook events.
+ */
+ post: operations['allV2ProjectsByRefWebhooks']
+ /**
+ * Delete all endpoints
+ * @description Delete all endpoints including all events and deliveries.
+ *
+ * Any in-flight webhooks will result in a no-op.
+ */
+ delete: operations['allV2ProjectsByRefWebhooks']
+ options?: never
+ head?: never
+ patch?: never
+ trace?: never
+ }
+ '/v2/projects/{ref}/webhooks/endpoints/{id}': {
+ parameters: {
+ query?: never
+ header?: never
+ path?: never
+ cookie?: never
+ }
+ /**
+ * Get endpoint
+ * @description Get details of a specific endpoint.
+ */
+ get: operations['allV2ProjectsByRefWebhooks']
+ put?: never
+ post?: never
+ /**
+ * Delete endpoint
+ * @description Delete the endpoint including all events and deliveries
+ *
+ * Any in-flight webhooks will result in a no-op.
+ */
+ delete: operations['allV2ProjectsByRefWebhooks']
+ options?: never
+ head?: never
+ /**
+ * Update endpoint
+ * @description Update endpoint's configuration.
+ */
+ patch: operations['allV2ProjectsByRefWebhooks']
+ trace?: never
+ }
+ '/v2/projects/{ref}/webhooks/endpoints/{id}/deliveries': {
+ parameters: {
+ query?: never
+ header?: never
+ path?: never
+ cookie?: never
+ }
+ /**
+ * List deliveries
+ * @description List all deliveries for a specific endpoint in descending order (newest first).
+ *
+ * Deliveries which has expired are no longer available and will not be listed.
+ */
+ get: operations['allV2ProjectsByRefWebhooks']
+ put?: never
+ post?: never
+ delete?: never
+ options?: never
+ head?: never
+ patch?: never
+ trace?: never
+ }
+ '/v2/projects/{ref}/webhooks/endpoints/{id}/test': {
+ parameters: {
+ query?: never
+ header?: never
+ path?: never
+ cookie?: never
+ }
+ get?: never
+ put?: never
+ /**
+ * Send test event
+ * @description Ingests and schedules a test webhook event to be published out this endpoints.
+ *
+ * Which event type to use can be specified in the request body, otherwise
+ * it will use any matching type the endpoint is listening for.
+ *
+ * The event will contain `is_test: true` in it's payload.
+ *
+ * This endpoint is heavy rate-limited to allow for 10 request within 60 seconds.
+ */
+ post: operations['allV2ProjectsByRefWebhooks']
+ delete?: never
+ options?: never
+ head?: never
+ patch?: never
+ trace?: never
+ }
+ '/v2/projects/{ref}/workers': {
+ parameters: {
+ query?: never
+ header?: never
+ path?: never
+ cookie?: never
+ }
+ /**
+ * [Alpha] List all workers
+ * @description Returns all workers you've previously deployed to the specified project.
+ */
+ get: operations['v2-list-all-workers']
+ put?: never
+ post?: never
+ delete?: never
+ options?: never
+ head?: never
+ patch?: never
+ trace?: never
+ }
+ '/v2/projects/{ref}/workers/{name}': {
+ parameters: {
+ query?: never
+ header?: never
+ path?: never
+ cookie?: never
+ }
+ /**
+ * [Alpha] Retrieve a worker
+ * @description Returns a worker along with its instance tally. Poll this after a deploy until `build_state` leaves `building`.
+ */
+ get: operations['v2-get-a-worker']
+ put?: never
+ post?: never
+ /**
+ * [Alpha] Delete a worker
+ * @description Tombstones the worker. Its instances and image are torn down asynchronously.
+ */
+ delete: operations['v2-delete-a-worker']
+ options?: never
+ head?: never
+ patch?: never
+ trace?: never
+ }
+ '/v2/projects/{ref}/workers/{name}/deploy': {
+ parameters: {
+ query?: never
+ header?: never
+ path?: never
+ cookie?: never
+ }
+ get?: never
+ put?: never
+ /**
+ * [Alpha] Deploy a worker
+ * @description Creates the worker if it does not exist, building from a context staged through the uploads endpoint. The build runs asynchronously: this answers 202 and the worker reaches `build_state` `active` or `failed` later.
+ */
+ post: operations['v2-deploy-a-worker']
+ delete?: never
+ options?: never
+ head?: never
+ patch?: never
+ trace?: never
+ }
+ '/v2/projects/{ref}/workers/{name}/uploads': {
+ parameters: {
+ query?: never
+ header?: never
+ path?: never
+ cookie?: never
+ }
+ get?: never
+ put?: never
+ /**
+ * [Alpha] Mint a presigned slot for a build-context upload
+ * @description PUT the `.tar.gz` build context to the returned `url` before `expires_at`, then deploy with the upload id as `context_upload_id`. The bytes go straight to storage — no management API request carries them.
+ */
+ post: operations['v2-create-worker-upload']
+ delete?: never
+ options?: never
+ head?: never
+ patch?: never
+ trace?: never
+ }
+}
+export type webhooks = Record
+export interface components {
+ schemas: {
+ APIErrorObject: {
+ code: string
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ message: string
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ CreateLogDrainRequestOpenApi: {
+ data: {
+ attributes: {
+ /** @enum {string} */
+ backend_type:
+ | 'postgres'
+ | 'bigquery'
+ | 'clickhouse'
+ | 'webhook'
+ | 'datadog'
+ | 'loki'
+ | 'sentry'
+ | 's3'
+ | 'axiom'
+ | 'last9'
+ | 'otlp'
+ | 'syslog'
+ config:
+ | {
+ hostname?: string
+ password?: string | null
+ port?: number | null
+ schema?: string
+ url?: string | null
+ username?: string | null
+ }
+ | {
+ gzip?: boolean
+ headers?: {
+ [key: string]: string
+ }
+ /** @enum {string} */
+ http?: 'http1' | 'http2'
+ url?: string
+ }
+ | {
+ dataset_id?: string
+ project_id?: string
+ }
+ | {
+ api_key?: string
+ region?: string
+ }
+ | {
+ headers?: {
+ [key: string]: string
+ }
+ password?: string | null
+ url?: string
+ username?: string | null
+ }
+ | {
+ dsn?: string
+ }
+ | {
+ api_token?: string
+ dataset_name?: string
+ domain?: string
+ }
+ | {
+ ca_cert?: string
+ cipher_key?: string
+ client_cert?: string
+ client_key?: string
+ host?: string
+ port?: number
+ structured_data?: string
+ /** @default false */
+ tls?: boolean
+ }
+ description?: string
+ name: string
+ }
+ /**
+ * @description Resource type.
+ * @enum {string}
+ */
+ type: 'log_drain'
+ }
+ }
+ ErrorResponseBody: {
+ error: components['schemas']['ErrorResponseBodyAPIErrorObject']
+ }
+ ErrorResponseBodyAPIErrorObject: {
+ code: string
+ description?: string
+ id?: string
+ issues?: components['schemas']['ErrorResponseBodyAPIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ message: string
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ ListLogDrainsResponse: {
+ data: {
+ attributes: {
+ /** @enum {string} */
+ backend_type:
+ | 'postgres'
+ | 'bigquery'
+ | 'clickhouse'
+ | 'webhook'
+ | 'datadog'
+ | 'loki'
+ | 'sentry'
+ | 's3'
+ | 'axiom'
+ | 'last9'
+ | 'otlp'
+ | 'syslog'
+ config:
+ | {
+ hostname?: string
+ password?: string | null
+ port?: number | null
+ schema?: string
+ url?: string | null
+ username?: string | null
+ }
+ | {
+ gzip?: boolean
+ headers?: {
+ [key: string]: string
+ }
+ /** @enum {string} */
+ http?: 'http1' | 'http2'
+ url?: string
+ }
+ | {
+ dataset_id?: string
+ project_id?: string
+ }
+ | {
+ api_key?: string
+ region?: string
+ }
+ | {
+ headers?: {
+ [key: string]: string
+ }
+ password?: string | null
+ url?: string
+ username?: string | null
+ }
+ | {
+ dsn?: string
+ }
+ | {
+ api_token?: string
+ dataset_name?: string
+ domain?: string
+ }
+ | {
+ ca_cert?: string
+ cipher_key?: string
+ client_cert?: string
+ client_key?: string
+ host?: string
+ port?: number
+ structured_data?: string
+ /** @default false */
+ tls?: boolean
+ }
+ description?: string
+ name: string
+ }
+ id: string
+ /**
+ * @description Resource type.
+ * @enum {string}
+ */
+ type: 'log_drain'
+ }[]
+ }
+ LogDrainResponse: {
+ data: {
+ attributes: {
+ /** @enum {string} */
+ backend_type:
+ | 'postgres'
+ | 'bigquery'
+ | 'clickhouse'
+ | 'webhook'
+ | 'datadog'
+ | 'loki'
+ | 'sentry'
+ | 's3'
+ | 'axiom'
+ | 'last9'
+ | 'otlp'
+ | 'syslog'
+ config:
+ | {
+ hostname?: string
+ password?: string | null
+ port?: number | null
+ schema?: string
+ url?: string | null
+ username?: string | null
+ }
+ | {
+ gzip?: boolean
+ headers?: {
+ [key: string]: string
+ }
+ /** @enum {string} */
+ http?: 'http1' | 'http2'
+ url?: string
+ }
+ | {
+ dataset_id?: string
+ project_id?: string
+ }
+ | {
+ api_key?: string
+ region?: string
+ }
+ | {
+ headers?: {
+ [key: string]: string
+ }
+ password?: string | null
+ url?: string
+ username?: string | null
+ }
+ | {
+ dsn?: string
+ }
+ | {
+ api_token?: string
+ dataset_name?: string
+ domain?: string
+ }
+ | {
+ ca_cert?: string
+ cipher_key?: string
+ client_cert?: string
+ client_key?: string
+ host?: string
+ port?: number
+ structured_data?: string
+ /** @default false */
+ tls?: boolean
+ }
+ description?: string
+ name: string
+ }
+ id: string
+ /**
+ * @description Resource type.
+ * @enum {string}
+ */
+ type: 'log_drain'
+ }
+ }
+ OrganizationMemberRoleResponse: {
+ data: {
+ attributes: {
+ /**
+ * @description Role name. For project-scoped assignments this is the base role name.
+ * @example developer
+ */
+ name: string
+ /** @description Project refs this role is scoped to. Empty array for org-level roles. */
+ projects: {
+ name: string
+ ref: string
+ }[]
+ /**
+ * @description Whether this role applies org-wide or is scoped to specific projects for the user.
+ * @enum {string}
+ */
+ scope: 'organization' | 'project'
+ }
+ /**
+ * @description Resource type.
+ * @enum {string}
+ */
+ type: 'organization_member_role'
+ }
+ }
+ UpdateLogDrainRequestOpenApi: {
+ data: {
+ attributes: {
+ /** @enum {string} */
+ backend_type:
+ | 'postgres'
+ | 'bigquery'
+ | 'clickhouse'
+ | 'webhook'
+ | 'datadog'
+ | 'loki'
+ | 'sentry'
+ | 's3'
+ | 'axiom'
+ | 'last9'
+ | 'otlp'
+ | 'syslog'
+ config?:
+ | {
+ hostname?: string
+ password?: string | null
+ port?: number | null
+ schema?: string
+ url?: string | null
+ username?: string | null
+ }
+ | {
+ gzip?: boolean
+ headers?: {
+ [key: string]: string
+ }
+ /** @enum {string} */
+ http?: 'http1' | 'http2'
+ url?: string
+ }
+ | {
+ dataset_id?: string
+ project_id?: string
+ }
+ | {
+ api_key?: string
+ region?: string
+ }
+ | {
+ headers?: {
+ [key: string]: string
+ }
+ password?: string | null
+ url?: string
+ username?: string | null
+ }
+ | {
+ dsn?: string
+ }
+ | {
+ api_token?: string
+ dataset_name?: string
+ domain?: string
+ }
+ | {
+ ca_cert?: string
+ cipher_key?: string
+ client_cert?: string
+ client_key?: string
+ host?: string
+ port?: number
+ structured_data?: string
+ /** @default false */
+ tls?: boolean
+ }
+ description?: string
+ name?: string
+ }
+ /**
+ * @description Resource type.
+ * @enum {string}
+ */
+ type: 'log_drain'
+ }
+ }
+ V2AssignOrganizationMemberRoleRequest: {
+ data: {
+ attributes: {
+ /** @description The projects to assign a project-scoped role for. If omitted, assigns an org-wide role. */
+ projects?: {
+ /**
+ * @description Project ref
+ * @example abcjuqabhgwjjutfvtpa
+ */
+ ref: string
+ }[]
+ /**
+ * @description Role name to assign. Must be one of: owner, administrator, developer, read-only. Must be on a Team or Enterprise plan to use the read-only role.
+ * @example developer
+ * @enum {string}
+ */
+ role: 'owner' | 'administrator' | 'developer' | 'read-only'
+ }
+ /**
+ * @description Resource type.
+ * @enum {string}
+ */
+ type: 'organization_member_role'
+ }
+ }
+ V2CreateInvitationsRequest: {
+ data: {
+ attributes: {
+ /** Format: email */
+ email: string
+ /** @description The projects to limit a user to. If omitted, user will have org-wide access with the provided role. */
+ projects?: {
+ /**
+ * @description Project ref
+ * @example abcjuqabhgwjjutfvtpa
+ */
+ ref: string
+ }[]
+ require_sso?: boolean
+ /**
+ * @description Role name to assign. Must be on a Team or Enterprise plan to use the read-only role.
+ * @example developer
+ * @enum {string}
+ */
+ role: 'owner' | 'administrator' | 'developer' | 'read-only'
+ }
+ /**
+ * @description Resource type.
+ * @enum {string}
+ */
+ type: 'organization_invitation'
+ }[]
+ }
+ V2CreateInvitationsResponse: {
+ data: {
+ attributes: {
+ /** Format: email */
+ email: string
+ }
+ /**
+ * @description Resource type.
+ * @enum {string}
+ */
+ type: 'organization_invitation'
+ }[]
+ error?: {
+ code: string
+ description?: string
+ id?: string
+ issues?: {
+ code: string
+ description?: string
+ id?: string
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ message: string
+ meta: {
+ /** Format: email */
+ email: string
+ }
+ }[]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ message: string
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ }
+ V2CreatePrivateLinkAssociationRequest: {
+ data: {
+ attributes: {
+ /** @description Optional human-readable name for the AWS account. */
+ account_name?: string
+ /** @description The AWS account ID to add to the project PrivateLink share. */
+ aws_account_id: string
+ /** @description Identifier of the read replica this PrivateLink share should target. Omit to target the primary database. */
+ database_identifier?: string
+ }
+ /**
+ * @description Resource type.
+ * @enum {string}
+ */
+ type: 'private_link_association'
+ }
+ }
+ V2DeleteInvitationsRequest: {
+ data: {
+ attributes: {
+ /** Format: email */
+ email: string
+ }
+ /**
+ * @description Resource type.
+ * @enum {string}
+ */
+ type: 'organization_invitation'
+ }[]
+ }
+ V2DeleteInvitationsResponse: {
+ data: {
+ attributes: {
+ /** Format: email */
+ email: string
+ }
+ /**
+ * @description Resource type.
+ * @enum {string}
+ */
+ type: 'organization_invitation'
+ }[]
+ }
+ V2DeployWorkerRequest: {
+ data: {
+ attributes: {
+ /** @description Id of a build context staged through the uploads endpoint. Required unless `runtime` is set. */
+ context_upload_id?: string
+ spec: {
+ backend?: string
+ /** @example public */
+ exposure: string
+ /** @example 1 */
+ instances: number
+ /** @example node */
+ runtime?: string
+ /** @example 2gb-1vcpu */
+ size: string
+ }
+ }
+ /**
+ * @description Resource type.
+ * @enum {string}
+ */
+ type: 'project_worker'
+ }
+ }
+ V2ListGitHubConnectionsResponse: {
+ data: {
+ attributes: {
+ /** @description Maximum number of preview branches */
+ branch_limit: number
+ /** @description When the connection was created */
+ inserted_at: string
+ /** @description GitHub App installation id */
+ installation_id: number
+ /** @description Whether a preview branch is created for every pull request */
+ new_branch_per_pr: boolean
+ /** @description The connected Supabase project */
+ project: {
+ id: number
+ name: string
+ /**
+ * @description Project ref
+ * @example abcdefghijklmnopqrst
+ */
+ ref: string
+ }
+ /** @description The connected GitHub repository */
+ repository: {
+ id: number
+ name: string
+ }
+ /** @description Whether branches are only created for changes under `supabase/` */
+ supabase_changes_only: boolean
+ /** @description When the connection was last updated */
+ updated_at: string
+ /** @description The user who created the connection, if still known */
+ user: {
+ id: number
+ primary_email: string | null
+ username: string
+ } | null
+ /** @description Directory within the repository the project lives in */
+ workdir: string
+ }
+ /**
+ * @description Connection id.
+ * @example 7
+ */
+ id: string
+ /**
+ * @description Resource type.
+ * @enum {string}
+ */
+ type: 'github_connection'
+ }[]
+ links: {
+ /**
+ * @description URL path to the first page if available.
+ * @example /v2/organizations/my-org/integrations/github/connections?page[size]=10
+ */
+ first?: string | null
+ /**
+ * @description URL path to the last page if available.
+ * @example /v2/organizations/my-org/integrations/github/connections?page[size]=10&page[after]=019adf7d-4513-71ba-b264-21900edb4295
+ */
+ last?: string | null
+ /**
+ * @description URL path to the next page.
+ * @example /v2/organizations/my-org/integrations/github/connections?page[size]=10&page[after]=019adf7d-4513-7062-b292-78b86cc470a4
+ */
+ next: string | null
+ /**
+ * @description URL path to the previous page.
+ * @example /v2/organizations/my-org/integrations/github/connections?page[size]=10&page[before]=019adf7d-4513-74c5-bb9a-f1bc0f7a95d7
+ */
+ prev: string | null
+ }
+ }
+ V2ListMembersResponse: {
+ data: {
+ attributes: {
+ /** @description Member's avatar URL */
+ avatar_url: string | null
+ /** @description Whether this member is a Single Sign-On user */
+ is_sso_user: boolean
+ /** @description Whether Multi-Factor Authentication is enabled for this member */
+ mfa_enabled: boolean
+ /** @description Member's primary email */
+ primary_email: string | null
+ /** @description Roles assigned to this member. Includes both org-level and project-scoped roles. */
+ roles: {
+ /**
+ * @description Role name. For project-scoped roles this is the base role name.
+ * @example developer
+ */
+ name: string
+ /** @description Project refs this role is scoped to. Empty array for org-level roles. */
+ projects: {
+ name: string
+ ref: string
+ }[]
+ /**
+ * @description Whether this role applies org-wide or is scoped to specific projects for the user.
+ * @enum {string}
+ */
+ scope: 'organization' | 'project'
+ }[]
+ /** @description Member's username */
+ username: string | null
+ }
+ /** Format: uuid */
+ id: string
+ /**
+ * @description Resource type.
+ * @enum {string}
+ */
+ type: 'organization_member'
+ }[]
+ links: {
+ /**
+ * @description URL path to the first page if available.
+ * @example /v2/organizations/my-org/members?page[size]=10
+ */
+ first?: string | null
+ /**
+ * @description URL path to the last page if available.
+ * @example /v2/organizations/my-org/members?page[size]=10&page[after]=019adf7d-4513-71ba-b264-21900edb4295
+ */
+ last?: string | null
+ /**
+ * @description URL path to the next page.
+ * @example /v2/organizations/my-org/members?page[size]=10&page[after]=019adf7d-4513-7062-b292-78b86cc470a4
+ */
+ next: string | null
+ /**
+ * @description URL path to the previous page.
+ * @example /v2/organizations/my-org/members?page[size]=10&page[before]=019adf7d-4513-74c5-bb9a-f1bc0f7a95d7
+ */
+ prev: string | null
+ }
+ }
+ V2ListPrivateLinkAssociationsResponse: {
+ data: {
+ attributes: {
+ /** @description Human-readable name for the AWS account. */
+ account_name?: string
+ /** @description The AWS account ID this PrivateLink share is associated with. */
+ aws_account_id: string
+ /** @description Identifier of the database this PrivateLink share targets - the project ref for the primary, or the read replica identifier. */
+ database_identifier: string
+ /**
+ * @description Whether this PrivateLink share targets the primary database or a read replica.
+ * @enum {string}
+ */
+ database_type: 'PRIMARY' | 'READ_REPLICA'
+ /** @description ARN of the AWS VPC Lattice resource configuration backing this PrivateLink share. */
+ resource_access_manager_resource_config_arn?: string
+ /** @description ID of the AWS VPC Lattice resource configuration backing this PrivateLink share. */
+ resource_access_manager_resource_config_id?: string
+ /** @description ARN of the AWS Resource Access Manager resource share for this association. */
+ resource_access_manager_share_arn?: string
+ /**
+ * Format: date-time
+ * @description The time and date at which the AWS Resource Share Association was requested from Supabase. `null` means that the association was not yet requested while the PrivateLink Association is pending.
+ */
+ shared_at: string | null
+ /**
+ * @description
+ * - `CREATING`: The PrivateLink resources and the Association are in the process of being created. The PrivateLink Share cannot be accepted yet.
+ * - `READY`: The PrivateLink resources have been created and the PrivateLink Share can be accepted for the duration of 12h after sharing. See `shared_at`.
+ * - `ASSOCIATION_REQUEST_EXPIRED`: The PrivateLink Share has not been accepted within the 12h time limit. This association can now be deleted.
+ * - `ASSOCIATION_ACCEPTED`: The PrivateLink Share was successfully accepted.
+ * - `CREATION_FAILED`: The PrivateLink resources failed to create. This likely means something went wrong on Supabase's and and support should be contacted.
+ * - `DELETING`: The PrivateLink resources and the Association are in the process of being deleted. The PrivateLink Share cannot be accepted yet.
+ *
+ * @enum {string}
+ */
+ status:
+ | 'CREATING'
+ | 'READY'
+ | 'ASSOCIATION_REQUEST_EXPIRED'
+ | 'ASSOCIATION_ACCEPTED'
+ | 'CREATION_FAILED'
+ | 'DELETING'
+ }
+ id: string
+ /**
+ * @description Resource type.
+ * @enum {string}
+ */
+ type: 'private_link_association'
+ }[]
+ }
+ V2ListProjectsResponse: {
+ data: {
+ attributes: {
+ /** @description Cloud provider hosting the project */
+ cloud_provider: string
+ /** @description The project's databases including compute and disk attributes. */
+ databases: {
+ cloud_provider: string
+ disk_last_modified_at?: string
+ disk_throughput_mbps?: number
+ /** @enum {string} */
+ disk_type?: 'gp3' | 'io2'
+ disk_volume_size_gb?: number
+ identifier: string
+ /** @enum {string} */
+ infra_compute_size?:
+ | 'pico'
+ | 'nano'
+ | 'micro'
+ | 'small'
+ | 'medium'
+ | 'large'
+ | 'xlarge'
+ | '2xlarge'
+ | '4xlarge'
+ | '8xlarge'
+ | '12xlarge'
+ | '16xlarge'
+ | '24xlarge'
+ | '24xlarge_optimized_memory'
+ | '24xlarge_optimized_cpu'
+ | '24xlarge_high_memory'
+ | '48xlarge'
+ | '48xlarge_optimized_memory'
+ | '48xlarge_optimized_cpu'
+ | '48xlarge_high_memory'
+ region: string | null
+ /** @enum {string} */
+ status:
+ | 'ACTIVE_HEALTHY'
+ | 'ACTIVE_UNHEALTHY'
+ | 'COMING_UP'
+ | 'GOING_DOWN'
+ | 'INIT_FAILED'
+ | 'REMOVED'
+ | 'RESTORING'
+ | 'UNKNOWN'
+ | 'INIT_READ_REPLICA'
+ | 'INIT_READ_REPLICA_FAILED'
+ | 'RESTARTING'
+ | 'RESIZING'
+ /** @enum {string} */
+ type: 'PRIMARY' | 'READ_REPLICA'
+ }[]
+ /** @description When the project was created */
+ inserted_at: string
+ /** @description Project name */
+ name: string
+ /** @description Region the project is hosted in */
+ region: string
+ /**
+ * @description Project status
+ * @enum {string}
+ */
+ status:
+ | 'INACTIVE'
+ | 'ACTIVE_HEALTHY'
+ | 'ACTIVE_UNHEALTHY'
+ | 'COMING_UP'
+ | 'UNKNOWN'
+ | 'GOING_DOWN'
+ | 'INIT_FAILED'
+ | 'REMOVED'
+ | 'RESTORING'
+ | 'UPGRADING'
+ | 'PAUSING'
+ | 'RESTORE_FAILED'
+ | 'RESTARTING'
+ | 'PAUSE_FAILED'
+ | 'RESIZING'
+ }
+ /**
+ * @description Project ref
+ * @example abcdefghijklmnopqrst
+ */
+ id: string
+ /**
+ * @description Resource type.
+ * @enum {string}
+ */
+ type: 'project'
+ }[]
+ links: {
+ /**
+ * @description URL path to the first page if available.
+ * @example /v2/organizations/my-org/projects?page[size]=10
+ */
+ first?: string | null
+ /**
+ * @description URL path to the last page if available.
+ * @example /v2/organizations/my-org/projects?page[size]=10&page[after]=019adf7d-4513-71ba-b264-21900edb4295
+ */
+ last?: string | null
+ /**
+ * @description URL path to the next page.
+ * @example /v2/organizations/my-org/projects?page[size]=10&page[after]=019adf7d-4513-7062-b292-78b86cc470a4
+ */
+ next: string | null
+ /**
+ * @description URL path to the previous page.
+ * @example /v2/organizations/my-org/projects?page[size]=10&page[before]=019adf7d-4513-74c5-bb9a-f1bc0f7a95d7
+ */
+ prev: string | null
+ }
+ }
+ V2ListRolesResponse: {
+ data: {
+ attributes: {
+ /**
+ * @description Role name.
+ * @example developer
+ */
+ name: string
+ }
+ /**
+ * @description Resource type.
+ * @enum {string}
+ */
+ type: 'organization_role'
+ }[]
+ }
+ V2ListWorkersResponse: {
+ data: {
+ attributes: {
+ /** @enum {string} */
+ build_state: 'building' | 'active' | 'failed'
+ deleting?: boolean
+ image_version?: string
+ instances?: {
+ declared: number
+ live: number
+ ready: number
+ stale: number
+ }
+ instances_error?: string
+ secret_generation: string
+ spec: {
+ backend?: string
+ /** @example public */
+ exposure: string
+ /** @example 1 */
+ instances: number
+ /** @example node */
+ runtime?: string
+ /** @example 2gb-1vcpu */
+ size: string
+ }
+ state_reason?: string
+ }
+ /**
+ * @description Worker name.
+ * @example hello-world
+ */
+ id: string
+ /**
+ * @description Resource type.
+ * @enum {string}
+ */
+ type: 'project_worker'
+ }[]
+ }
+ V2PreviewProjectTransferResponse: {
+ data: {
+ attributes: {
+ errors: {
+ key: string
+ message: string
+ }[]
+ info: {
+ key: string
+ message: string
+ }[]
+ valid: boolean
+ warnings: {
+ key: string
+ message: string
+ }[]
+ }
+ /**
+ * @description Resource type.
+ * @enum {string}
+ */
+ type: 'project_transfer_result'
+ }
+ }
+ V2PrivateLinkAssociationResponse: {
+ data: {
+ attributes: {
+ /** @description Human-readable name for the AWS account. */
+ account_name?: string
+ /** @description The AWS account ID this PrivateLink share is associated with. */
+ aws_account_id: string
+ /** @description Identifier of the database this PrivateLink share targets - the project ref for the primary, or the read replica identifier. */
+ database_identifier: string
+ /**
+ * @description Whether this PrivateLink share targets the primary database or a read replica.
+ * @enum {string}
+ */
+ database_type: 'PRIMARY' | 'READ_REPLICA'
+ /** @description ARN of the AWS VPC Lattice resource configuration backing this PrivateLink share. */
+ resource_access_manager_resource_config_arn?: string
+ /** @description ID of the AWS VPC Lattice resource configuration backing this PrivateLink share. */
+ resource_access_manager_resource_config_id?: string
+ /** @description ARN of the AWS Resource Access Manager resource share for this association. */
+ resource_access_manager_share_arn?: string
+ /**
+ * Format: date-time
+ * @description The time and date at which the AWS Resource Share Association was requested from Supabase. `null` means that the association was not yet requested while the PrivateLink Association is pending.
+ */
+ shared_at: string | null
+ /**
+ * @description
+ * - `CREATING`: The PrivateLink resources and the Association are in the process of being created. The PrivateLink Share cannot be accepted yet.
+ * - `READY`: The PrivateLink resources have been created and the PrivateLink Share can be accepted for the duration of 12h after sharing. See `shared_at`.
+ * - `ASSOCIATION_REQUEST_EXPIRED`: The PrivateLink Share has not been accepted within the 12h time limit. This association can now be deleted.
+ * - `ASSOCIATION_ACCEPTED`: The PrivateLink Share was successfully accepted.
+ * - `CREATION_FAILED`: The PrivateLink resources failed to create. This likely means something went wrong on Supabase's and and support should be contacted.
+ * - `DELETING`: The PrivateLink resources and the Association are in the process of being deleted. The PrivateLink Share cannot be accepted yet.
+ *
+ * @enum {string}
+ */
+ status:
+ | 'CREATING'
+ | 'READY'
+ | 'ASSOCIATION_REQUEST_EXPIRED'
+ | 'ASSOCIATION_ACCEPTED'
+ | 'CREATION_FAILED'
+ | 'DELETING'
+ }
+ id: string
+ /**
+ * @description Resource type.
+ * @enum {string}
+ */
+ type: 'private_link_association'
+ }
+ }
+ V2ProjectConfigResponse: {
+ data: {
+ attributes: {
+ api: {
+ db_extra_search_path: string
+ /** @description If `null`, no pool size is written to the project's PostgREST config and PostgREST's own default applies. The platform does not pick a value here. */
+ db_pool: number | null
+ db_pool_acquisition_timeout: number
+ /** @description Schemas exposed through the Data API */
+ db_schema: string
+ max_rows: number
+ }
+ /** @description Effective Auth config, keyed by lowercased GoTrue setting name and resolved through the `gotrue_config` view, so a setting the project has never overridden is reported at its platform default. Secrets are returned as an HMAC of their value, never in plaintext. */
+ auth: {
+ [key: string]: unknown
+ }
+ database: {
+ network_restrictions: {
+ allowed_cidrs: {
+ address: string
+ /** @enum {string} */
+ type: 'v4' | 'v6'
+ }[]
+ applied_at?: string
+ /** @enum {string} */
+ entitlement: 'disallowed' | 'allowed'
+ /**
+ * @description Whether the allowlist below is applied to the project or only stored.
+ * @enum {string}
+ */
+ status: 'stored' | 'applied'
+ updated_at?: string
+ }
+ /** @description Postgres parameter overrides. Empty when the project runs entirely on defaults. */
+ postgres_settings: {
+ /** @description Default unit: s */
+ checkpoint_timeout?: string
+ cron_log_statement?: boolean
+ effective_cache_size?: string
+ hot_standby_feedback?: boolean
+ /** @description Default unit: ms */
+ log_autovacuum_min_duration?: string
+ log_checkpoints?: boolean
+ log_connections?: boolean
+ log_disconnections?: boolean
+ log_duration?: boolean
+ log_lock_waits?: boolean
+ log_recovery_conflict_waits?: boolean
+ log_replication_commands?: boolean
+ /** @description Default unit: ms */
+ log_startup_progress_interval?: string
+ log_temp_files?: string
+ logical_decoding_work_mem?: string
+ maintenance_work_mem?: string
+ max_connections?: number
+ max_locks_per_transaction?: number
+ max_logical_replication_workers?: number
+ max_parallel_maintenance_workers?: number
+ max_parallel_workers?: number
+ max_parallel_workers_per_gather?: number
+ max_replication_slots?: number
+ max_slot_wal_keep_size?: string
+ max_standby_archive_delay?: string
+ max_standby_streaming_delay?: string
+ max_sync_workers_per_subscription?: number
+ max_wal_senders?: number
+ max_wal_size?: string
+ max_worker_processes?: number
+ /** @enum {string} */
+ session_replication_role?: 'origin' | 'replica' | 'local'
+ shared_buffers?: string
+ /** @description Default unit: ms */
+ statement_timeout?: string
+ track_activity_query_size?: string
+ track_commit_timestamp?: boolean
+ wal_keep_size?: string
+ /** @description Default unit: ms */
+ wal_sender_timeout?: string
+ work_mem?: string
+ }
+ /** @description Whether the database rejects plaintext connections */
+ ssl_enforced: boolean
+ }
+ pooler: {
+ /** @description Defaults to the pooler's size for the project's compute when not overridden. */
+ default_pool_size: number
+ ignore_startup_parameters: string
+ /** @description Defaults to the pooler's size for the project's compute when not overridden. */
+ max_client_conn: number
+ /** @enum {string} */
+ pool_mode: 'transaction' | 'session' | 'statement'
+ query_wait_timeout: number
+ reserve_pool_size: number
+ server_idle_timeout: number
+ server_lifetime: number
+ }
+ realtime: {
+ /** @description Defaults to Realtime's pool size for the project's compute when not overridden. */
+ connection_pool: number
+ max_bytes_per_second: number
+ max_channels_per_client: number
+ max_concurrent_users: number
+ max_events_per_second: number
+ max_joins_per_second: number
+ max_payload_size_in_kb: number
+ max_presence_events_per_second: number
+ /** @description If `null`, no override is stored and Realtime applies its own default. */
+ postgres_changes_pool: number | null
+ presence_enabled: boolean
+ private_only: boolean
+ suspend: boolean
+ }
+ /** @description Read from the storage service's admin API rather than the middleware DB, so unlike the rest of this resource it reflects the tenant's live config. */
+ storage: {
+ capabilities: {
+ iceberg_catalog: boolean
+ list_v2: boolean
+ }
+ database_pool_mode: string
+ features: {
+ iceberg_catalog: {
+ enabled: boolean
+ max_catalogs: number
+ max_namespaces: number
+ max_tables: number
+ }
+ image_transformation: {
+ enabled: boolean
+ }
+ purge_cache: {
+ enabled: boolean
+ }
+ s3_protocol: {
+ enabled: boolean
+ }
+ vector_buckets: {
+ enabled: boolean
+ max_buckets: number
+ max_indexes: number
+ }
+ }
+ /** Format: int64 */
+ file_size_limit: number
+ migration_version: string
+ /** @enum {string} */
+ upstream_target: 'main' | 'canary'
+ }
+ }
+ /** @description Project ref. */
+ id: string
+ /**
+ * @description Resource type.
+ * @enum {string}
+ */
+ type: 'project_config'
+ }
+ }
+ V2TransferProjectBody: {
+ data: {
+ attributes: {
+ target_organization_slug: string
+ }
+ /**
+ * @description Resource type.
+ * @enum {string}
+ */
+ type: 'project_transfer_input'
+ }
+ }
+ V2WorkerResponse: {
+ data: {
+ attributes: {
+ /** @enum {string} */
+ build_state: 'building' | 'active' | 'failed'
+ deleting?: boolean
+ image_version?: string
+ instances?: {
+ declared: number
+ live: number
+ ready: number
+ stale: number
+ }
+ instances_error?: string
+ secret_generation: string
+ spec: {
+ backend?: string
+ /** @example public */
+ exposure: string
+ /** @example 1 */
+ instances: number
+ /** @example node */
+ runtime?: string
+ /** @example 2gb-1vcpu */
+ size: string
+ }
+ state_reason?: string
+ }
+ /**
+ * @description Worker name.
+ * @example hello-world
+ */
+ id: string
+ /**
+ * @description Resource type.
+ * @enum {string}
+ */
+ type: 'project_worker'
+ }
+ }
+ V2WorkerUploadResponse: {
+ data: {
+ attributes: {
+ /** @description When the slot stops accepting the upload. */
+ expires_at: string
+ /** @example PUT */
+ method: string
+ /** @description Presigned destination for the `.tar.gz` build context. */
+ url: string
+ }
+ /**
+ * @description Upload id to pass to the deploy endpoint as `context_upload_id`.
+ * @example cafe0000000000000000000000000000
+ */
+ id: string
+ /**
+ * @description Resource type.
+ * @enum {string}
+ */
+ type: 'project_worker_upload'
+ }
+ }
+ }
+ responses: never
+ parameters: never
+ requestBodies: never
+ headers: never
+ pathItems: never
+}
+export type $defs = Record
+export interface operations {
+ postV1WebhooksEvents: {
+ parameters: {
+ query?: never
+ header?: never
+ path?: never
+ cookie?: never
+ }
+ requestBody: {
+ content: {
+ 'application/json': {
+ data: {
+ attributes: {
+ /**
+ * @description Organization slug
+ * @example tsrqponmlkjihgfedcba
+ */
+ organization_slug: string
+ /** @description Extra data to pass to consumers. `organization_slug` and `project_ref` (if applicable) are always provided by default. */
+ payload?: {
+ [key: string]: unknown
+ }
+ /** @description Project's ref. If left unspecified or `null`, the event will published as organization-wide, only to organization-wide endpoints. */
+ project_ref?: string | null
+ /**
+ * Format: date-time
+ * @description Optional timestamp of event publication.
+ */
+ timestamp?: string
+ /**
+ * @description Webhook event type.
+ * @enum {string}
+ */
+ type:
+ | 'v1.project.paused'
+ | 'v1.project.created'
+ | 'v1.project.restored'
+ | 'v1.project.transferred'
+ | 'v1.project.removed'
+ | 'v1.project.restarted'
+ | 'v1.project.status.changed'
+ | 'v1.project.backup.started'
+ | 'v1.project.branch.created'
+ | 'v1.project.branch.updated'
+ | 'v1.project.branch.removed'
+ | 'v1.organization.member.invitation.created'
+ | 'v1.organization.member.invitation.canceled'
+ | 'v1.organization.member.added'
+ | 'v1.organization.member.removed'
+ | 'v1.organization.member.role.assigned'
+ | 'v1.organization.member.role.removed'
+ | 'v1.organization.member.role.updated'
+ | 'v1.organization.billing.plan.upgraded'
+ | 'v1.organization.billing.plan.downgraded'
+ | 'project.v1.paused'
+ | 'project.v1.created'
+ | 'project.v1.restored'
+ | 'project.v1.transferred'
+ | 'project.v1.removed'
+ | 'project.v1.restarted'
+ | 'project.v1.status.changed'
+ | 'project.v1.backup.started'
+ | 'project.v1.branch.created'
+ | 'project.v1.branch.updated'
+ | 'project.v1.branch.removed'
+ | 'organization.v1.member.invitation.created'
+ | 'organization.v1.member.invitation.canceled'
+ | 'organization.v1.member.added'
+ | 'organization.v1.member.removed'
+ | 'organization.v1.member.role.assigned'
+ | 'organization.v1.member.role.removed'
+ | 'organization.v1.member.role.updated'
+ | 'organization.v1.billing.plan.upgraded'
+ | 'organization.v1.billing.plan.downgraded'
+ | 'project.v1.branch.deleted'
+ }
+ /**
+ * @description Resource type.
+ * @constant
+ */
+ type: 'event'
+ }
+ meta: {
+ /** @description Idempotency key. */
+ idempotency_key: string
+ }
+ }
+ }
+ }
+ responses: {
+ /** @description Events published */
+ 201: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ data: {
+ id: string
+ /**
+ * @description Resource type.
+ * @constant
+ */
+ type: 'ingress'
+ }
+ }
+ }
+ }
+ /** @description PermissionDenied */
+ 403: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'forbidden.permission_denied'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Forbidden: Permission denied'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description GenericRequestTimeout */
+ 408: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'request_timeout'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Request Timeout'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description GenericTooManyRequests */
+ 429: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'too_many_requests'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Too Many Requests'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description Multiple error responses */
+ 500: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error:
+ | {
+ /** @constant */
+ code: 'internal_server_error'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Internal Server Error'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ | {
+ /** @constant */
+ code: 'internal_server_error.event.ingress_failed'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Internal Server Error: Failed to ingress the event'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description TemporarilyDisabled */
+ 503: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'service_unavailable.temporarily_disabled'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Service Unavailable: Temporarily disabled'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ }
+ }
+ 'v2-list-organization-github-connections': {
+ parameters: {
+ query?: {
+ filter?: {
+ /**
+ * @description Project ref
+ * @example abcdefghijklmnopqrst
+ */
+ project_ref?: string
+ }
+ page?: {
+ /**
+ * @description Project ref
+ * @example abcdefghijklmnopqrst
+ */
+ after?: string
+ /**
+ * @description Project ref
+ * @example abcdefghijklmnopqrst
+ */
+ before?: string
+ size?: number
+ }
+ }
+ header?: never
+ path: {
+ /** @description Organization slug */
+ slug: string
+ }
+ cookie?: never
+ }
+ requestBody?: never
+ responses: {
+ 200: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['V2ListGitHubConnectionsResponse']
+ }
+ }
+ /** @description Unauthorized */
+ 401: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['ErrorResponseBody']
+ }
+ }
+ /** @description Forbidden action */
+ 403: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['ErrorResponseBody']
+ }
+ }
+ /** @description Rate limit exceeded */
+ 429: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['ErrorResponseBody']
+ }
+ }
+ }
+ }
+ 'v2-list-organization-members': {
+ parameters: {
+ query?: {
+ filter?: {
+ /** Format: email */
+ primary_email?: string
+ username?: string
+ }
+ page?: {
+ /** Format: uuid */
+ after?: string
+ /** Format: uuid */
+ before?: string
+ size?: number
+ }
+ }
+ header?: never
+ path: {
+ /** @description Organization slug */
+ slug: string
+ }
+ cookie?: never
+ }
+ requestBody?: never
+ responses: {
+ 200: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['V2ListMembersResponse']
+ }
+ }
+ /** @description Unauthorized */
+ 401: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['ErrorResponseBody']
+ }
+ }
+ /** @description Forbidden action */
+ 403: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['ErrorResponseBody']
+ }
+ }
+ /** @description Rate limit exceeded */
+ 429: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['ErrorResponseBody']
+ }
+ }
+ }
+ }
+ 'v2-assign-organization-member-role': {
+ parameters: {
+ query?: never
+ header?: never
+ path: {
+ /** @description Organization slug */
+ slug: string
+ user_id: string
+ }
+ cookie?: never
+ }
+ requestBody: {
+ content: {
+ 'application/json': components['schemas']['V2AssignOrganizationMemberRoleRequest']
+ }
+ }
+ responses: {
+ 200: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['OrganizationMemberRoleResponse']
+ }
+ }
+ /** @description Unauthorized */
+ 401: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['ErrorResponseBody']
+ }
+ }
+ /** @description This feature requires the Enterprise organization plan. */
+ 402: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['ErrorResponseBody']
+ }
+ }
+ /** @description Forbidden action */
+ 403: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['ErrorResponseBody']
+ }
+ }
+ /** @description Rate limit exceeded */
+ 429: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['ErrorResponseBody']
+ }
+ }
+ /** @description Failed to assign organization member role */
+ 500: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['ErrorResponseBody']
+ }
+ }
+ }
+ }
+ 'v2-create-organization-invitations': {
+ parameters: {
+ query?: never
+ header?: never
+ path: {
+ /** @description Organization slug */
+ slug: string
+ }
+ cookie?: never
+ }
+ requestBody: {
+ content: {
+ 'application/json': components['schemas']['V2CreateInvitationsRequest']
+ }
+ }
+ responses: {
+ 201: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['V2CreateInvitationsResponse']
+ }
+ }
+ /** @description Unauthorized */
+ 401: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['ErrorResponseBody']
+ }
+ }
+ /** @description This feature requires the Enterprise organization plan. */
+ 402: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['ErrorResponseBody']
+ }
+ }
+ /** @description Forbidden action */
+ 403: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['ErrorResponseBody']
+ }
+ }
+ /** @description Rate limit exceeded */
+ 429: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['ErrorResponseBody']
+ }
+ }
+ }
+ }
+ 'v2-delete-organization-invitations': {
+ parameters: {
+ query?: never
+ header?: never
+ path: {
+ /** @description Organization slug */
+ slug: string
+ }
+ cookie?: never
+ }
+ requestBody: {
+ content: {
+ 'application/json': components['schemas']['V2DeleteInvitationsRequest']
+ }
+ }
+ responses: {
+ 200: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['V2DeleteInvitationsResponse']
+ }
+ }
+ /** @description Unauthorized */
+ 401: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['ErrorResponseBody']
+ }
+ }
+ /** @description This feature requires the Enterprise organization plan. */
+ 402: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['ErrorResponseBody']
+ }
+ }
+ /** @description Forbidden action */
+ 403: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['ErrorResponseBody']
+ }
+ }
+ /** @description Rate limit exceeded */
+ 429: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['ErrorResponseBody']
+ }
+ }
+ }
+ }
+ 'v2-list-organization-projects': {
+ parameters: {
+ query?: {
+ page?: {
+ after?: string
+ before?: string
+ size?: number
+ }
+ /** @description Case-insensitive substring match on the project name. */
+ search?: string
+ /** @description Sort order by creation time: `inserted_at` (oldest first) or `-inserted_at` (newest first). Defaults to `inserted_at`. */
+ sort?: 'inserted_at' | '-inserted_at'
+ }
+ header?: never
+ path: {
+ /** @description Organization slug */
+ slug: string
+ }
+ cookie?: never
+ }
+ requestBody?: never
+ responses: {
+ 200: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['V2ListProjectsResponse']
+ }
+ }
+ /** @description Unauthorized */
+ 401: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['ErrorResponseBody']
+ }
+ }
+ /** @description Forbidden action */
+ 403: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['ErrorResponseBody']
+ }
+ }
+ /** @description Rate limit exceeded */
+ 429: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['ErrorResponseBody']
+ }
+ }
+ }
+ }
+ 'v2-list-organization-roles': {
+ parameters: {
+ query?: never
+ header?: never
+ path: {
+ /** @description Organization slug */
+ slug: string
+ }
+ cookie?: never
+ }
+ requestBody?: never
+ responses: {
+ 200: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['V2ListRolesResponse']
+ }
+ }
+ /** @description Unauthorized */
+ 401: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['ErrorResponseBody']
+ }
+ }
+ /** @description Forbidden action */
+ 403: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['ErrorResponseBody']
+ }
+ }
+ /** @description Rate limit exceeded */
+ 429: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['ErrorResponseBody']
+ }
+ }
+ }
+ }
+ allV2OrganizationsBySlugWebhooks: {
+ parameters: {
+ query?: never
+ header?: never
+ path: {
+ /** @description Identifier of a delivery (UUID v7). */
+ id: string
+ /** @description Organization slug */
+ slug: string
+ }
+ cookie?: never
+ }
+ requestBody?: never
+ responses: {
+ /** @description Delivery details */
+ 200: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ data: {
+ attributes: {
+ /**
+ * Format: date-time
+ * @description Timestamp of the attempt.
+ */
+ attempt_timestamp: string
+ event: {
+ /** @description Final data sent to the consumer. */
+ payload: {
+ /**
+ * @description Organization slug
+ * @example tsrqponmlkjihgfedcba
+ */
+ organization_slug: string
+ project_ref: string | null
+ } & {
+ [key: string]: unknown
+ }
+ /**
+ * Format: date-time
+ * @description Timestamp of event publication.
+ */
+ timestamp: string
+ /**
+ * @description Webhook event type.
+ * @enum {string}
+ */
+ type:
+ | 'v1.project.paused'
+ | 'v1.project.created'
+ | 'v1.project.restored'
+ | 'v1.project.transferred'
+ | 'v1.project.removed'
+ | 'v1.project.restarted'
+ | 'v1.project.status.changed'
+ | 'v1.project.backup.started'
+ | 'v1.project.branch.created'
+ | 'v1.project.branch.updated'
+ | 'v1.project.branch.removed'
+ | 'v1.organization.member.invitation.created'
+ | 'v1.organization.member.invitation.canceled'
+ | 'v1.organization.member.added'
+ | 'v1.organization.member.removed'
+ | 'v1.organization.member.role.assigned'
+ | 'v1.organization.member.role.removed'
+ | 'v1.organization.member.role.updated'
+ | 'v1.organization.billing.plan.upgraded'
+ | 'v1.organization.billing.plan.downgraded'
+ | 'project.v1.paused'
+ | 'project.v1.created'
+ | 'project.v1.restored'
+ | 'project.v1.transferred'
+ | 'project.v1.removed'
+ | 'project.v1.restarted'
+ | 'project.v1.status.changed'
+ | 'project.v1.backup.started'
+ | 'project.v1.branch.created'
+ | 'project.v1.branch.updated'
+ | 'project.v1.branch.removed'
+ | 'organization.v1.member.invitation.created'
+ | 'organization.v1.member.invitation.canceled'
+ | 'organization.v1.member.added'
+ | 'organization.v1.member.removed'
+ | 'organization.v1.member.role.assigned'
+ | 'organization.v1.member.role.removed'
+ | 'organization.v1.member.role.updated'
+ | 'organization.v1.billing.plan.upgraded'
+ | 'organization.v1.billing.plan.downgraded'
+ | 'project.v1.branch.deleted'
+ }
+ /**
+ * Format: uuid
+ * @description Identifier of the event, which triggered the delivery (UUID v7).
+ */
+ event_id: string
+ /**
+ * Format: uuid
+ * @description Identifier of a delivery (UUID v7).
+ */
+ id: string
+ response_body:
+ | (
+ | {
+ [key: string]: string
+ }
+ | string
+ )
+ | null
+ /** @description HTTP status code of the response, `0` if unavailable. */
+ response_code: number
+ /** @description HTTP headers of the response, `{}` if unavailable. */
+ response_headers: {
+ [key: string]: string
+ } | null
+ /**
+ * @description Status of the delivery attempt.
+ * @enum {string}
+ */
+ status: 'pending' | 'success' | 'failure' | 'skipped'
+ }
+ /**
+ * Format: uuid
+ * @description Identifier of a delivery (UUID v7).
+ */
+ id: string
+ /**
+ * @description Resource type.
+ * @constant
+ */
+ type: 'delivery'
+ }
+ }
+ }
+ }
+ /** @description Multiple error responses */
+ 400: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error:
+ | {
+ /** @constant */
+ code: 'bad_request.invalid_slug'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Bad Request: Invalid organization slug'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ | {
+ /** @constant */
+ code: 'bad_request.invalid_ref'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Bad Request: Invalid project ref'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description GenericUnauthorized */
+ 401: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'unauthorized'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Unauthorized'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description Multiple error responses */
+ 403: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error:
+ | {
+ /** @constant */
+ code: 'forbidden.permission_denied'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Forbidden: Permission denied'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ | {
+ /** @constant */
+ code: 'forbidden.access_disabled'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Forbidden: Access disabled'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description DeliveryNotFound */
+ 404: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'not_found.delivery'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Not Found: Delivery not found'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description GenericRequestTimeout */
+ 408: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'request_timeout'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Request Timeout'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description GenericTooManyRequests */
+ 429: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'too_many_requests'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Too Many Requests'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description GenericInternalServerError */
+ 500: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'internal_server_error'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Internal Server Error'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ }
+ }
+ allV2OrganizationsBySlugWebhooks: {
+ parameters: {
+ query?: never
+ header?: never
+ path: {
+ /** @description Identifier of a delivery (UUID v7). */
+ id: string
+ /** @description Organization slug */
+ slug: string
+ }
+ cookie?: never
+ }
+ requestBody?: never
+ responses: {
+ /** @description Delivery details */
+ 201: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ data: {
+ id: string
+ /**
+ * @description Resource type.
+ * @constant
+ */
+ type: 'ingress'
+ }
+ }
+ }
+ }
+ /** @description Multiple error responses */
+ 400: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error:
+ | {
+ /** @constant */
+ code: 'bad_request.invalid_slug'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Bad Request: Invalid organization slug'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ | {
+ /** @constant */
+ code: 'bad_request.invalid_ref'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Bad Request: Invalid project ref'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description GenericUnauthorized */
+ 401: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'unauthorized'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Unauthorized'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description Multiple error responses */
+ 403: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error:
+ | {
+ /** @constant */
+ code: 'forbidden.permission_denied'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Forbidden: Permission denied'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ | {
+ /** @constant */
+ code: 'forbidden.access_disabled'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Forbidden: Access disabled'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description DeliveryNotFound */
+ 404: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'not_found.delivery'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Not Found: Delivery not found'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description GenericRequestTimeout */
+ 408: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'request_timeout'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Request Timeout'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description GenericTooManyRequests */
+ 429: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'too_many_requests'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Too Many Requests'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description GenericInternalServerError */
+ 500: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'internal_server_error'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Internal Server Error'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ }
+ }
+ allV2OrganizationsBySlugWebhooks: {
+ parameters: {
+ query?: {
+ /** @description Up to how many records to return. */
+ 'page[limit]'?: string
+ /** @description Offset for offset-based pagination.
+ *
+ * Offset should be dividable by `page[limit]` without a reminder (`offset % limit === 0`), otherwise it will cause weird behavior when used on a frontend. */
+ 'page[offset]'?: string
+ }
+ header?: never
+ path: {
+ /** @description Organization slug */
+ slug: string
+ }
+ cookie?: never
+ }
+ requestBody?: never
+ responses: {
+ /** @description Collection of endpoints */
+ 200: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ data: {
+ attributes: {
+ /**
+ * Format: date-time
+ * @description Timestamp of endpoint's creation.
+ */
+ created_at: string
+ /**
+ * Format: uuid
+ * @description ID of the user who created the endpoint.
+ */
+ created_by: string
+ /**
+ * @description Additional request headers to pass when performing HTTP request location defined by `url`. Both keys and values must be strings and a valid HTTP headers.
+ * @example {
+ * "Authorization": "Bearer example_token"
+ * }
+ */
+ custom_headers?: {
+ [key: string]: string
+ } | null
+ /** @description Optional description for the endpoint. */
+ description: string | null
+ /** @description Whether the endpoint is enabled or not - disabled endpoints won't emit any events. */
+ enabled: boolean
+ /**
+ * @description List of subscribed events for which to receive the webhook event.
+ * @example [
+ * {
+ * "type": "v1.project.paused"
+ * }
+ * ]
+ */
+ event_types: {
+ /**
+ * @description Webhook event type.
+ * @enum {string}
+ */
+ type:
+ | 'v1.project.paused'
+ | 'v1.project.created'
+ | 'v1.project.restored'
+ | 'v1.project.transferred'
+ | 'v1.project.removed'
+ | 'v1.project.restarted'
+ | 'v1.project.status.changed'
+ | 'v1.project.backup.started'
+ | 'v1.project.branch.created'
+ | 'v1.project.branch.updated'
+ | 'v1.project.branch.removed'
+ | 'v1.organization.member.invitation.created'
+ | 'v1.organization.member.invitation.canceled'
+ | 'v1.organization.member.added'
+ | 'v1.organization.member.removed'
+ | 'v1.organization.member.role.assigned'
+ | 'v1.organization.member.role.removed'
+ | 'v1.organization.member.role.updated'
+ | 'v1.organization.billing.plan.upgraded'
+ | 'v1.organization.billing.plan.downgraded'
+ | '*'
+ }[]
+ /**
+ * Format: uuid
+ * @description Identifier of an endpoint (UUID v7).
+ */
+ id: string
+ /**
+ * Format: uri
+ * @description Publicly available URL where to send the events, must use a domain and be resolvable to a non-reserved IP address.
+ * @example https://mydomain.com/path/to/handler
+ */
+ url: string
+ }
+ /**
+ * Format: uuid
+ * @description Identifier of an endpoint (UUID v7).
+ */
+ id: string
+ /**
+ * @description Resource type.
+ * @constant
+ */
+ type: 'endpoint'
+ }[]
+ links: {
+ /**
+ * @description URL path to the first page if available.
+ * @example /v2/organization/slug/webhooks/endpoints?page[limit]=10&page[offset]=0
+ */
+ first?: string | null
+ /**
+ * @description URL path to the last page if available.
+ * @example /v2/organization/slug/webhooks/endpoints?page[limit]=10&page[offset]=30
+ */
+ last?: string | null
+ /**
+ * @description URL path to the next page.
+ * @example /v2/organization/slug/webhooks/endpoints?page[limit]=10&page[offset]=20
+ */
+ next: string | null
+ /**
+ * @description URL path to the previous page.
+ * @example /v2/organization/slug/webhooks/endpoints?page[limit]=10&page[offset]=0
+ */
+ prev: string | null
+ }
+ }
+ }
+ }
+ /** @description Multiple error responses */
+ 400: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error:
+ | {
+ /** @constant */
+ code: 'bad_request.invalid_slug'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Bad Request: Invalid organization slug'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ | {
+ /** @constant */
+ code: 'bad_request.invalid_ref'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Bad Request: Invalid project ref'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description GenericUnauthorized */
+ 401: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'unauthorized'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Unauthorized'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description Multiple error responses */
+ 403: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error:
+ | {
+ /** @constant */
+ code: 'forbidden.permission_denied'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Forbidden: Permission denied'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ | {
+ /** @constant */
+ code: 'forbidden.access_disabled'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Forbidden: Access disabled'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description GenericRequestTimeout */
+ 408: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'request_timeout'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Request Timeout'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description GenericTooManyRequests */
+ 429: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'too_many_requests'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Too Many Requests'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description GenericInternalServerError */
+ 500: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'internal_server_error'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Internal Server Error'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ }
+ }
+ allV2OrganizationsBySlugWebhooks: {
+ parameters: {
+ query?: never
+ header?: never
+ path: {
+ /** @description Organization slug */
+ slug: string
+ }
+ cookie?: never
+ }
+ requestBody: {
+ content: {
+ 'application/json': {
+ data: {
+ attributes: {
+ /**
+ * @description Additional request headers to pass when performing HTTP request location defined by `url`. Both keys and values must be strings and a valid HTTP headers.
+ * @example {
+ * "Authorization": "Bearer example_token"
+ * }
+ */
+ custom_headers?: {
+ [key: string]: string
+ } | null
+ /** @description Optional description for the endpoint. */
+ description?: string | null
+ /**
+ * @description Whether the endpoint is enabled or not - disabled endpoints won't emit any events.
+ * @default true
+ */
+ enabled?: boolean
+ /**
+ * @description List of subscribed events for which to receive the webhook event.
+ * @example [
+ * {
+ * "type": "v1.project.paused"
+ * }
+ * ]
+ */
+ event_types: {
+ /**
+ * @description Webhook event type.
+ * @enum {string}
+ */
+ type:
+ | 'v1.project.paused'
+ | 'v1.project.created'
+ | 'v1.project.restored'
+ | 'v1.project.transferred'
+ | 'v1.project.removed'
+ | 'v1.project.restarted'
+ | 'v1.project.status.changed'
+ | 'v1.project.backup.started'
+ | 'v1.project.branch.created'
+ | 'v1.project.branch.updated'
+ | 'v1.project.branch.removed'
+ | 'v1.organization.member.invitation.created'
+ | 'v1.organization.member.invitation.canceled'
+ | 'v1.organization.member.added'
+ | 'v1.organization.member.removed'
+ | 'v1.organization.member.role.assigned'
+ | 'v1.organization.member.role.removed'
+ | 'v1.organization.member.role.updated'
+ | 'v1.organization.billing.plan.upgraded'
+ | 'v1.organization.billing.plan.downgraded'
+ | '*'
+ }[]
+ /** @description Secret key to use when signing. All events will be signed according to the [Standard Webhooks](https://www.standardwebhooks.com/) specification. */
+ signing_secret: string
+ /**
+ * Format: uri
+ * @description Publicly available URL where to send the events, must use a domain and be resolvable to a non-reserved IP address.
+ * @example https://mydomain.com/path/to/handler
+ */
+ url: string
+ }
+ /**
+ * @description Resource type.
+ * @constant
+ */
+ type: 'endpoint'
+ }
+ }
+ }
+ }
+ responses: {
+ /** @description Created endpoint */
+ 201: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ data: {
+ attributes: {
+ /**
+ * Format: date-time
+ * @description Timestamp of endpoint's creation.
+ */
+ created_at: string
+ /**
+ * Format: uuid
+ * @description ID of the user who created the endpoint.
+ */
+ created_by: string
+ /**
+ * @description Additional request headers to pass when performing HTTP request location defined by `url`. Both keys and values must be strings and a valid HTTP headers.
+ * @example {
+ * "Authorization": "Bearer example_token"
+ * }
+ */
+ custom_headers?: {
+ [key: string]: string
+ } | null
+ /** @description Optional description for the endpoint. */
+ description: string | null
+ /** @description Whether the endpoint is enabled or not - disabled endpoints won't emit any events. */
+ enabled: boolean
+ /**
+ * @description List of subscribed events for which to receive the webhook event.
+ * @example [
+ * {
+ * "type": "v1.project.paused"
+ * }
+ * ]
+ */
+ event_types: {
+ /**
+ * @description Webhook event type.
+ * @enum {string}
+ */
+ type:
+ | 'v1.project.paused'
+ | 'v1.project.created'
+ | 'v1.project.restored'
+ | 'v1.project.transferred'
+ | 'v1.project.removed'
+ | 'v1.project.restarted'
+ | 'v1.project.status.changed'
+ | 'v1.project.backup.started'
+ | 'v1.project.branch.created'
+ | 'v1.project.branch.updated'
+ | 'v1.project.branch.removed'
+ | 'v1.organization.member.invitation.created'
+ | 'v1.organization.member.invitation.canceled'
+ | 'v1.organization.member.added'
+ | 'v1.organization.member.removed'
+ | 'v1.organization.member.role.assigned'
+ | 'v1.organization.member.role.removed'
+ | 'v1.organization.member.role.updated'
+ | 'v1.organization.billing.plan.upgraded'
+ | 'v1.organization.billing.plan.downgraded'
+ | '*'
+ }[]
+ /**
+ * Format: uuid
+ * @description Identifier of an endpoint (UUID v7).
+ */
+ id: string
+ /**
+ * Format: uri
+ * @description Publicly available URL where to send the events, must use a domain and be resolvable to a non-reserved IP address.
+ * @example https://mydomain.com/path/to/handler
+ */
+ url: string
+ }
+ /**
+ * Format: uuid
+ * @description Identifier of an endpoint (UUID v7).
+ */
+ id: string
+ /**
+ * @description Resource type.
+ * @constant
+ */
+ type: 'endpoint'
+ }
+ }
+ }
+ }
+ /** @description Multiple error responses */
+ 400: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error:
+ | {
+ /** @constant */
+ code: 'bad_request.invalid_slug'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Bad Request: Invalid organization slug'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ | {
+ /** @constant */
+ code: 'bad_request.invalid_ref'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Bad Request: Invalid project ref'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description GenericUnauthorized */
+ 401: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'unauthorized'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Unauthorized'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description Multiple error responses */
+ 403: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error:
+ | {
+ /** @constant */
+ code: 'forbidden.permission_denied'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Forbidden: Permission denied'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ | {
+ /** @constant */
+ code: 'forbidden.access_disabled'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Forbidden: Access disabled'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description GenericRequestTimeout */
+ 408: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'request_timeout'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Request Timeout'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description GenericTooManyRequests */
+ 429: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'too_many_requests'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Too Many Requests'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description GenericInternalServerError */
+ 500: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'internal_server_error'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Internal Server Error'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ }
+ }
+ allV2OrganizationsBySlugWebhooks: {
+ parameters: {
+ query?: never
+ header?: never
+ path: {
+ /** @description Organization slug */
+ slug: string
+ }
+ cookie?: never
+ }
+ requestBody?: never
+ responses: {
+ /** @description Deleted endpoints */
+ 200: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ data: {
+ attributes: {
+ /**
+ * Format: date-time
+ * @description Timestamp of endpoint's creation.
+ */
+ created_at: string
+ /**
+ * Format: uuid
+ * @description ID of the user who created the endpoint.
+ */
+ created_by: string
+ /**
+ * @description Additional request headers to pass when performing HTTP request location defined by `url`. Both keys and values must be strings and a valid HTTP headers.
+ * @example {
+ * "Authorization": "Bearer example_token"
+ * }
+ */
+ custom_headers?: {
+ [key: string]: string
+ } | null
+ /** @description Optional description for the endpoint. */
+ description: string | null
+ /** @description Whether the endpoint is enabled or not - disabled endpoints won't emit any events. */
+ enabled: boolean
+ /**
+ * @description List of subscribed events for which to receive the webhook event.
+ * @example [
+ * {
+ * "type": "v1.project.paused"
+ * }
+ * ]
+ */
+ event_types: {
+ /**
+ * @description Webhook event type.
+ * @enum {string}
+ */
+ type:
+ | 'v1.project.paused'
+ | 'v1.project.created'
+ | 'v1.project.restored'
+ | 'v1.project.transferred'
+ | 'v1.project.removed'
+ | 'v1.project.restarted'
+ | 'v1.project.status.changed'
+ | 'v1.project.backup.started'
+ | 'v1.project.branch.created'
+ | 'v1.project.branch.updated'
+ | 'v1.project.branch.removed'
+ | 'v1.organization.member.invitation.created'
+ | 'v1.organization.member.invitation.canceled'
+ | 'v1.organization.member.added'
+ | 'v1.organization.member.removed'
+ | 'v1.organization.member.role.assigned'
+ | 'v1.organization.member.role.removed'
+ | 'v1.organization.member.role.updated'
+ | 'v1.organization.billing.plan.upgraded'
+ | 'v1.organization.billing.plan.downgraded'
+ | '*'
+ }[]
+ /**
+ * Format: uuid
+ * @description Identifier of an endpoint (UUID v7).
+ */
+ id: string
+ /**
+ * Format: uri
+ * @description Publicly available URL where to send the events, must use a domain and be resolvable to a non-reserved IP address.
+ * @example https://mydomain.com/path/to/handler
+ */
+ url: string
+ }
+ /**
+ * Format: uuid
+ * @description Identifier of an endpoint (UUID v7).
+ */
+ id: string
+ /**
+ * @description Resource type.
+ * @constant
+ */
+ type: 'endpoint'
+ }[]
+ }
+ }
+ }
+ /** @description Multiple error responses */
+ 400: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error:
+ | {
+ /** @constant */
+ code: 'bad_request.invalid_slug'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Bad Request: Invalid organization slug'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ | {
+ /** @constant */
+ code: 'bad_request.invalid_ref'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Bad Request: Invalid project ref'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description GenericUnauthorized */
+ 401: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'unauthorized'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Unauthorized'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description Multiple error responses */
+ 403: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error:
+ | {
+ /** @constant */
+ code: 'forbidden.permission_denied'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Forbidden: Permission denied'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ | {
+ /** @constant */
+ code: 'forbidden.access_disabled'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Forbidden: Access disabled'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description GenericRequestTimeout */
+ 408: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'request_timeout'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Request Timeout'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description GenericTooManyRequests */
+ 429: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'too_many_requests'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Too Many Requests'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description GenericInternalServerError */
+ 500: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'internal_server_error'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Internal Server Error'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ }
+ }
+ allV2OrganizationsBySlugWebhooks: {
+ parameters: {
+ query?: never
+ header?: never
+ path: {
+ /** @description Identifier of an endpoint (UUID v7). */
+ id: string
+ /** @description Organization slug */
+ slug: string
+ }
+ cookie?: never
+ }
+ requestBody?: never
+ responses: {
+ /** @description Endpoint details */
+ 200: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ data: {
+ attributes: {
+ /**
+ * Format: date-time
+ * @description Timestamp of endpoint's creation.
+ */
+ created_at: string
+ /**
+ * Format: uuid
+ * @description ID of the user who created the endpoint.
+ */
+ created_by: string
+ /**
+ * @description Additional request headers to pass when performing HTTP request location defined by `url`. Both keys and values must be strings and a valid HTTP headers.
+ * @example {
+ * "Authorization": "Bearer example_token"
+ * }
+ */
+ custom_headers?: {
+ [key: string]: string
+ } | null
+ /** @description Optional description for the endpoint. */
+ description: string | null
+ /** @description Whether the endpoint is enabled or not - disabled endpoints won't emit any events. */
+ enabled: boolean
+ /**
+ * @description List of subscribed events for which to receive the webhook event.
+ * @example [
+ * {
+ * "type": "v1.project.paused"
+ * }
+ * ]
+ */
+ event_types: {
+ /**
+ * @description Webhook event type.
+ * @enum {string}
+ */
+ type:
+ | 'v1.project.paused'
+ | 'v1.project.created'
+ | 'v1.project.restored'
+ | 'v1.project.transferred'
+ | 'v1.project.removed'
+ | 'v1.project.restarted'
+ | 'v1.project.status.changed'
+ | 'v1.project.backup.started'
+ | 'v1.project.branch.created'
+ | 'v1.project.branch.updated'
+ | 'v1.project.branch.removed'
+ | 'v1.organization.member.invitation.created'
+ | 'v1.organization.member.invitation.canceled'
+ | 'v1.organization.member.added'
+ | 'v1.organization.member.removed'
+ | 'v1.organization.member.role.assigned'
+ | 'v1.organization.member.role.removed'
+ | 'v1.organization.member.role.updated'
+ | 'v1.organization.billing.plan.upgraded'
+ | 'v1.organization.billing.plan.downgraded'
+ | '*'
+ }[]
+ /**
+ * Format: uuid
+ * @description Identifier of an endpoint (UUID v7).
+ */
+ id: string
+ /**
+ * Format: uri
+ * @description Publicly available URL where to send the events, must use a domain and be resolvable to a non-reserved IP address.
+ * @example https://mydomain.com/path/to/handler
+ */
+ url: string
+ }
+ /**
+ * Format: uuid
+ * @description Identifier of an endpoint (UUID v7).
+ */
+ id: string
+ /**
+ * @description Resource type.
+ * @constant
+ */
+ type: 'endpoint'
+ }
+ }
+ }
+ }
+ /** @description Multiple error responses */
+ 400: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error:
+ | {
+ /** @constant */
+ code: 'bad_request.invalid_slug'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Bad Request: Invalid organization slug'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ | {
+ /** @constant */
+ code: 'bad_request.invalid_ref'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Bad Request: Invalid project ref'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description GenericUnauthorized */
+ 401: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'unauthorized'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Unauthorized'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description Multiple error responses */
+ 403: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error:
+ | {
+ /** @constant */
+ code: 'forbidden.permission_denied'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Forbidden: Permission denied'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ | {
+ /** @constant */
+ code: 'forbidden.access_disabled'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Forbidden: Access disabled'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description EndpointNotFound */
+ 404: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'not_found.endpoint'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Not Found: Endpoint not found'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description GenericRequestTimeout */
+ 408: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'request_timeout'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Request Timeout'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description GenericTooManyRequests */
+ 429: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'too_many_requests'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Too Many Requests'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description GenericInternalServerError */
+ 500: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'internal_server_error'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Internal Server Error'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ }
+ }
+ allV2OrganizationsBySlugWebhooks: {
+ parameters: {
+ query?: never
+ header?: never
+ path: {
+ /** @description Identifier of an endpoint (UUID v7). */
+ id: string
+ /** @description Organization slug */
+ slug: string
+ }
+ cookie?: never
+ }
+ requestBody?: never
+ responses: {
+ /** @description Deleted endpoint details */
+ 200: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ data: {
+ attributes: {
+ /**
+ * Format: date-time
+ * @description Timestamp of endpoint's creation.
+ */
+ created_at: string
+ /**
+ * Format: uuid
+ * @description ID of the user who created the endpoint.
+ */
+ created_by: string
+ /**
+ * @description Additional request headers to pass when performing HTTP request location defined by `url`. Both keys and values must be strings and a valid HTTP headers.
+ * @example {
+ * "Authorization": "Bearer example_token"
+ * }
+ */
+ custom_headers?: {
+ [key: string]: string
+ } | null
+ /** @description Optional description for the endpoint. */
+ description: string | null
+ /** @description Whether the endpoint is enabled or not - disabled endpoints won't emit any events. */
+ enabled: boolean
+ /**
+ * @description List of subscribed events for which to receive the webhook event.
+ * @example [
+ * {
+ * "type": "v1.project.paused"
+ * }
+ * ]
+ */
+ event_types: {
+ /**
+ * @description Webhook event type.
+ * @enum {string}
+ */
+ type:
+ | 'v1.project.paused'
+ | 'v1.project.created'
+ | 'v1.project.restored'
+ | 'v1.project.transferred'
+ | 'v1.project.removed'
+ | 'v1.project.restarted'
+ | 'v1.project.status.changed'
+ | 'v1.project.backup.started'
+ | 'v1.project.branch.created'
+ | 'v1.project.branch.updated'
+ | 'v1.project.branch.removed'
+ | 'v1.organization.member.invitation.created'
+ | 'v1.organization.member.invitation.canceled'
+ | 'v1.organization.member.added'
+ | 'v1.organization.member.removed'
+ | 'v1.organization.member.role.assigned'
+ | 'v1.organization.member.role.removed'
+ | 'v1.organization.member.role.updated'
+ | 'v1.organization.billing.plan.upgraded'
+ | 'v1.organization.billing.plan.downgraded'
+ | '*'
+ }[]
+ /**
+ * Format: uuid
+ * @description Identifier of an endpoint (UUID v7).
+ */
+ id: string
+ /**
+ * Format: uri
+ * @description Publicly available URL where to send the events, must use a domain and be resolvable to a non-reserved IP address.
+ * @example https://mydomain.com/path/to/handler
+ */
+ url: string
+ }
+ /**
+ * Format: uuid
+ * @description Identifier of an endpoint (UUID v7).
+ */
+ id: string
+ /**
+ * @description Resource type.
+ * @constant
+ */
+ type: 'endpoint'
+ }
+ }
+ }
+ }
+ /** @description Multiple error responses */
+ 400: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error:
+ | {
+ /** @constant */
+ code: 'bad_request.invalid_slug'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Bad Request: Invalid organization slug'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ | {
+ /** @constant */
+ code: 'bad_request.invalid_ref'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Bad Request: Invalid project ref'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description GenericUnauthorized */
+ 401: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'unauthorized'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Unauthorized'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description Multiple error responses */
+ 403: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error:
+ | {
+ /** @constant */
+ code: 'forbidden.permission_denied'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Forbidden: Permission denied'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ | {
+ /** @constant */
+ code: 'forbidden.access_disabled'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Forbidden: Access disabled'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description EndpointNotFound */
+ 404: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'not_found.endpoint'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Not Found: Endpoint not found'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description GenericRequestTimeout */
+ 408: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'request_timeout'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Request Timeout'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description GenericTooManyRequests */
+ 429: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'too_many_requests'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Too Many Requests'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description GenericInternalServerError */
+ 500: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'internal_server_error'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Internal Server Error'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ }
+ }
+ allV2OrganizationsBySlugWebhooks: {
+ parameters: {
+ query?: never
+ header?: never
+ path: {
+ /** @description Identifier of an endpoint (UUID v7). */
+ id: string
+ /** @description Organization slug */
+ slug: string
+ }
+ cookie?: never
+ }
+ requestBody: {
+ content: {
+ 'application/json': {
+ data: {
+ attributes: {
+ /**
+ * @description Additional request headers to pass when performing HTTP request location defined by `url`. Both keys and values must be strings and a valid HTTP headers.
+ * @example {
+ * "Authorization": "Bearer example_token"
+ * }
+ */
+ custom_headers?: {
+ [key: string]: string
+ } | null
+ /** @description Optional description for the endpoint. */
+ description?: string | null
+ /** @description Whether the endpoint is enabled or not - disabled endpoints won't emit any events. */
+ enabled?: boolean
+ /**
+ * @description List of subscribed events for which to receive the webhook event.
+ * @example [
+ * {
+ * "type": "v1.project.paused"
+ * }
+ * ]
+ */
+ event_types?: {
+ /**
+ * @description Webhook event type.
+ * @enum {string}
+ */
+ type:
+ | 'v1.project.paused'
+ | 'v1.project.created'
+ | 'v1.project.restored'
+ | 'v1.project.transferred'
+ | 'v1.project.removed'
+ | 'v1.project.restarted'
+ | 'v1.project.status.changed'
+ | 'v1.project.backup.started'
+ | 'v1.project.branch.created'
+ | 'v1.project.branch.updated'
+ | 'v1.project.branch.removed'
+ | 'v1.organization.member.invitation.created'
+ | 'v1.organization.member.invitation.canceled'
+ | 'v1.organization.member.added'
+ | 'v1.organization.member.removed'
+ | 'v1.organization.member.role.assigned'
+ | 'v1.organization.member.role.removed'
+ | 'v1.organization.member.role.updated'
+ | 'v1.organization.billing.plan.upgraded'
+ | 'v1.organization.billing.plan.downgraded'
+ | '*'
+ }[]
+ /** @description Secret key to use when signing. All events will be signed according to the [Standard Webhooks](https://www.standardwebhooks.com/) specification. */
+ signing_secret?: string
+ /**
+ * Format: uri
+ * @description Publicly available URL where to send the events, must use a domain and be resolvable to a non-reserved IP address.
+ * @example https://mydomain.com/path/to/handler
+ */
+ url?: string
+ }
+ /**
+ * @description Resource type.
+ * @constant
+ */
+ type: 'endpoint'
+ }
+ }
+ }
+ }
+ responses: {
+ /** @description Updated endpoint details */
+ 200: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ data: {
+ attributes: {
+ /**
+ * Format: date-time
+ * @description Timestamp of endpoint's creation.
+ */
+ created_at: string
+ /**
+ * Format: uuid
+ * @description ID of the user who created the endpoint.
+ */
+ created_by: string
+ /**
+ * @description Additional request headers to pass when performing HTTP request location defined by `url`. Both keys and values must be strings and a valid HTTP headers.
+ * @example {
+ * "Authorization": "Bearer example_token"
+ * }
+ */
+ custom_headers?: {
+ [key: string]: string
+ } | null
+ /** @description Optional description for the endpoint. */
+ description: string | null
+ /** @description Whether the endpoint is enabled or not - disabled endpoints won't emit any events. */
+ enabled: boolean
+ /**
+ * @description List of subscribed events for which to receive the webhook event.
+ * @example [
+ * {
+ * "type": "v1.project.paused"
+ * }
+ * ]
+ */
+ event_types: {
+ /**
+ * @description Webhook event type.
+ * @enum {string}
+ */
+ type:
+ | 'v1.project.paused'
+ | 'v1.project.created'
+ | 'v1.project.restored'
+ | 'v1.project.transferred'
+ | 'v1.project.removed'
+ | 'v1.project.restarted'
+ | 'v1.project.status.changed'
+ | 'v1.project.backup.started'
+ | 'v1.project.branch.created'
+ | 'v1.project.branch.updated'
+ | 'v1.project.branch.removed'
+ | 'v1.organization.member.invitation.created'
+ | 'v1.organization.member.invitation.canceled'
+ | 'v1.organization.member.added'
+ | 'v1.organization.member.removed'
+ | 'v1.organization.member.role.assigned'
+ | 'v1.organization.member.role.removed'
+ | 'v1.organization.member.role.updated'
+ | 'v1.organization.billing.plan.upgraded'
+ | 'v1.organization.billing.plan.downgraded'
+ | '*'
+ }[]
+ /**
+ * Format: uuid
+ * @description Identifier of an endpoint (UUID v7).
+ */
+ id: string
+ /**
+ * Format: uri
+ * @description Publicly available URL where to send the events, must use a domain and be resolvable to a non-reserved IP address.
+ * @example https://mydomain.com/path/to/handler
+ */
+ url: string
+ }
+ /**
+ * Format: uuid
+ * @description Identifier of an endpoint (UUID v7).
+ */
+ id: string
+ /**
+ * @description Resource type.
+ * @constant
+ */
+ type: 'endpoint'
+ }
+ }
+ }
+ }
+ /** @description Multiple error responses */
+ 400: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error:
+ | {
+ /** @constant */
+ code: 'bad_request.invalid_slug'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Bad Request: Invalid organization slug'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ | {
+ /** @constant */
+ code: 'bad_request.invalid_ref'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Bad Request: Invalid project ref'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description GenericUnauthorized */
+ 401: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'unauthorized'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Unauthorized'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description Multiple error responses */
+ 403: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error:
+ | {
+ /** @constant */
+ code: 'forbidden.permission_denied'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Forbidden: Permission denied'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ | {
+ /** @constant */
+ code: 'forbidden.access_disabled'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Forbidden: Access disabled'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description EndpointNotFound */
+ 404: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'not_found.endpoint'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Not Found: Endpoint not found'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description GenericRequestTimeout */
+ 408: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'request_timeout'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Request Timeout'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description GenericTooManyRequests */
+ 429: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'too_many_requests'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Too Many Requests'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description GenericInternalServerError */
+ 500: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'internal_server_error'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Internal Server Error'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ }
+ }
+ allV2OrganizationsBySlugWebhooks: {
+ parameters: {
+ query?: {
+ /** @description Cursor in cursor-based pagination to return up to `page[size]` records after (exclusive) the entry specified by this query param. */
+ 'page[after]'?: string
+ /** @description Cursor in cursor-based pagination to return up to `page[size]` records before (exclusive) the entry specified by this query param. */
+ 'page[before]'?: string
+ /** @description Up to how many records to return. */
+ 'page[size]'?: string
+ }
+ header?: never
+ path: {
+ /** @description Identifier of an endpoint (UUID v7). */
+ id: string
+ /** @description Organization slug */
+ slug: string
+ }
+ cookie?: never
+ }
+ requestBody?: never
+ responses: {
+ /** @description List of deliveries */
+ 200: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ data: {
+ attributes: {
+ /**
+ * Format: date-time
+ * @description Timestamp of the attempt.
+ */
+ attempt_timestamp: string
+ /**
+ * Format: uuid
+ * @description Identifier of the event, which triggered the delivery (UUID v7).
+ */
+ event_id: string
+ /**
+ * Format: uuid
+ * @description Identifier of a delivery (UUID v7).
+ */
+ id: string
+ response_body:
+ | (
+ | {
+ [key: string]: string
+ }
+ | string
+ )
+ | null
+ /** @description HTTP status code of the response, `0` if unavailable. */
+ response_code: number
+ /** @description HTTP headers of the response, `{}` if unavailable. */
+ response_headers: {
+ [key: string]: string
+ } | null
+ /**
+ * @description Status of the delivery attempt.
+ * @enum {string}
+ */
+ status: 'pending' | 'success' | 'failure' | 'skipped'
+ }
+ /**
+ * Format: uuid
+ * @description Identifier of a delivery (UUID v7).
+ */
+ id: string
+ /**
+ * @description Resource type.
+ * @constant
+ */
+ type: 'delivery'
+ }[]
+ links: {
+ /**
+ * @description URL path to the first page if available.
+ * @example /v2/organizations/slug/webhooks/endpoints/{id}/deliveries?page[size]=10
+ */
+ first?: string | null
+ /**
+ * @description URL path to the last page if available.
+ * @example /v2/organizations/slug/webhooks/endpoints/{id}/deliveries?page[size]=10&page[after]=019adf7d-4513-71ba-b264-21900edb4295
+ */
+ last?: string | null
+ /**
+ * @description URL path to the next page.
+ * @example /v2/organizations/slug/webhooks/endpoints/{id}/deliveries?page[size]=10&page[after]=019adf7d-4513-7062-b292-78b86cc470a4
+ */
+ next: string | null
+ /**
+ * @description URL path to the previous page.
+ * @example /v2/organizations/slug/webhooks/endpoints/{id}/deliveries?page[size]=10&page[before]=019adf7d-4513-74c5-bb9a-f1bc0f7a95d7
+ */
+ prev: string | null
+ }
+ }
+ }
+ }
+ /** @description Multiple error responses */
+ 400: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error:
+ | {
+ /** @constant */
+ code: 'bad_request.invalid_slug'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Bad Request: Invalid organization slug'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ | {
+ /** @constant */
+ code: 'bad_request.invalid_ref'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Bad Request: Invalid project ref'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description GenericUnauthorized */
+ 401: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'unauthorized'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Unauthorized'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description Multiple error responses */
+ 403: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error:
+ | {
+ /** @constant */
+ code: 'forbidden.permission_denied'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Forbidden: Permission denied'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ | {
+ /** @constant */
+ code: 'forbidden.access_disabled'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Forbidden: Access disabled'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description EndpointNotFound */
+ 404: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'not_found.endpoint'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Not Found: Endpoint not found'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description GenericRequestTimeout */
+ 408: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'request_timeout'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Request Timeout'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description GenericTooManyRequests */
+ 429: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'too_many_requests'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Too Many Requests'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description GenericInternalServerError */
+ 500: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'internal_server_error'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Internal Server Error'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ }
+ }
+ allV2OrganizationsBySlugWebhooks: {
+ parameters: {
+ query?: never
+ header?: never
+ path: {
+ /** @description Identifier of an endpoint (UUID v7). */
+ id: string
+ /** @description Organization slug */
+ slug: string
+ }
+ cookie?: never
+ }
+ requestBody: {
+ content: {
+ 'application/json': {
+ data?: {
+ attributes: {
+ /**
+ * @description Webhook event type.
+ * @enum {string}
+ */
+ type:
+ | 'v1.project.paused'
+ | 'v1.project.created'
+ | 'v1.project.restored'
+ | 'v1.project.transferred'
+ | 'v1.project.removed'
+ | 'v1.project.restarted'
+ | 'v1.project.status.changed'
+ | 'v1.project.backup.started'
+ | 'v1.project.branch.created'
+ | 'v1.project.branch.updated'
+ | 'v1.project.branch.removed'
+ | 'v1.organization.member.invitation.created'
+ | 'v1.organization.member.invitation.canceled'
+ | 'v1.organization.member.added'
+ | 'v1.organization.member.removed'
+ | 'v1.organization.member.role.assigned'
+ | 'v1.organization.member.role.removed'
+ | 'v1.organization.member.role.updated'
+ | 'v1.organization.billing.plan.upgraded'
+ | 'v1.organization.billing.plan.downgraded'
+ | 'project.v1.paused'
+ | 'project.v1.created'
+ | 'project.v1.restored'
+ | 'project.v1.transferred'
+ | 'project.v1.removed'
+ | 'project.v1.restarted'
+ | 'project.v1.status.changed'
+ | 'project.v1.backup.started'
+ | 'project.v1.branch.created'
+ | 'project.v1.branch.updated'
+ | 'project.v1.branch.removed'
+ | 'organization.v1.member.invitation.created'
+ | 'organization.v1.member.invitation.canceled'
+ | 'organization.v1.member.added'
+ | 'organization.v1.member.removed'
+ | 'organization.v1.member.role.assigned'
+ | 'organization.v1.member.role.removed'
+ | 'organization.v1.member.role.updated'
+ | 'organization.v1.billing.plan.upgraded'
+ | 'organization.v1.billing.plan.downgraded'
+ | 'project.v1.branch.deleted'
+ }
+ /**
+ * @description Resource type.
+ * @constant
+ */
+ type: 'event'
+ }
+ }
+ }
+ }
+ responses: {
+ /** @description Event published */
+ 201: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ data: {
+ id: string
+ /**
+ * @description Resource type.
+ * @constant
+ */
+ type: 'ingress'
+ }
+ }
+ }
+ }
+ /** @description Multiple error responses */
+ 400: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error:
+ | {
+ /** @constant */
+ code: 'bad_request.endpoint.test.disabled'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Bad Request: Endpoint is disabled'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ | {
+ /** @constant */
+ code: 'bad_request.endpoint.test.wrong_event_type'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Bad Request: Provided event type is not subscribed to by the endpoint'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ | {
+ /** @constant */
+ code: 'bad_request.invalid_slug'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Bad Request: Invalid organization slug'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ | {
+ /** @constant */
+ code: 'bad_request.invalid_ref'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Bad Request: Invalid project ref'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description GenericUnauthorized */
+ 401: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'unauthorized'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Unauthorized'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description Multiple error responses */
+ 403: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error:
+ | {
+ /** @constant */
+ code: 'forbidden.permission_denied'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Forbidden: Permission denied'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ | {
+ /** @constant */
+ code: 'forbidden.access_disabled'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Forbidden: Access disabled'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description EndpointNotFound */
+ 404: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'not_found.endpoint'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Not Found: Endpoint not found'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description GenericRequestTimeout */
+ 408: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'request_timeout'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Request Timeout'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description GenericTooManyRequests */
+ 429: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'too_many_requests'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Too Many Requests'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description GenericInternalServerError */
+ 500: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'internal_server_error'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Internal Server Error'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ }
+ }
+ 'v2-list-log-drains': {
+ parameters: {
+ query?: never
+ header?: never
+ path: {
+ /** @description Project ref */
+ ref: string
+ }
+ cookie?: never
+ }
+ requestBody?: never
+ responses: {
+ 200: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['ListLogDrainsResponse']
+ }
+ }
+ /** @description Unauthorized */
+ 401: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['ErrorResponseBody']
+ }
+ }
+ /** @description Forbidden action */
+ 403: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['ErrorResponseBody']
+ }
+ }
+ /** @description Rate limit exceeded */
+ 429: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['ErrorResponseBody']
+ }
+ }
+ /** @description Failed to fetch log drains */
+ 500: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['ErrorResponseBody']
+ }
+ }
+ }
+ }
+ 'v2-create-log-drain': {
+ parameters: {
+ query?: never
+ header?: never
+ path: {
+ /** @description Project ref */
+ ref: string
+ }
+ cookie?: never
+ }
+ requestBody: {
+ content: {
+ 'application/json': components['schemas']['CreateLogDrainRequestOpenApi']
+ }
+ }
+ responses: {
+ 201: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['LogDrainResponse']
+ }
+ }
+ /** @description Unauthorized */
+ 401: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['ErrorResponseBody']
+ }
+ }
+ /** @description This feature requires the Pro, Team, or Enterprise organization plan. */
+ 402: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['ErrorResponseBody']
+ }
+ }
+ /** @description Forbidden action */
+ 403: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['ErrorResponseBody']
+ }
+ }
+ /** @description Rate limit exceeded */
+ 429: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['ErrorResponseBody']
+ }
+ }
+ /** @description Failed to create a log drain */
+ 500: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['ErrorResponseBody']
+ }
+ }
+ }
+ }
+ 'v2-update-log-drain': {
+ parameters: {
+ query?: never
+ header?: never
+ path: {
+ /** @description Log drains identifier */
+ id: string
+ /** @description Project ref */
+ ref: string
+ }
+ cookie?: never
+ }
+ requestBody: {
+ content: {
+ 'application/json': components['schemas']['UpdateLogDrainRequestOpenApi']
+ }
+ }
+ responses: {
+ 200: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['LogDrainResponse']
+ }
+ }
+ /** @description Unauthorized */
+ 401: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['ErrorResponseBody']
+ }
+ }
+ /** @description Forbidden action */
+ 403: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['ErrorResponseBody']
+ }
+ }
+ /** @description Rate limit exceeded */
+ 429: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['ErrorResponseBody']
+ }
+ }
+ /** @description Failed to update log drain */
+ 500: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['ErrorResponseBody']
+ }
+ }
+ }
+ }
+ 'v2-delete-log-drain': {
+ parameters: {
+ query?: never
+ header?: never
+ path: {
+ /** @description Log drains identifier */
+ id: string
+ /** @description Project ref */
+ ref: string
+ }
+ cookie?: never
+ }
+ requestBody?: never
+ responses: {
+ 204: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ /** @description Unauthorized */
+ 401: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['ErrorResponseBody']
+ }
+ }
+ /** @description Forbidden action */
+ 403: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['ErrorResponseBody']
+ }
+ }
+ /** @description Rate limit exceeded */
+ 429: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['ErrorResponseBody']
+ }
+ }
+ /** @description Failed to delete a log drain */
+ 500: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['ErrorResponseBody']
+ }
+ }
+ }
+ }
+ 'v2-get-project-config': {
+ parameters: {
+ query?: never
+ header?: never
+ path: {
+ /** @description Project ref */
+ ref: string
+ }
+ cookie?: never
+ }
+ requestBody?: never
+ responses: {
+ 200: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['V2ProjectConfigResponse']
+ }
+ }
+ /** @description Unauthorized */
+ 401: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['ErrorResponseBody']
+ }
+ }
+ /** @description Forbidden action */
+ 403: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['ErrorResponseBody']
+ }
+ }
+ /** @description Rate limit exceeded */
+ 429: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['ErrorResponseBody']
+ }
+ }
+ }
+ }
+ 'v2-list-private-link-associations': {
+ parameters: {
+ query?: never
+ header?: never
+ path: {
+ /** @description Project ref */
+ ref: string
+ }
+ cookie?: never
+ }
+ requestBody?: never
+ responses: {
+ 200: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['V2ListPrivateLinkAssociationsResponse']
+ }
+ }
+ /** @description Unauthorized */
+ 401: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['ErrorResponseBody']
+ }
+ }
+ /** @description Forbidden action */
+ 403: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['ErrorResponseBody']
+ }
+ }
+ /** @description Rate limit exceeded */
+ 429: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['ErrorResponseBody']
+ }
+ }
+ /** @description Failed to retrieve AWS accounts for project */
+ 500: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['ErrorResponseBody']
+ }
+ }
+ }
+ }
+ 'v2-create-private-link-association': {
+ parameters: {
+ query?: never
+ header?: never
+ path: {
+ /** @description Project ref */
+ ref: string
+ }
+ cookie?: never
+ }
+ requestBody: {
+ content: {
+ 'application/json': components['schemas']['V2CreatePrivateLinkAssociationRequest']
+ }
+ }
+ responses: {
+ 201: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['V2PrivateLinkAssociationResponse']
+ }
+ }
+ /** @description Unauthorized */
+ 401: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['ErrorResponseBody']
+ }
+ }
+ /** @description This feature requires the Team, or Enterprise organization plan. */
+ 402: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['ErrorResponseBody']
+ }
+ }
+ /** @description Forbidden action */
+ 403: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['ErrorResponseBody']
+ }
+ }
+ /** @description Rate limit exceeded */
+ 429: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['ErrorResponseBody']
+ }
+ }
+ /** @description Failed to add AWS account to PrivateLink share */
+ 500: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['ErrorResponseBody']
+ }
+ }
+ }
+ }
+ 'v2-delete-private-link-association': {
+ parameters: {
+ query?: never
+ header?: never
+ path: {
+ /** @description AWS account ID used in PrivateLink association */
+ aws_account_id: string
+ /** @description Project ref */
+ ref: string
+ }
+ cookie?: never
+ }
+ requestBody?: never
+ responses: {
+ 204: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ /** @description Unauthorized */
+ 401: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['ErrorResponseBody']
+ }
+ }
+ /** @description Forbidden action */
+ 403: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['ErrorResponseBody']
+ }
+ }
+ /** @description Rate limit exceeded */
+ 429: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['ErrorResponseBody']
+ }
+ }
+ /** @description Failed to remove AWS account from PrivateLink share */
+ 500: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['ErrorResponseBody']
+ }
+ }
+ }
+ }
+ 'v2-delete-private-link-association-for-database': {
+ parameters: {
+ query?: never
+ header?: never
+ path: {
+ /** @description AWS account ID used in PrivateLink association */
+ aws_account_id: string
+ /** @description Identifier of the read replica this PrivateLink association targets */
+ database_identifier: string
+ /** @description Project ref */
+ ref: string
+ }
+ cookie?: never
+ }
+ requestBody?: never
+ responses: {
+ 204: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ /** @description Unauthorized */
+ 401: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['ErrorResponseBody']
+ }
+ }
+ /** @description Forbidden action */
+ 403: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['ErrorResponseBody']
+ }
+ }
+ /** @description Rate limit exceeded */
+ 429: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['ErrorResponseBody']
+ }
+ }
+ /** @description Failed to remove AWS account from PrivateLink share */
+ 500: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['ErrorResponseBody']
+ }
+ }
+ }
+ }
+ 'v2-transfer-a-project': {
+ parameters: {
+ query?: never
+ header?: never
+ path: {
+ /** @description Project ref */
+ ref: string
+ }
+ cookie?: never
+ }
+ requestBody: {
+ content: {
+ 'application/json': components['schemas']['V2TransferProjectBody']
+ }
+ }
+ responses: {
+ 200: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ /** @description Unauthorized */
+ 401: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['ErrorResponseBody']
+ }
+ }
+ /** @description Forbidden action */
+ 403: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['ErrorResponseBody']
+ }
+ }
+ /** @description Rate limit exceeded */
+ 429: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['ErrorResponseBody']
+ }
+ }
+ }
+ }
+ 'v2-preview-a-project-transfer': {
+ parameters: {
+ query?: never
+ header?: never
+ path: {
+ /** @description Project ref */
+ ref: string
+ }
+ cookie?: never
+ }
+ requestBody: {
+ content: {
+ 'application/json': components['schemas']['V2TransferProjectBody']
+ }
+ }
+ responses: {
+ 200: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['V2PreviewProjectTransferResponse']
+ }
+ }
+ /** @description Unauthorized */
+ 401: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['ErrorResponseBody']
+ }
+ }
+ /** @description Forbidden action */
+ 403: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['ErrorResponseBody']
+ }
+ }
+ /** @description Rate limit exceeded */
+ 429: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['ErrorResponseBody']
+ }
+ }
+ }
+ }
+ allV2ProjectsByRefWebhooks: {
+ parameters: {
+ query?: never
+ header?: never
+ path: {
+ /** @description Identifier of a delivery (UUID v7). */
+ id: string
+ /** @description Project ref */
+ ref: string
+ }
+ cookie?: never
+ }
+ requestBody?: never
+ responses: {
+ /** @description Delivery details */
+ 200: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ data: {
+ attributes: {
+ /**
+ * Format: date-time
+ * @description Timestamp of the attempt.
+ */
+ attempt_timestamp: string
+ event: {
+ /** @description Final data sent to the consumer. */
+ payload: {
+ /**
+ * @description Organization slug
+ * @example tsrqponmlkjihgfedcba
+ */
+ organization_slug: string
+ project_ref: string | null
+ } & {
+ [key: string]: unknown
+ }
+ /**
+ * Format: date-time
+ * @description Timestamp of event publication.
+ */
+ timestamp: string
+ /**
+ * @description Webhook event type.
+ * @enum {string}
+ */
+ type:
+ | 'v1.project.paused'
+ | 'v1.project.created'
+ | 'v1.project.restored'
+ | 'v1.project.transferred'
+ | 'v1.project.removed'
+ | 'v1.project.restarted'
+ | 'v1.project.status.changed'
+ | 'v1.project.backup.started'
+ | 'v1.project.branch.created'
+ | 'v1.project.branch.updated'
+ | 'v1.project.branch.removed'
+ | 'v1.organization.member.invitation.created'
+ | 'v1.organization.member.invitation.canceled'
+ | 'v1.organization.member.added'
+ | 'v1.organization.member.removed'
+ | 'v1.organization.member.role.assigned'
+ | 'v1.organization.member.role.removed'
+ | 'v1.organization.member.role.updated'
+ | 'v1.organization.billing.plan.upgraded'
+ | 'v1.organization.billing.plan.downgraded'
+ | 'project.v1.paused'
+ | 'project.v1.created'
+ | 'project.v1.restored'
+ | 'project.v1.transferred'
+ | 'project.v1.removed'
+ | 'project.v1.restarted'
+ | 'project.v1.status.changed'
+ | 'project.v1.backup.started'
+ | 'project.v1.branch.created'
+ | 'project.v1.branch.updated'
+ | 'project.v1.branch.removed'
+ | 'organization.v1.member.invitation.created'
+ | 'organization.v1.member.invitation.canceled'
+ | 'organization.v1.member.added'
+ | 'organization.v1.member.removed'
+ | 'organization.v1.member.role.assigned'
+ | 'organization.v1.member.role.removed'
+ | 'organization.v1.member.role.updated'
+ | 'organization.v1.billing.plan.upgraded'
+ | 'organization.v1.billing.plan.downgraded'
+ | 'project.v1.branch.deleted'
+ }
+ /**
+ * Format: uuid
+ * @description Identifier of the event, which triggered the delivery (UUID v7).
+ */
+ event_id: string
+ /**
+ * Format: uuid
+ * @description Identifier of a delivery (UUID v7).
+ */
+ id: string
+ response_body:
+ | (
+ | {
+ [key: string]: string
+ }
+ | string
+ )
+ | null
+ /** @description HTTP status code of the response, `0` if unavailable. */
+ response_code: number
+ /** @description HTTP headers of the response, `{}` if unavailable. */
+ response_headers: {
+ [key: string]: string
+ } | null
+ /**
+ * @description Status of the delivery attempt.
+ * @enum {string}
+ */
+ status: 'pending' | 'success' | 'failure' | 'skipped'
+ }
+ /**
+ * Format: uuid
+ * @description Identifier of a delivery (UUID v7).
+ */
+ id: string
+ /**
+ * @description Resource type.
+ * @constant
+ */
+ type: 'delivery'
+ }
+ }
+ }
+ }
+ /** @description Multiple error responses */
+ 400: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error:
+ | {
+ /** @constant */
+ code: 'bad_request.invalid_slug'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Bad Request: Invalid organization slug'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ | {
+ /** @constant */
+ code: 'bad_request.invalid_ref'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Bad Request: Invalid project ref'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description GenericUnauthorized */
+ 401: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'unauthorized'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Unauthorized'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description Multiple error responses */
+ 403: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error:
+ | {
+ /** @constant */
+ code: 'forbidden.permission_denied'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Forbidden: Permission denied'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ | {
+ /** @constant */
+ code: 'forbidden.access_disabled'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Forbidden: Access disabled'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description DeliveryNotFound */
+ 404: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'not_found.delivery'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Not Found: Delivery not found'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description GenericRequestTimeout */
+ 408: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'request_timeout'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Request Timeout'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description GenericTooManyRequests */
+ 429: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'too_many_requests'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Too Many Requests'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description GenericInternalServerError */
+ 500: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'internal_server_error'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Internal Server Error'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ }
+ }
+ allV2ProjectsByRefWebhooks: {
+ parameters: {
+ query?: never
+ header?: never
+ path: {
+ /** @description Identifier of a delivery (UUID v7). */
+ id: string
+ /** @description Project ref */
+ ref: string
+ }
+ cookie?: never
+ }
+ requestBody?: never
+ responses: {
+ /** @description Delivery details */
+ 201: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ data: {
+ id: string
+ /**
+ * @description Resource type.
+ * @constant
+ */
+ type: 'ingress'
+ }
+ }
+ }
+ }
+ /** @description Multiple error responses */
+ 400: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error:
+ | {
+ /** @constant */
+ code: 'bad_request.invalid_slug'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Bad Request: Invalid organization slug'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ | {
+ /** @constant */
+ code: 'bad_request.invalid_ref'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Bad Request: Invalid project ref'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description GenericUnauthorized */
+ 401: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'unauthorized'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Unauthorized'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description Multiple error responses */
+ 403: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error:
+ | {
+ /** @constant */
+ code: 'forbidden.permission_denied'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Forbidden: Permission denied'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ | {
+ /** @constant */
+ code: 'forbidden.access_disabled'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Forbidden: Access disabled'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description DeliveryNotFound */
+ 404: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'not_found.delivery'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Not Found: Delivery not found'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description GenericRequestTimeout */
+ 408: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'request_timeout'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Request Timeout'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description GenericTooManyRequests */
+ 429: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'too_many_requests'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Too Many Requests'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description GenericInternalServerError */
+ 500: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'internal_server_error'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Internal Server Error'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ }
+ }
+ allV2ProjectsByRefWebhooks: {
+ parameters: {
+ query?: {
+ /** @description Up to how many records to return. */
+ 'page[limit]'?: string
+ /** @description Offset for offset-based pagination.
+ *
+ * Offset should be dividable by `page[limit]` without a reminder (`offset % limit === 0`), otherwise it will cause weird behavior when used on a frontend. */
+ 'page[offset]'?: string
+ }
+ header?: never
+ path: {
+ /** @description Project ref */
+ ref: string
+ }
+ cookie?: never
+ }
+ requestBody?: never
+ responses: {
+ /** @description Collection of endpoints */
+ 200: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ data: {
+ attributes: {
+ /**
+ * Format: date-time
+ * @description Timestamp of endpoint's creation.
+ */
+ created_at: string
+ /**
+ * Format: uuid
+ * @description ID of the user who created the endpoint.
+ */
+ created_by: string
+ /**
+ * @description Additional request headers to pass when performing HTTP request location defined by `url`. Both keys and values must be strings and a valid HTTP headers.
+ * @example {
+ * "Authorization": "Bearer example_token"
+ * }
+ */
+ custom_headers?: {
+ [key: string]: string
+ } | null
+ /** @description Optional description for the endpoint. */
+ description: string | null
+ /** @description Whether the endpoint is enabled or not - disabled endpoints won't emit any events. */
+ enabled: boolean
+ /**
+ * @description List of subscribed events for which to receive the webhook event.
+ * @example [
+ * {
+ * "type": "v1.project.paused"
+ * }
+ * ]
+ */
+ event_types: {
+ /**
+ * @description Webhook event type.
+ * @enum {string}
+ */
+ type:
+ | 'v1.project.paused'
+ | 'v1.project.created'
+ | 'v1.project.restored'
+ | 'v1.project.transferred'
+ | 'v1.project.removed'
+ | 'v1.project.restarted'
+ | 'v1.project.status.changed'
+ | 'v1.project.backup.started'
+ | 'v1.project.branch.created'
+ | 'v1.project.branch.updated'
+ | 'v1.project.branch.removed'
+ | 'v1.organization.member.invitation.created'
+ | 'v1.organization.member.invitation.canceled'
+ | 'v1.organization.member.added'
+ | 'v1.organization.member.removed'
+ | 'v1.organization.member.role.assigned'
+ | 'v1.organization.member.role.removed'
+ | 'v1.organization.member.role.updated'
+ | 'v1.organization.billing.plan.upgraded'
+ | 'v1.organization.billing.plan.downgraded'
+ | '*'
+ }[]
+ /**
+ * Format: uuid
+ * @description Identifier of an endpoint (UUID v7).
+ */
+ id: string
+ /**
+ * Format: uri
+ * @description Publicly available URL where to send the events, must use a domain and be resolvable to a non-reserved IP address.
+ * @example https://mydomain.com/path/to/handler
+ */
+ url: string
+ }
+ /**
+ * Format: uuid
+ * @description Identifier of an endpoint (UUID v7).
+ */
+ id: string
+ /**
+ * @description Resource type.
+ * @constant
+ */
+ type: 'endpoint'
+ }[]
+ links: {
+ /**
+ * @description URL path to the first page if available.
+ * @example /v2/organization/slug/webhooks/endpoints?page[limit]=10&page[offset]=0
+ */
+ first?: string | null
+ /**
+ * @description URL path to the last page if available.
+ * @example /v2/organization/slug/webhooks/endpoints?page[limit]=10&page[offset]=30
+ */
+ last?: string | null
+ /**
+ * @description URL path to the next page.
+ * @example /v2/organization/slug/webhooks/endpoints?page[limit]=10&page[offset]=20
+ */
+ next: string | null
+ /**
+ * @description URL path to the previous page.
+ * @example /v2/organization/slug/webhooks/endpoints?page[limit]=10&page[offset]=0
+ */
+ prev: string | null
+ }
+ }
+ }
+ }
+ /** @description Multiple error responses */
+ 400: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error:
+ | {
+ /** @constant */
+ code: 'bad_request.invalid_slug'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Bad Request: Invalid organization slug'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ | {
+ /** @constant */
+ code: 'bad_request.invalid_ref'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Bad Request: Invalid project ref'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description GenericUnauthorized */
+ 401: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'unauthorized'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Unauthorized'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description Multiple error responses */
+ 403: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error:
+ | {
+ /** @constant */
+ code: 'forbidden.permission_denied'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Forbidden: Permission denied'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ | {
+ /** @constant */
+ code: 'forbidden.access_disabled'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Forbidden: Access disabled'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description GenericRequestTimeout */
+ 408: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'request_timeout'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Request Timeout'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description GenericTooManyRequests */
+ 429: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'too_many_requests'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Too Many Requests'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description GenericInternalServerError */
+ 500: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'internal_server_error'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Internal Server Error'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ }
+ }
+ allV2ProjectsByRefWebhooks: {
+ parameters: {
+ query?: never
+ header?: never
+ path: {
+ /** @description Project ref */
+ ref: string
+ }
+ cookie?: never
+ }
+ requestBody: {
+ content: {
+ 'application/json': {
+ data: {
+ attributes: {
+ /**
+ * @description Additional request headers to pass when performing HTTP request location defined by `url`. Both keys and values must be strings and a valid HTTP headers.
+ * @example {
+ * "Authorization": "Bearer example_token"
+ * }
+ */
+ custom_headers?: {
+ [key: string]: string
+ } | null
+ /** @description Optional description for the endpoint. */
+ description?: string | null
+ /**
+ * @description Whether the endpoint is enabled or not - disabled endpoints won't emit any events.
+ * @default true
+ */
+ enabled?: boolean
+ /**
+ * @description List of subscribed events for which to receive the webhook event.
+ * @example [
+ * {
+ * "type": "v1.project.paused"
+ * }
+ * ]
+ */
+ event_types: {
+ /**
+ * @description Webhook event type.
+ * @enum {string}
+ */
+ type:
+ | 'v1.project.paused'
+ | 'v1.project.created'
+ | 'v1.project.restored'
+ | 'v1.project.transferred'
+ | 'v1.project.removed'
+ | 'v1.project.restarted'
+ | 'v1.project.status.changed'
+ | 'v1.project.backup.started'
+ | 'v1.project.branch.created'
+ | 'v1.project.branch.updated'
+ | 'v1.project.branch.removed'
+ | 'v1.organization.member.invitation.created'
+ | 'v1.organization.member.invitation.canceled'
+ | 'v1.organization.member.added'
+ | 'v1.organization.member.removed'
+ | 'v1.organization.member.role.assigned'
+ | 'v1.organization.member.role.removed'
+ | 'v1.organization.member.role.updated'
+ | 'v1.organization.billing.plan.upgraded'
+ | 'v1.organization.billing.plan.downgraded'
+ | '*'
+ }[]
+ /** @description Secret key to use when signing. All events will be signed according to the [Standard Webhooks](https://www.standardwebhooks.com/) specification. */
+ signing_secret: string
+ /**
+ * Format: uri
+ * @description Publicly available URL where to send the events, must use a domain and be resolvable to a non-reserved IP address.
+ * @example https://mydomain.com/path/to/handler
+ */
+ url: string
+ }
+ /**
+ * @description Resource type.
+ * @constant
+ */
+ type: 'endpoint'
+ }
+ }
+ }
+ }
+ responses: {
+ /** @description Created endpoint */
+ 201: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ data: {
+ attributes: {
+ /**
+ * Format: date-time
+ * @description Timestamp of endpoint's creation.
+ */
+ created_at: string
+ /**
+ * Format: uuid
+ * @description ID of the user who created the endpoint.
+ */
+ created_by: string
+ /**
+ * @description Additional request headers to pass when performing HTTP request location defined by `url`. Both keys and values must be strings and a valid HTTP headers.
+ * @example {
+ * "Authorization": "Bearer example_token"
+ * }
+ */
+ custom_headers?: {
+ [key: string]: string
+ } | null
+ /** @description Optional description for the endpoint. */
+ description: string | null
+ /** @description Whether the endpoint is enabled or not - disabled endpoints won't emit any events. */
+ enabled: boolean
+ /**
+ * @description List of subscribed events for which to receive the webhook event.
+ * @example [
+ * {
+ * "type": "v1.project.paused"
+ * }
+ * ]
+ */
+ event_types: {
+ /**
+ * @description Webhook event type.
+ * @enum {string}
+ */
+ type:
+ | 'v1.project.paused'
+ | 'v1.project.created'
+ | 'v1.project.restored'
+ | 'v1.project.transferred'
+ | 'v1.project.removed'
+ | 'v1.project.restarted'
+ | 'v1.project.status.changed'
+ | 'v1.project.backup.started'
+ | 'v1.project.branch.created'
+ | 'v1.project.branch.updated'
+ | 'v1.project.branch.removed'
+ | 'v1.organization.member.invitation.created'
+ | 'v1.organization.member.invitation.canceled'
+ | 'v1.organization.member.added'
+ | 'v1.organization.member.removed'
+ | 'v1.organization.member.role.assigned'
+ | 'v1.organization.member.role.removed'
+ | 'v1.organization.member.role.updated'
+ | 'v1.organization.billing.plan.upgraded'
+ | 'v1.organization.billing.plan.downgraded'
+ | '*'
+ }[]
+ /**
+ * Format: uuid
+ * @description Identifier of an endpoint (UUID v7).
+ */
+ id: string
+ /**
+ * Format: uri
+ * @description Publicly available URL where to send the events, must use a domain and be resolvable to a non-reserved IP address.
+ * @example https://mydomain.com/path/to/handler
+ */
+ url: string
+ }
+ /**
+ * Format: uuid
+ * @description Identifier of an endpoint (UUID v7).
+ */
+ id: string
+ /**
+ * @description Resource type.
+ * @constant
+ */
+ type: 'endpoint'
+ }
+ }
+ }
+ }
+ /** @description Multiple error responses */
+ 400: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error:
+ | {
+ /** @constant */
+ code: 'bad_request.invalid_slug'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Bad Request: Invalid organization slug'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ | {
+ /** @constant */
+ code: 'bad_request.invalid_ref'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Bad Request: Invalid project ref'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description GenericUnauthorized */
+ 401: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'unauthorized'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Unauthorized'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description Multiple error responses */
+ 403: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error:
+ | {
+ /** @constant */
+ code: 'forbidden.permission_denied'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Forbidden: Permission denied'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ | {
+ /** @constant */
+ code: 'forbidden.access_disabled'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Forbidden: Access disabled'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description GenericRequestTimeout */
+ 408: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'request_timeout'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Request Timeout'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description GenericTooManyRequests */
+ 429: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'too_many_requests'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Too Many Requests'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description GenericInternalServerError */
+ 500: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'internal_server_error'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Internal Server Error'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ }
+ }
+ allV2ProjectsByRefWebhooks: {
+ parameters: {
+ query?: never
+ header?: never
+ path: {
+ /** @description Project ref */
+ ref: string
+ }
+ cookie?: never
+ }
+ requestBody?: never
+ responses: {
+ /** @description Deleted endpoints */
+ 200: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ data: {
+ attributes: {
+ /**
+ * Format: date-time
+ * @description Timestamp of endpoint's creation.
+ */
+ created_at: string
+ /**
+ * Format: uuid
+ * @description ID of the user who created the endpoint.
+ */
+ created_by: string
+ /**
+ * @description Additional request headers to pass when performing HTTP request location defined by `url`. Both keys and values must be strings and a valid HTTP headers.
+ * @example {
+ * "Authorization": "Bearer example_token"
+ * }
+ */
+ custom_headers?: {
+ [key: string]: string
+ } | null
+ /** @description Optional description for the endpoint. */
+ description: string | null
+ /** @description Whether the endpoint is enabled or not - disabled endpoints won't emit any events. */
+ enabled: boolean
+ /**
+ * @description List of subscribed events for which to receive the webhook event.
+ * @example [
+ * {
+ * "type": "v1.project.paused"
+ * }
+ * ]
+ */
+ event_types: {
+ /**
+ * @description Webhook event type.
+ * @enum {string}
+ */
+ type:
+ | 'v1.project.paused'
+ | 'v1.project.created'
+ | 'v1.project.restored'
+ | 'v1.project.transferred'
+ | 'v1.project.removed'
+ | 'v1.project.restarted'
+ | 'v1.project.status.changed'
+ | 'v1.project.backup.started'
+ | 'v1.project.branch.created'
+ | 'v1.project.branch.updated'
+ | 'v1.project.branch.removed'
+ | 'v1.organization.member.invitation.created'
+ | 'v1.organization.member.invitation.canceled'
+ | 'v1.organization.member.added'
+ | 'v1.organization.member.removed'
+ | 'v1.organization.member.role.assigned'
+ | 'v1.organization.member.role.removed'
+ | 'v1.organization.member.role.updated'
+ | 'v1.organization.billing.plan.upgraded'
+ | 'v1.organization.billing.plan.downgraded'
+ | '*'
+ }[]
+ /**
+ * Format: uuid
+ * @description Identifier of an endpoint (UUID v7).
+ */
+ id: string
+ /**
+ * Format: uri
+ * @description Publicly available URL where to send the events, must use a domain and be resolvable to a non-reserved IP address.
+ * @example https://mydomain.com/path/to/handler
+ */
+ url: string
+ }
+ /**
+ * Format: uuid
+ * @description Identifier of an endpoint (UUID v7).
+ */
+ id: string
+ /**
+ * @description Resource type.
+ * @constant
+ */
+ type: 'endpoint'
+ }[]
+ }
+ }
+ }
+ /** @description Multiple error responses */
+ 400: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error:
+ | {
+ /** @constant */
+ code: 'bad_request.invalid_slug'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Bad Request: Invalid organization slug'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ | {
+ /** @constant */
+ code: 'bad_request.invalid_ref'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Bad Request: Invalid project ref'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description GenericUnauthorized */
+ 401: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'unauthorized'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Unauthorized'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description Multiple error responses */
+ 403: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error:
+ | {
+ /** @constant */
+ code: 'forbidden.permission_denied'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Forbidden: Permission denied'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ | {
+ /** @constant */
+ code: 'forbidden.access_disabled'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Forbidden: Access disabled'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description GenericRequestTimeout */
+ 408: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'request_timeout'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Request Timeout'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description GenericTooManyRequests */
+ 429: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'too_many_requests'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Too Many Requests'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description GenericInternalServerError */
+ 500: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'internal_server_error'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Internal Server Error'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ }
+ }
+ allV2ProjectsByRefWebhooks: {
+ parameters: {
+ query?: never
+ header?: never
+ path: {
+ /** @description Identifier of an endpoint (UUID v7). */
+ id: string
+ /** @description Project ref */
+ ref: string
+ }
+ cookie?: never
+ }
+ requestBody?: never
+ responses: {
+ /** @description Endpoint details */
+ 200: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ data: {
+ attributes: {
+ /**
+ * Format: date-time
+ * @description Timestamp of endpoint's creation.
+ */
+ created_at: string
+ /**
+ * Format: uuid
+ * @description ID of the user who created the endpoint.
+ */
+ created_by: string
+ /**
+ * @description Additional request headers to pass when performing HTTP request location defined by `url`. Both keys and values must be strings and a valid HTTP headers.
+ * @example {
+ * "Authorization": "Bearer example_token"
+ * }
+ */
+ custom_headers?: {
+ [key: string]: string
+ } | null
+ /** @description Optional description for the endpoint. */
+ description: string | null
+ /** @description Whether the endpoint is enabled or not - disabled endpoints won't emit any events. */
+ enabled: boolean
+ /**
+ * @description List of subscribed events for which to receive the webhook event.
+ * @example [
+ * {
+ * "type": "v1.project.paused"
+ * }
+ * ]
+ */
+ event_types: {
+ /**
+ * @description Webhook event type.
+ * @enum {string}
+ */
+ type:
+ | 'v1.project.paused'
+ | 'v1.project.created'
+ | 'v1.project.restored'
+ | 'v1.project.transferred'
+ | 'v1.project.removed'
+ | 'v1.project.restarted'
+ | 'v1.project.status.changed'
+ | 'v1.project.backup.started'
+ | 'v1.project.branch.created'
+ | 'v1.project.branch.updated'
+ | 'v1.project.branch.removed'
+ | 'v1.organization.member.invitation.created'
+ | 'v1.organization.member.invitation.canceled'
+ | 'v1.organization.member.added'
+ | 'v1.organization.member.removed'
+ | 'v1.organization.member.role.assigned'
+ | 'v1.organization.member.role.removed'
+ | 'v1.organization.member.role.updated'
+ | 'v1.organization.billing.plan.upgraded'
+ | 'v1.organization.billing.plan.downgraded'
+ | '*'
+ }[]
+ /**
+ * Format: uuid
+ * @description Identifier of an endpoint (UUID v7).
+ */
+ id: string
+ /**
+ * Format: uri
+ * @description Publicly available URL where to send the events, must use a domain and be resolvable to a non-reserved IP address.
+ * @example https://mydomain.com/path/to/handler
+ */
+ url: string
+ }
+ /**
+ * Format: uuid
+ * @description Identifier of an endpoint (UUID v7).
+ */
+ id: string
+ /**
+ * @description Resource type.
+ * @constant
+ */
+ type: 'endpoint'
+ }
+ }
+ }
+ }
+ /** @description Multiple error responses */
+ 400: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error:
+ | {
+ /** @constant */
+ code: 'bad_request.invalid_slug'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Bad Request: Invalid organization slug'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ | {
+ /** @constant */
+ code: 'bad_request.invalid_ref'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Bad Request: Invalid project ref'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description GenericUnauthorized */
+ 401: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'unauthorized'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Unauthorized'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description Multiple error responses */
+ 403: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error:
+ | {
+ /** @constant */
+ code: 'forbidden.permission_denied'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Forbidden: Permission denied'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ | {
+ /** @constant */
+ code: 'forbidden.access_disabled'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Forbidden: Access disabled'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description EndpointNotFound */
+ 404: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'not_found.endpoint'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Not Found: Endpoint not found'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description GenericRequestTimeout */
+ 408: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'request_timeout'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Request Timeout'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description GenericTooManyRequests */
+ 429: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'too_many_requests'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Too Many Requests'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description GenericInternalServerError */
+ 500: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'internal_server_error'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Internal Server Error'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ }
+ }
+ allV2ProjectsByRefWebhooks: {
+ parameters: {
+ query?: never
+ header?: never
+ path: {
+ /** @description Identifier of an endpoint (UUID v7). */
+ id: string
+ /** @description Project ref */
+ ref: string
+ }
+ cookie?: never
+ }
+ requestBody?: never
+ responses: {
+ /** @description Deleted endpoint details */
+ 200: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ data: {
+ attributes: {
+ /**
+ * Format: date-time
+ * @description Timestamp of endpoint's creation.
+ */
+ created_at: string
+ /**
+ * Format: uuid
+ * @description ID of the user who created the endpoint.
+ */
+ created_by: string
+ /**
+ * @description Additional request headers to pass when performing HTTP request location defined by `url`. Both keys and values must be strings and a valid HTTP headers.
+ * @example {
+ * "Authorization": "Bearer example_token"
+ * }
+ */
+ custom_headers?: {
+ [key: string]: string
+ } | null
+ /** @description Optional description for the endpoint. */
+ description: string | null
+ /** @description Whether the endpoint is enabled or not - disabled endpoints won't emit any events. */
+ enabled: boolean
+ /**
+ * @description List of subscribed events for which to receive the webhook event.
+ * @example [
+ * {
+ * "type": "v1.project.paused"
+ * }
+ * ]
+ */
+ event_types: {
+ /**
+ * @description Webhook event type.
+ * @enum {string}
+ */
+ type:
+ | 'v1.project.paused'
+ | 'v1.project.created'
+ | 'v1.project.restored'
+ | 'v1.project.transferred'
+ | 'v1.project.removed'
+ | 'v1.project.restarted'
+ | 'v1.project.status.changed'
+ | 'v1.project.backup.started'
+ | 'v1.project.branch.created'
+ | 'v1.project.branch.updated'
+ | 'v1.project.branch.removed'
+ | 'v1.organization.member.invitation.created'
+ | 'v1.organization.member.invitation.canceled'
+ | 'v1.organization.member.added'
+ | 'v1.organization.member.removed'
+ | 'v1.organization.member.role.assigned'
+ | 'v1.organization.member.role.removed'
+ | 'v1.organization.member.role.updated'
+ | 'v1.organization.billing.plan.upgraded'
+ | 'v1.organization.billing.plan.downgraded'
+ | '*'
+ }[]
+ /**
+ * Format: uuid
+ * @description Identifier of an endpoint (UUID v7).
+ */
+ id: string
+ /**
+ * Format: uri
+ * @description Publicly available URL where to send the events, must use a domain and be resolvable to a non-reserved IP address.
+ * @example https://mydomain.com/path/to/handler
+ */
+ url: string
+ }
+ /**
+ * Format: uuid
+ * @description Identifier of an endpoint (UUID v7).
+ */
+ id: string
+ /**
+ * @description Resource type.
+ * @constant
+ */
+ type: 'endpoint'
+ }
+ }
+ }
+ }
+ /** @description Multiple error responses */
+ 400: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error:
+ | {
+ /** @constant */
+ code: 'bad_request.invalid_slug'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Bad Request: Invalid organization slug'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ | {
+ /** @constant */
+ code: 'bad_request.invalid_ref'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Bad Request: Invalid project ref'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description GenericUnauthorized */
+ 401: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'unauthorized'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Unauthorized'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description Multiple error responses */
+ 403: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error:
+ | {
+ /** @constant */
+ code: 'forbidden.permission_denied'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Forbidden: Permission denied'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ | {
+ /** @constant */
+ code: 'forbidden.access_disabled'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Forbidden: Access disabled'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description EndpointNotFound */
+ 404: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'not_found.endpoint'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Not Found: Endpoint not found'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description GenericRequestTimeout */
+ 408: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'request_timeout'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Request Timeout'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description GenericTooManyRequests */
+ 429: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'too_many_requests'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Too Many Requests'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description GenericInternalServerError */
+ 500: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'internal_server_error'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Internal Server Error'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ }
+ }
+ allV2ProjectsByRefWebhooks: {
+ parameters: {
+ query?: never
+ header?: never
+ path: {
+ /** @description Identifier of an endpoint (UUID v7). */
+ id: string
+ /** @description Project ref */
+ ref: string
+ }
+ cookie?: never
+ }
+ requestBody: {
+ content: {
+ 'application/json': {
+ data: {
+ attributes: {
+ /**
+ * @description Additional request headers to pass when performing HTTP request location defined by `url`. Both keys and values must be strings and a valid HTTP headers.
+ * @example {
+ * "Authorization": "Bearer example_token"
+ * }
+ */
+ custom_headers?: {
+ [key: string]: string
+ } | null
+ /** @description Optional description for the endpoint. */
+ description?: string | null
+ /** @description Whether the endpoint is enabled or not - disabled endpoints won't emit any events. */
+ enabled?: boolean
+ /**
+ * @description List of subscribed events for which to receive the webhook event.
+ * @example [
+ * {
+ * "type": "v1.project.paused"
+ * }
+ * ]
+ */
+ event_types?: {
+ /**
+ * @description Webhook event type.
+ * @enum {string}
+ */
+ type:
+ | 'v1.project.paused'
+ | 'v1.project.created'
+ | 'v1.project.restored'
+ | 'v1.project.transferred'
+ | 'v1.project.removed'
+ | 'v1.project.restarted'
+ | 'v1.project.status.changed'
+ | 'v1.project.backup.started'
+ | 'v1.project.branch.created'
+ | 'v1.project.branch.updated'
+ | 'v1.project.branch.removed'
+ | 'v1.organization.member.invitation.created'
+ | 'v1.organization.member.invitation.canceled'
+ | 'v1.organization.member.added'
+ | 'v1.organization.member.removed'
+ | 'v1.organization.member.role.assigned'
+ | 'v1.organization.member.role.removed'
+ | 'v1.organization.member.role.updated'
+ | 'v1.organization.billing.plan.upgraded'
+ | 'v1.organization.billing.plan.downgraded'
+ | '*'
+ }[]
+ /** @description Secret key to use when signing. All events will be signed according to the [Standard Webhooks](https://www.standardwebhooks.com/) specification. */
+ signing_secret?: string
+ /**
+ * Format: uri
+ * @description Publicly available URL where to send the events, must use a domain and be resolvable to a non-reserved IP address.
+ * @example https://mydomain.com/path/to/handler
+ */
+ url?: string
+ }
+ /**
+ * @description Resource type.
+ * @constant
+ */
+ type: 'endpoint'
+ }
+ }
+ }
+ }
+ responses: {
+ /** @description Updated endpoint details */
+ 200: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ data: {
+ attributes: {
+ /**
+ * Format: date-time
+ * @description Timestamp of endpoint's creation.
+ */
+ created_at: string
+ /**
+ * Format: uuid
+ * @description ID of the user who created the endpoint.
+ */
+ created_by: string
+ /**
+ * @description Additional request headers to pass when performing HTTP request location defined by `url`. Both keys and values must be strings and a valid HTTP headers.
+ * @example {
+ * "Authorization": "Bearer example_token"
+ * }
+ */
+ custom_headers?: {
+ [key: string]: string
+ } | null
+ /** @description Optional description for the endpoint. */
+ description: string | null
+ /** @description Whether the endpoint is enabled or not - disabled endpoints won't emit any events. */
+ enabled: boolean
+ /**
+ * @description List of subscribed events for which to receive the webhook event.
+ * @example [
+ * {
+ * "type": "v1.project.paused"
+ * }
+ * ]
+ */
+ event_types: {
+ /**
+ * @description Webhook event type.
+ * @enum {string}
+ */
+ type:
+ | 'v1.project.paused'
+ | 'v1.project.created'
+ | 'v1.project.restored'
+ | 'v1.project.transferred'
+ | 'v1.project.removed'
+ | 'v1.project.restarted'
+ | 'v1.project.status.changed'
+ | 'v1.project.backup.started'
+ | 'v1.project.branch.created'
+ | 'v1.project.branch.updated'
+ | 'v1.project.branch.removed'
+ | 'v1.organization.member.invitation.created'
+ | 'v1.organization.member.invitation.canceled'
+ | 'v1.organization.member.added'
+ | 'v1.organization.member.removed'
+ | 'v1.organization.member.role.assigned'
+ | 'v1.organization.member.role.removed'
+ | 'v1.organization.member.role.updated'
+ | 'v1.organization.billing.plan.upgraded'
+ | 'v1.organization.billing.plan.downgraded'
+ | '*'
+ }[]
+ /**
+ * Format: uuid
+ * @description Identifier of an endpoint (UUID v7).
+ */
+ id: string
+ /**
+ * Format: uri
+ * @description Publicly available URL where to send the events, must use a domain and be resolvable to a non-reserved IP address.
+ * @example https://mydomain.com/path/to/handler
+ */
+ url: string
+ }
+ /**
+ * Format: uuid
+ * @description Identifier of an endpoint (UUID v7).
+ */
+ id: string
+ /**
+ * @description Resource type.
+ * @constant
+ */
+ type: 'endpoint'
+ }
+ }
+ }
+ }
+ /** @description Multiple error responses */
+ 400: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error:
+ | {
+ /** @constant */
+ code: 'bad_request.invalid_slug'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Bad Request: Invalid organization slug'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ | {
+ /** @constant */
+ code: 'bad_request.invalid_ref'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Bad Request: Invalid project ref'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description GenericUnauthorized */
+ 401: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'unauthorized'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Unauthorized'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description Multiple error responses */
+ 403: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error:
+ | {
+ /** @constant */
+ code: 'forbidden.permission_denied'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Forbidden: Permission denied'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ | {
+ /** @constant */
+ code: 'forbidden.access_disabled'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Forbidden: Access disabled'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description EndpointNotFound */
+ 404: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'not_found.endpoint'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Not Found: Endpoint not found'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description GenericRequestTimeout */
+ 408: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'request_timeout'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Request Timeout'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description GenericTooManyRequests */
+ 429: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'too_many_requests'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Too Many Requests'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description GenericInternalServerError */
+ 500: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'internal_server_error'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Internal Server Error'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ }
+ }
+ allV2ProjectsByRefWebhooks: {
+ parameters: {
+ query?: {
+ /** @description Cursor in cursor-based pagination to return up to `page[size]` records after (exclusive) the entry specified by this query param. */
+ 'page[after]'?: string
+ /** @description Cursor in cursor-based pagination to return up to `page[size]` records before (exclusive) the entry specified by this query param. */
+ 'page[before]'?: string
+ /** @description Up to how many records to return. */
+ 'page[size]'?: string
+ }
+ header?: never
+ path: {
+ /** @description Identifier of an endpoint (UUID v7). */
+ id: string
+ /** @description Project ref */
+ ref: string
+ }
+ cookie?: never
+ }
+ requestBody?: never
+ responses: {
+ /** @description List of deliveries */
+ 200: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ data: {
+ attributes: {
+ /**
+ * Format: date-time
+ * @description Timestamp of the attempt.
+ */
+ attempt_timestamp: string
+ /**
+ * Format: uuid
+ * @description Identifier of the event, which triggered the delivery (UUID v7).
+ */
+ event_id: string
+ /**
+ * Format: uuid
+ * @description Identifier of a delivery (UUID v7).
+ */
+ id: string
+ response_body:
+ | (
+ | {
+ [key: string]: string
+ }
+ | string
+ )
+ | null
+ /** @description HTTP status code of the response, `0` if unavailable. */
+ response_code: number
+ /** @description HTTP headers of the response, `{}` if unavailable. */
+ response_headers: {
+ [key: string]: string
+ } | null
+ /**
+ * @description Status of the delivery attempt.
+ * @enum {string}
+ */
+ status: 'pending' | 'success' | 'failure' | 'skipped'
+ }
+ /**
+ * Format: uuid
+ * @description Identifier of a delivery (UUID v7).
+ */
+ id: string
+ /**
+ * @description Resource type.
+ * @constant
+ */
+ type: 'delivery'
+ }[]
+ links: {
+ /**
+ * @description URL path to the first page if available.
+ * @example /v2/organizations/slug/webhooks/endpoints/{id}/deliveries?page[size]=10
+ */
+ first?: string | null
+ /**
+ * @description URL path to the last page if available.
+ * @example /v2/organizations/slug/webhooks/endpoints/{id}/deliveries?page[size]=10&page[after]=019adf7d-4513-71ba-b264-21900edb4295
+ */
+ last?: string | null
+ /**
+ * @description URL path to the next page.
+ * @example /v2/organizations/slug/webhooks/endpoints/{id}/deliveries?page[size]=10&page[after]=019adf7d-4513-7062-b292-78b86cc470a4
+ */
+ next: string | null
+ /**
+ * @description URL path to the previous page.
+ * @example /v2/organizations/slug/webhooks/endpoints/{id}/deliveries?page[size]=10&page[before]=019adf7d-4513-74c5-bb9a-f1bc0f7a95d7
+ */
+ prev: string | null
+ }
+ }
+ }
+ }
+ /** @description Multiple error responses */
+ 400: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error:
+ | {
+ /** @constant */
+ code: 'bad_request.invalid_slug'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Bad Request: Invalid organization slug'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ | {
+ /** @constant */
+ code: 'bad_request.invalid_ref'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Bad Request: Invalid project ref'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description GenericUnauthorized */
+ 401: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'unauthorized'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Unauthorized'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description Multiple error responses */
+ 403: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error:
+ | {
+ /** @constant */
+ code: 'forbidden.permission_denied'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Forbidden: Permission denied'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ | {
+ /** @constant */
+ code: 'forbidden.access_disabled'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Forbidden: Access disabled'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description EndpointNotFound */
+ 404: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'not_found.endpoint'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Not Found: Endpoint not found'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description GenericRequestTimeout */
+ 408: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'request_timeout'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Request Timeout'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description GenericTooManyRequests */
+ 429: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'too_many_requests'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Too Many Requests'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description GenericInternalServerError */
+ 500: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'internal_server_error'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Internal Server Error'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ }
+ }
+ allV2ProjectsByRefWebhooks: {
+ parameters: {
+ query?: never
+ header?: never
+ path: {
+ /** @description Identifier of an endpoint (UUID v7). */
+ id: string
+ /** @description Project ref */
+ ref: string
+ }
+ cookie?: never
+ }
+ requestBody: {
+ content: {
+ 'application/json': {
+ data?: {
+ attributes: {
+ /**
+ * @description Webhook event type.
+ * @enum {string}
+ */
+ type:
+ | 'v1.project.paused'
+ | 'v1.project.created'
+ | 'v1.project.restored'
+ | 'v1.project.transferred'
+ | 'v1.project.removed'
+ | 'v1.project.restarted'
+ | 'v1.project.status.changed'
+ | 'v1.project.backup.started'
+ | 'v1.project.branch.created'
+ | 'v1.project.branch.updated'
+ | 'v1.project.branch.removed'
+ | 'v1.organization.member.invitation.created'
+ | 'v1.organization.member.invitation.canceled'
+ | 'v1.organization.member.added'
+ | 'v1.organization.member.removed'
+ | 'v1.organization.member.role.assigned'
+ | 'v1.organization.member.role.removed'
+ | 'v1.organization.member.role.updated'
+ | 'v1.organization.billing.plan.upgraded'
+ | 'v1.organization.billing.plan.downgraded'
+ | 'project.v1.paused'
+ | 'project.v1.created'
+ | 'project.v1.restored'
+ | 'project.v1.transferred'
+ | 'project.v1.removed'
+ | 'project.v1.restarted'
+ | 'project.v1.status.changed'
+ | 'project.v1.backup.started'
+ | 'project.v1.branch.created'
+ | 'project.v1.branch.updated'
+ | 'project.v1.branch.removed'
+ | 'organization.v1.member.invitation.created'
+ | 'organization.v1.member.invitation.canceled'
+ | 'organization.v1.member.added'
+ | 'organization.v1.member.removed'
+ | 'organization.v1.member.role.assigned'
+ | 'organization.v1.member.role.removed'
+ | 'organization.v1.member.role.updated'
+ | 'organization.v1.billing.plan.upgraded'
+ | 'organization.v1.billing.plan.downgraded'
+ | 'project.v1.branch.deleted'
+ }
+ /**
+ * @description Resource type.
+ * @constant
+ */
+ type: 'event'
+ }
+ }
+ }
+ }
+ responses: {
+ /** @description Event published */
+ 201: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ data: {
+ id: string
+ /**
+ * @description Resource type.
+ * @constant
+ */
+ type: 'ingress'
+ }
+ }
+ }
+ }
+ /** @description Multiple error responses */
+ 400: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error:
+ | {
+ /** @constant */
+ code: 'bad_request.endpoint.test.disabled'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Bad Request: Endpoint is disabled'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ | {
+ /** @constant */
+ code: 'bad_request.endpoint.test.wrong_event_type'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Bad Request: Provided event type is not subscribed to by the endpoint'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ | {
+ /** @constant */
+ code: 'bad_request.invalid_slug'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Bad Request: Invalid organization slug'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ | {
+ /** @constant */
+ code: 'bad_request.invalid_ref'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Bad Request: Invalid project ref'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description GenericUnauthorized */
+ 401: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'unauthorized'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Unauthorized'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description Multiple error responses */
+ 403: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error:
+ | {
+ /** @constant */
+ code: 'forbidden.permission_denied'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Forbidden: Permission denied'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ | {
+ /** @constant */
+ code: 'forbidden.access_disabled'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Forbidden: Access disabled'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description EndpointNotFound */
+ 404: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'not_found.endpoint'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Not Found: Endpoint not found'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description GenericRequestTimeout */
+ 408: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'request_timeout'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Request Timeout'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description GenericTooManyRequests */
+ 429: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'too_many_requests'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Too Many Requests'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ /** @description GenericInternalServerError */
+ 500: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': {
+ error: {
+ /** @constant */
+ code: 'internal_server_error'
+ description?: string
+ id?: string
+ issues?: components['schemas']['APIErrorObject'][]
+ links?: {
+ [key: string]: {
+ describedby?: string
+ href: string
+ meta?: {
+ [key: string]: unknown
+ }
+ rel?: string
+ title?: string
+ type?: string
+ }
+ }
+ /** @constant */
+ message: 'Internal Server Error'
+ meta?: {
+ [key: string]: unknown
+ }
+ }
+ $defs: {
+ APIErrorObject: components['schemas']['APIErrorObject']
+ }
+ }
+ }
+ }
+ }
+ }
+ 'v2-list-all-workers': {
+ parameters: {
+ query?: never
+ header?: never
+ path: {
+ /** @description Project ref */
+ ref: string
+ }
+ cookie?: never
+ }
+ requestBody?: never
+ responses: {
+ 200: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['V2ListWorkersResponse']
+ }
+ }
+ /** @description Unauthorized */
+ 401: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['ErrorResponseBody']
+ }
+ }
+ /** @description Forbidden action */
+ 403: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['ErrorResponseBody']
+ }
+ }
+ /** @description Rate limit exceeded */
+ 429: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['ErrorResponseBody']
+ }
+ }
+ }
+ }
+ 'v2-get-a-worker': {
+ parameters: {
+ query?: never
+ header?: never
+ path: {
+ name: string
+ /** @description Project ref */
+ ref: string
+ }
+ cookie?: never
+ }
+ requestBody?: never
+ responses: {
+ 200: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['V2WorkerResponse']
+ }
+ }
+ /** @description Unauthorized */
+ 401: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['ErrorResponseBody']
+ }
+ }
+ /** @description Forbidden action */
+ 403: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['ErrorResponseBody']
+ }
+ }
+ /** @description Rate limit exceeded */
+ 429: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['ErrorResponseBody']
+ }
+ }
+ }
+ }
+ 'v2-delete-a-worker': {
+ parameters: {
+ query?: never
+ header?: never
+ path: {
+ name: string
+ /** @description Project ref */
+ ref: string
+ }
+ cookie?: never
+ }
+ requestBody?: never
+ responses: {
+ 204: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ /** @description Unauthorized */
+ 401: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['ErrorResponseBody']
+ }
+ }
+ /** @description Forbidden action */
+ 403: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['ErrorResponseBody']
+ }
+ }
+ /** @description Rate limit exceeded */
+ 429: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['ErrorResponseBody']
+ }
+ }
+ }
+ }
+ 'v2-deploy-a-worker': {
+ parameters: {
+ query?: never
+ header?: never
+ path: {
+ name: string
+ /** @description Project ref */
+ ref: string
+ }
+ cookie?: never
+ }
+ requestBody: {
+ content: {
+ 'application/json': components['schemas']['V2DeployWorkerRequest']
+ }
+ }
+ responses: {
+ 202: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['V2WorkerResponse']
+ }
+ }
+ /** @description Unauthorized */
+ 401: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['ErrorResponseBody']
+ }
+ }
+ /** @description Forbidden action */
+ 403: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['ErrorResponseBody']
+ }
+ }
+ /** @description Rate limit exceeded */
+ 429: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['ErrorResponseBody']
+ }
+ }
+ }
+ }
+ 'v2-create-worker-upload': {
+ parameters: {
+ query?: never
+ header?: never
+ path: {
+ name: string
+ /** @description Project ref */
+ ref: string
+ }
+ cookie?: never
+ }
+ requestBody?: never
+ responses: {
+ 201: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['V2WorkerUploadResponse']
+ }
+ }
+ /** @description Unauthorized */
+ 401: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['ErrorResponseBody']
+ }
+ }
+ /** @description Forbidden action */
+ 403: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['ErrorResponseBody']
+ }
+ }
+ /** @description Rate limit exceeded */
+ 429: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['ErrorResponseBody']
+ }
+ }
+ }
+ }
+}
diff --git a/packages/api-types/types/platform.d.ts b/packages/api-types/types/platform.d.ts
index 622b9dd1b784a..5b5b673b49555 100644
--- a/packages/api-types/types/platform.d.ts
+++ b/packages/api-types/types/platform.d.ts
@@ -520,23 +520,6 @@ export interface paths {
patch?: never
trace?: never
}
- '/platform/feedback/docs': {
- parameters: {
- query?: never
- header?: never
- path?: never
- cookie?: never
- }
- get?: never
- put?: never
- /** Send feedback on docs */
- post: operations['SendFeedbackController_sendDocsFeedback']
- delete?: never
- options?: never
- head?: never
- patch?: never
- trace?: never
- }
'/platform/feedback/downgrade': {
parameters: {
query?: never
@@ -683,6 +666,26 @@ export interface paths {
patch: operations['GitHubConnectionsController_updateGitHubConnection']
trace?: never
}
+ '/platform/integrations/github/connections/{connection_id}/config': {
+ parameters: {
+ query?: never
+ header?: never
+ path?: never
+ cookie?: never
+ }
+ /**
+ * Gets the Supabase config of a connected GitHub repository
+ * @description Reads `supabase/config.toml` from the workdir of the connected repository and returns it as JSON.
+ */
+ get: operations['GitHubConnectionsController_getGitHubConnectionConfig']
+ put?: never
+ post?: never
+ delete?: never
+ options?: never
+ head?: never
+ patch?: never
+ trace?: never
+ }
'/platform/integrations/github/repositories': {
parameters: {
query?: never
@@ -1984,11 +1987,9 @@ export interface paths {
}
/** Gets the given organization's tax ID */
get: operations['TaxIdsController_getTaxId']
- /** Creates or updates a tax ID for the given organization */
- put: operations['TaxIdsController_updateTaxId']
+ put?: never
post?: never
- /** Delete the tax ID with the given ID */
- delete: operations['TaxIdsController_deleteTaxId']
+ delete?: never
options?: never
head?: never
patch?: never
@@ -2592,6 +2593,24 @@ export interface paths {
patch?: never
trace?: never
}
+ '/platform/projects/{ref}/analytics/endpoints/logs': {
+ parameters: {
+ query?: never
+ header?: never
+ path?: never
+ cookie?: never
+ }
+ /** Gets project's logs from the unified logs stream */
+ get: operations['LogsController_getProjectLogsViaGetNew']
+ put?: never
+ /** Gets project's logs from the unified logs stream */
+ post: operations['LogsController_getProjectLogsViaPostNew']
+ delete?: never
+ options?: never
+ head?: never
+ patch?: never
+ trace?: never
+ }
'/platform/projects/{ref}/analytics/endpoints/logs.all': {
parameters: {
query?: never
@@ -2599,10 +2618,16 @@ export interface paths {
path?: never
cookie?: never
}
- /** Gets project's logs */
+ /**
+ * Gets project's logs from legacy logs tables
+ * @deprecated
+ */
get: operations['LogsController_getProjectLogsViaGet']
put?: never
- /** Gets project's logs */
+ /**
+ * Gets project's logs from legacy logs tables
+ * @deprecated
+ */
post: operations['LogsController_getProjectLogsViaPost']
delete?: never
options?: never
@@ -2617,10 +2642,16 @@ export interface paths {
path?: never
cookie?: never
}
- /** Gets project's logs from the ClickHouse-backed endpoint */
+ /**
+ * Gets project's logs from the unified logs stream
+ * @deprecated
+ */
get: operations['LogsController_getProjectLogsOtelViaGet']
put?: never
- /** Gets project's logs from the ClickHouse-backed endpoint */
+ /**
+ * Gets project's logs from the unified logs stream
+ * @deprecated
+ */
post: operations['LogsController_getProjectLogsOtelViaPost']
delete?: never
options?: never
@@ -2767,6 +2798,26 @@ export interface paths {
patch?: never
trace?: never
}
+ '/platform/projects/{ref}/analytics/metrics': {
+ parameters: {
+ query?: never
+ header?: never
+ path?: never
+ cookie?: never
+ }
+ /**
+ * Scrape a project's metrics
+ * @description Prometheus scrape endpoint. Returns metrics of a customer project in the Prometheus open exposition format. Replaces `/customer/v1/privileged/metrics`.
+ */
+ get: operations['scrape-project-metrics']
+ put?: never
+ post?: never
+ delete?: never
+ options?: never
+ head?: never
+ patch?: never
+ trace?: never
+ }
'/platform/projects/{ref}/api-keys/temporary': {
parameters: {
query?: never
@@ -3394,7 +3445,7 @@ export interface paths {
post?: never
/**
* Remove AWS account from PrivateLink share for the project
- * @description Removes an AWS account from the project's PrivateLink configuration. Cleans up associated AWS resources.
+ * @description Removes an AWS account from the project's PrivateLink configuration (targeting the primary database). Cleans up associated AWS resources.
*/
delete: operations['ProjectPrivateLinkController_removeAwsAccountFromPrivateLink']
options?: never
@@ -3402,6 +3453,26 @@ export interface paths {
patch?: never
trace?: never
}
+ '/platform/projects/{ref}/privatelink/associations/aws-account/{aws_account_id}/database/{database_identifier}': {
+ parameters: {
+ query?: never
+ header?: never
+ path?: never
+ cookie?: never
+ }
+ get?: never
+ put?: never
+ post?: never
+ /**
+ * Remove AWS account from a specific database PrivateLink share for the project
+ * @description Removes an AWS account from the project's PrivateLink configuration for the given read replica. Cleans up associated AWS resources.
+ */
+ delete: operations['ProjectPrivateLinkController_removeAwsAccountFromPrivateLinkForDatabase']
+ options?: never
+ head?: never
+ patch?: never
+ trace?: never
+ }
'/platform/projects/{ref}/resize': {
parameters: {
query?: never
@@ -3504,57 +3575,6 @@ export interface paths {
patch?: never
trace?: never
}
- '/platform/projects/{ref}/run-lints/{name}': {
- parameters: {
- query?: never
- header?: never
- path?: never
- cookie?: never
- }
- /** Run project lint by name */
- get: operations['ProjectRunLintsController_runLintByName']
- put?: never
- post?: never
- delete?: never
- options?: never
- head?: never
- patch?: never
- trace?: never
- }
- '/platform/projects/{ref}/run-lints/leaked-service-key': {
- parameters: {
- query?: never
- header?: never
- path?: never
- cookie?: never
- }
- /** Run project leaked service key lint */
- get: operations['ProjectRunLintsController_runLeakedServiceKeyLint']
- put?: never
- post?: never
- delete?: never
- options?: never
- head?: never
- patch?: never
- trace?: never
- }
- '/platform/projects/{ref}/run-lints/no-backup-admin': {
- parameters: {
- query?: never
- header?: never
- path?: never
- cookie?: never
- }
- /** Run project backup admin lint */
- get: operations['ProjectRunLintsController_runAuthBackupAdminLint']
- put?: never
- post?: never
- delete?: never
- options?: never
- head?: never
- patch?: never
- trace?: never
- }
'/platform/projects/{ref}/service-versions': {
parameters: {
query?: never
@@ -4104,7 +4124,7 @@ export interface paths {
}
/**
* Estimate replication cost for a publication
- * @description Estimate the cost of replicating a publication's tables. Returns the flat per-pipeline fee, a per-table breakdown of the one-time initial-copy cost derived from the tables’ on-disk size, and the usage-based streaming rate. Requires bearer auth and an active, healthy project.
+ * @description Estimate the cost of replicating a publication's tables. Returns the hourly (and projected monthly) per-pipeline fee, a per-table breakdown of the one-time initial-copy cost derived from the tables’ on-disk size, and the usage-based streaming rate. Requires bearer auth and an active, healthy project.
*/
get: operations['ReplicationSourcesController_getCostEstimate']
put?: never
@@ -4539,6 +4559,40 @@ export interface paths {
patch?: never
trace?: never
}
+ '/platform/storage/{ref}/cdn/purge-bucket': {
+ parameters: {
+ query?: never
+ header?: never
+ path?: never
+ cookie?: never
+ }
+ get?: never
+ put?: never
+ /** Purges CDN cache for an entire bucket */
+ post: operations['StorageCdnController_purgeBucketCache']
+ delete?: never
+ options?: never
+ head?: never
+ patch?: never
+ trace?: never
+ }
+ '/platform/storage/{ref}/cdn/purge-object': {
+ parameters: {
+ query?: never
+ header?: never
+ path?: never
+ cookie?: never
+ }
+ get?: never
+ put?: never
+ /** Purges CDN cache for a single object */
+ post: operations['StorageCdnController_purgeObjectCache']
+ delete?: never
+ options?: never
+ head?: never
+ patch?: never
+ trace?: never
+ }
'/platform/storage/{ref}/credentials': {
parameters: {
query?: never
@@ -4903,90 +4957,220 @@ export interface paths {
patch?: never
trace?: never
}
- '/platform/workflow-runs': {
+ '/platform/warehouse/{ref}/catalog': {
parameters: {
query?: never
header?: never
path?: never
cookie?: never
}
- /** Get a list of workflow runs */
- get: operations['WorkflowRunController_listWorkflowRuns']
+ /**
+ * Get Warehouse catalog access
+ * @description Return whether external Warehouse catalog access is enabled and credentials when enabled.
+ */
+ get: operations['WarehouseController_getCatalog']
put?: never
- post?: never
+ /**
+ * Update Warehouse catalog access
+ * @description Enable or disable external Warehouse catalog access for the project.
+ */
+ post: operations['WarehouseController_updateCatalog']
delete?: never
options?: never
head?: never
patch?: never
trace?: never
}
- '/platform/workflow-runs/{workflow_run_id}/logs': {
+ '/platform/warehouse/{ref}/refresh-schema': {
parameters: {
query?: never
header?: never
path?: never
cookie?: never
}
- /** Get the logs of a workflow run */
- get: operations['WorkflowRunController_getWorkflowRunLogs']
+ get?: never
put?: never
- post?: never
+ /**
+ * Refresh the Warehouse foreign schema
+ * @description Reinstall the project Warehouse FDW schema asynchronously without restarting replication or waiting for a table copy.
+ */
+ post: operations['WarehouseController_refreshSchema']
delete?: never
options?: never
head?: never
patch?: never
trace?: never
}
-}
-export type webhooks = Record
-export interface components {
- schemas: {
- AccessControlPermission: {
- actions: string[] | null
- condition:
- | (
- | string
- | number
- | boolean
- | unknown[]
- | {
- [key: string]: unknown
- }
- )
- | null
- organization_id: number | null
- organization_slug: string
- project_ids: number[] | null
- project_refs: string[] | null
- resources: string[] | null
- restrictive: boolean | null
+ '/platform/warehouse/{ref}/setup-status': {
+ parameters: {
+ query?: never
+ header?: never
+ path?: never
+ cookie?: never
}
- AccessToken: {
- created_at: string
- expires_at: string | null
- id: number
- last_used_at: string | null
- name: string
- /** @enum {string} */
- scope?: 'V0'
- token_alias: string
+ /**
+ * Get Warehouse setup status
+ * @description Return the async Warehouse setup status for the project. Overall completion follows the replication pipeline and table copy state; project database FDW markers are informational.
+ */
+ get: operations['WarehouseController_getSetupStatus']
+ put?: never
+ post?: never
+ delete?: never
+ options?: never
+ head?: never
+ patch?: never
+ trace?: never
+ }
+ '/platform/warehouse/{ref}/tables': {
+ parameters: {
+ query?: never
+ header?: never
+ path?: never
+ cookie?: never
}
- AccountRequestDetailsDto: {
- email: string
- email_matches: boolean
- expires_at: string
- id: string
- linked_organization?: {
- id: number
- name: string
- slug: string
- }
- /** @enum {string} */
- status: 'pending' | 'complete' | 'expired' | 'error'
+ /**
+ * List Warehouse linked tables
+ * @description List tables copied to Warehouse for the project. Requires bearer auth and an active, healthy project.
+ */
+ get: operations['WarehouseController_getTables']
+ put?: never
+ /**
+ * Copy a table to Warehouse
+ * @description Ensure the project Warehouse pipeline exists, add the table to its publication, and start syncing. Warehouse FDW installation is opt-in.
+ */
+ post: operations['WarehouseController_linkTable']
+ delete?: never
+ options?: never
+ head?: never
+ patch?: never
+ trace?: never
+ }
+ '/platform/warehouse/{ref}/tables/{schema}/{name}': {
+ parameters: {
+ query?: never
+ header?: never
+ path?: never
+ cookie?: never
}
- AddAwsAccountToPrivateLinkBody: {
- account_name?: string
+ get?: never
+ put?: never
+ post?: never
+ /**
+ * Detach a table from Warehouse
+ * @description Remove the table from the Warehouse publication so it stops syncing. Existing DuckLake data is left in place.
+ */
+ delete: operations['WarehouseController_detachTable']
+ options?: never
+ head?: never
+ patch?: never
+ trace?: never
+ }
+ '/platform/warehouse/{ref}/tables/{schema}/{name}/snapshots': {
+ parameters: {
+ query?: never
+ header?: never
+ path?: never
+ cookie?: never
+ }
+ /**
+ * List Warehouse snapshots for a table
+ * @description Return available DuckLake snapshots for a Warehouse-linked table. The snapshots are read from the Warehouse FDW in the project database.
+ */
+ get: operations['WarehouseController_getTableSnapshots']
+ put?: never
+ post?: never
+ delete?: never
+ options?: never
+ head?: never
+ patch?: never
+ trace?: never
+ }
+ '/platform/workflow-runs': {
+ parameters: {
+ query?: never
+ header?: never
+ path?: never
+ cookie?: never
+ }
+ /** Get a list of workflow runs */
+ get: operations['WorkflowRunController_listWorkflowRuns']
+ put?: never
+ post?: never
+ delete?: never
+ options?: never
+ head?: never
+ patch?: never
+ trace?: never
+ }
+ '/platform/workflow-runs/{workflow_run_id}/logs': {
+ parameters: {
+ query?: never
+ header?: never
+ path?: never
+ cookie?: never
+ }
+ /** Get the logs of a workflow run */
+ get: operations['WorkflowRunController_getWorkflowRunLogs']
+ put?: never
+ post?: never
+ delete?: never
+ options?: never
+ head?: never
+ patch?: never
+ trace?: never
+ }
+}
+export type webhooks = Record
+export interface components {
+ schemas: {
+ AccessControlPermission: {
+ actions: string[] | null
+ condition:
+ | (
+ | string
+ | number
+ | boolean
+ | unknown[]
+ | {
+ [key: string]: unknown
+ }
+ )
+ | null
+ organization_id: number | null
+ organization_slug: string
+ project_ids: number[] | null
+ project_refs: string[] | null
+ resources: string[] | null
+ restrictive: boolean | null
+ }
+ AccessToken: {
+ created_at: string
+ expires_at: string | null
+ id: number
+ last_used_at: string | null
+ name: string
+ /** @enum {string} */
+ scope?: 'V0'
+ token_alias: string
+ }
+ AccountRequestDetailsDto: {
+ email: string
+ email_matches: boolean
+ expires_at: string
+ id: string
+ linked_organization?: {
+ id: number
+ name: string
+ slug: string
+ }
+ /** @enum {string} */
+ status: 'pending' | 'complete' | 'expired' | 'error'
+ }
+ AddAwsAccountToPrivateLinkBody: {
+ account_name?: string
aws_account_id: string
+ /** @description Identifier of the read replica this PrivateLink share should target. Omit to target the primary database. */
+ database_identifier?: string
}
AnalyticsResponse: {
error?:
@@ -5020,6 +5204,9 @@ export interface components {
}
method: string
name: string
+ params?: {
+ [key: string]: unknown
+ }
route: string
status: number
}
@@ -5027,10 +5214,24 @@ export interface components {
app_id?: string
app_name?: string
email?: string
+ /** @description Only present when token_type=app */
+ installation_id?: string
ip?: string
+ /** @description JWT issuer. Only present for branching service JWTs */
+ jwt_issuer?: string
+ /** @description JWT subject. Only present for branching service JWTs */
+ jwt_subject?: string
oauth_app_id?: string
oauth_app_name?: string
+ /** @description Organization whose grant was used. Only present when token_type=oauth */
+ organization_id?: string
+ /** @description GoTrue login session. Only present when token_type=jwt */
+ session_id?: string
+ /** @description Access token alias, as shown in the dashboard. Only present when token_type=v0, token_type=v1 or token_type=scoped_pat */
+ token_alias?: string
token_hash?: string
+ /** @description Only present when token_type=scoped_pat */
+ token_scope?: string
token_type: string
user_id?: string
}
@@ -5041,60 +5242,6 @@ export interface components {
}[]
retention_period: number
}
- AuthBackupAdminLintResponse: {
- lints: {
- cache_key: string
- categories: ('PERFORMANCE' | 'SECURITY')[]
- description: string
- detail: string
- /** @enum {string} */
- facing: 'EXTERNAL'
- /** @enum {string} */
- level: 'ERROR' | 'WARN' | 'INFO'
- metadata?: {
- entity?: string
- fkey_columns?: number[]
- fkey_name?: string
- name?: string
- schema?: string
- /** @enum {string} */
- type?: 'table' | 'view' | 'auth' | 'function' | 'extension' | 'compliance'
- }
- /** @enum {string} */
- name:
- | 'unindexed_foreign_keys'
- | 'auth_users_exposed'
- | 'auth_rls_initplan'
- | 'no_primary_key'
- | 'unused_index'
- | 'multiple_permissive_policies'
- | 'policy_exists_rls_disabled'
- | 'rls_enabled_no_policy'
- | 'duplicate_index'
- | 'security_definer_view'
- | 'function_search_path_mutable'
- | 'rls_disabled_in_public'
- | 'extension_in_public'
- | 'rls_references_user_metadata'
- | 'materialized_view_in_api'
- | 'foreign_table_in_api'
- | 'unsupported_reg_types'
- | 'auth_otp_long_expiry'
- | 'auth_otp_short_length'
- | 'ssl_not_enforced'
- | 'network_restrictions_not_set'
- | 'password_requirements_min_length'
- | 'pitr_not_enabled'
- | 'auth_leaked_password_protection'
- | 'auth_insufficient_mfa_options'
- | 'auth_password_policy_missing'
- | 'leaked_service_key'
- | 'no_backup_admin'
- | 'vulnerable_postgres_version'
- remediation: string
- title: string
- }[]
- }
BackendConnectionTest: {
'connected?': boolean
reason: string
@@ -5131,7 +5278,7 @@ export interface components {
clear_tax_id?: true
dry_run?: boolean
tax_id?: {
- country?: string
+ country: string
type: string
value: string
}
@@ -5220,6 +5367,81 @@ export interface components {
CopyObjectResponse: {
path: string
}
+ CostEstimateResponse: {
+ /**
+ * @description Currency of all amounts
+ * @example usd
+ * @enum {string}
+ */
+ currency: 'usd'
+ /** @description Recurring per-pipeline cost */
+ pipeline: {
+ /**
+ * @description Hourly rate charged per active pipeline
+ * @example 0.053
+ */
+ hourly_cost: number
+ /**
+ * @description Projected monthly cost for an active pipeline, based on an average 730-hour month. Pipelines are billed hourly, so this is an estimate, not a metered amount.
+ * @example 38.69
+ */
+ monthly_cost: number
+ }
+ /** @description Usage-based streaming cost, expressed as a rate */
+ streaming: {
+ /**
+ * @description Usage-based streaming rate per GB. Actual cost depends on the change volume.
+ * @example 3
+ */
+ rate_per_gb: number
+ }
+ /** @description One-time cost for the initial table copy */
+ table_copy: {
+ /**
+ * @description One-time initial-copy rate per GB
+ * @example 0.6
+ */
+ rate_per_gb: number
+ /** @description Per-table initial-copy cost estimate */
+ tables: {
+ /**
+ * @description Estimated on-disk size of the table in bytes
+ * @example 10960896
+ */
+ estimated_bytes: number
+ /**
+ * @description Estimated one-time initial-copy cost for the table, in the response currency
+ * @example 0.01
+ */
+ estimated_cost: number
+ /**
+ * @description Whether this table has a row filter. The estimate does not account for how many rows the filter excludes, so the actual replicated volume may be lower than shown.
+ * @example false
+ */
+ is_row_filtered: boolean
+ /**
+ * @description Table name
+ * @example orders
+ */
+ name: string
+ /**
+ * @description Table schema
+ * @example public
+ */
+ schema: string
+ }[]
+ /**
+ * @description Total estimated bytes across all tables
+ * @example 11911168
+ */
+ total_bytes: number
+ /**
+ * @description Total estimated one-time initial-copy cost
+ * @example 0.01
+ */
+ total_cost: number
+ }
+ }
CreateAccessTokenBody: {
/** Format: date-time */
expires_at?: string
@@ -5389,12 +5611,7 @@ export interface components {
workdir: string
}
CreateInvitationBody: {
- /**
- * Format: email
- * @deprecated
- */
- email?: string
- emails?: string[]
+ emails: string[]
require_sso?: boolean
role_id: number
role_scoped_projects?: string[]
@@ -5566,7 +5783,7 @@ export interface components {
payment_method?: string
size?: string
tax_id?: {
- country?: string
+ country: string
type: string
value: string
}
@@ -5579,37 +5796,6 @@ export interface components {
| 'tier_enterprise'
| 'tier_platform'
}
- CreateOrganizationResponse:
- | {
- pending_payment_intent_secret: string | null
- }
- | {
- billing_email: string | null
- /** @enum {string|null} */
- billing_partner: 'fly' | 'aws_marketplace' | 'vercel_marketplace' | null
- id: number
- integration_source: string | null
- is_owner: boolean
- name: string
- opt_in_tags: string[]
- organization_missing_address: boolean
- organization_missing_tax_id: boolean
- organization_requires_mfa: boolean
- plan: {
- /** @enum {string} */
- id: 'free' | 'pro' | 'team' | 'enterprise' | 'platform'
- name: string
- }
- restriction_data: {
- [key: string]: string
- } | null
- /** @enum {string|null} */
- restriction_status: 'grace_period' | 'grace_period_over' | 'restricted' | null
- slug: string
- stripe_customer_id: string | null
- subscription_id: string | null
- usage_billing_enabled: boolean
- }
CreatePipelineResponse: {
/**
* @description Pipeline id
@@ -5631,6 +5817,8 @@ export interface components {
| 'members_write'
| 'organization_projects_read'
| 'organization_projects_create'
+ | 'platform_webhooks_organization_read'
+ | 'platform_webhooks_organization_write'
| 'project_admin_read'
| 'project_admin_write'
| 'action_runs_read'
@@ -5700,6 +5888,10 @@ export interface components {
| 'storage_config_write'
| 'vanity_subdomain_read'
| 'vanity_subdomain_write'
+ | 'platform_webhooks_projects_read'
+ | 'platform_webhooks_projects_write'
+ | 'workers_read'
+ | 'workers_write'
)[]
}
CreatePlatformAppResponse: {
@@ -5728,9 +5920,9 @@ export interface components {
CreateProjectBody: {
auth_site_url?: string
/** @enum {string} */
- cloud_provider: 'AWS' | 'FLY' | 'AWS_K8S' | 'AWS_NIMBUS'
+ cloud_provider: 'AWS' | 'AWS_K8S' | 'AWS_NIMBUS'
custom_supabase_internal_requests?: {
- ami: {
+ ami?: {
/**
* @description Exact AWS instance type to provision (e.g. `t3.nano`, `t4g.nano`). Hard pin — no ODCR fallback. Only for internal use; rejected for user-facing requests in production.
* @enum {string}
@@ -5740,16 +5932,68 @@ export interface components {
| 't3a.nano'
| 't3.nano'
| 't4g.micro'
+ | 't3a.micro'
+ | 't3.micro'
| 't4g.small'
+ | 't3a.small'
+ | 't3.small'
| 't4g.medium'
+ | 't3a.medium'
+ | 't3.medium'
| 'm6g.medium'
+ | 'm7g.medium'
+ | 'm8g.medium'
+ | 'm9g.medium'
+ | 'c6g.medium'
| 'm6g.large'
+ | 'm6a.large'
+ | 'm6i.large'
+ | 'm7i.large'
+ | 'm8i.large'
+ | 'm7a.large'
+ | 'm8a.large'
| 'm6g.xlarge'
+ | 'm6a.xlarge'
+ | 'm6i.xlarge'
+ | 'm7i.xlarge'
+ | 'm8i.xlarge'
+ | 'm7a.xlarge'
+ | 'm8a.xlarge'
| 'm6g.2xlarge'
+ | 'm6a.2xlarge'
+ | 'm6i.2xlarge'
+ | 'm7i.2xlarge'
+ | 'm8i.2xlarge'
+ | 'm7a.2xlarge'
+ | 'm8a.2xlarge'
| 'm6g.4xlarge'
+ | 'm6a.4xlarge'
+ | 'm6i.4xlarge'
+ | 'm7i.4xlarge'
+ | 'm8i.4xlarge'
+ | 'm7a.4xlarge'
+ | 'm8a.4xlarge'
| 'm6g.8xlarge'
+ | 'm6a.8xlarge'
+ | 'm6i.8xlarge'
+ | 'm7i.8xlarge'
+ | 'm8i.8xlarge'
+ | 'm7a.8xlarge'
+ | 'm8a.8xlarge'
| 'm6g.12xlarge'
+ | 'm6a.12xlarge'
+ | 'm6i.12xlarge'
+ | 'm7i.12xlarge'
+ | 'm8i.12xlarge'
+ | 'm7a.12xlarge'
+ | 'm8a.12xlarge'
| 'm6g.16xlarge'
+ | 'm6a.16xlarge'
+ | 'm6i.16xlarge'
+ | 'm7i.16xlarge'
+ | 'm8i.16xlarge'
+ | 'm7a.16xlarge'
+ | 'm8a.16xlarge'
| 'm8g.24xlarge'
| 'c8g.24xlarge'
| 'r8g.24xlarge'
@@ -5767,6 +6011,26 @@ export interface components {
[key: string]: string
}
}
+ warehouse_fdw?: {
+ /** @description AWS ACM Private CA ARN used by the worker to issue per-project warehouse FDW client certificates. Defaults to the worker environment configuration when omitted. */
+ client_certificate_authority_arn?: string
+ /** @description Optional URI SAN to place in the issued client certificate. Defaults to spiffe://supabase//postgres//. */
+ client_certificate_identity_uri?: string
+ client_certificate_ttl_days?: number
+ connect_timeout_ms?: number
+ enabled?: boolean
+ endpoint: string
+ jwt_audience?: string
+ jwt_issuer?: string
+ jwt_kid: string
+ jwt_ttl_secs?: number
+ request_timeout_ms?: number
+ /** @description Optional legacy input. The platform derives the runtime AWS Secrets Manager prefix from the project ref as warehouse-fdw/. */
+ secret_prefix?: string
+ secret_region?: string
+ stream_idle_timeout_ms?: number
+ tls_domain_name?: string
+ }
}
data_api_exposed_schemas?: string[]
data_api_revoke_default_privileges?: boolean
@@ -5815,7 +6079,29 @@ export interface components {
/** @description Provider region selection. Only one of db_region or region_selection can be specified. */
region_selection?:
| {
- code: string
+ /**
+ * @description The selected region code must be valid for the specified cloud provider.
+ * @enum {string}
+ */
+ code:
+ | 'us-east-1'
+ | 'us-east-2'
+ | 'us-west-1'
+ | 'us-west-2'
+ | 'ap-east-1'
+ | 'ap-southeast-1'
+ | 'ap-northeast-1'
+ | 'ap-northeast-2'
+ | 'ap-southeast-2'
+ | 'eu-west-1'
+ | 'eu-west-2'
+ | 'eu-west-3'
+ | 'eu-north-1'
+ | 'eu-central-1'
+ | 'eu-central-2'
+ | 'ca-central-1'
+ | 'ap-south-1'
+ | 'sa-east-1'
/** @enum {string} */
type: 'specific'
}
@@ -6167,7 +6453,7 @@ export interface components {
private_key_passphrase?: string | null
/**
* @description Optional Snowflake role
- * @example ETL_ROLE
+ * @example PIPELINES_ROLE
*/
role?: string | null
/**
@@ -6177,7 +6463,7 @@ export interface components {
schema: string
/**
* @description Snowflake user configured for key-pair authentication
- * @example ETL_USER
+ * @example PIPELINES_USER
*/
user: string
}
@@ -6479,7 +6765,7 @@ export interface components {
private_key_passphrase?: string | null
/**
* @description Optional Snowflake role
- * @example ETL_ROLE
+ * @example PIPELINES_ROLE
*/
role?: string | null
/**
@@ -6489,7 +6775,7 @@ export interface components {
schema: string
/**
* @description Snowflake user configured for key-pair authentication
- * @example ETL_USER
+ * @example PIPELINES_USER
*/
user: string
}
@@ -6530,7 +6816,7 @@ export interface components {
* @example info
* @enum {string|null}
*/
- log_level?: 'debug' | 'error' | 'info' | 'trace' | 'warn' | null
+ log_level?: 'trace' | 'debug' | 'info' | 'warn' | 'error' | null
/** @description Maximum number of copy connections per table */
max_copy_connections_per_table?: number | null
/** @description Maximum number of table sync workers */
@@ -6605,7 +6891,7 @@ export interface components {
/** @enum {string} */
type: 'skip_tables'
}
- | (never | null)
+ | never
}
/**
* @description Source id
@@ -6645,7 +6931,7 @@ export interface components {
* @example info
* @enum {string|null}
*/
- log_level?: 'debug' | 'error' | 'info' | 'trace' | 'warn' | null
+ log_level?: 'trace' | 'debug' | 'info' | 'warn' | 'error' | null
/** @description Maximum number of copy connections per table */
max_copy_connections_per_table?: number | null
/** @description Maximum number of table sync workers */
@@ -6720,7 +7006,7 @@ export interface components {
/** @enum {string} */
type: 'skip_tables'
}
- | (never | null)
+ | never
}
/**
* @description Destination id
@@ -6769,6 +7055,8 @@ export interface components {
| 'members_write'
| 'organization_projects_read'
| 'organization_projects_create'
+ | 'platform_webhooks_organization_read'
+ | 'platform_webhooks_organization_write'
| 'project_admin_read'
| 'project_admin_write'
| 'action_runs_read'
@@ -6838,6 +7126,10 @@ export interface components {
| 'storage_config_write'
| 'vanity_subdomain_read'
| 'vanity_subdomain_write'
+ | 'platform_webhooks_projects_read'
+ | 'platform_webhooks_projects_write'
+ | 'workers_read'
+ | 'workers_write'
)[]
project_refs?: string[]
}
@@ -6891,46 +7183,13 @@ export interface components {
metadata_xml_url: string
user_name_mapping?: string[]
}
- CreateSSOProviderResponse:
- | {
- /** @default [] */
- domains?: string[]
- email_mapping: string[]
- enabled: boolean
- first_name_mapping?: string[]
- /** Format: uri */
- idjag_issuer_url?: string | null
- join_org_on_signup_enabled: boolean
- /** @enum {string} */
- join_org_on_signup_role?: 'Administrator' | 'Developer' | 'Owner' | 'Read-only'
- last_name_mapping?: string[]
- metadata_xml_file: string
- /** Format: uri */
- metadata_xml_url?: string
- user_name_mapping?: string[]
- }
- | {
- /** @default [] */
- domains?: string[]
- email_mapping: string[]
- enabled: boolean
- first_name_mapping?: string[]
- /** Format: uri */
- idjag_issuer_url?: string | null
- join_org_on_signup_enabled: boolean
- /** @enum {string} */
- join_org_on_signup_role?: 'Administrator' | 'Developer' | 'Owner' | 'Read-only'
- last_name_mapping?: string[]
- metadata_xml_file?: string
- metadata_xml_url: string
- user_name_mapping?: string[]
- }
CreateStorageAnalyticsBucketBody: {
bucketName: string
}
CreateStorageBucketBody: {
allowed_mime_types?: string[]
file_size_limit?: number
+ /** @description Storage bucket id */
id: string
public: boolean
/** @enum {string} */
@@ -6948,11 +7207,6 @@ export interface components {
CreateStorageVectorBucketBody: {
bucketName: string
}
- CreateTaxIdBody: {
- country?: string
- type: string
- value: string
- }
CreateTenantSourceResponse: {
/**
* @description Source id
@@ -6977,7 +7231,7 @@ export interface components {
parent_id?: string | null
project_id: number
}
- CreateUserReponse: {
+ CreateUserResponse: {
aud?: string
banned_until?: string
confirmation_sent_at?: string
@@ -7055,7 +7309,6 @@ export interface components {
}
CreditRedemptionResponse: {
amount_cents: number
- /** Format: date-time */
credits_expire_at: string | null
}
CreditsTopUpRequest: {
@@ -7112,7 +7365,7 @@ export interface components {
}
DatabaseDetailResponse: {
/** @enum {string} */
- cloud_provider: 'AWS' | 'FLY' | 'AWS_K8S' | 'AWS_NIMBUS'
+ cloud_provider: 'AWS' | 'AWS_K8S' | 'AWS_NIMBUS'
/** @default null */
connection_string_read_only?: string | null
/** @default null */
@@ -7325,7 +7578,6 @@ export interface components {
logo_uri?: string
redirect_uris: string[]
response_types?: string[]
- /** @default organizations:read projects:read projects:write database:write database:read analytics:read secrets:read edge_functions:read edge_functions:write environment:read environment:write storage:read */
scope?: string
token_endpoint_auth_method?: string
}
@@ -7346,71 +7598,26 @@ export interface components {
private: number
shared: number
}
- GetJwtSecretUpdateStatus: {
- update_status: {
- change_tracking_id: string
- /** @enum {number} */
- error?: 0 | 1 | 2 | 3 | 4 | 5
- /** @enum {number} */
+ GetGitHubConnectionConfigResponse: {
+ /** @description JSON representation of the parsed `supabase/config.toml`. Its shape is owned by the Supabase CLI and is passed through as-is. */
+ config: {
+ [key: string]: unknown
+ }
+ /** @description Path of the config file within the connected repository, relative to its root. */
+ path: string
+ /** @description Git ref the config was read from, or `null` when the default branch of the connected repository was used. */
+ ref: string | null
+ /** @description Blob SHA of the config file, to detect changes between requests. */
+ sha: string
+ }
+ GetJwtSecretUpdateStatus: {
+ update_status: {
+ change_tracking_id: string
+ error?: 0 | 1 | 2 | 3 | 4 | 5
progress: 0 | 1 | 2 | 3 | 4 | 5
- /** @enum {number} */
status: 0 | 1 | 2
} | null
}
- GetLeakedServiceKeyLintResponse: {
- lints: {
- cache_key: string
- categories: ('PERFORMANCE' | 'SECURITY')[]
- description: string
- detail: string
- /** @enum {string} */
- facing: 'EXTERNAL'
- /** @enum {string} */
- level: 'ERROR' | 'WARN' | 'INFO'
- metadata?: {
- entity?: string
- fkey_columns?: number[]
- fkey_name?: string
- name?: string
- schema?: string
- /** @enum {string} */
- type?: 'table' | 'view' | 'auth' | 'function' | 'extension' | 'compliance'
- }
- /** @enum {string} */
- name:
- | 'unindexed_foreign_keys'
- | 'auth_users_exposed'
- | 'auth_rls_initplan'
- | 'no_primary_key'
- | 'unused_index'
- | 'multiple_permissive_policies'
- | 'policy_exists_rls_disabled'
- | 'rls_enabled_no_policy'
- | 'duplicate_index'
- | 'security_definer_view'
- | 'function_search_path_mutable'
- | 'rls_disabled_in_public'
- | 'extension_in_public'
- | 'rls_references_user_metadata'
- | 'materialized_view_in_api'
- | 'foreign_table_in_api'
- | 'unsupported_reg_types'
- | 'auth_otp_long_expiry'
- | 'auth_otp_short_length'
- | 'ssl_not_enforced'
- | 'network_restrictions_not_set'
- | 'password_requirements_min_length'
- | 'pitr_not_enabled'
- | 'auth_leaked_password_protection'
- | 'auth_insufficient_mfa_options'
- | 'auth_password_policy_missing'
- | 'leaked_service_key'
- | 'no_backup_admin'
- | 'vulnerable_postgres_version'
- remediation: string
- title: string
- }[]
- }
GetOAuthAuthorizationResponse: {
approved_at?: string
approved_organization_slug?: string
@@ -7495,13 +7702,19 @@ export interface components {
integration: {
name: string
}
- /** @description Any JSON-serializable value */
- metadata: unknown
+ metadata: components['schemas']['GetOrganizationIntegrationResponseJsonValue']
organization: {
slug: string
}
updated_at: string
}
+ /** @description Any JSON-serializable value */
+ GetOrganizationIntegrationResponseJsonValue:
+ | ((string | number | boolean) | null)
+ | components['schemas']['GetOrganizationIntegrationResponseJsonValue'][]
+ | {
+ [key: string]: components['schemas']['GetOrganizationIntegrationResponseJsonValue']
+ }
GetPlatformAppInstallationResponse: {
/** Format: uuid */
app_id: string
@@ -7541,6 +7754,19 @@ export interface components {
private_link_associations: {
account_name?: string
aws_account_id: string
+ /** @description Identifier of the database this PrivateLink share targets - the project ref for the primary, or the read replica identifier. */
+ database_identifier: string
+ /**
+ * @description Whether this PrivateLink share targets the primary database or a read replica.
+ * @enum {string}
+ */
+ database_type: 'PRIMARY' | 'READ_REPLICA'
+ /** @description ARN of the AWS VPC Lattice resource configuration backing this PrivateLink share. */
+ resource_access_manager_resource_config_arn?: string
+ /** @description ID of the AWS VPC Lattice resource configuration backing this PrivateLink share. */
+ resource_access_manager_resource_config_id?: string
+ /** @description ARN of the AWS Resource Access Manager resource share for this association. */
+ resource_access_manager_share_arn?: string
/**
* Format: date-time
* @description The time and date at which the AWS Resource Share Association was requested from Supabase. `null` means that the association was not yet requested while the PrivateLink Association is pending.
@@ -7750,40 +7976,6 @@ export interface components {
}
path: string[]
}
- GetSSOProviderResponse:
- | {
- /** @default [] */
- domains?: string[]
- email_mapping: string[]
- enabled: boolean
- first_name_mapping?: string[]
- /** Format: uri */
- idjag_issuer_url?: string | null
- join_org_on_signup_enabled: boolean
- /** @enum {string} */
- join_org_on_signup_role?: 'Administrator' | 'Developer' | 'Owner' | 'Read-only'
- last_name_mapping?: string[]
- metadata_xml_file: string
- /** Format: uri */
- metadata_xml_url?: string
- user_name_mapping?: string[]
- }
- | {
- /** @default [] */
- domains?: string[]
- email_mapping: string[]
- enabled: boolean
- first_name_mapping?: string[]
- /** Format: uri */
- idjag_issuer_url?: string | null
- join_org_on_signup_enabled: boolean
- /** @enum {string} */
- join_org_on_signup_role?: 'Administrator' | 'Developer' | 'Owner' | 'Read-only'
- last_name_mapping?: string[]
- metadata_xml_file?: string
- metadata_xml_url: string
- user_name_mapping?: string[]
- }
GetStorageCredentialsResponse: {
data: {
created_at: string
@@ -7799,7 +7991,7 @@ export interface components {
}[]
billing_cycle_anchor: number
/** @enum {string} */
- billing_partner?: 'fly' | 'aws_marketplace' | 'vercel_marketplace'
+ billing_partner?: 'aws_marketplace' | 'vercel_marketplace'
billing_via_partner: boolean
current_period_end: number
current_period_start: number
@@ -7854,8 +8046,7 @@ export interface components {
| 'auth_mfa_web_authn_default'
| 'log_drain_default'
| 'etl_pipeline_default'
- /** @description Any JSON-serializable value */
- meta?: unknown
+ meta?: components['schemas']['GetSubscriptionResponseJsonValue']
name: string
price: number
price_description: string
@@ -7869,7 +8060,6 @@ export interface components {
ref: string
}[]
scheduled_plan_change: {
- /** Format: date-time */
at: string
/** @enum {string} */
target_plan: 'free' | 'pro' | 'team' | 'enterprise' | 'platform'
@@ -7877,6 +8067,13 @@ export interface components {
} | null
usage_billing_enabled: boolean
}
+ /** @description Any JSON-serializable value */
+ GetSubscriptionResponseJsonValue:
+ | ((string | number | boolean) | null)
+ | components['schemas']['GetSubscriptionResponseJsonValue'][]
+ | {
+ [key: string]: components['schemas']['GetSubscriptionResponseJsonValue']
+ }
GetUserContentByIdResponse: {
content: {
[key: string]: unknown
@@ -7964,13 +8161,19 @@ export interface components {
integration: {
name: string
}
- /** @description Any JSON-serializable value */
- metadata: unknown
+ metadata: components['schemas']['GetUserOrganizationIntegrationResponseJsonValue']
organization: {
slug: string
}
updated_at: string
}
+ /** @description Any JSON-serializable value */
+ GetUserOrganizationIntegrationResponseJsonValue:
+ | ((string | number | boolean) | null)
+ | components['schemas']['GetUserOrganizationIntegrationResponseJsonValue'][]
+ | {
+ [key: string]: components['schemas']['GetUserOrganizationIntegrationResponseJsonValue']
+ }
GetVercelProjectsResponse: {
pagination: {
count: number
@@ -8380,14 +8583,14 @@ export interface components {
tls?: boolean
}
description?: string
- id: number
- metadata: {
+ readonly id: number
+ readonly metadata: {
project_ref: string
/** @enum {string} */
type: 'log-drain'
} | null
name: string
- token: string
+ readonly token: string
/** @enum {string} */
type:
| 'postgres'
@@ -8402,7 +8605,7 @@ export interface components {
| 'last9'
| 'otlp'
| 'syslog'
- user_id: number
+ readonly user_id: number
}
LinkClazarBuyerBody: {
buyer_id: string
@@ -8437,6 +8640,7 @@ export interface components {
| 'storage.image_transformations'
| 'storage.vector_buckets'
| 'storage.iceberg_catalog'
+ | 'storage.purge_cache'
| 'security.audit_logs_days'
| 'security.questionnaire'
| 'security.soc2_report'
@@ -8486,6 +8690,8 @@ export interface components {
| 'integrations.github_connections'
| 'dedicated_pooler'
| 'observability.dashboard_advanced_metrics'
+ | 'api.members.invitations'
+ | 'api.members.roles'
/** @enum {string} */
type: 'boolean' | 'numeric' | 'set'
}
@@ -8678,6 +8884,7 @@ export interface components {
is_sensitive: boolean
}
Member: {
+ avatar_url: string | null
gotrue_id: string
is_sso_user: boolean | null
metadata: {
@@ -8736,18 +8943,23 @@ export interface components {
'table-uuid'?: string
}
NotificationResponse: {
- /** @description Any JSON-serializable value */
- data: unknown
+ data: components['schemas']['NotificationResponseJsonValue']
id: string
inserted_at: string
- /** @description Any JSON-serializable value */
- meta: unknown
+ meta: components['schemas']['NotificationResponseJsonValue']
name: string
/** @enum {string} */
priority: 'Critical' | 'Warning' | 'Info'
/** @enum {string} */
status: 'new' | 'seen' | 'archived'
}
+ /** @description Any JSON-serializable value */
+ NotificationResponseJsonValue:
+ | ((string | number | boolean) | null)
+ | components['schemas']['NotificationResponseJsonValue'][]
+ | {
+ [key: string]: components['schemas']['NotificationResponseJsonValue']
+ }
NotificationsSummary: {
has_critical: boolean
has_warning: boolean
@@ -8887,7 +9099,7 @@ export interface components {
OrganizationResponse: {
billing_email: string | null
/** @enum {string|null} */
- billing_partner: 'fly' | 'aws_marketplace' | 'vercel_marketplace' | null
+ billing_partner: 'aws_marketplace' | 'vercel_marketplace' | null
id: number
integration_source: string | null
is_owner: boolean
@@ -8943,7 +9155,7 @@ export interface components {
}
OrganizationSlugAvailableVersionsBody: {
/** @enum {string} */
- provider: 'AWS' | 'FLY' | 'AWS_K8S' | 'AWS_NIMBUS'
+ provider: 'AWS' | 'AWS_K8S' | 'AWS_NIMBUS'
region: string
}
OrganizationSlugAvailableVersionsResponse: {
@@ -8958,7 +9170,7 @@ export interface components {
OrganizationSlugResponse: {
billing_email: string | null
/** @enum {string|null} */
- billing_partner: 'fly' | 'aws_marketplace' | 'vercel_marketplace' | null
+ billing_partner: 'aws_marketplace' | 'vercel_marketplace' | null
has_oriole_project: boolean
id: number
integration_source: string | null
@@ -8988,6 +9200,7 @@ export interface components {
egress_storage: number
egress_supavisor: number
} | null
+ /** Format: date */
date: string
/** @enum {string} */
metric:
@@ -9037,6 +9250,8 @@ export interface components {
| 'IPV4'
| 'LOG_DRAIN'
| 'ETL_PIPELINE'
+ | 'ETL_REPLICATED_DATA'
+ | 'ETL_COPY_BACKFILL_DATA'
| 'LOG_INGESTION'
| 'LOG_QUERYING'
| 'LOG_STORAGE'
@@ -9102,6 +9317,8 @@ export interface components {
| 'IPV4'
| 'LOG_DRAIN'
| 'ETL_PIPELINE'
+ | 'ETL_REPLICATED_DATA'
+ | 'ETL_COPY_BACKFILL_DATA'
| 'LOG_INGESTION'
| 'LOG_QUERYING'
| 'LOG_STORAGE'
@@ -9241,6 +9458,22 @@ export interface components {
}
}
}
+ PlanGateErrorBody: {
+ /** @description Present on entitlement denials. Other errors with this status code (validation, billing state) carry only message. */
+ error?: {
+ /**
+ * @description Machine-readable marker for plan-gated denials
+ * @enum {string}
+ */
+ code: 'entitlement_required'
+ /** @description Entitlement feature key that failed the check */
+ feature: string
+ /** @description Billing page URL for the organization, present when the org is resolvable */
+ upgrade_url?: string
+ }
+ /** @description Human-readable explanation of the plan gate */
+ message: string
+ }
PlansResponse: {
plans: {
/** @enum {string} */
@@ -9507,7 +9740,7 @@ export interface components {
state?: string | null
}
tax_id?: {
- country?: string
+ country: string
type: string
value: string
}
@@ -9682,23 +9915,7 @@ export interface components {
}
ProfileResponse: {
auth0_id: string
- disabled_features: (
- | 'organizations:create'
- | 'organizations:delete'
- | 'organization_members:create'
- | 'organization_members:delete'
- | 'projects:create'
- | 'projects:transfer'
- | 'project_auth:all'
- | 'project_storage:all'
- | 'project_edge_function:all'
- | 'profile:update'
- | 'billing:account_data'
- | 'billing:credits'
- | 'billing:invoices'
- | 'billing:payment_methods'
- | 'realtime:all'
- )[]
+ disabled_features: string[]
first_name: string | null
free_project_limit: number | null
gotrue_id: string
@@ -9753,8 +9970,7 @@ export interface components {
| 'auth_mfa_web_authn_default'
| 'log_drain_default'
| 'etl_pipeline_default'
- /** @description Any JSON-serializable value */
- meta?: unknown
+ meta?: components['schemas']['ProjectAddonsResponseJsonValue']
name: string
price: number
price_description: string
@@ -9806,8 +10022,7 @@ export interface components {
| 'auth_mfa_web_authn_default'
| 'log_drain_default'
| 'etl_pipeline_default'
- /** @description Any JSON-serializable value */
- meta?: unknown
+ meta?: components['schemas']['ProjectAddonsResponseJsonValue']
name: string
price: number
price_description: string
@@ -9818,6 +10033,13 @@ export interface components {
}
}[]
}
+ /** @description Any JSON-serializable value */
+ ProjectAddonsResponseJsonValue:
+ | ((string | number | boolean) | null)
+ | components['schemas']['ProjectAddonsResponseJsonValue'][]
+ | {
+ [key: string]: components['schemas']['ProjectAddonsResponseJsonValue']
+ }
ProjectClonedResponse: {
source_project_ref: string
target_disk_size_gb: number
@@ -9992,6 +10214,15 @@ export interface components {
PublicUrlResponse: {
publicUrl: string
}
+ PurgeBucketCacheBody: {
+ /** @description Storage bucket id */
+ bucket_id: string
+ }
+ PurgeObjectCacheBody: {
+ /** @description Storage bucket id */
+ bucket_id: string
+ path: string
+ }
PutOAuthAppResponse: {
client_id: string
created_at: string
@@ -10057,7 +10288,7 @@ export interface components {
| 'sa-east-1'
name: string
/** @enum {string} */
- provider: 'AWS' | 'FLY' | 'AWS_K8S' | 'AWS_NIMBUS'
+ provider: 'AWS' | 'AWS_K8S' | 'AWS_NIMBUS'
/** @enum {string} */
status?: 'capacity' | 'other'
/** @enum {string} */
@@ -10095,7 +10326,7 @@ export interface components {
| 'sa-east-1'
name: string
/** @enum {string} */
- provider: 'AWS' | 'FLY' | 'AWS_K8S' | 'AWS_NIMBUS'
+ provider: 'AWS' | 'AWS_K8S' | 'AWS_NIMBUS'
/** @enum {string} */
status?: 'capacity' | 'other'
/** @enum {string} */
@@ -10267,7 +10498,7 @@ export interface components {
database: string
/**
* @description Optional Snowflake role
- * @example ETL_ROLE
+ * @example PIPELINES_ROLE
*/
role?: string
/**
@@ -10277,7 +10508,7 @@ export interface components {
schema: string
/**
* @description Snowflake user configured for key-pair authentication
- * @example ETL_USER
+ * @example PIPELINES_USER
*/
user: string
}
@@ -10456,7 +10687,7 @@ export interface components {
database: string
/**
* @description Optional Snowflake role
- * @example ETL_ROLE
+ * @example PIPELINES_ROLE
*/
role?: string
/**
@@ -10466,7 +10697,7 @@ export interface components {
schema: string
/**
* @description Snowflake user configured for key-pair authentication
- * @example ETL_USER
+ * @example PIPELINES_USER
*/
user: string
}
@@ -10526,7 +10757,7 @@ export interface components {
* @example reserved
* @enum {string}
*/
- wal_status?: 'extended' | 'lost' | 'reserved' | 'unknown' | 'unreserved'
+ wal_status?: 'reserved' | 'extended' | 'unreserved' | 'lost' | 'unknown'
/**
* @description Write lag expressed in milliseconds.
* @example 1500
@@ -10646,7 +10877,7 @@ export interface components {
* @example reserved
* @enum {string}
*/
- wal_status?: 'extended' | 'lost' | 'reserved' | 'unknown' | 'unreserved'
+ wal_status?: 'reserved' | 'extended' | 'unreserved' | 'lost' | 'unknown'
/**
* @description Write lag expressed in milliseconds.
* @example 1500
@@ -10688,7 +10919,7 @@ export interface components {
* @example info
* @enum {string}
*/
- log_level?: 'debug' | 'error' | 'info' | 'trace' | 'warn'
+ log_level?: 'trace' | 'debug' | 'info' | 'warn' | 'error'
/** @description Maximum number of copy connections per table */
max_copy_connections_per_table?: number
/** @description Maximum number of table sync workers */
@@ -10834,7 +11065,7 @@ export interface components {
* @example info
* @enum {string}
*/
- log_level?: 'debug' | 'error' | 'info' | 'trace' | 'warn'
+ log_level?: 'trace' | 'debug' | 'info' | 'warn' | 'error'
/** @description Maximum number of copy connections per table */
max_copy_connections_per_table?: number
/** @description Maximum number of table sync workers */
@@ -10995,81 +11226,6 @@ export interface components {
name: string
}
}
- CostEstimateResponse: {
- /**
- * @description Currency of all amounts
- * @example usd
- * @enum {string}
- */
- currency: 'usd'
- /** @description Recurring per-pipeline cost */
- pipeline: {
- /**
- * @description Hourly rate charged per active pipeline
- * @example 0.053
- */
- hourly_cost: number
- /**
- * @description Projected monthly cost for an active pipeline, based on an average 730-hour month. Pipelines are billed hourly, so this is an estimate, not a metered amount.
- * @example 38.69
- */
- monthly_cost: number
- }
- /** @description Usage-based streaming cost, expressed as a rate */
- streaming: {
- /**
- * @description Usage-based streaming rate per GB. Actual cost depends on the change volume.
- * @example 3
- */
- rate_per_gb: number
- }
- /** @description One-time cost for the initial table copy */
- table_copy: {
- /**
- * @description One-time initial-copy rate per GB
- * @example 0.6
- */
- rate_per_gb: number
- /** @description Per-table initial-copy cost estimate */
- tables: {
- /**
- * @description Estimated on-disk size of the table in bytes
- * @example 10960896
- */
- estimated_bytes: number
- /**
- * @description Estimated one-time initial-copy cost for the table, in the response currency
- * @example 0.01
- */
- estimated_cost: number
- /**
- * @description Whether this table has a row filter. The estimate does not account for how many rows the filter excludes, so the actual replicated volume may be lower than shown.
- * @example false
- */
- is_row_filtered: boolean
- /**
- * @description Table name
- * @example orders
- */
- name: string
- /**
- * @description Table schema
- * @example public
- */
- schema: string
- }[]
- /**
- * @description Total estimated bytes across all tables
- * @example 11911168
- */
- total_bytes: number
- /**
- * @description Total estimated one-time initial-copy cost
- * @example 0.01
- */
- total_cost: number
- }
- }
ReplicationPublicationsResponse: {
/** @description List of publications */
publications: {
@@ -11308,73 +11464,12 @@ export interface components {
table_id: number
}[]
}
- RunLintByNameResponse: {
- lints: {
- cache_key: string
- categories: ('PERFORMANCE' | 'SECURITY')[]
- description: string
- detail: string
- /** @enum {string} */
- facing: 'EXTERNAL'
- /** @enum {string} */
- level: 'ERROR' | 'WARN' | 'INFO'
- metadata?: {
- entity?: string
- fkey_columns?: number[]
- fkey_name?: string
- name?: string
- schema?: string
- /** @enum {string} */
- type?: 'table' | 'view' | 'auth' | 'function' | 'extension' | 'compliance'
- }
- /** @enum {string} */
- name:
- | 'unindexed_foreign_keys'
- | 'auth_users_exposed'
- | 'auth_rls_initplan'
- | 'no_primary_key'
- | 'unused_index'
- | 'multiple_permissive_policies'
- | 'policy_exists_rls_disabled'
- | 'rls_enabled_no_policy'
- | 'duplicate_index'
- | 'security_definer_view'
- | 'function_search_path_mutable'
- | 'rls_disabled_in_public'
- | 'extension_in_public'
- | 'rls_references_user_metadata'
- | 'materialized_view_in_api'
- | 'foreign_table_in_api'
- | 'unsupported_reg_types'
- | 'auth_otp_long_expiry'
- | 'auth_otp_short_length'
- | 'ssl_not_enforced'
- | 'network_restrictions_not_set'
- | 'password_requirements_min_length'
- | 'pitr_not_enabled'
- | 'auth_leaked_password_protection'
- | 'auth_insufficient_mfa_options'
- | 'auth_password_policy_missing'
- | 'leaked_service_key'
- | 'no_backup_admin'
- | 'vulnerable_postgres_version'
- remediation: string
- title: string
- }[]
- }
RunQueryBody: {
/** @default false */
disable_statement_timeout?: boolean
parameters?: unknown[]
query: string
}
- SendDocsFeedbackBody: {
- feedback?: string
- isHelpful: boolean
- page: string
- team?: string
- title: string
- }
SendExitSurveyBody: {
additionalFeedback?: string
exitAction?: string
@@ -11494,6 +11589,9 @@ export interface components {
imageTransformation: {
enabled: boolean
}
+ purgeCache: {
+ enabled: boolean
+ }
s3Protocol: {
enabled: boolean
}
@@ -11654,7 +11752,7 @@ export interface components {
}
TelemetryFeatureFlagBody: {
feature_flag_name: string
- feature_flag_value?: unknown
+ feature_flag_value: unknown
}
TelemetryGroupsIdentityBody: {
organization_slug?: string
@@ -11710,9 +11808,7 @@ export interface components {
UpcomingInvoice: {
amount_projected?: number
amount_total: number
- /** Format: date-time */
billing_cycle_end: string
- /** Format: date-time */
billing_cycle_start: string
currency: string
customer_balance: number
@@ -11773,9 +11869,7 @@ export interface components {
is_read_replica?: boolean
}
period?: {
- /** Format: date-time */
end: string
- /** Format: date-time */
start: string
}
proration: boolean
@@ -11831,6 +11925,8 @@ export interface components {
| 'IPV4'
| 'LOG_DRAIN'
| 'ETL_PIPELINE'
+ | 'ETL_REPLICATED_DATA'
+ | 'ETL_COPY_BACKFILL_DATA'
| 'LOG_INGESTION'
| 'LOG_QUERYING'
| 'LOG_STORAGE'
@@ -12367,6 +12463,8 @@ export interface components {
| 'members_write'
| 'organization_projects_read'
| 'organization_projects_create'
+ | 'platform_webhooks_organization_read'
+ | 'platform_webhooks_organization_write'
| 'project_admin_read'
| 'project_admin_write'
| 'action_runs_read'
@@ -12436,6 +12534,10 @@ export interface components {
| 'storage_config_write'
| 'vanity_subdomain_read'
| 'vanity_subdomain_write'
+ | 'platform_webhooks_projects_read'
+ | 'platform_webhooks_projects_write'
+ | 'workers_read'
+ | 'workers_write'
)[]
}
UpdatePlatformAppInstallationResponse: {
@@ -12471,6 +12573,7 @@ export interface components {
UpdatePostgrestConfigBody: {
db_extra_search_path?: string
db_pool?: number
+ db_pool_acquisition_timeout?: number
db_schema?: string
max_rows?: number
}
@@ -12478,6 +12581,8 @@ export interface components {
db_extra_search_path: string
/** @description If `null`, the value is automatically configured based on compute size. */
db_pool: number | null
+ /** @description If `null`, the value is automatically configured to 10. */
+ db_pool_acquisition_timeout: number | null
db_schema: string
max_rows: number
}
@@ -12807,7 +12912,7 @@ export interface components {
private_key_passphrase?: string | null
/**
* @description Optional Snowflake role
- * @example ETL_ROLE
+ * @example PIPELINES_ROLE
*/
role?: string | null
/**
@@ -12817,7 +12922,7 @@ export interface components {
schema?: string | null
/**
* @description Snowflake user configured for key-pair authentication
- * @example ETL_USER
+ * @example PIPELINES_USER
*/
user?: string | null
}
@@ -13115,7 +13220,7 @@ export interface components {
private_key_passphrase?: string | null
/**
* @description Optional Snowflake role
- * @example ETL_ROLE
+ * @example PIPELINES_ROLE
*/
role?: string | null
/**
@@ -13125,7 +13230,7 @@ export interface components {
schema?: string | null
/**
* @description Snowflake user configured for key-pair authentication
- * @example ETL_USER
+ * @example PIPELINES_USER
*/
user?: string | null
}
@@ -13166,7 +13271,7 @@ export interface components {
* @example info
* @enum {string|null}
*/
- log_level?: 'debug' | 'error' | 'info' | 'trace' | 'warn' | null
+ log_level?: 'trace' | 'debug' | 'info' | 'warn' | 'error' | null
/** @description Maximum number of copy connections per table */
max_copy_connections_per_table?: number | null
/** @description Maximum number of table sync workers */
@@ -13190,7 +13295,7 @@ export interface components {
*/
memory_refresh_interval_ms?: number | null
/**
- * @description Publication name. Omission preserves the stored value; ETL rejects clearing it with `null`.
+ * @description Publication name. Omission preserves the stored value; Pipelines rejects clearing it with `null`.
* @example pub_orders
*/
publication_name?: string | null
@@ -13241,7 +13346,7 @@ export interface components {
/** @enum {string} */
type: 'skip_tables'
}
- | (never | null)
+ | never
}
/**
* @description Source id
@@ -13281,7 +13386,7 @@ export interface components {
* @example info
* @enum {string|null}
*/
- log_level?: 'debug' | 'error' | 'info' | 'trace' | 'warn' | null
+ log_level?: 'trace' | 'debug' | 'info' | 'warn' | 'error' | null
/** @description Maximum number of copy connections per table */
max_copy_connections_per_table?: number | null
/** @description Maximum number of table sync workers */
@@ -13305,7 +13410,7 @@ export interface components {
*/
memory_refresh_interval_ms?: number | null
/**
- * @description Publication name. Omission preserves the stored value; ETL rejects clearing it with `null`.
+ * @description Publication name. Omission preserves the stored value; Pipelines rejects clearing it with `null`.
* @example pub_orders
*/
publication_name?: string | null
@@ -13356,7 +13461,7 @@ export interface components {
/** @enum {string} */
type: 'skip_tables'
}
- | (never | null)
+ | never
}
/**
* @description Destination id
@@ -13432,40 +13537,6 @@ export interface components {
metadata_xml_url: string
user_name_mapping?: string[]
}
- UpdateSSOProviderResponse:
- | {
- /** @default [] */
- domains?: string[]
- email_mapping: string[]
- enabled: boolean
- first_name_mapping?: string[]
- /** Format: uri */
- idjag_issuer_url?: string | null
- join_org_on_signup_enabled: boolean
- /** @enum {string} */
- join_org_on_signup_role?: 'Administrator' | 'Developer' | 'Owner' | 'Read-only'
- last_name_mapping?: string[]
- metadata_xml_file: string
- /** Format: uri */
- metadata_xml_url?: string
- user_name_mapping?: string[]
- }
- | {
- /** @default [] */
- domains?: string[]
- email_mapping: string[]
- enabled: boolean
- first_name_mapping?: string[]
- /** Format: uri */
- idjag_issuer_url?: string | null
- join_org_on_signup_enabled: boolean
- /** @enum {string} */
- join_org_on_signup_role?: 'Administrator' | 'Developer' | 'Owner' | 'Read-only'
- last_name_mapping?: string[]
- metadata_xml_file?: string
- metadata_xml_url: string
- user_name_mapping?: string[]
- }
UpdateStorageBucketBody: {
allowed_mime_types?: string[] | null
file_size_limit?: number | null
@@ -13494,6 +13565,9 @@ export interface components {
imageTransformation?: {
enabled: boolean
}
+ purgeCache?: {
+ enabled: boolean
+ }
s3Protocol?: {
enabled: boolean
}
@@ -13537,7 +13611,7 @@ export interface components {
UpdateUserBody: {
ban_duration?: string
}
- UpdateUserReponse: {
+ UpdateUserResponse: {
aud?: string
banned_until?: string
confirmation_sent_at?: string
@@ -13584,6 +13658,10 @@ export interface components {
env_sync_targets?: ('production' | 'preview' | 'development')[]
public_env_var_prefix?: string
}
+ UpdateWarehouseCatalogBody: {
+ /** @description Whether external catalog access should be enabled */
+ enabled: boolean
+ }
UpsertContentBody: {
content?: {
[key: string]: unknown
@@ -13594,7 +13672,6 @@ export interface components {
* @default false
*/
favorite?: boolean
- /** Format: uuid */
folder_id?: (null | (string | null)) | null
id?: string
name: string
@@ -13613,6 +13690,9 @@ export interface components {
}
method: string
name: string
+ params?: {
+ [key: string]: unknown
+ }
route: string
status: number
}
@@ -13620,10 +13700,24 @@ export interface components {
app_id?: string
app_name?: string
email?: string
+ /** @description Only present when token_type=app */
+ installation_id?: string
ip?: string
+ /** @description JWT issuer. Only present for branching service JWTs */
+ jwt_issuer?: string
+ /** @description JWT subject. Only present for branching service JWTs */
+ jwt_subject?: string
oauth_app_id?: string
oauth_app_name?: string
+ /** @description Organization whose grant was used. Only present when token_type=oauth */
+ organization_id?: string
+ /** @description GoTrue login session. Only present when token_type=jwt */
+ session_id?: string
+ /** @description Access token alias, as shown in the dashboard. Only present when token_type=v0, token_type=v1 or token_type=scoped_pat */
+ token_alias?: string
token_hash?: string
+ /** @description Only present when token_type=scoped_pat */
+ token_scope?: string
token_type: string
user_id?: string
}
@@ -14010,7 +14104,7 @@ export interface components {
private_key_passphrase?: string | null
/**
* @description Optional Snowflake role
- * @example ETL_ROLE
+ * @example PIPELINES_ROLE
*/
role?: string | null
/**
@@ -14020,7 +14114,7 @@ export interface components {
schema: string
/**
* @description Snowflake user configured for key-pair authentication
- * @example ETL_USER
+ * @example PIPELINES_USER
*/
user: string
}
@@ -14056,7 +14150,7 @@ export interface components {
* @example info
* @enum {string|null}
*/
- log_level?: 'debug' | 'error' | 'info' | 'trace' | 'warn' | null
+ log_level?: 'trace' | 'debug' | 'info' | 'warn' | 'error' | null
/** @description Maximum number of copy connections per table */
max_copy_connections_per_table?: number | null
/** @description Maximum number of table sync workers */
@@ -14131,7 +14225,7 @@ export interface components {
/** @enum {string} */
type: 'skip_tables'
}
- | (never | null)
+ | never
}
/**
* @description Source id
@@ -14171,7 +14265,7 @@ export interface components {
* @example info
* @enum {string|null}
*/
- log_level?: 'debug' | 'error' | 'info' | 'trace' | 'warn' | null
+ log_level?: 'trace' | 'debug' | 'info' | 'warn' | 'error' | null
/** @description Maximum number of copy connections per table */
max_copy_connections_per_table?: number | null
/** @description Maximum number of table sync workers */
@@ -14246,7 +14340,7 @@ export interface components {
/** @enum {string} */
type: 'skip_tables'
}
- | (never | null)
+ | never
}
/**
* @description Source id
@@ -14275,45 +14369,316 @@ export interface components {
/** @enum {string} */
result: 'success'
}
- WorkflowRunResponse: {
- branch_id: string
- check_run_id: number | null
- created_at: string
- git_config?: unknown
- id: string
- /** @enum {string} */
- status:
- | 'CREATING_PROJECT'
- | 'RUNNING_MIGRATIONS'
- | 'MIGRATIONS_PASSED'
- | 'MIGRATIONS_FAILED'
- | 'FUNCTIONS_DEPLOYED'
- | 'FUNCTIONS_FAILED'
- updated_at: string
- workdir: string | null
- }
- }
- responses: never
- parameters: never
- requestBodies: never
- headers: never
- pathItems: never
-}
-export type $defs = Record
-export interface operations {
- GoTrueConfigController_getGoTrueConfig: {
- parameters: {
- query?: never
- header?: never
- path: {
- /** @description Project ref */
- ref: string
+ WarehouseCatalogResponse: {
+ /** @description External catalog credentials. Present only when enabled. */
+ credentials?: {
+ /**
+ * @description DuckLake catalog Postgres URL
+ * @example postgres://postgres:@db.example.supabase.co:5432/postgres
+ */
+ catalog_url: string
+ /**
+ * @description DuckLake object storage path
+ * @example s3://warehouse/
+ */
+ data_path: string
+ /**
+ * @description DuckLake metadata schema in the catalog database
+ * @example ducklake
+ */
+ metadata_schema: string
+ /** @description S3 access key id */
+ s3_access_key_id: string
+ /**
+ * @description S3-compatible storage endpoint without protocol
+ * @example abcjuqabhgwjjutfvtpa.storage.supabase.co/storage/v1/s3
+ */
+ s3_endpoint: string
+ /**
+ * @description S3-compatible storage region
+ * @example us-east-1
+ */
+ s3_region: string
+ /** @description S3 secret access key */
+ s3_secret_access_key: string
}
- cookie?: never
+ /** @description Whether external catalog access is enabled */
+ enabled: boolean
}
- requestBody?: never
- responses: {
- 200: {
+ WarehouseLinkedTable: {
+ /**
+ * @description Warehouse-facing table name
+ * @example warehouse.orders
+ */
+ copy_name: string
+ /**
+ * @description Replication lag in milliseconds, when available
+ * @example 12000
+ */
+ lag_ms?: number
+ /**
+ * Format: date-time
+ * @description Last sync timestamp, when available
+ * @example 2026-06-23T17:48:00Z
+ */
+ last_synced_at?: string
+ /**
+ * @description Postgres table name
+ * @example orders
+ */
+ name: string
+ /**
+ * @description Postgres schema name
+ * @example public
+ */
+ schema: string
+ /**
+ * @description Warehouse copy sync state derived from replication status
+ * @example live
+ * @enum {string}
+ */
+ state: 'syncing' | 'live' | 'error'
+ /**
+ * @description Warehouse table size in bytes, when available
+ * @example 197912092672
+ */
+ warehouse_size_bytes?: number
+ }
+ WarehouseLinkTableBody: {
+ /**
+ * @description Whether to configure and install the Warehouse FDW in the project database. Defaults to false.
+ * @example false
+ */
+ install_fdw?: boolean
+ /**
+ * @description Postgres table name
+ * @example orders
+ */
+ name: string
+ /**
+ * @description Postgres schema name
+ * @example public
+ */
+ schema: string
+ }
+ WarehouseSetupStatusResponse: {
+ /** @description Project database FDW setup markers used to derive the Warehouse FDW phase */
+ fdw_status: {
+ /**
+ * @description Whether fdw_warehouse is available to install on the project database instance
+ * @example true
+ */
+ extension_available: boolean
+ /**
+ * @description Whether the fdw_warehouse extension exists in the project database
+ * @example true
+ */
+ extension_installed: boolean
+ /**
+ * @description Whether the Warehouse foreign schema import has exposed the Warehouse snapshots table
+ * @example true
+ */
+ foreign_schema_imported: boolean
+ /**
+ * @description Whether the local Warehouse schema exists in the project database
+ * @example true
+ */
+ schema_created: boolean
+ /**
+ * @description Whether the Warehouse foreign server exists in the project database
+ * @example true
+ */
+ server_configured: boolean
+ /**
+ * @description Whether the Warehouse foreign data wrapper exists in the project database
+ * @example true
+ */
+ wrapper_installed: boolean
+ }
+ /**
+ * @description Warehouse replication pipeline id when it exists
+ * @example 101
+ */
+ pipeline_id?: number
+ /**
+ * @description Overall Warehouse setup status derived from replication state
+ * @example copying
+ * @enum {string}
+ */
+ setup_status: 'not_started' | 'setting_up' | 'copying' | 'complete' | 'error'
+ /** @description Warehouse setup phases in execution order */
+ steps: {
+ /**
+ * @description Best-effort progress or error message derived from Warehouse state
+ * @example Pending initial copy: public.orders:copying_table
+ */
+ message?: string
+ /**
+ * @description Observable Warehouse setup phase
+ * @example warehouse_copy
+ * @enum {string}
+ */
+ name: 'warehouse_pipeline' | 'warehouse_copy' | 'warehouse_fdw'
+ /**
+ * @description Derived Warehouse setup step status
+ * @example running
+ * @enum {string}
+ */
+ status: 'waiting' | 'running' | 'completed' | 'skipped' | 'error'
+ }[]
+ /** @description Warehouse linked tables and replication-derived sync state */
+ tables: {
+ /**
+ * @description Warehouse-facing table name
+ * @example warehouse.orders
+ */
+ copy_name: string
+ /**
+ * @description Replication lag in milliseconds, when available
+ * @example 12000
+ */
+ lag_ms?: number
+ /**
+ * Format: date-time
+ * @description Last sync timestamp, when available
+ * @example 2026-06-23T17:48:00Z
+ */
+ last_synced_at?: string
+ /**
+ * @description Postgres table name
+ * @example orders
+ */
+ name: string
+ /**
+ * @description Postgres schema name
+ * @example public
+ */
+ schema: string
+ /**
+ * @description Warehouse copy sync state derived from replication status
+ * @example live
+ * @enum {string}
+ */
+ state: 'syncing' | 'live' | 'error'
+ /**
+ * @description Warehouse table size in bytes, when available
+ * @example 197912092672
+ */
+ warehouse_size_bytes?: number
+ }[]
+ }
+ WarehouseTableSnapshotsResponse: {
+ /** @description Available Warehouse snapshots for the project catalog. */
+ snapshots: {
+ /**
+ * @description Snapshot author, when available.
+ * @example postgres
+ */
+ author: string | null
+ /** @description Snapshot change metadata returned by the Warehouse FDW. */
+ changes: string | null
+ /** @description Additional snapshot commit metadata returned by the Warehouse FDW. */
+ commit_extra_info: string | null
+ /** @description Snapshot commit message, when available. */
+ commit_message: string | null
+ /**
+ * @description DuckLake schema version. Returned as a string because the source value is bigint.
+ * @example 7
+ */
+ schema_version: string | null
+ /**
+ * @description DuckLake snapshot id. Returned as a string because the source value is bigint.
+ * @example 42
+ */
+ snapshot_id: string
+ /**
+ * @description Snapshot timestamp returned by the Warehouse FDW.
+ * @example 2026-06-24 08:00:00+00
+ */
+ snapshot_time: string | null
+ }[]
+ }
+ WarehouseTablesResponse: {
+ /** @description Tables with Warehouse copies */
+ tables: {
+ /**
+ * @description Warehouse-facing table name
+ * @example warehouse.orders
+ */
+ copy_name: string
+ /**
+ * @description Replication lag in milliseconds, when available
+ * @example 12000
+ */
+ lag_ms?: number
+ /**
+ * Format: date-time
+ * @description Last sync timestamp, when available
+ * @example 2026-06-23T17:48:00Z
+ */
+ last_synced_at?: string
+ /**
+ * @description Postgres table name
+ * @example orders
+ */
+ name: string
+ /**
+ * @description Postgres schema name
+ * @example public
+ */
+ schema: string
+ /**
+ * @description Warehouse copy sync state derived from replication status
+ * @example live
+ * @enum {string}
+ */
+ state: 'syncing' | 'live' | 'error'
+ /**
+ * @description Warehouse table size in bytes, when available
+ * @example 197912092672
+ */
+ warehouse_size_bytes?: number
+ }[]
+ }
+ WorkflowRunResponse: {
+ branch_id: string
+ check_run_id: number | null
+ created_at: string
+ git_config?: unknown
+ id: string
+ /** @enum {string} */
+ status:
+ | 'CREATING_PROJECT'
+ | 'RUNNING_MIGRATIONS'
+ | 'MIGRATIONS_PASSED'
+ | 'MIGRATIONS_FAILED'
+ | 'FUNCTIONS_DEPLOYED'
+ | 'FUNCTIONS_FAILED'
+ updated_at: string
+ workdir: string | null
+ }
+ }
+ responses: never
+ parameters: never
+ requestBodies: never
+ headers: never
+ pathItems: never
+}
+export type $defs = Record
+export interface operations {
+ GoTrueConfigController_getGoTrueConfig: {
+ parameters: {
+ query?: never
+ header?: never
+ path: {
+ /** @description Project ref */
+ ref: string
+ }
+ cookie?: never
+ }
+ requestBody?: never
+ responses: {
+ 200: {
headers: {
[name: string]: unknown
}
@@ -14791,7 +15156,7 @@ export interface operations {
[name: string]: unknown
}
content: {
- 'application/json': components['schemas']['CreateUserReponse']
+ 'application/json': components['schemas']['CreateUserResponse']
}
}
/** @description Unauthorized */
@@ -14827,8 +15192,12 @@ export interface operations {
UsersController_deleteUserById: {
parameters: {
query?: {
- /** @description Boolean string, true or false */
- soft_delete?: boolean
+ /** @description Boolean string.
+ *
+ * Truthy values: `true`, `1`, `yes`, `on`, `y`, `enabled`
+ *
+ * Falsy values: `false`, `0`, `no`, `off`, `n`, `disabled` */
+ soft_delete?: string
}
header?: never
path: {
@@ -14898,7 +15267,7 @@ export interface operations {
[name: string]: unknown
}
content: {
- 'application/json': components['schemas']['UpdateUserReponse']
+ 'application/json': components['schemas']['UpdateUserResponse']
}
}
/** @description Unauthorized */
@@ -15587,7 +15956,9 @@ export interface operations {
headers: {
[name: string]: unknown
}
- content?: never
+ content: {
+ 'application/json': components['schemas']['PlanGateErrorBody']
+ }
}
/** @description Forbidden action */
403: {
@@ -15853,36 +16224,6 @@ export interface operations {
}
}
}
- SendFeedbackController_sendDocsFeedback: {
- parameters: {
- query?: never
- header?: never
- path?: never
- cookie?: never
- }
- requestBody: {
- content: {
- 'application/json': components['schemas']['SendDocsFeedbackBody']
- }
- }
- responses: {
- 201: {
- headers: {
- [name: string]: unknown
- }
- content: {
- 'application/json': components['schemas']['SendFeedbackResponse']
- }
- }
- /** @description Failed to send feedback for docs */
- 500: {
- headers: {
- [name: string]: unknown
- }
- content?: never
- }
- }
- }
SendFeedbackController_sendExitSurvey: {
parameters: {
query?: never
@@ -16137,6 +16478,7 @@ export interface operations {
parameters: {
query: {
organization_id: number
+ project_ref?: string
}
header?: never
path?: never
@@ -16247,6 +16589,58 @@ export interface operations {
}
}
}
+ GitHubConnectionsController_getGitHubConnectionConfig: {
+ parameters: {
+ query?: {
+ /** @description Git branch, tag or commit SHA to read the config from. Defaults to the default branch of the connected repository. */
+ ref?: string
+ }
+ header?: never
+ path: {
+ connection_id: number
+ }
+ cookie?: never
+ }
+ requestBody?: never
+ responses: {
+ 200: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['GetGitHubConnectionConfigResponse']
+ }
+ }
+ /** @description Not allowed to read the config of this connection */
+ 403: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ /** @description GitHub connection not found, or the repository has no config file */
+ 404: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ /** @description The config file could not be parsed as TOML */
+ 422: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ /** @description Failed to get the Supabase config of the connected GitHub repository */
+ 500: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ }
+ }
GitHubRepositoriesController_listRepositories: {
parameters: {
query?: never
@@ -16522,7 +16916,9 @@ export interface operations {
headers: {
[name: string]: unknown
}
- content?: never
+ content: {
+ 'application/json': components['schemas']['PlanGateErrorBody']
+ }
}
/** @description Forbidden action */
403: {
@@ -16582,7 +16978,9 @@ export interface operations {
headers: {
[name: string]: unknown
}
- content?: never
+ content: {
+ 'application/json': components['schemas']['PlanGateErrorBody']
+ }
}
/** @description Forbidden action */
403: {
@@ -17004,7 +17402,35 @@ export interface operations {
[name: string]: unknown
}
content: {
- 'application/json': components['schemas']['CreateOrganizationResponse']
+ 'application/json':
+ | {
+ pending_payment_intent_secret: string | null
+ }
+ | {
+ billing_email: string | null
+ billing_partner: ('aws_marketplace' | 'vercel_marketplace') | null
+ id: number
+ integration_source: string | null
+ is_owner: boolean
+ name: string
+ opt_in_tags: string[]
+ organization_missing_address: boolean
+ organization_missing_tax_id: boolean
+ organization_requires_mfa: boolean
+ plan: {
+ /** @enum {string} */
+ id: 'free' | 'pro' | 'team' | 'enterprise' | 'platform'
+ name: string
+ }
+ restriction_data: {
+ [key: string]: string
+ } | null
+ restriction_status: ('grace_period' | 'grace_period_over' | 'restricted') | null
+ slug: string
+ stripe_customer_id: string | null
+ subscription_id: string | null
+ usage_billing_enabled: boolean
+ }
}
}
/** @description Unexpected error creating an organization */
@@ -17247,7 +17673,9 @@ export interface operations {
headers: {
[name: string]: unknown
}
- content?: never
+ content: {
+ 'application/json': components['schemas']['PlanGateErrorBody']
+ }
}
/** @description Forbidden action */
403: {
@@ -19333,7 +19761,9 @@ export interface operations {
headers: {
[name: string]: unknown
}
- content?: never
+ content: {
+ 'application/json': components['schemas']['PlanGateErrorBody']
+ }
}
/** @description Unauthorized */
401: {
@@ -19383,7 +19813,9 @@ export interface operations {
headers: {
[name: string]: unknown
}
- content?: never
+ content: {
+ 'application/json': components['schemas']['PlanGateErrorBody']
+ }
}
/** @description Unauthorized */
401: {
@@ -19433,7 +19865,9 @@ export interface operations {
headers: {
[name: string]: unknown
}
- content?: never
+ content: {
+ 'application/json': components['schemas']['PlanGateErrorBody']
+ }
}
/** @description Unauthorized */
401: {
@@ -19808,7 +20242,14 @@ export interface operations {
[name: string]: unknown
}
content: {
- 'application/json': components['schemas']['CreateInvitationResponse']
+ 'application/json': {
+ failed: {
+ /** Format: email */
+ email: string
+ error: string
+ }[]
+ succeeded: string[]
+ } | null
}
}
/** @description Unauthorized */
@@ -20036,7 +20477,9 @@ export interface operations {
headers: {
[name: string]: unknown
}
- content?: never
+ content: {
+ 'application/json': components['schemas']['PlanGateErrorBody']
+ }
}
/** @description Forbidden action */
403: {
@@ -20873,7 +21316,38 @@ export interface operations {
[name: string]: unknown
}
content: {
- 'application/json': components['schemas']['GetSSOProviderResponse']
+ 'application/json':
+ | {
+ /** @default [] */
+ domains: string[]
+ email_mapping: string[]
+ enabled: boolean
+ first_name_mapping?: string[]
+ idjag_issuer_url?: string | null
+ join_org_on_signup_enabled: boolean
+ /** @enum {string} */
+ join_org_on_signup_role?: 'Administrator' | 'Developer' | 'Owner' | 'Read-only'
+ last_name_mapping?: string[]
+ metadata_xml_file: string
+ /** Format: uri */
+ metadata_xml_url?: string
+ user_name_mapping?: string[]
+ }
+ | {
+ /** @default [] */
+ domains: string[]
+ email_mapping: string[]
+ enabled: boolean
+ first_name_mapping?: string[]
+ idjag_issuer_url?: string | null
+ join_org_on_signup_enabled: boolean
+ /** @enum {string} */
+ join_org_on_signup_role?: 'Administrator' | 'Developer' | 'Owner' | 'Read-only'
+ last_name_mapping?: string[]
+ metadata_xml_file?: string
+ metadata_xml_url: string
+ user_name_mapping?: string[]
+ }
}
}
/** @description Unauthorized */
@@ -20920,7 +21394,38 @@ export interface operations {
[name: string]: unknown
}
content: {
- 'application/json': components['schemas']['UpdateSSOProviderResponse']
+ 'application/json':
+ | {
+ /** @default [] */
+ domains: string[]
+ email_mapping: string[]
+ enabled: boolean
+ first_name_mapping?: string[]
+ idjag_issuer_url?: string | null
+ join_org_on_signup_enabled: boolean
+ /** @enum {string} */
+ join_org_on_signup_role?: 'Administrator' | 'Developer' | 'Owner' | 'Read-only'
+ last_name_mapping?: string[]
+ metadata_xml_file: string
+ /** Format: uri */
+ metadata_xml_url?: string
+ user_name_mapping?: string[]
+ }
+ | {
+ /** @default [] */
+ domains: string[]
+ email_mapping: string[]
+ enabled: boolean
+ first_name_mapping?: string[]
+ idjag_issuer_url?: string | null
+ join_org_on_signup_enabled: boolean
+ /** @enum {string} */
+ join_org_on_signup_role?: 'Administrator' | 'Developer' | 'Owner' | 'Read-only'
+ last_name_mapping?: string[]
+ metadata_xml_file?: string
+ metadata_xml_url: string
+ user_name_mapping?: string[]
+ }
}
}
/** @description Unauthorized */
@@ -20967,7 +21472,38 @@ export interface operations {
[name: string]: unknown
}
content: {
- 'application/json': components['schemas']['CreateSSOProviderResponse']
+ 'application/json':
+ | {
+ /** @default [] */
+ domains: string[]
+ email_mapping: string[]
+ enabled: boolean
+ first_name_mapping?: string[]
+ idjag_issuer_url?: string | null
+ join_org_on_signup_enabled: boolean
+ /** @enum {string} */
+ join_org_on_signup_role?: 'Administrator' | 'Developer' | 'Owner' | 'Read-only'
+ last_name_mapping?: string[]
+ metadata_xml_file: string
+ /** Format: uri */
+ metadata_xml_url?: string
+ user_name_mapping?: string[]
+ }
+ | {
+ /** @default [] */
+ domains: string[]
+ email_mapping: string[]
+ enabled: boolean
+ first_name_mapping?: string[]
+ idjag_issuer_url?: string | null
+ join_org_on_signup_enabled: boolean
+ /** @enum {string} */
+ join_org_on_signup_role?: 'Administrator' | 'Developer' | 'Owner' | 'Read-only'
+ last_name_mapping?: string[]
+ metadata_xml_file?: string
+ metadata_xml_url: string
+ user_name_mapping?: string[]
+ }
}
}
/** @description Unauthorized */
@@ -20982,7 +21518,9 @@ export interface operations {
headers: {
[name: string]: unknown
}
- content?: never
+ content: {
+ 'application/json': components['schemas']['PlanGateErrorBody']
+ }
}
/** @description Forbidden action */
403: {
@@ -21091,108 +21629,6 @@ export interface operations {
}
}
}
- TaxIdsController_updateTaxId: {
- parameters: {
- query?: never
- header?: never
- path: {
- /** @description Organization slug */
- slug: string
- }
- cookie?: never
- }
- requestBody: {
- content: {
- 'application/json': components['schemas']['CreateTaxIdBody']
- }
- }
- responses: {
- 200: {
- headers: {
- [name: string]: unknown
- }
- content: {
- 'application/json': components['schemas']['TaxIdResponse']
- }
- }
- /** @description Unauthorized */
- 401: {
- headers: {
- [name: string]: unknown
- }
- content?: never
- }
- /** @description Forbidden action */
- 403: {
- headers: {
- [name: string]: unknown
- }
- content?: never
- }
- /** @description Rate limit exceeded */
- 429: {
- headers: {
- [name: string]: unknown
- }
- content?: never
- }
- /** @description Failed to create the tax ID */
- 500: {
- headers: {
- [name: string]: unknown
- }
- content?: never
- }
- }
- }
- TaxIdsController_deleteTaxId: {
- parameters: {
- query?: never
- header?: never
- path: {
- /** @description Organization slug */
- slug: string
- }
- cookie?: never
- }
- requestBody?: never
- responses: {
- 204: {
- headers: {
- [name: string]: unknown
- }
- content?: never
- }
- /** @description Unauthorized */
- 401: {
- headers: {
- [name: string]: unknown
- }
- content?: never
- }
- /** @description Forbidden action */
- 403: {
- headers: {
- [name: string]: unknown
- }
- content?: never
- }
- /** @description Rate limit exceeded */
- 429: {
- headers: {
- [name: string]: unknown
- }
- content?: never
- }
- /** @description Failed to delete the tax ID */
- 500: {
- headers: {
- [name: string]: unknown
- }
- content?: never
- }
- }
- }
OrgUsageController_getOrgUsage: {
parameters: {
query?: {
@@ -21351,7 +21787,35 @@ export interface operations {
[name: string]: unknown
}
content: {
- 'application/json': components['schemas']['CreateOrganizationResponse']
+ 'application/json':
+ | {
+ pending_payment_intent_secret: string | null
+ }
+ | {
+ billing_email: string | null
+ billing_partner: ('aws_marketplace' | 'vercel_marketplace') | null
+ id: number
+ integration_source: string | null
+ is_owner: boolean
+ name: string
+ opt_in_tags: string[]
+ organization_missing_address: boolean
+ organization_missing_tax_id: boolean
+ organization_requires_mfa: boolean
+ plan: {
+ /** @enum {string} */
+ id: 'free' | 'pro' | 'team' | 'enterprise' | 'platform'
+ name: string
+ }
+ restriction_data: {
+ [key: string]: string
+ } | null
+ restriction_status: ('grace_period' | 'grace_period_over' | 'restricted') | null
+ slug: string
+ stripe_customer_id: string | null
+ subscription_id: string | null
+ usage_billing_enabled: boolean
+ }
}
}
202: {
@@ -22064,6 +22528,7 @@ export interface operations {
| 'storage.image_transformations'
| 'storage.vector_buckets'
| 'storage.iceberg_catalog'
+ | 'storage.purge_cache'
| 'security.audit_logs_days'
| 'security.questionnaire'
| 'security.soc2_report'
@@ -22113,6 +22578,8 @@ export interface operations {
| 'integrations.github_connections'
| 'dedicated_pooler'
| 'observability.dashboard_advanced_metrics'
+ | 'api.members.invitations'
+ | 'api.members.roles'
}
header?: never
path?: never
@@ -22726,9 +23193,9 @@ export interface operations {
ApiKeysLastUsedController_getApiKeysLastUsed: {
parameters: {
query?: {
- iso_timestamp_start?: string
- iso_timestamp_end?: string
days?: string
+ iso_timestamp_end?: string
+ iso_timestamp_start?: string
}
header?: never
path: {
@@ -22988,6 +23455,115 @@ export interface operations {
}
}
}
+ LogsController_getProjectLogsViaGetNew: {
+ parameters: {
+ query?: {
+ iso_timestamp_end?: string
+ iso_timestamp_start?: string
+ lql?: string
+ sql?: string
+ }
+ header?: never
+ path: {
+ /** @description Project ref */
+ ref: string
+ }
+ cookie?: never
+ }
+ requestBody?: never
+ responses: {
+ 200: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['AnalyticsResponse']
+ }
+ }
+ /** @description Unauthorized */
+ 401: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ /** @description Forbidden action */
+ 403: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ /** @description Rate limit exceeded */
+ 429: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ /** @description Failed to get project's logs */
+ 500: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ }
+ }
+ LogsController_getProjectLogsViaPostNew: {
+ parameters: {
+ query?: never
+ header?: never
+ path: {
+ /** @description Project ref */
+ ref: string
+ }
+ cookie?: never
+ }
+ requestBody: {
+ content: {
+ 'application/json': components['schemas']['GetProjectLogsBody']
+ }
+ }
+ responses: {
+ 201: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['AnalyticsResponse']
+ }
+ }
+ /** @description Unauthorized */
+ 401: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ /** @description Forbidden action */
+ 403: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ /** @description Rate limit exceeded */
+ 429: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ /** @description Failed to get project's logs */
+ 500: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ }
+ }
LogsController_getProjectLogsViaGet: {
parameters: {
query?: {
@@ -23554,7 +24130,9 @@ export interface operations {
headers: {
[name: string]: unknown
}
- content?: never
+ content: {
+ 'application/json': components['schemas']['PlanGateErrorBody']
+ }
}
/** @description Forbidden action */
403: {
@@ -23793,11 +24371,11 @@ export interface operations {
}
}
}
- ApiKeysController_createTemporaryApiKey: {
+ 'scrape-project-metrics': {
parameters: {
- query: {
- authorization_exp: string
- claims: string
+ query?: {
+ /** @description Project service to include in the scrape. Valid values are `database`. Defaults to `database`. */
+ services?: string
}
header?: never
path: {
@@ -23808,13 +24386,68 @@ export interface operations {
}
requestBody?: never
responses: {
- /** @description Temporary API key */
- 201: {
+ /** @description Prometheus / OpenMetrics text exposition */
+ 200: {
headers: {
[name: string]: unknown
}
content: {
- 'application/json': components['schemas']['TemporaryApiKeyResponse']
+ 'application/openmetrics-text': string
+ 'text/plain': string
+ }
+ }
+ /** @description Unauthorized */
+ 401: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ /** @description Forbidden action */
+ 403: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ /** @description Rate limit exceeded */
+ 429: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ /** @description Failed to fetch project's metrics */
+ 500: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ }
+ }
+ ApiKeysController_createTemporaryApiKey: {
+ parameters: {
+ query: {
+ authorization_exp: string
+ claims: string
+ }
+ header?: never
+ path: {
+ /** @description Project ref */
+ ref: string
+ }
+ cookie?: never
+ }
+ requestBody?: never
+ responses: {
+ /** @description Temporary API key */
+ 201: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['TemporaryApiKeyResponse']
}
}
/** @description Unauthorized */
@@ -24778,8 +25411,12 @@ export interface operations {
parameters: {
query?: {
cursor?: string
- /** @description Boolean string, true or false */
- favorite?: boolean
+ /** @description Boolean string.
+ *
+ * Truthy values: `true`, `1`, `yes`, `on`, `y`, `enabled`
+ *
+ * Falsy values: `false`, `0`, `no`, `off`, `n`, `disabled` */
+ favorite?: string
limit?: string
name?: string
sort_by?: 'name' | 'inserted_at'
@@ -25847,65 +26484,68 @@ export interface operations {
| 'physical_replication_lag_physical_replication_lag_seconds'
| 'pg_stat_database_num_backends'
| 'max_db_connections'
- attributes?: (
- | 'cpu_usage'
- | 'cpu_usage_busy_system'
- | 'cpu_usage_busy_user'
- | 'cpu_usage_busy_iowait'
- | 'cpu_usage_busy_irqs'
- | 'cpu_usage_busy_other'
- | 'cpu_usage_busy_idle'
- | 'max_cpu_usage'
- | 'avg_cpu_usage'
- | 'ram_usage'
- | 'ram_usage_total'
- | 'ram_usage_available'
- | 'ram_usage_used'
- | 'ram_usage_free'
- | 'ram_usage_cache_and_buffers'
- | 'ram_usage_swap'
- | 'ram_commit_used'
- | 'ram_commit_limit'
- | 'swap_usage'
- | 'client_connections_pgbouncer'
- | 'network_receive_bytes'
- | 'network_transmit_bytes'
- | 'pgbouncer_pools_client_active_connections'
- | 'supavisor_connections_active'
- | 'client_connections_postgres'
- | 'client_connections_authenticator'
- | 'client_connections_supabase_auth_admin'
- | 'client_connections_supabase_storage_admin'
- | 'client_connections_supabase_admin'
- | 'client_connections_other'
- | 'realtime_connections_connected'
- | 'realtime_channel_joins'
- | 'realtime_channel_events'
- | 'realtime_channel_presence_events'
- | 'realtime_channel_db_events'
- | 'realtime_authorization_rls_execution_time'
- | 'realtime_read_authorization_rls_execution_time'
- | 'realtime_write_authorization_rls_execution_time'
- | 'realtime_payload_size'
- | 'realtime_replication_connection_lag'
- | 'realtime_sum_connections_connected'
- | 'disk_io_budget'
- | 'disk_io_consumption'
- | 'disk_io_usage'
- | 'disk_iops_read'
- | 'disk_iops_write'
- | 'disk_bytes_read'
- | 'disk_bytes_written'
- | 'pg_database_size'
- | 'disk_fs_size'
- | 'disk_fs_avail'
- | 'disk_fs_used'
- | 'disk_fs_used_wal'
- | 'disk_fs_used_system'
- | 'physical_replication_lag_physical_replication_lag_seconds'
- | 'pg_stat_database_num_backends'
- | 'max_db_connections'
- )[]
+ /** @description Comma-separated list of enums or array of enums. */
+ attributes?:
+ | string
+ | (
+ | 'cpu_usage'
+ | 'cpu_usage_busy_system'
+ | 'cpu_usage_busy_user'
+ | 'cpu_usage_busy_iowait'
+ | 'cpu_usage_busy_irqs'
+ | 'cpu_usage_busy_other'
+ | 'cpu_usage_busy_idle'
+ | 'max_cpu_usage'
+ | 'avg_cpu_usage'
+ | 'ram_usage'
+ | 'ram_usage_total'
+ | 'ram_usage_available'
+ | 'ram_usage_used'
+ | 'ram_usage_free'
+ | 'ram_usage_cache_and_buffers'
+ | 'ram_usage_swap'
+ | 'ram_commit_used'
+ | 'ram_commit_limit'
+ | 'swap_usage'
+ | 'client_connections_pgbouncer'
+ | 'network_receive_bytes'
+ | 'network_transmit_bytes'
+ | 'pgbouncer_pools_client_active_connections'
+ | 'supavisor_connections_active'
+ | 'client_connections_postgres'
+ | 'client_connections_authenticator'
+ | 'client_connections_supabase_auth_admin'
+ | 'client_connections_supabase_storage_admin'
+ | 'client_connections_supabase_admin'
+ | 'client_connections_other'
+ | 'realtime_connections_connected'
+ | 'realtime_channel_joins'
+ | 'realtime_channel_events'
+ | 'realtime_channel_presence_events'
+ | 'realtime_channel_db_events'
+ | 'realtime_authorization_rls_execution_time'
+ | 'realtime_read_authorization_rls_execution_time'
+ | 'realtime_write_authorization_rls_execution_time'
+ | 'realtime_payload_size'
+ | 'realtime_replication_connection_lag'
+ | 'realtime_sum_connections_connected'
+ | 'disk_io_budget'
+ | 'disk_io_consumption'
+ | 'disk_io_usage'
+ | 'disk_iops_read'
+ | 'disk_iops_write'
+ | 'disk_bytes_read'
+ | 'disk_bytes_written'
+ | 'pg_database_size'
+ | 'disk_fs_size'
+ | 'disk_fs_avail'
+ | 'disk_fs_used'
+ | 'disk_fs_used_wal'
+ | 'disk_fs_used_system'
+ | 'physical_replication_lag_physical_replication_lag_seconds'
+ | 'pg_stat_database_num_backends'
+ | 'max_db_connections'
+ )[]
databaseIdentifier?: string
endDate: string
interval?: '1m' | '5m' | '10m' | '30m' | '1h' | '1d'
@@ -26432,7 +27072,9 @@ export interface operations {
headers: {
[name: string]: unknown
}
- content?: never
+ content: {
+ 'application/json': components['schemas']['PlanGateErrorBody']
+ }
}
/** @description Forbidden action */
403: {
@@ -26514,6 +27156,64 @@ export interface operations {
}
}
}
+ ProjectPrivateLinkController_removeAwsAccountFromPrivateLinkForDatabase: {
+ parameters: {
+ query?: never
+ header?: never
+ path: {
+ aws_account_id: string
+ database_identifier: string
+ /** @description Project ref */
+ ref: string
+ }
+ cookie?: never
+ }
+ requestBody?: never
+ responses: {
+ /** @description Scheduled AWS PrivateLink resources to be removed. */
+ 200: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ /** @description Invalid AWS account ID format or association does not have a valid status for deletion. */
+ 400: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ /** @description Unauthorized */
+ 401: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ /** @description Forbidden action */
+ 403: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ /** @description Rate limit exceeded */
+ 429: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ /** @description Failed to remove AWS account from PrivateLink share */
+ 500: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ }
+ }
ResizeController_resizeDatabase: {
parameters: {
query?: never
@@ -26548,7 +27248,9 @@ export interface operations {
headers: {
[name: string]: unknown
}
- content?: never
+ content: {
+ 'application/json': components['schemas']['PlanGateErrorBody']
+ }
}
/** @description Forbidden action */
403: {
@@ -26824,41 +27526,11 @@ export interface operations {
}
}
}
- ProjectRunLintsController_runLintByName: {
+ ProjectServiceVersionsController_getServiceVersions: {
parameters: {
query?: never
header?: never
path: {
- name:
- | 'unindexed_foreign_keys'
- | 'auth_users_exposed'
- | 'auth_rls_initplan'
- | 'no_primary_key'
- | 'unused_index'
- | 'multiple_permissive_policies'
- | 'policy_exists_rls_disabled'
- | 'rls_enabled_no_policy'
- | 'duplicate_index'
- | 'security_definer_view'
- | 'function_search_path_mutable'
- | 'rls_disabled_in_public'
- | 'extension_in_public'
- | 'rls_references_user_metadata'
- | 'materialized_view_in_api'
- | 'foreign_table_in_api'
- | 'unsupported_reg_types'
- | 'auth_otp_long_expiry'
- | 'auth_otp_short_length'
- | 'ssl_not_enforced'
- | 'network_restrictions_not_set'
- | 'password_requirements_min_length'
- | 'pitr_not_enabled'
- | 'auth_leaked_password_protection'
- | 'auth_insufficient_mfa_options'
- | 'auth_password_policy_missing'
- | 'leaked_service_key'
- | 'no_backup_admin'
- | 'vulnerable_postgres_version'
/** @description Project ref */
ref: string
}
@@ -26871,7 +27543,7 @@ export interface operations {
[name: string]: unknown
}
content: {
- 'application/json': components['schemas']['RunLintByNameResponse']
+ 'application/json': components['schemas']['ServiceVersions']
}
}
/** @description Unauthorized */
@@ -26897,7 +27569,7 @@ export interface operations {
}
}
}
- ProjectRunLintsController_runLeakedServiceKeyLint: {
+ SettingsController_getProjectSettings: {
parameters: {
query?: never
header?: never
@@ -26914,7 +27586,7 @@ export interface operations {
[name: string]: unknown
}
content: {
- 'application/json': components['schemas']['GetLeakedServiceKeyLintResponse']
+ 'application/json': components['schemas']['ProjectSettingsResponse']
}
}
/** @description Unauthorized */
@@ -26938,9 +27610,16 @@ export interface operations {
}
content?: never
}
+ /** @description Failed to retrieve project's settings */
+ 500: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
}
}
- ProjectRunLintsController_runAuthBackupAdminLint: {
+ SensitivityController_updateProjectSensitivity: {
parameters: {
query?: never
header?: never
@@ -26950,14 +27629,18 @@ export interface operations {
}
cookie?: never
}
- requestBody?: never
+ requestBody: {
+ content: {
+ 'application/json': components['schemas']['MarkSensitiveBody']
+ }
+ }
responses: {
200: {
headers: {
[name: string]: unknown
}
content: {
- 'application/json': components['schemas']['AuthBackupAdminLintResponse']
+ 'application/json': components['schemas']['ProjectSensitivityResponse']
}
}
/** @description Unauthorized */
@@ -26981,9 +27664,16 @@ export interface operations {
}
content?: never
}
+ /** @description Failed to update project */
+ 500: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
}
}
- ProjectServiceVersionsController_getServiceVersions: {
+ ProjectStatusController_getStatus: {
parameters: {
query?: never
header?: never
@@ -26999,9 +27689,7 @@ export interface operations {
headers: {
[name: string]: unknown
}
- content: {
- 'application/json': components['schemas']['ServiceVersions']
- }
+ content?: never
}
/** @description Unauthorized */
401: {
@@ -27024,9 +27712,16 @@ export interface operations {
}
content?: never
}
+ /** @description Failed to get project's status */
+ 500: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
}
}
- SettingsController_getProjectSettings: {
+ ProjectTransferController_transferProject: {
parameters: {
query?: never
header?: never
@@ -27036,15 +27731,17 @@ export interface operations {
}
cookie?: never
}
- requestBody?: never
+ requestBody: {
+ content: {
+ 'application/json': components['schemas']['TransferProjectBody']
+ }
+ }
responses: {
- 200: {
+ 201: {
headers: {
[name: string]: unknown
}
- content: {
- 'application/json': components['schemas']['ProjectSettingsResponse']
- }
+ content?: never
}
/** @description Unauthorized */
401: {
@@ -27067,16 +27764,9 @@ export interface operations {
}
content?: never
}
- /** @description Failed to retrieve project's settings */
- 500: {
- headers: {
- [name: string]: unknown
- }
- content?: never
- }
}
}
- SensitivityController_updateProjectSensitivity: {
+ ProjectTransferController_previewTransfer: {
parameters: {
query?: never
header?: never
@@ -27088,16 +27778,16 @@ export interface operations {
}
requestBody: {
content: {
- 'application/json': components['schemas']['MarkSensitiveBody']
+ 'application/json': components['schemas']['TransferProjectBody']
}
}
responses: {
- 200: {
+ 201: {
headers: {
[name: string]: unknown
}
content: {
- 'application/json': components['schemas']['ProjectSensitivityResponse']
+ 'application/json': components['schemas']['PreviewProjectTransferResponse']
}
}
/** @description Unauthorized */
@@ -27121,156 +27811,9 @@ export interface operations {
}
content?: never
}
- /** @description Failed to update project */
- 500: {
- headers: {
- [name: string]: unknown
- }
- content?: never
- }
}
}
- ProjectStatusController_getStatus: {
- parameters: {
- query?: never
- header?: never
- path: {
- /** @description Project ref */
- ref: string
- }
- cookie?: never
- }
- requestBody?: never
- responses: {
- 200: {
- headers: {
- [name: string]: unknown
- }
- content?: never
- }
- /** @description Unauthorized */
- 401: {
- headers: {
- [name: string]: unknown
- }
- content?: never
- }
- /** @description Forbidden action */
- 403: {
- headers: {
- [name: string]: unknown
- }
- content?: never
- }
- /** @description Rate limit exceeded */
- 429: {
- headers: {
- [name: string]: unknown
- }
- content?: never
- }
- /** @description Failed to get project's status */
- 500: {
- headers: {
- [name: string]: unknown
- }
- content?: never
- }
- }
- }
- ProjectTransferController_transferProject: {
- parameters: {
- query?: never
- header?: never
- path: {
- /** @description Project ref */
- ref: string
- }
- cookie?: never
- }
- requestBody: {
- content: {
- 'application/json': components['schemas']['TransferProjectBody']
- }
- }
- responses: {
- 201: {
- headers: {
- [name: string]: unknown
- }
- content?: never
- }
- /** @description Unauthorized */
- 401: {
- headers: {
- [name: string]: unknown
- }
- content?: never
- }
- /** @description Forbidden action */
- 403: {
- headers: {
- [name: string]: unknown
- }
- content?: never
- }
- /** @description Rate limit exceeded */
- 429: {
- headers: {
- [name: string]: unknown
- }
- content?: never
- }
- }
- }
- ProjectTransferController_previewTransfer: {
- parameters: {
- query?: never
- header?: never
- path: {
- /** @description Project ref */
- ref: string
- }
- cookie?: never
- }
- requestBody: {
- content: {
- 'application/json': components['schemas']['TransferProjectBody']
- }
- }
- responses: {
- 201: {
- headers: {
- [name: string]: unknown
- }
- content: {
- 'application/json': components['schemas']['PreviewProjectTransferResponse']
- }
- }
- /** @description Unauthorized */
- 401: {
- headers: {
- [name: string]: unknown
- }
- content?: never
- }
- /** @description Forbidden action */
- 403: {
- headers: {
- [name: string]: unknown
- }
- content?: never
- }
- /** @description Rate limit exceeded */
- 429: {
- headers: {
- [name: string]: unknown
- }
- content?: never
- }
- }
- }
- ProjectWakeController_wakeUpProject: {
+ ProjectWakeController_wakeUpProject: {
parameters: {
query?: never
header?: never
@@ -27316,7 +27859,7 @@ export interface operations {
ProjectsController_getRegions: {
parameters: {
query: {
- cloud_provider: 'AWS' | 'FLY' | 'AWS_K8S' | 'AWS_NIMBUS'
+ cloud_provider: 'AWS' | 'AWS_K8S' | 'AWS_NIMBUS'
desired_instance_size?:
| 'micro'
| 'small'
@@ -27437,6 +27980,15 @@ export interface operations {
}
content?: never
}
+ /** @description This feature requires the Pro, Team, or Enterprise organization plan. */
+ 402: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['PlanGateErrorBody']
+ }
+ }
/** @description Forbidden action */
403: {
headers: {
@@ -27492,6 +28044,15 @@ export interface operations {
}
content?: never
}
+ /** @description This feature requires the Pro, Team, or Enterprise organization plan. */
+ 402: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['PlanGateErrorBody']
+ }
+ }
/** @description Forbidden action */
403: {
headers: {
@@ -27549,6 +28110,15 @@ export interface operations {
}
content?: never
}
+ /** @description This feature requires the Pro, Team, or Enterprise organization plan. */
+ 402: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['PlanGateErrorBody']
+ }
+ }
/** @description Forbidden action */
403: {
headers: {
@@ -27604,6 +28174,15 @@ export interface operations {
}
content?: never
}
+ /** @description This feature requires the Pro, Team, or Enterprise organization plan. */
+ 402: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['PlanGateErrorBody']
+ }
+ }
/** @description Forbidden action */
403: {
headers: {
@@ -27726,6 +28305,15 @@ export interface operations {
}
content?: never
}
+ /** @description This feature requires the Pro, Team, or Enterprise organization plan. */
+ 402: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['PlanGateErrorBody']
+ }
+ }
/** @description Forbidden action */
403: {
headers: {
@@ -27777,6 +28365,15 @@ export interface operations {
}
content?: never
}
+ /** @description This feature requires the Pro, Team, or Enterprise organization plan. */
+ 402: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['PlanGateErrorBody']
+ }
+ }
/** @description Forbidden action */
403: {
headers: {
@@ -27952,6 +28549,15 @@ export interface operations {
}
content?: never
}
+ /** @description This feature requires the Pro, Team, or Enterprise organization plan. */
+ 402: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['PlanGateErrorBody']
+ }
+ }
/** @description Forbidden action */
403: {
headers: {
@@ -28060,6 +28666,15 @@ export interface operations {
}
content?: never
}
+ /** @description This feature requires the Pro, Team, or Enterprise organization plan. */
+ 402: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['PlanGateErrorBody']
+ }
+ }
/** @description Forbidden action */
403: {
headers: {
@@ -28111,6 +28726,15 @@ export interface operations {
}
content?: never
}
+ /** @description This feature requires the Pro, Team, or Enterprise organization plan. */
+ 402: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['PlanGateErrorBody']
+ }
+ }
/** @description Forbidden action */
403: {
headers: {
@@ -28201,7 +28825,7 @@ export interface operations {
}
}
}
- ReplicationPipelinesController_rollbackTables: {
+ ReplicationPipelinesController_restartPipeline: {
parameters: {
query?: never
header?: never
@@ -28213,20 +28837,14 @@ export interface operations {
}
cookie?: never
}
- requestBody: {
- content: {
- 'application/json': components['schemas']['RollbackTablesBody']
- }
- }
+ requestBody?: never
responses: {
- /** @description New table states after rollback. */
- 200: {
+ /** @description Pipeline restart accepted. */
+ 202: {
headers: {
[name: string]: unknown
}
- content: {
- 'application/json': components['schemas']['RollbackTablesResponse']
- }
+ content?: never
}
/** @description Unauthorized */
401: {
@@ -28235,6 +28853,15 @@ export interface operations {
}
content?: never
}
+ /** @description This feature requires the Pro, Team, or Enterprise organization plan. */
+ 402: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['PlanGateErrorBody']
+ }
+ }
/** @description Forbidden action */
403: {
headers: {
@@ -28242,6 +28869,13 @@ export interface operations {
}
content?: never
}
+ /** @description Pipeline is not running. */
+ 409: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
/** @description Rate limit exceeded */
429: {
headers: {
@@ -28249,7 +28883,7 @@ export interface operations {
}
content?: never
}
- /** @description Unexpected error while rolling back tables. */
+ /** @description Unexpected error while restarting pipeline. */
500: {
headers: {
[name: string]: unknown
@@ -28258,7 +28892,7 @@ export interface operations {
}
}
}
- ReplicationPipelinesController_startPipeline: {
+ ReplicationPipelinesController_rollbackTables: {
parameters: {
query?: never
header?: never
@@ -28270,22 +28904,37 @@ export interface operations {
}
cookie?: never
}
- requestBody?: never
+ requestBody: {
+ content: {
+ 'application/json': components['schemas']['RollbackTablesBody']
+ }
+ }
responses: {
- /** @description Pipeline started. */
+ /** @description New table states after rollback. */
200: {
headers: {
[name: string]: unknown
}
- content?: never
- }
- /** @description Unauthorized */
+ content: {
+ 'application/json': components['schemas']['RollbackTablesResponse']
+ }
+ }
+ /** @description Unauthorized */
401: {
headers: {
[name: string]: unknown
}
content?: never
}
+ /** @description This feature requires the Pro, Team, or Enterprise organization plan. */
+ 402: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['PlanGateErrorBody']
+ }
+ }
/** @description Forbidden action */
403: {
headers: {
@@ -28300,7 +28949,7 @@ export interface operations {
}
content?: never
}
- /** @description Unexpected error while starting pipeline. */
+ /** @description Unexpected error while rolling back tables. */
500: {
headers: {
[name: string]: unknown
@@ -28309,7 +28958,7 @@ export interface operations {
}
}
}
- ReplicationPipelinesController_restartPipeline: {
+ ReplicationPipelinesController_startPipeline: {
parameters: {
query?: never
header?: never
@@ -28323,8 +28972,8 @@ export interface operations {
}
requestBody?: never
responses: {
- /** @description Pipeline restart accepted. */
- 202: {
+ /** @description Pipeline started. */
+ 200: {
headers: {
[name: string]: unknown
}
@@ -28337,15 +28986,17 @@ export interface operations {
}
content?: never
}
- /** @description Forbidden action */
- 403: {
+ /** @description This feature requires the Pro, Team, or Enterprise organization plan. */
+ 402: {
headers: {
[name: string]: unknown
}
- content?: never
+ content: {
+ 'application/json': components['schemas']['PlanGateErrorBody']
+ }
}
- /** @description Pipeline is not running. */
- 409: {
+ /** @description Forbidden action */
+ 403: {
headers: {
[name: string]: unknown
}
@@ -28358,7 +29009,7 @@ export interface operations {
}
content?: never
}
- /** @description Unexpected error while restarting pipeline. */
+ /** @description Unexpected error while starting pipeline. */
500: {
headers: {
[name: string]: unknown
@@ -28448,6 +29099,15 @@ export interface operations {
}
content?: never
}
+ /** @description This feature requires the Pro, Team, or Enterprise organization plan. */
+ 402: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['PlanGateErrorBody']
+ }
+ }
/** @description Forbidden action */
403: {
headers: {
@@ -28556,6 +29216,15 @@ export interface operations {
}
content?: never
}
+ /** @description This feature requires the Pro, Team, or Enterprise organization plan. */
+ 402: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['PlanGateErrorBody']
+ }
+ }
/** @description Forbidden action */
403: {
headers: {
@@ -28718,7 +29387,9 @@ export interface operations {
headers: {
[name: string]: unknown
}
- content?: never
+ content: {
+ 'application/json': components['schemas']['PlanGateErrorBody']
+ }
}
/** @description Forbidden action */
403: {
@@ -28796,13 +29467,11 @@ export interface operations {
}
}
}
- ReplicationSourcesController_getCostEstimate: {
+ ReplicationSourcesController_createPublication: {
parameters: {
query?: never
header?: never
path: {
- /** @description Publication name */
- publication_name: string
/** @description Project ref */
ref: string
/** @description Source id */
@@ -28810,16 +29479,18 @@ export interface operations {
}
cookie?: never
}
- requestBody?: never
+ requestBody: {
+ content: {
+ 'application/json': components['schemas']['CreateReplicationPublicationBody']
+ }
+ }
responses: {
- /** @description Cost estimate for replicating the publication. */
+ /** @description Publication created. */
200: {
headers: {
[name: string]: unknown
}
- content: {
- 'application/json': components['schemas']['CostEstimateResponse']
- }
+ content?: never
}
/** @description Unauthorized */
401: {
@@ -28828,6 +29499,15 @@ export interface operations {
}
content?: never
}
+ /** @description This feature requires the Pro, Team, or Enterprise organization plan. */
+ 402: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['PlanGateErrorBody']
+ }
+ }
/** @description Forbidden action */
403: {
headers: {
@@ -28842,7 +29522,7 @@ export interface operations {
}
content?: never
}
- /** @description Unexpected error while estimating replication cost. */
+ /** @description Unexpected error while creating publication. */
500: {
headers: {
[name: string]: unknown
@@ -28851,11 +29531,13 @@ export interface operations {
}
}
}
- ReplicationSourcesController_createPublication: {
+ ReplicationSourcesController_updatePublication: {
parameters: {
query?: never
header?: never
path: {
+ /** @description Publication name */
+ publication_name: string
/** @description Project ref */
ref: string
/** @description Source id */
@@ -28865,11 +29547,11 @@ export interface operations {
}
requestBody: {
content: {
- 'application/json': components['schemas']['CreateReplicationPublicationBody']
+ 'application/json': components['schemas']['UpdateReplicationPublicationBody']
}
}
responses: {
- /** @description Publication created. */
+ /** @description Publication updated. */
200: {
headers: {
[name: string]: unknown
@@ -28883,6 +29565,15 @@ export interface operations {
}
content?: never
}
+ /** @description This feature requires the Pro, Team, or Enterprise organization plan. */
+ 402: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['PlanGateErrorBody']
+ }
+ }
/** @description Forbidden action */
403: {
headers: {
@@ -28897,7 +29588,7 @@ export interface operations {
}
content?: never
}
- /** @description Unexpected error while creating publication. */
+ /** @description Unexpected error while updating publication. */
500: {
headers: {
[name: string]: unknown
@@ -28906,7 +29597,7 @@ export interface operations {
}
}
}
- ReplicationSourcesController_updatePublication: {
+ ReplicationSourcesController_deletePublication: {
parameters: {
query?: never
header?: never
@@ -28920,13 +29611,9 @@ export interface operations {
}
cookie?: never
}
- requestBody: {
- content: {
- 'application/json': components['schemas']['UpdateReplicationPublicationBody']
- }
- }
+ requestBody?: never
responses: {
- /** @description Publication updated. */
+ /** @description Publication deleted. */
200: {
headers: {
[name: string]: unknown
@@ -28940,6 +29627,15 @@ export interface operations {
}
content?: never
}
+ /** @description This feature requires the Pro, Team, or Enterprise organization plan. */
+ 402: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['PlanGateErrorBody']
+ }
+ }
/** @description Forbidden action */
403: {
headers: {
@@ -28947,6 +29643,13 @@ export interface operations {
}
content?: never
}
+ /** @description Source not found. */
+ 404: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
/** @description Rate limit exceeded */
429: {
headers: {
@@ -28954,7 +29657,7 @@ export interface operations {
}
content?: never
}
- /** @description Unexpected error while updating publication. */
+ /** @description Unexpected error while deleting publication. */
500: {
headers: {
[name: string]: unknown
@@ -28963,7 +29666,7 @@ export interface operations {
}
}
}
- ReplicationSourcesController_deletePublication: {
+ ReplicationSourcesController_getCostEstimate: {
parameters: {
query?: never
header?: never
@@ -28979,12 +29682,14 @@ export interface operations {
}
requestBody?: never
responses: {
- /** @description Publication deleted. */
+ /** @description Cost estimate for replicating the publication. */
200: {
headers: {
[name: string]: unknown
}
- content?: never
+ content: {
+ 'application/json': components['schemas']['CostEstimateResponse']
+ }
}
/** @description Unauthorized */
401: {
@@ -29000,13 +29705,6 @@ export interface operations {
}
content?: never
}
- /** @description Source not found. */
- 404: {
- headers: {
- [name: string]: unknown
- }
- content?: never
- }
/** @description Rate limit exceeded */
429: {
headers: {
@@ -29014,7 +29712,7 @@ export interface operations {
}
content?: never
}
- /** @description Unexpected error while deleting publication. */
+ /** @description Unexpected error while estimating replication cost. */
500: {
headers: {
[name: string]: unknown
@@ -29102,6 +29800,15 @@ export interface operations {
}
content?: never
}
+ /** @description This feature requires the Pro, Team, or Enterprise organization plan. */
+ 402: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['PlanGateErrorBody']
+ }
+ }
/** @description Forbidden action */
403: {
headers: {
@@ -29172,7 +29879,9 @@ export interface operations {
headers: {
[name: string]: unknown
}
- content?: never
+ content: {
+ 'application/json': components['schemas']['PlanGateErrorBody']
+ }
}
/** @description Forbidden action */
403: {
@@ -29383,7 +30092,7 @@ export interface operations {
query?: never
header?: never
path: {
- /** @description Analytics Bucket ID */
+ /** @description Storage bucket id */
id: string
/** @description Project ref */
ref: string
@@ -29435,7 +30144,7 @@ export interface operations {
query?: never
header?: never
path: {
- /** @description Analytics Bucket ID */
+ /** @description Storage bucket id */
id: string
/** @description Project ref */
ref: string
@@ -29487,7 +30196,7 @@ export interface operations {
query?: never
header?: never
path: {
- /** @description Analytics Bucket ID */
+ /** @description Storage bucket id */
id: string
/** @description Project ref */
ref: string
@@ -29700,8 +30409,12 @@ export interface operations {
StorageAnalyticsBucketNamespaceTableController_dropTable: {
parameters: {
query?: {
- /** @description Boolean string, true or false */
- purge?: boolean
+ /** @description Boolean string.
+ *
+ * Truthy values: `true`, `1`, `yes`, `on`, `y`, `enabled`
+ *
+ * Falsy values: `false`, `0`, `no`, `off`, `n`, `disabled` */
+ purge?: string
}
header?: never
path: {
@@ -30608,7 +31321,7 @@ export interface operations {
}
}
}
- StorageS3CredentialsController_getAllCredentials: {
+ StorageCdnController_purgeBucketCache: {
parameters: {
query?: never
header?: never
@@ -30618,15 +31331,17 @@ export interface operations {
}
cookie?: never
}
- requestBody?: never
+ requestBody: {
+ content: {
+ 'application/json': components['schemas']['PurgeBucketCacheBody']
+ }
+ }
responses: {
- 200: {
+ 201: {
headers: {
[name: string]: unknown
}
- content: {
- 'application/json': components['schemas']['GetStorageCredentialsResponse']
- }
+ content?: never
}
/** @description Unauthorized */
401: {
@@ -30635,6 +31350,15 @@ export interface operations {
}
content?: never
}
+ /** @description This feature requires the Pro, Team, or Enterprise organization plan. */
+ 402: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['PlanGateErrorBody']
+ }
+ }
/** @description Forbidden action */
403: {
headers: {
@@ -30649,7 +31373,7 @@ export interface operations {
}
content?: never
}
- /** @description Failed to get project storage credentials */
+ /** @description Failed to purge CDN cache for bucket */
500: {
headers: {
[name: string]: unknown
@@ -30658,7 +31382,7 @@ export interface operations {
}
}
}
- StorageS3CredentialsController_createCredential: {
+ StorageCdnController_purgeObjectCache: {
parameters: {
query?: never
header?: never
@@ -30670,7 +31394,7 @@ export interface operations {
}
requestBody: {
content: {
- 'application/json': components['schemas']['CreateStorageCredentialBody']
+ 'application/json': components['schemas']['PurgeObjectCacheBody']
}
}
responses: {
@@ -30678,9 +31402,7 @@ export interface operations {
headers: {
[name: string]: unknown
}
- content: {
- 'application/json': components['schemas']['CreateStorageCredentialResponse']
- }
+ content?: never
}
/** @description Unauthorized */
401: {
@@ -30689,6 +31411,15 @@ export interface operations {
}
content?: never
}
+ /** @description This feature requires the Pro, Team, or Enterprise organization plan. */
+ 402: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['PlanGateErrorBody']
+ }
+ }
/** @description Forbidden action */
403: {
headers: {
@@ -30703,7 +31434,7 @@ export interface operations {
}
content?: never
}
- /** @description Failed to create project storage credential */
+ /** @description Failed to purge CDN cache for object */
500: {
headers: {
[name: string]: unknown
@@ -30712,13 +31443,11 @@ export interface operations {
}
}
}
- StorageS3CredentialsController_deleteCredential: {
+ StorageS3CredentialsController_getAllCredentials: {
parameters: {
query?: never
header?: never
path: {
- /** @description Storage credential id */
- id: string
/** @description Project ref */
ref: string
}
@@ -30726,11 +31455,13 @@ export interface operations {
}
requestBody?: never
responses: {
- 204: {
+ 200: {
headers: {
[name: string]: unknown
}
- content?: never
+ content: {
+ 'application/json': components['schemas']['GetStorageCredentialsResponse']
+ }
}
/** @description Unauthorized */
401: {
@@ -30753,7 +31484,7 @@ export interface operations {
}
content?: never
}
- /** @description Failed to delete project storage credential */
+ /** @description Failed to get project storage credentials */
500: {
headers: {
[name: string]: unknown
@@ -30762,11 +31493,9 @@ export interface operations {
}
}
}
- StorageVectorBucketsController_getBuckets: {
+ StorageS3CredentialsController_createCredential: {
parameters: {
- query?: {
- nextToken?: string
- }
+ query?: never
header?: never
path: {
/** @description Project ref */
@@ -30774,14 +31503,18 @@ export interface operations {
}
cookie?: never
}
- requestBody?: never
+ requestBody: {
+ content: {
+ 'application/json': components['schemas']['CreateStorageCredentialBody']
+ }
+ }
responses: {
- 200: {
+ 201: {
headers: {
[name: string]: unknown
}
content: {
- 'application/json': components['schemas']['StorageVectorBucketsResponse']
+ 'application/json': components['schemas']['CreateStorageCredentialResponse']
}
}
/** @description Unauthorized */
@@ -30805,7 +31538,7 @@ export interface operations {
}
content?: never
}
- /** @description Failed to get list of vector buckets */
+ /** @description Failed to create project storage credential */
500: {
headers: {
[name: string]: unknown
@@ -30814,23 +31547,21 @@ export interface operations {
}
}
}
- StorageVectorBucketsController_createBucket: {
+ StorageS3CredentialsController_deleteCredential: {
parameters: {
query?: never
header?: never
path: {
+ /** @description Storage credential id */
+ id: string
/** @description Project ref */
ref: string
}
cookie?: never
}
- requestBody: {
- content: {
- 'application/json': components['schemas']['CreateStorageVectorBucketBody']
- }
- }
+ requestBody?: never
responses: {
- 201: {
+ 204: {
headers: {
[name: string]: unknown
}
@@ -30857,7 +31588,7 @@ export interface operations {
}
content?: never
}
- /** @description Failed to create vector bucket */
+ /** @description Failed to delete project storage credential */
500: {
headers: {
[name: string]: unknown
@@ -30866,12 +31597,13 @@ export interface operations {
}
}
}
- StorageVectorBucketIdController_getBucket: {
+ StorageVectorBucketsController_getBuckets: {
parameters: {
- query?: never
+ query?: {
+ nextToken?: string
+ }
header?: never
path: {
- id: string
/** @description Project ref */
ref: string
}
@@ -30884,7 +31616,7 @@ export interface operations {
[name: string]: unknown
}
content: {
- 'application/json': components['schemas']['StorageVectorBucketResponse']
+ 'application/json': components['schemas']['StorageVectorBucketsResponse']
}
}
/** @description Unauthorized */
@@ -30908,7 +31640,7 @@ export interface operations {
}
content?: never
}
- /** @description Failed to get bucket */
+ /** @description Failed to get list of vector buckets */
500: {
headers: {
[name: string]: unknown
@@ -30917,19 +31649,122 @@ export interface operations {
}
}
}
- StorageVectorBucketIdController_deleteBucket: {
+ StorageVectorBucketsController_createBucket: {
parameters: {
query?: never
header?: never
path: {
- id: string
/** @description Project ref */
ref: string
}
cookie?: never
}
- requestBody?: never
- responses: {
+ requestBody: {
+ content: {
+ 'application/json': components['schemas']['CreateStorageVectorBucketBody']
+ }
+ }
+ responses: {
+ 201: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ /** @description Unauthorized */
+ 401: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ /** @description Forbidden action */
+ 403: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ /** @description Rate limit exceeded */
+ 429: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ /** @description Failed to create vector bucket */
+ 500: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ }
+ }
+ StorageVectorBucketIdController_getBucket: {
+ parameters: {
+ query?: never
+ header?: never
+ path: {
+ id: string
+ /** @description Project ref */
+ ref: string
+ }
+ cookie?: never
+ }
+ requestBody?: never
+ responses: {
+ 200: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['StorageVectorBucketResponse']
+ }
+ }
+ /** @description Unauthorized */
+ 401: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ /** @description Forbidden action */
+ 403: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ /** @description Rate limit exceeded */
+ 429: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ /** @description Failed to get bucket */
+ 500: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ }
+ }
+ StorageVectorBucketIdController_deleteBucket: {
+ parameters: {
+ query?: never
+ header?: never
+ path: {
+ id: string
+ /** @description Project ref */
+ ref: string
+ }
+ cookie?: never
+ }
+ requestBody?: never
+ responses: {
200: {
headers: {
[name: string]: unknown
@@ -31500,6 +32335,465 @@ export interface operations {
}
}
}
+ WarehouseController_getCatalog: {
+ parameters: {
+ query?: never
+ header?: never
+ path: {
+ /** @description Project ref */
+ ref: string
+ }
+ cookie?: never
+ }
+ requestBody?: never
+ responses: {
+ /** @description Warehouse catalog access. */
+ 200: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['WarehouseCatalogResponse']
+ }
+ }
+ /** @description Unauthorized */
+ 401: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ /** @description Forbidden action */
+ 403: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ /** @description Rate limit exceeded */
+ 429: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ /** @description Unexpected error while retrieving Warehouse catalog. */
+ 500: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ }
+ }
+ WarehouseController_updateCatalog: {
+ parameters: {
+ query?: never
+ header?: never
+ path: {
+ /** @description Project ref */
+ ref: string
+ }
+ cookie?: never
+ }
+ requestBody: {
+ content: {
+ 'application/json': components['schemas']['UpdateWarehouseCatalogBody']
+ }
+ }
+ responses: {
+ /** @description Warehouse catalog access updated. */
+ 200: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['WarehouseCatalogResponse']
+ }
+ }
+ /** @description Unauthorized */
+ 401: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ /** @description This feature requires the Pro, Team, or Enterprise organization plan. */
+ 402: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['PlanGateErrorBody']
+ }
+ }
+ /** @description Forbidden action */
+ 403: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ /** @description Rate limit exceeded */
+ 429: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ /** @description Unexpected error while updating Warehouse catalog. */
+ 500: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ }
+ }
+ WarehouseController_refreshSchema: {
+ parameters: {
+ query?: never
+ header?: never
+ path: {
+ /** @description Project ref */
+ ref: string
+ }
+ cookie?: never
+ }
+ requestBody?: never
+ responses: {
+ /** @description Warehouse foreign schema refresh accepted. */
+ 202: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ /** @description Unauthorized */
+ 401: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ /** @description This feature requires the Pro, Team, or Enterprise organization plan. */
+ 402: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['PlanGateErrorBody']
+ }
+ }
+ /** @description Forbidden action */
+ 403: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ /** @description Rate limit exceeded */
+ 429: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ /** @description Unexpected error while refreshing the Warehouse foreign schema. */
+ 500: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ }
+ }
+ WarehouseController_getSetupStatus: {
+ parameters: {
+ query?: never
+ header?: never
+ path: {
+ /** @description Project ref */
+ ref: string
+ }
+ cookie?: never
+ }
+ requestBody?: never
+ responses: {
+ /** @description Warehouse setup status. */
+ 200: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['WarehouseSetupStatusResponse']
+ }
+ }
+ /** @description Unauthorized */
+ 401: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ /** @description Forbidden action */
+ 403: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ /** @description Rate limit exceeded */
+ 429: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ /** @description Unexpected error while retrieving Warehouse setup status. */
+ 500: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ }
+ }
+ WarehouseController_getTables: {
+ parameters: {
+ query?: never
+ header?: never
+ path: {
+ /** @description Project ref */
+ ref: string
+ }
+ cookie?: never
+ }
+ requestBody?: never
+ responses: {
+ /** @description Warehouse linked tables. */
+ 200: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['WarehouseTablesResponse']
+ }
+ }
+ /** @description Unauthorized */
+ 401: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ /** @description Forbidden action */
+ 403: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ /** @description Rate limit exceeded */
+ 429: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ /** @description Unexpected error while listing Warehouse tables. */
+ 500: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ }
+ }
+ WarehouseController_linkTable: {
+ parameters: {
+ query?: never
+ header?: never
+ path: {
+ /** @description Project ref */
+ ref: string
+ }
+ cookie?: never
+ }
+ requestBody: {
+ content: {
+ 'application/json': components['schemas']['WarehouseLinkTableBody']
+ }
+ }
+ responses: {
+ /** @description Warehouse table link accepted. */
+ 202: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['WarehouseLinkedTable']
+ }
+ }
+ /** @description Unauthorized */
+ 401: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ /** @description This feature requires the Pro, Team, or Enterprise organization plan. */
+ 402: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['PlanGateErrorBody']
+ }
+ }
+ /** @description Forbidden action */
+ 403: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ /** @description Rate limit exceeded */
+ 429: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ /** @description Unexpected error while linking Warehouse table. */
+ 500: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ }
+ }
+ WarehouseController_detachTable: {
+ parameters: {
+ query?: never
+ header?: never
+ path: {
+ /** @description Postgres table name */
+ name: string
+ /** @description Project ref */
+ ref: string
+ /** @description Postgres schema name */
+ schema: string
+ }
+ cookie?: never
+ }
+ requestBody?: never
+ responses: {
+ /** @description Warehouse table detached. */
+ 204: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ /** @description Unauthorized */
+ 401: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ /** @description This feature requires the Pro, Team, or Enterprise organization plan. */
+ 402: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['PlanGateErrorBody']
+ }
+ }
+ /** @description Forbidden action */
+ 403: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ /** @description Rate limit exceeded */
+ 429: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ /** @description Unexpected error while detaching Warehouse table. */
+ 500: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ }
+ }
+ WarehouseController_getTableSnapshots: {
+ parameters: {
+ query?: {
+ /** @description Maximum number of snapshots to return. */
+ limit?: number
+ }
+ header?: never
+ path: {
+ /** @description Postgres table name */
+ name: string
+ /** @description Project ref */
+ ref: string
+ /** @description Postgres schema name */
+ schema: string
+ }
+ cookie?: never
+ }
+ requestBody?: never
+ responses: {
+ /** @description Warehouse snapshots. */
+ 200: {
+ headers: {
+ [name: string]: unknown
+ }
+ content: {
+ 'application/json': components['schemas']['WarehouseTableSnapshotsResponse']
+ }
+ }
+ /** @description Unauthorized */
+ 401: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ /** @description Forbidden action */
+ 403: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ /** @description Rate limit exceeded */
+ 429: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ /** @description Unexpected error while listing Warehouse snapshots. */
+ 500: {
+ headers: {
+ [name: string]: unknown
+ }
+ content?: never
+ }
+ }
+ }
WorkflowRunController_listWorkflowRuns: {
parameters: {
query?: {
diff --git a/packages/ui-patterns/src/Chart/charts/chart-bar.tsx b/packages/ui-patterns/src/Chart/charts/chart-bar.tsx
index 79c0f16f512ea..e81034adabb74 100644
--- a/packages/ui-patterns/src/Chart/charts/chart-bar.tsx
+++ b/packages/ui-patterns/src/Chart/charts/chart-bar.tsx
@@ -73,6 +73,9 @@ export interface ChartBarProps {
}
}
+// [Joshen] JFYI - shouldn't rely on xKey's value to determine if its a time-based format
+// Preferably provide an additional param like xFormat to be more deterministic
+
export const ChartBar = ({
data,
xKey = 'timestamp',
diff --git a/packages/ui-patterns/src/Chart/charts/chart-line.tsx b/packages/ui-patterns/src/Chart/charts/chart-line.tsx
index 1811933d845a0..a2571ff78c540 100644
--- a/packages/ui-patterns/src/Chart/charts/chart-line.tsx
+++ b/packages/ui-patterns/src/Chart/charts/chart-line.tsx
@@ -84,6 +84,9 @@ export interface ChartLineProps {
referenceLines?: ChartReferenceLine[]
}
+// [Joshen] JFYI - shouldn't rely on xKey's value to determine if its a time-based format
+// Preferably provide an additional param like xFormat to be more deterministic
+
export const ChartLine = ({
data,
xKey = 'timestamp',
@@ -305,7 +308,7 @@ export const ChartLine = ({
fillOpacity={fillOpacity}
stroke={lineColor}
strokeWidth={strokeWidth}
- stackId={`stack-${key}`}
+ stackId={keysToRender.length > 1 ? `stack-${key}` : undefined}
/>
)
})}