Plugins

Lists the catalog of available plugins (v_plugins) and tenant plugin installations (v_plugin_installations). Install, update, and uninstall plugins for a tenant. Outbound webhooks are driven by audit.entity_changes when you add allowlisted subscriptions; deliveries are processed in-database via pg_net and pg_cron (see How to build a plugin and Building plugins). Installing and managing installations and subscriptions requires tenant.admin permission. Set tenant context before listing or managing installations.

List plugins (catalog)

List all available plugins (from v_plugins). No tenant context required.

client.plugins.list()

const plugins = await client.plugins.list()
// Returns PluginRow[] (id, key, name, description, is_active, is_integration, created_at, updated_at)

Get plugin by ID

Fetch a single plugin from the catalog by ID.

client.plugins.getById(id)

const plugin = await client.plugins.getById('uuid-of-plugin')
// Returns PluginRow | null

List installations

List plugin installations for the current tenant (from v_plugin_installations). Requires tenant context and tenant.admin permission.

client.plugins.listInstallations()

await client.setTenant(tenantId)

const installations = await client.plugins.listInstallations()
// Returns PluginInstallationRow[] (id, plugin_id, plugin_key, plugin_name, tenant_id, status, config, secret_ref, installed_at, installed_by, updated_at, is_integration)

Install plugin

Install a plugin for a tenant. Returns the installation UUID. Requires tenant.admin permission. Rate limited (e.g. 10 requests per minute per user).

client.plugins.install(params)

const installationId = await client.plugins.install({
  tenantId: 'uuid-of-tenant',
  pluginKey: 'my-integration',
  secretRef: null,
  config: { apiEndpoint: 'https://example.com' },
})
// Returns string (UUID)
  • Name
    tenantId
    Description

    Required. Tenant UUID.

  • Name
    pluginKey
    Description

    Required. Plugin key (from catalog).

  • Name
    secretRef
    Description

    Optional. Opaque reference to stored secret (e.g. API key); not the secret value.

  • Name
    config
    Description

    Optional. Installation config (JSON object).

Update installation

Update a plugin installation (status, secret_ref, config). Requires tenant.admin permission.

client.plugins.updateInstallation(params)

await client.plugins.updateInstallation({
  tenantId: 'uuid-of-tenant',
  installationId: 'uuid-of-installation',
  status: 'active',
  secretRef: 'vault-ref-123',
  config: { apiEndpoint: 'https://api.example.com' },
})
  • Name
    tenantId
    Description

    Required. Tenant UUID.

  • Name
    installationId
    Description

    Required. Installation UUID (from listInstallations).

  • Name
    status
    Description

    Optional. Status (e.g. active, paused).

  • Name
    secretRef
    Description

    Optional. Opaque reference to stored secret.

  • Name
    config
    Description

    Optional. Installation config (JSON object).

Uninstall plugin

Uninstall a plugin for a tenant. Requires tenant.admin permission. Rate limited.

client.plugins.uninstall(params)

await client.plugins.uninstall({
  tenantId: 'uuid-of-tenant',
  installationId: 'uuid-of-installation',
})
  • Name
    tenantId
    Description

    Required. Tenant UUID.

  • Name
    installationId
    Description

    Required. Installation UUID.

Webhook subscriptions

Allowlist which audited tables and operations should enqueue outbound webhook deliveries for an installation. No subscription rows means no outbound events for that installation. Requires tenant.admin and tenant context.

client.plugins.upsertWebhookSubscription(params)

await client.setTenant(tenantId)

const subscriptionId = await client.plugins.upsertWebhookSubscription({
  tenantId,
  installationId,
  tableSchema: 'app',
  tableName: 'work_orders',
  operations: ['INSERT', 'UPDATE'],
  changedFieldsAllowlist: null, // optional: for UPDATE, require overlap with these columns
  includePayload: false, // when false, snapshot omits full old_data/new_data (recommended)
})
// Returns string (subscription UUID)

client.plugins.listWebhookSubscriptions()

await client.setTenant(tenantId)

const subs = await client.plugins.listWebhookSubscriptions()
// v_plugin_webhook_subscriptions — plugin_key, table_schema, table_name, operations, include_payload, …

client.plugins.deleteWebhookSubscription(params)

await client.plugins.deleteWebhookSubscription({
  tenantId,
  subscriptionId: 'uuid-of-subscription',
})

Installation config should include a webhook_url string for the subscriber HTTPS endpoint. Optional: timeout_ms (1000–120000), and headers (json object of non-secret header names/values). Signing uses Supabase Vault: store the HMAC secret under a unique name, and set secret_ref on the installation to that same name (see Building plugins).

Recent webhook deliveries

Tenant admins can read metadata for recent outbound deliveries (status, attempts, last error). Payload bodies are not exposed here.

client.plugins.listRecentDeliveries()

await client.setTenant(tenantId)

const rows = await client.plugins.listRecentDeliveries()
// v_plugin_delivery_queue_recent — event_type, status, attempts, last_error, …

Processing is normally scheduled every minute (pg_cron calling rpc_process_plugin_deliveries). For automation or diagnostics, a client using the service role JWT can call client.plugins.processDeliveries(batchSize?) (not available to end-user sessions).

Was this page helpful?