Extensions

Extensions Overview

Extensions let you embed custom UI panels, receive live event webhooks, or do both — all from inside the Throttle dashboard and API surface, with an authenticated identity token, scoped API access, and signed event delivery.

Two-level model: catalog vs installs

Extensions live at two levels. The catalog is workspace-scoped: one extension definition per workspace, with a name, surfaces (iframe URL and/or webhook URL + events), and a list of requested scopes. An extension can be authored by your workspace and used only internally, or promoted to public for any Throttle workspace to install.

Installs are per-application. When a dashboard user installs an extension into an application, a single-use API key and (if a webhook URL is declared) a per-install signing secret are issued. Both are shown exactly once at install time. Multiple applications in the same workspace can each have their own independent installation of the same extension, with separate API keys, signing secrets, and configuration values.

Catalog browsing supports cursor pagination and search. Use q to search extension name, slug, author, and description, and installable=true to return only private/public extensions with a published version before pagination is applied.

Catalog (workspace-level)

  • POST /api/v1/extensions — create
  • GET /api/v1/extensions — list
  • PATCH /api/v1/extensions/:id — update manifest
  • POST /api/v1/extensions/:id/versions — create version
  • POST /api/v1/extensions/:id/versions/:vid/publish — publish
  • POST /api/v1/extensions/:id/lifecycle — promote/demote

Installs (application-level)

  • POST /api/v1/extensions/:id/install — install (pinned to a version)
  • GET /api/v1/installations — list for this app
  • POST /api/v1/installations/:id/upgrade — upgrade to new version
  • PATCH /api/v1/installations/:id/config — update config
  • POST /api/v1/extensions/:id/uninstall — uninstall

Surfaces

An extension manifest declares one or both surfaces. You can mix them freely.

UI iframe

Declare an iframeUrl in the manifest. The dashboard renders a sandboxed <iframe> at that URL when the extension panel is open. Your page calls createBridge() from @usethrottle/extension-bridge (or the hosted script tag) to handshake with the dashboard, obtain a signed identity token, and make authenticated API calls. See the Build guide and the Identity JWT reference.

Event webhooks

Declare a webhookUrl plus the list of eventSubscriptions your extension wants to receive. Throttle creates a managed webhook endpoint for the install and delivers signed events to that URL automatically. The per-install webhookSigningSecret is shown once at install time. See the Events reference.

Hybrid extensions
An extension can declare both iframeUrl and webhookUrl. The iframe bridge and the webhook delivery pipeline are independent — the bridge token gives the iframe REST access, while the webhook pipeline delivers async events to your server. Use both when you need a live UI panel and background event processing.

Lifecycle: draft → private → public

Every extension starts as draft. You iterate freely — create versions, update the manifest — before promoting it.

stateDiagram-v2
  [*] --> draft: POST /extensions
  draft --> private: POST /extensions/:id/lifecycle (lifecycle=private)
  private --> draft: lifecycle=draft
  private --> public: lifecycle=public (admin only)
  public --> private: lifecycle=private
  draft --> [*]: DELETE /extensions/:id
Extension lifecycle transitions. Promoting to public requires the admin permission.
  • draft — visible only within your workspace; can only be installed by your own workspace's applications; no published version required.
  • private — still workspace-private but signifies the extension is production-ready. Installs within your workspace are in this state during internal testing.
  • public — listed in the global marketplace; any Throttle workspace can install it. Requires the application:extensions:admin permission. Throttle must enable the public marketplace for your workspace.

Versioning and pinned installs

Installs are always pinned to a specific published version. Publishing a new version does not automatically upgrade existing installs — each install retains the version it was pinned to until explicitly upgraded via POST /api/v1/installations/:id/upgrade. If the new version declares additional scopes, the installer must acknowledge them; Throttle returns 409 new_scopes_require_consent listing the delta. See the Versioning guide.

Environment isolation

Installs carry the workspace environmentId selected by the installing caller. A UAT install issues a UAT API key and receives only UAT events; a production install issues a production API key and receives only production events. The catalog itself (the extension definition and its versions) is shared across environments.