InstallationActions
The things a creator can have an installation do on its platform beyond gating, declared as data so the dashboard, the REST API, the MCP server, the automation surfaces and the Copilot all offer them the same way.
Subscriby\Connector\Contracts\Ports\InstallationActions. Bound by connectors that declare installation_actions.
An action is a creator-facing verb the core cannot know in advance: build a members area in a fresh server, rename the bot in it, re-register the platform's commands. Declared with a label, a description, optional fields and an optional confirmation sentence, it reaches every surface through one door, with the core's authorisation already done.
The methods
public function actions(InstallationRef $installation): array; // list<InstallationAction>
public function run(InstallationRef $installation, CredentialBag $credentials, string $action, array $fields): InstallationActionResult;actions() answers what is offered right now for that installation, in display order; an action that no longer applies (the members area already exists) is simply left out. Each InstallationAction has a lower-case key, a translated label and description, fields (the same Field objects the install form uses, so the dashboard and the apps render them and validate the answers by their rules) and a confirm sentence when a surface should ask first.
run() receives the validated answers and does the work, answering InstallationActionResult::done($sentence, $details) or InstallationActionResult::refused($sentence, $failure). A refusal is an answer the creator reads on the surface they asked from; an exception is for a platform you could not reach at all. An unknown key is refused, never thrown.
What the core does around you
- The project's Connectors tab lists the actions under the installation with a button each; one with
confirmopens a dialog first. POST /v1/projects/{project}/connectors/{key}/installation/actions/{action}runs one with a JSON body of answers (project-connector:update, anIdempotency-Key); the MCPrun_connector_installation_actiontool, a Zapier action and an n8n operation do the same, and Subscriby Copilot offers them as tools with the confirmation card.connector.settings_updatedis not emitted for an action; what an action creates announces itself (a resource created announcesproject.resource.created).
How Discord does it
setup_members_area creates a Members category with a text channel, an announcements channel and a voice channel, a Members role with the overwrites, records the spaces, creates the first Role resource and sets the announcements channel for broadcasts; the creator confirms first. A server that already has a Subscriby-made area is not offered it again.
What the kit checks
actions.unknown_action_refused: every listed action is an InstallationAction with a unique key and well-formed fields, and run() with a key nobody listed answers a refusal rather than throwing.
Keep actions to what only the platform can do
A plan, a coupon or a broadcast is the core's and has its own surface already. An action is for the platform's own furniture: channels, roles, names and registrations a creator would otherwise arrange by hand on the platform.
How is this guide?
Last updated on
Announcer
Carrying a broadcast as one post where the platform keeps a place for announcements, mentioning the audience in the platform's idiom, instead of a message to every member.
SpaceCatalog
How a creator picks a place to gate and whether the installation controls it — link requests by purpose, instructions, diagnosis, and what the SDK does not yet let a third party complete.