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).