# SuperPlane Docs (Full) > Comprehensive companion to `/llms.txt` with full page content for the current docs table of contents. SuperPlane is an open source DevOps control plane for long-lived, event-driven workflows. ## Get Started - [Welcome](https://docs.superplane.com/): Get up and running with SuperPlane, the open source automation engine for AI-driven engineering. - [Quickstart](https://docs.superplane.com/get-started/quickstart): Build and run your first workflow on the Canvas (no integrations required). - [Example use cases](https://docs.superplane.com/get-started/example-use-cases): Six templates you can copy and adapt to your own workflows. ## SuperPlane Apps - [Overview](https://docs.superplane.com/concepts/superplane-apps): A SuperPlane app is a control plane for long-lived, event-driven software engineering workflows across your existing tools. - [Canvas](https://docs.superplane.com/concepts/canvas): Learn about canvases and how to use the canvas page to design and manage workflows. - [Console](https://docs.superplane.com/): Get up and running with SuperPlane, the open source automation engine for AI-driven engineering. - [Memory](https://docs.superplane.com/concepts/canvas-memory): Persistent, app-scoped storage you can read and write from workflows using dedicated components. - [Files](https://docs.superplane.com/concepts/files): Each app has a git repository. It stores canvas.yaml, console.yaml, and any other files your app needs. - [Agent](https://docs.superplane.com/concepts/agent): How to use the built-in AI agent to build and operate SuperPlane apps. - [Sharing apps](https://docs.superplane.com/concepts/sharing-apps): Export a SuperPlane app as a Git repository so anyone can install it with one click. ## Workflow Orchestration - [Overview](https://docs.superplane.com/concepts/data-flow): How events and payloads flow between nodes in SuperPlane workflows. - [Runs](https://docs.superplane.com/concepts/runs): Understand how SuperPlane executes workflows, preserves state, and tracks execution history. - [Component Nodes](https://docs.superplane.com/concepts/component-nodes): Learn about components and component nodes, and how to add, configure, and use them in your workflows. - [Expressions](https://docs.superplane.com/concepts/expressions): How to write expressions and access payload data in SuperPlane workflows. - [Expression Functions](https://docs.superplane.com/concepts/expression-functions): Complete list of functions available in SuperPlane expressions. - [Runners](https://docs.superplane.com/concepts/runners): How SuperPlane runs shell commands and scripts on remote machines as part of workflows. ## Security - [Authentication & Accounts](https://docs.superplane.com/security/authentication): Manage your user account, authenticate via the UI and CLI, and configure API tokens. - [Secrets](https://docs.superplane.com/security/secrets): How to store and use secrets in SuperPlane workflows. - [RBAC](https://docs.superplane.com/security/access-control): Roles, permissions, groups, and member access in SuperPlane organizations. - [Service accounts](https://docs.superplane.com/security/service-accounts): Use service accounts and API tokens for programmatic and automation access. ## Installation - [Overview](https://docs.superplane.com/installation/overview): Choose the right installation path for local, single-host, or Kubernetes deployments. - [Try it on your computer](https://docs.superplane.com/installation/local): Run SuperPlane locally with Docker in less than a minute. - [EC2 on AWS](https://docs.superplane.com/installation/single-host/aws-ec2): Install SuperPlane on a single Amazon EC2 instance. - [Compute Engine on GCP](https://docs.superplane.com/installation/single-host/gcp-compute-engine): Install SuperPlane on a single Google Compute Engine VM. - [Hetzner](https://docs.superplane.com/installation/single-host/hetzner): Install SuperPlane on a single Hetzner server. - [DigitalOcean](https://docs.superplane.com/installation/single-host/digitalocean): Install SuperPlane on a single DigitalOcean Droplet. - [Linode](https://docs.superplane.com/installation/single-host/linode): Install SuperPlane on a single Linode instance. - [Generic server](https://docs.superplane.com/installation/single-host/generic-server): Install SuperPlane on a generic Linux server. - [Google Kubernetes Engine](https://docs.superplane.com/installation/kubernetes/gke): Run SuperPlane on a Google Kubernetes Engine (GKE) cluster with Cloud SQL PostgreSQL. - [Amazon Kubernetes (EKS)](https://docs.superplane.com/installation/kubernetes/amazon-eks): Run SuperPlane on an Amazon Elastic Kubernetes Service (EKS) cluster with RDS PostgreSQL. - [Beacon](https://docs.superplane.com/installation/beacon): Understand what the SuperPlane beacon sends and how to disable it. ## Command Line Interface (CLI) - [Overview & Installation](https://docs.superplane.com/cli/overview): Install the SuperPlane CLI, authenticate, and manage your configuration. - [Managing Apps](https://docs.superplane.com/cli/apps): Create and manage apps, canvases, consoles, drafts, and files via the CLI. - [Runs & Executions](https://docs.superplane.com/cli/runs): Inspect app runs, executions, and queues from the CLI. - [Integrations & Secrets](https://docs.superplane.com/cli/resources): Manage organizations, connected integrations, and secrets via the CLI. - [Discovery Index](https://docs.superplane.com/cli/discovery): Discover available integrations, triggers, actions, and widgets via the CLI. ## Reference - [Public API Reference](https://docs.superplane.com/concepts/api-reference): Explore the SuperPlane REST API using the interactive Swagger documentation. - [Glossary](https://docs.superplane.com/concepts/glossary): Definitions for key SuperPlane concepts and terms. ## Components - [AWS](https://docs.superplane.com/components/aws): Manage resources and execute AWS commands in workflows - [Bitbucket](https://docs.superplane.com/components/bitbucket): React to events in your Bitbucket repositories - [CircleCI](https://docs.superplane.com/components/circleci): Trigger and monitor CircleCI pipelines - [Claude](https://docs.superplane.com/components/claude): Use Claude models in workflows - [Cloudflare](https://docs.superplane.com/components/cloudflare): Manage Cloudflare zones, rules, and DNS - [Cloudsmith](https://docs.superplane.com/components/cloudsmith): Automate repository, package, and artifact management on Cloudsmith - [Coolify](https://docs.superplane.com/components/coolify): List and control Coolify applications and services, and trigger deployments - [Core](https://docs.superplane.com/components/core): Built-in SuperPlane components. - [Cursor](https://docs.superplane.com/components/cursor): Build workflows with Cursor AI Agents and track usage - [Dash0](https://docs.superplane.com/components/dash0): Connect to Dash0 to query data using Prometheus API - [Datadog](https://docs.superplane.com/components/datadog): Create events in Datadog - [Daytona](https://docs.superplane.com/components/daytona): Execute code in isolated sandbox environments - [DigitalOcean](https://docs.superplane.com/components/digitalocean): Manage and monitor your DigitalOcean infrastructure - [Discord](https://docs.superplane.com/components/discord): Send messages to Discord channels and fetch mentions - [DockerHub](https://docs.superplane.com/components/dockerhub): Manage and react to DockerHub repositories and tags - [Elastic](https://docs.superplane.com/components/elastic): Index documents into Elasticsearch and receive Kibana webhooks - [FireHydrant](https://docs.superplane.com/components/firehydrant): Manage and react to incidents in FireHydrant - [GitHub](https://docs.superplane.com/components/github): Manage and react to changes in your GitHub repositories - [GitLab](https://docs.superplane.com/components/gitlab): Manage and react to changes in your GitLab repositories - [Google Cloud](https://docs.superplane.com/components/googlecloud): Manage and use Google Cloud resources in your workflows - [Grafana](https://docs.superplane.com/components/grafana): Connect Grafana alerts, alert rules, dashboards, annotations, silences, and data queries to SuperPlane workflows - [Harness](https://docs.superplane.com/components/harness): Run and monitor Harness pipelines from SuperPlane workflows - [Hetzner Cloud](https://docs.superplane.com/components/hetznercloud): Create and delete Hetzner Cloud servers/load balancers and create/delete server snapshots - [Honeycomb](https://docs.superplane.com/components/honeycomb): Monitor observability alerts and send events to Honeycomb datasets - [Incident](https://docs.superplane.com/components/incident): Manage and react to incidents in incident.io - [JFrog Artifactory](https://docs.superplane.com/components/jfrogartifactory): Manage artifacts in JFrog Artifactory repositories - [Jira](https://docs.superplane.com/components/jira): Manage issues in Jira - [LaunchDarkly](https://docs.superplane.com/components/launchdarkly): Manage feature flags and react to flag changes in LaunchDarkly - [Logfire](https://docs.superplane.com/components/logfire): Set up Logfire for AI Observability - [Microsoft Azure](https://docs.superplane.com/components/microsoftazure): Manage and automate Microsoft Azure resources and services - [Microsoft Teams](https://docs.superplane.com/components/microsoftteams): Send and receive messages in Microsoft Teams channels - [New Relic](https://docs.superplane.com/components/newrelic): React to alerts and query telemetry data from New Relic - [Octopus Deploy](https://docs.superplane.com/components/octopusdeploy): Deploy releases and react to deployment events in Octopus Deploy - [OpenAI](https://docs.superplane.com/components/openai): Generate text responses with OpenAI models - [Oracle Cloud Infrastructure](https://docs.superplane.com/components/oraclecloudinfrastructure): Manage Oracle Cloud Infrastructure resources in workflows - [PagerDuty](https://docs.superplane.com/components/pagerduty): Manage and react to incidents in PagerDuty - [Perplexity](https://docs.superplane.com/components/perplexity): Run AI agents with Perplexity - [Prometheus](https://docs.superplane.com/components/prometheus): Monitor alerts from Prometheus and Alertmanager - [Render](https://docs.superplane.com/components/render): Deploy and manage Render services, and react to Render deploy/build events - [Rootly](https://docs.superplane.com/components/rootly): Manage and react to incidents in Rootly - [Semaphore](https://docs.superplane.com/components/semaphore): Run and react to your Semaphore workflows - [SendGrid](https://docs.superplane.com/components/sendgrid): Send transactional and marketing email with SendGrid - [Sentry](https://docs.superplane.com/components/sentry): React to issue events and manage issues and metric alerts in Sentry - [ServiceNow](https://docs.superplane.com/components/servicenow): Manage and react to incidents in ServiceNow - [Slack](https://docs.superplane.com/components/slack): Send and react to Slack messages and interactions - [SMTP](https://docs.superplane.com/components/smtp): Send emails via any SMTP server - [Statuspage](https://docs.superplane.com/components/statuspage): Create and manage incidents on your Atlassian Statuspage - [Telegram](https://docs.superplane.com/components/telegram): Send messages and react to events via Telegram bots ## Full Content ### Get Started #### Welcome Source URL: https://docs.superplane.com/ SuperPlane is an open source automation engine for AI-driven engineering. As AI accelerates engineering throughput, traditional manual approvals and fragile scripts break down. To safely scale AI, you must automate every manual check and enforce strict quality guardrails across your software development lifecycle. SuperPlane lets you model these high-velocity workflows as fully operational [apps](/concepts/superplane-apps). Apps execute your processes deterministically using graphs, providing the exact guardrails AI needs to safely interact with your tools—like Git, CI/CD, and observability. ![Run chain view showing end-to-end workflow execution history](../../assets/superplane-canvas-example.png) ## What you can build SuperPlane is built for workflows that are too complex for a single script or CI job. You can build: - **AI-driven code review**: Automatically review pull requests, enforce style guides, perform QA, fill documentation gaps, and calculate change risk scores using LLMs. - **Release management**: Coordinate complex, multi-regional deployments that span hours or days, incorporating automatic health checks, manual approvals, and instant rollback paths. - **Operational dashboards**: Unify data from any engineering event into a custom live UI. Track DORA metrics, active incidents, or deployment health across your entire stack—generated in minutes by the built-in AI agent. - **Incident response**: Pull context from observability tools, page the on-call engineer, create a dedicated chat channel, and track the resolution state. - **Infrastructure provisioning**: Provide a self-serve portal for developers to request databases or create on-demand ephemeral environments, all with built-in policy checks. ## Try it locally (fastest path) If you want to click around and run a workflow, start the demo container: ```bash docker pull ghcr.io/superplanehq/superplane-demo:stable docker run --rm -p 3000:3000 -v spdata:/app/data -ti ghcr.io/superplanehq/superplane-demo:stable ``` Then open `http://localhost:3000`. For more details and options, see the [installation guide](/installation/overview). ## Project status: beta - **Cloud beta**: We are launching our managed cloud offering soon. - **Self-hostable**: SuperPlane is designed to run on your own infrastructure. - **Stabilizing**: Core primitives and integrations are maturing. Breaking changes are possible, but we'll do our best to avoid them. ## LLM and agent tooling For **agent-first engineering**, use the [SuperPlane skills repository](https://github.com/superplanehq/skills). It provides skills that help AI agents operate SuperPlane efficiently (CLI usage, canvas design, workflow debugging). Install all skills or a specific one: ```bash npx skills add superplanehq/skills # or a single skill, e.g.: npx skills add superplanehq/skills --skill superplane-cli ``` For **docs context** in your AI tooling, you can point at: - [`/llms.txt`](/llms.txt): compact docs index organized by docs sections. - [`/llms-full.txt`](/llms-full.txt): expanded companion with full page content. ## Get help / share feedback - Submit project issues and feature requests at [github.com/superplanehq/superplane](https://github.com/superplanehq/superplane). - Submit documentation issues at [github.com/superplanehq/docs](https://github.com/superplanehq/docs). - Talk to the devs in the [Discord server](https://discord.superplane.com). #### Quickstart Source URL: https://docs.superplane.com/get-started/quickstart This quickstart guides you to your first "hello world" moment in SuperPlane: building a small workflow on a **canvas**, running it, and inspecting the resulting **run**, **run items**, and **payloads**. You won't need to connect any third-party services. ## What you’ll build A tiny workflow that: - starts from a **Manual Run** - fetches a random cat fact via **HTTP Request** - branches with **If** (True/False output channels) based on the length of the cat fact - ends with one of the **No Operation** nodes Along the way you’ll learn the core mental model: nodes emit payloads, downstream nodes subscribe, and payloads accumulate into a **message chain** you can reference in expressions. ## Prerequisites - You can access the SuperPlane UI. - You can create or open a canvas in a project/workspace. ## Your first workflow (step-by-step) ### 1) Create a canvas Create a new canvas and name it **Hello world**. ### 2) Add the trigger: Manual Run 1. Click **“+ Components”**. 2. Add **Manual Run** to the canvas. When you drop it on the canvas, it will typically show up as a `start` node with a **Run** button. This is the trigger that will start the workflow. ![Manual Run node](../../../assets/quickstart/start-node.png) ### 3) Add an action: HTTP Request 1. Add **HTTP Request** to the canvas. 2. Connect **Manual Run → HTTP Request** (create a subscription). 3. Name the node **Get cat fact**. Configure the HTTP Request: - **Method**: `GET` - **URL**: `https://catfact.ninja/fact` - Click **Save** button at the bottom of the configuration panel. Next, click **Run** button on the manual trigger node to run the first HTTP request. Further nodes will use the response from this run to help us write expressions. This endpoint will fetch a random cat fact and return JSON like: ```json { "fact": "A cat will tremble or shiver when it is in extreme pain.", "length": 56 } ``` ![HTTP Request node](../../../assets/quickstart/get-cat-fact.png) ### 4) Add branching: If 1. Add **If** to the canvas. 2. Connect **HTTP Request → If**. For illustration purposes we will determine whether the cat fact can fit in an old-school tweet or not. Set the If expression to branch based on the API response. The If field is a condition — write it without `{{ }}`: ``` $['Get cat fact'].data.body.length <= 160 ``` As you type the expression, you'll see that SuperPlane will provide you with a list of possible data attributes to choose from via autocompletion. ![Writing an expression](../../../assets/quickstart/if-expression.png) ### 5) End both paths safely: No Operation Add **two** No Operation nodes: - Connect **If / True → No Operation** and name it `fact is short`. - Connect **If / False → No Operation** and name it `fact is long`. This keeps the tutorial completely safe: the workflow does real work (an HTTP call), but has no external side effects. ### 6) Run it 1. Click the **Manual Run** node. 2. Click **Run**. Run it a couple more times. You should see nodes update with statuses as each run item finishes. Successfully running the workflow should look like this: ![Full hello world canvas](../../../assets/quickstart/full-canvas.png) ## Inspect a run (payloads, history, message chain) You can inspect exactly what happened and what data flowed between nodes. ### 1) Open a run 1. Click the last node in your workflow (for example, your `Post short message` node). 2. In the sidebar, within the **Runs** tab, click the most recent event. You’ll be taken to a run-focused view with: - **This run was triggered by** (the root trigger, e.g. `start`) - **Steps** (each node that executed in this run) ![Inspecting a run](../../../assets/quickstart/run-inspection.png) ### 2) Explore steps (the run chain) In **Steps**, click different nodes (e.g. `Get cat fact`, `if fact is short`, your No Operation node) to see their details for this run. ### 3) Inspect payloads For the **HTTP Request** step (your `Get cat fact` node), open **Payload** and look for: - `data.status` (HTTP status code) - `data.body.fact` (the cat fact) - `data.body.length` (length of the fact) For any step, you can also open **Details** to see metadata like the event type and when it was emitted. The **Config** tab shows the node's resolved settings for this run. ### 4) Understand the message chain Each node's output is added to a message chain. Reference upstream data with `$['Node Name'].field`. See [Expressions](/concepts/expressions). For a deeper explanation, see [Data Flow](/concepts/data-flow) and [Expressions](/concepts/expressions). ## Troubleshooting - **HTTP Request fails**: Open the HTTP Request run item payload and check `data.status` and `data.error`. Public APIs sometimes rate-limit; re-run after a minute if needed. - **A node didn’t run**: Verify the subscription lines on the canvas (Manual Run → HTTP Request → If), and ensure the No Operation nodes are connected to the correct If output channels. ## Next steps The "hello world" was not exactly a DevOps workflow, but it was a good way to get started with the fundamentals of SuperPlane. In the next section, we'll explore some real-world use cases. #### Example use cases Source URL: https://docs.superplane.com/get-started/example-use-cases import { Aside, Card, CardGrid } from "@astrojs/starlight/components"; import { Image } from "astro:assets"; import t1PolicyGatedDeployment from "../../../assets/templates/policy-gated-deployment.png"; import t2AutomatedRollback from "../../../assets/templates/automated-rollback.png"; import t3IncidentDataCollection from "../../../assets/templates/incident-triage.png"; import t4StagedRelease from "../../../assets/templates/progressive-delivery.png"; import t5IncidentRouter from "../../../assets/templates/incident-router.png"; import t6MultiRepoRelease from "../../../assets/templates/multi-repo-release.png"; SuperPlane ships with a set of built-in templates you can copy into your workspace and adapt. This page gives you a quick tour of what each template is for, plus screenshots you can reference as you build. Policy-gated deployment template canvas (cropped preview).

Gate deployments with a policy check, business hours, and approval.

Automated rollback template canvas (cropped preview).

Automatically trigger rollback workflows when deployments fail and verify system health with Dash0 monitoring.

Incident data collection template canvas (cropped preview).

Collect data and metrics when new P1/P2 incident is opened and create a GitHub issue

Staged release template canvas (cropped preview).

Gradually roll out releases through 10%, 50%, and 100% stages with health checks at each step.

Incident router template canvas (cropped preview).

Route P1 incidents from Slack mentions to PagerDuty and GitHub with AI-generated titles and descriptions.

Multi-repo release template canvas (cropped preview).

Coordinate releases across multiple repositories with unified CI builds and deployments.

### SuperPlane Apps #### Overview Source URL: https://docs.superplane.com/concepts/superplane-apps import appOverviewCanvas from "../../../assets/app-overview-canvas.png"; import { Image } from "astro:assets"; A **SuperPlane app** is a workspace where you design and run long-lived, event-driven software engineering workflows.
Each app brings together five core building blocks: - **[Canvas](/concepts/canvas)** — The workspace where you design and run workflows. It is a graph of nodes connected by subscriptions that define how events flow between steps. Unlike a linear pipeline, a Canvas is an infinite space that can hold multiple independent graphs and define multiple workflows, each with their own paths of execution. - **[Console](/concepts/console)** — The operational surface for the app. It turns workflow state into an at-a-glance view with dashboards, runbooks, tables of live data, and charts. - **[Memory](/concepts/canvas-memory)** — Persistent, app-scoped storage for JSON data. Workflows can read and write to Memory to share state across runs and power Console dashboards. - **[Files](/concepts/files)** — The git repository backing the app. It stores the `canvas.yaml` and `console.yaml` definitions, along with any other files or scripts your app needs, enabling version control and infrastructure-as-code practices. - **[Agent](/concepts/agent)** — A built-in AI assistant that helps you design workflows, make canvas changes, and troubleshoot failed executions. These building blocks work together to provide a complete platform for software engineering automation. ## How building blocks work together When you build a SuperPlane app, the core components interact to create a complete operational tool: 1. **Events trigger workflows**: An external event (like a GitHub push or a PagerDuty incident) triggers a node on the **Canvas**. 2. **Workflows process data**: The **Canvas** executes the workflow, transforming data, calling external APIs, or waiting for human input. 3. **State is saved**: Throughout the workflow, nodes can read and write JSON data to **Memory**, preserving state across runs. 4. **Operators monitor and act**: The **Console** reads from **Memory** and live run data to display dashboards, KPIs, and actionable buttons for human operators. 5. **Everything is versioned**: The entire configuration of the **Canvas** and **Console** is saved in the **Files** repository, allowing you to draft, commit, and publish changes safely. 6. **AI assists operations**: The **Agent** can read the app's state, inspect runs, and propose changes to the canvas to fix issues or add features. This architecture means you do not just build a script—you build a fully operational application with its own UI, state, and version history. ## Getting started To get started with building your first app, see the [Quickstart](/get-started/quickstart) tutorial. #### Canvas Source URL: https://docs.superplane.com/concepts/canvas import canvasOverview from "../../../assets/canvas-overview.png"; import { Image } from "astro:assets"; A **canvas** is the workspace where you design and run workflows in SuperPlane. It's a visual graph of nodes connected by subscriptions that define how events flow between steps. Think of a canvas as: - **A workspace** for designing workflows visually - **A live system** where multiple runs can execute simultaneously - **A graph** that defines all possible execution paths A single canvas can represent multiple possible workflows, depending on which paths events take through the graph. The canvas provides a place to model complex, event-driven workflows that span multiple tools, wait for human input, and run over extended periods of time.
Hello World canvas with start, if, and action nodes connected on the workflow graph
The canvas consists of: 1. **Nodes** — Triggers and components. See [Component Nodes](/concepts/component-nodes). 2. **Connections** — Indicate which node listens to which. See [Data Flow](/concepts/data-flow). 3. **Edit** — Edit the canvas nodes and connections. 4. **Helper toolbar** — Navigation tools, select/pan mode, search. ## Editing and Updating Canvases You can edit and update canvases in two ways: ### Visual Editor (UI) Use the visual editor to build and modify canvases interactively: - **Add nodes**: Drag components from the component palette onto the canvas - **Connect nodes**: Create subscriptions by connecting nodes together - **Configure nodes**: Click on any node to edit its configuration - **Delete elements**: Remove nodes or connections as needed Changes are saved automatically, and you can see your workflow update in real-time. ### Command Line (CLI) Use the SuperPlane CLI to manage an app canvas programmatically: ```sh # Export a canvas superplane apps canvas get > my_canvas.yaml # Edit the YAML file # ... make your changes ... # Apply updates superplane apps canvas update -f my_canvas.yaml ``` ## Notes **Notes** are sticky notes on the canvas for labels, reminders, or links. They do not run in the workflow, emit payloads, or connect to subscriptions. Each note supports markdown text (up to 5000 characters). To add a note, click the **sticky-note** button in the top-right toolbar. ## Versioning Canvases are versioned using a Git repository in the background. You edit a draft, commit your changes, and publish when you're ready to update the live app. In the UI, versioned canvases expose an **Edit** mode and a **Versioning** view: 1. **Live vs Draft versions**: The live version is what currently runs in production. A draft is an isolated workspace where you can safely make changes. You can have multiple drafts active at the same time (a multi-draft lifecycle). 2. **Repository-backed staging**: When you edit a draft, your changes are written to a staging layer. You can view a visual diff of your staged changes before committing them. 3. **Commit vs Publish**: - **Commit**: Saves your staged changes to the draft's branch in the repository. - **Publish**: Merges your draft's branch into the live version, making your changes active. 4. **Discard/Reset**: If you don't like your staged changes, you can discard them to reset the draft back to its last commit. If a draft has conflicts with the live version, you can reset the draft to match the live version. 5. **Permanent versions sidebar**: The UI provides a sidebar to manage your drafts, view commit history, and switch between versions. For CLI commands, see [SuperPlane CLI](/cli/overview). ## Durable Execution SuperPlane provides **durable execution** for your workflows, preserving state across steps and system restarts. For more details on how executions are tracked and managed, see [Runs](/concepts/runs). ## The Canvas Page ### Nodes and Connections **Nodes** are instances of components. To add a node, click **"+ Components"** and drag onto the canvas. **Connections** define how events flow between nodes — drag from a source node's output channel to a target node. Nodes show status badges (running, succeeded, failed) and key information from their latest payload. For details on components, see [Component Nodes](/concepts/component-nodes). ### Payloads and Events Every node emits a **payload** — JSON data containing the results of its execution. Click any node and view the Payload tab to inspect it. ![Inspecting a node payload](../../../assets/canvas-overview-payload.png) When configuring nodes, type `{{` in expression fields to access payload data from upstream nodes. ![Selecting payload data in expressions](../../../assets/canvas-overview-selecting-payload.png) Use `{{` … `}}` to insert payload data into text fields, or write bare expressions in condition fields (If / Filter). See [Expressions](/concepts/expressions). ### Workflows and Runs A single canvas can express multiple workflows depending on which trigger fires and which paths events take. **Multiple runs execute simultaneously** — the canvas updates in real-time as runs execute, with each node showing its current or most recent status. Click any node to view its run history. Select a run item to see the full run chain showing all nodes that executed as part of that run. ## Best Practices - **Organize logically**: Arrange related nodes together visually - **Use clear node names**: Make it easy to understand what each node does - **Test incrementally**: Build and test workflows step by step - **Check for errors**: Review run history and node status regularly For more details on data flow, see [Data Flow](/concepts/data-flow). For component details, see [Component Nodes](/concepts/component-nodes). #### Console Source URL: https://docs.superplane.com/ SuperPlane is an open source automation engine for AI-driven engineering. As AI accelerates engineering throughput, traditional manual approvals and fragile scripts break down. To safely scale AI, you must automate every manual check and enforce strict quality guardrails across your software development lifecycle. SuperPlane lets you model these high-velocity workflows as fully operational [apps](/concepts/superplane-apps). Apps execute your processes deterministically using graphs, providing the exact guardrails AI needs to safely interact with your tools—like Git, CI/CD, and observability. ![Run chain view showing end-to-end workflow execution history](../../assets/superplane-canvas-example.png) ## What you can build SuperPlane is built for workflows that are too complex for a single script or CI job. You can build: - **AI-driven code review**: Automatically review pull requests, enforce style guides, perform QA, fill documentation gaps, and calculate change risk scores using LLMs. - **Release management**: Coordinate complex, multi-regional deployments that span hours or days, incorporating automatic health checks, manual approvals, and instant rollback paths. - **Operational dashboards**: Unify data from any engineering event into a custom live UI. Track DORA metrics, active incidents, or deployment health across your entire stack—generated in minutes by the built-in AI agent. - **Incident response**: Pull context from observability tools, page the on-call engineer, create a dedicated chat channel, and track the resolution state. - **Infrastructure provisioning**: Provide a self-serve portal for developers to request databases or create on-demand ephemeral environments, all with built-in policy checks. ## Try it locally (fastest path) If you want to click around and run a workflow, start the demo container: ```bash docker pull ghcr.io/superplanehq/superplane-demo:stable docker run --rm -p 3000:3000 -v spdata:/app/data -ti ghcr.io/superplanehq/superplane-demo:stable ``` Then open `http://localhost:3000`. For more details and options, see the [installation guide](/installation/overview). ## Project status: beta - **Cloud beta**: We are launching our managed cloud offering soon. - **Self-hostable**: SuperPlane is designed to run on your own infrastructure. - **Stabilizing**: Core primitives and integrations are maturing. Breaking changes are possible, but we'll do our best to avoid them. ## LLM and agent tooling For **agent-first engineering**, use the [SuperPlane skills repository](https://github.com/superplanehq/skills). It provides skills that help AI agents operate SuperPlane efficiently (CLI usage, canvas design, workflow debugging). Install all skills or a specific one: ```bash npx skills add superplanehq/skills # or a single skill, e.g.: npx skills add superplanehq/skills --skill superplane-cli ``` For **docs context** in your AI tooling, you can point at: - [`/llms.txt`](/llms.txt): compact docs index organized by docs sections. - [`/llms-full.txt`](/llms-full.txt): expanded companion with full page content. ## Get help / share feedback - Submit project issues and feature requests at [github.com/superplanehq/superplane](https://github.com/superplanehq/superplane). - Submit documentation issues at [github.com/superplanehq/docs](https://github.com/superplanehq/docs). - Talk to the devs in the [Discord server](https://discord.superplane.com). #### Memory Source URL: https://docs.superplane.com/concepts/canvas-memory import memoryOverview from "../../../assets/memory-overview.png"; import { Image } from "astro:assets"; **Memory** stores structured JSON data on an app, scoped by **namespace**. It persists across runs so workflows can keep state, pass data between branches, or look up records by matching fields.
Openclaw Manager memory view showing openclawAgents namespace with agent rows and JSON fields
## How it works - **App-scoped** — Data belongs to one app. - **Namespaces** — You choose a namespace string per use case (for example `deployments` or `incidents`). - **Rows** — Each write can add or update rows; each row holds JSON **values** (object). - **Matching** — Read, update, delete, and upsert operations can match rows by field values (JSON containment). ## Hello world example A common use case is tracking the status of an ongoing process, like an incident. 1. **Write**: When an incident is declared, use an **Add Memory** node. - **Namespace**: `incidents` - **Values**: `{"id": "{{ $.trigger.incident_id }}", "status": "open"}` 2. **Read**: Later in the workflow (or in a completely separate run triggered by a different event), use a **Read Memory** node to check the status. - **Namespace**: `incidents` - **Match**: `{"id": "{{ $.trigger.incident_id }}"}` 3. **Update**: When the incident is resolved, use an **Update Memory** node. - **Namespace**: `incidents` - **Match**: `{"id": "{{ $.trigger.incident_id }}"}` - **Values**: `{"status": "resolved"}` ## Namespaces Namespaces are arbitrary strings that group related memory records. You create a namespace simply by writing to it. **Examples of namespaces:** - `deployments`: Tracking the version, environment, and status of code rollouts. - `user_preferences`: Storing opt-in/opt-out flags for notifications. - `rate_limits`: Keeping counters for API usage to prevent throttling. - `approval_requests`: Storing pending requests that wait for human interaction. ## Persisting data across runs Runs on the same app are independent: payloads from one run do not automatically appear in the next. Memory is where you **store facts that should survive** until a later run needs them. | Pattern | How | | ------- | --- | | Staged rollout | **Upsert** the current stage; next run **Read** (latest) to decide whether to advance. | | Incident handoff | Run 1 **Add** IDs; Run 2 **Read** by key to continue the same incident. | | Deduplication | **Upsert** on a stable key; branch on `found` / `notFound`. | | Counters | **Update** to merge new values (e.g. attempt count); later runs read the totals. | ## Components SuperPlane provides five memory components: | Component | Purpose | | --------- | ------- | | **Add Memory** | Append a new row in a namespace. | | **Read Memory** | Find rows by namespace and match criteria; emits on `found` or `notFound`. | | **Update Memory** | Update matching rows by merging new fields; emits on `found` or `notFound`. | | **Delete Memory** | Delete matching rows; emits on `deleted` or `notFound`. | | **Upsert Memory** | Update the first match, or insert if none match. | **Read Memory** supports: - **Result mode** — `all` (every match) or `latest` (most recent). - **Emit mode** — `allAtOnce` (one event with all matches) or `oneByOne` (one event per row). See the [Components](/components/core) reference for field-level configuration. ## Manual memory entry and edits You don't have to rely solely on workflows to manage memory. You can manually view, add, edit, and delete records directly from the SuperPlane UI. 1. Open your app and navigate to the **Memory** tab. 2. Select a namespace from the sidebar. 3. Click **Add Record** to manually insert a new JSON object. 4. Click on any existing row to edit its JSON values or delete it. This is especially useful for seeding initial configuration data, updating feature flags, or correcting state during an incident. ### Read-only behavior Access to the Memory tab is governed by your app permissions: - Users with `canvases:update` permission can add, edit, and delete memory records manually. - Users with only `canvases:read` permission will see the Memory tab in **read-only mode**. They can browse namespaces and inspect JSON values, but the buttons to add, edit, or delete records will be hidden or disabled. ## Feeding console widgets Memory is a primary data source for the [Console](/concepts/console). You can build live operational dashboards that read directly from memory namespaces. For example, you can configure a **Table** widget to display the `incidents` namespace. As your workflows add or update memory records, the console table updates in real-time. You can also reference memory variables directly in **Markdown** widgets to display dynamic text (e.g., `{{ memory.incidents.length }} open incidents`). See [Console Data Sources](/concepts/console/data-sources) for more details. ## CLI and API You can list and export memory records using the [SuperPlane CLI](/cli/apps#managing-app-memory). This is useful for auditing, backups, or piping data into other scripts. List all memory records for an app: ```sh superplane apps memory list ``` Filter records to a specific namespace: ```sh superplane apps memory list --namespace "incidents" ``` Memory can also be managed via the REST API (see [Public API Reference](/concepts/api-reference)). Managing memory records requires permissions to read or update the app. #### Files Source URL: https://docs.superplane.com/concepts/files import filesOverview from "../../../assets/files-overview.png"; import { Image } from "astro:assets"; Every app is backed by a **git repository**. The **Files** tab is where you view and edit the files that define the app.
Openclaw Manager Files tab showing canvas.yaml in the editor with workflow nodes and subscriptions
## What's in the repository Because the app is backed by a standard Git repository, you can store any files you need inside it, such as scripts, READMEs, or custom configuration files. However, two files have a special meaning to SuperPlane: | File | Purpose | | ---- | ------- | | `canvas.yaml` | Workflow graph: nodes, subscriptions, and configuration | | `console.yaml` | Console layout and panels | Changes you make in the UI are reflected in these files. Edits in **Files** follow the same **draft and publish** flow as on the [Canvas](/concepts/canvas) and [Console](/concepts/console). ## How files connect to your workflows The files in your repository are not just static configuration—they interact with the other core components of your SuperPlane app. ### AI Agent The [built-in AI agent](/concepts/agent) has direct access to your app's repository. When you ask the agent to build or troubleshoot a workflow, it can: - **Read files**: Inspect `README.md`, documentation, or custom scripts to gain context about your app. - **Write files**: Create new scripts, update documentation, or modify configuration files. - **Manage configuration**: Update `canvas.yaml` and `console.yaml` directly to build workflows and dashboards. ### Runners [Runners](/concepts/runners) execute shell commands and scripts on remote machines. You can store complex scripts (e.g., a 500-line Python data processing script or a Bash deployment script) directly in your app's repository instead of pasting them into the Canvas UI. To use a repository script in a runner: 1. Store the script in your app's repository (e.g., `scripts/process-data.py`). 2. In your Runner node's **Setup commands**, clone the repository. 3. In the Runner node's **Script** field, simply execute the file: `python scripts/process-data.py`. This approach keeps your Canvas clean, allows you to version-control your scripts, and lets you use standard IDEs and linters for your code. ## Files tab Open **Files** from the app header (alongside **Canvas**, **Console**, and **Memory**). - View and edit files in the browser - Export files for review or backup - Import YAML to replace the graph or console in one update (console import is replace-all) ## CLI Inspect app files with the SuperPlane CLI. See [SuperPlane CLI](/cli/apps#reading-app-files) for `canvas.yaml` and `console.yaml` commands on a given app. #### Agent Source URL: https://docs.superplane.com/concepts/agent SuperPlane includes a built-in AI agent that helps you build workflows and console UI, debug executions, and manage repository files. The agent is context-aware, persistent, and operates safely within your app's permission boundaries. ## Agent modes The agent adapts to your current task using different modes: - **Build**: Helps you design workflows on the [canvas](/concepts/canvas), configure [nodes](/concepts/component-nodes), design [console](/concepts/console) UI, and make changes to the app. - **Ask**: A read-only mode to help you monitor runs, analyze data, and troubleshoot apps. You can switch modes in the chat interface to focus the agent's tools and context on your immediate goal. ## Chat persistence and streaming Each canvas has a single, permanent chat session. Your conversation history persists across browser reloads and sessions. When you send a message, the agent's responses stream back asynchronously. Because the agent performs actions in the background, you can continue working on the canvas while it processes your request. ### Interrupting the agent If the agent is heading in the wrong direction or taking too long, you can interrupt it mid-execution. Click **Stop** to send an interrupt event that halts the agent's current operation and returns control to you. ## Outcomes and rubrics For complex tasks, the agent uses a **rubric** to confirm its plan before building. When you ask the agent to build something broad or ambiguous (like "add health checking"), it will first ask you questions to clarify the requirements. Once it has enough information, it presents a rubric — a clear specification of what it intends to build, including the flow, components, and integrations needed. You can review the rubric and either request changes or click **Start Building** to approve the plan. The agent will not modify your canvas until you approve the rubric. ## Tools and capabilities The agent has built-in tools to interact with your app's configuration and runtime state. ### Repository file tools The agent can manage files in your app's repository: - **List and read**: Discover and read files like `README.md` or custom scripts. - **Stage changes**: Write or delete files in a draft branch. - **Commit**: Commit staged file changes to the repository. - **Update drafts**: Modify the `canvas.yaml` and `console.yaml` configurations directly. ### Runtime read tools When troubleshooting, the agent can inspect the live state of your app. It can read memory values, inspect recent [runs](/concepts/data-flow#runs-and-run-items), view event payloads, and check execution queues to help you diagnose issues. ### Node mentions You can explicitly reference canvas nodes in your messages by typing `@` followed by the node's name. This provides the agent with the exact ID and context of the node, ensuring it targets the correct component when answering questions or making updates. ## Permissions and safety boundaries The agent operates safely within strict boundaries: - **RBAC enforcement**: The agent shares your user session's permissions. It cannot perform any action that you do not have permission to do. See [RBAC](/security/access-control). - **Canvas isolation**: The agent is strictly bound to its parent canvas. It cannot read or modify data from other apps. - **Drafts only**: The agent can only update draft versions of your app. It cannot publish changes directly to production. - **File safety**: The agent cannot access sensitive system paths (like `.superplane/`) or traverse outside the repository workspace. ## Limits To ensure performance and stability, the agent operates with specific limits: - **Query limits**: Runtime reads and file listings are paginated (e.g., returning up to 40 components per query). - **Context management**: Long conversations are automatically rewound and truncated to fit within the provider's context window, preserving the most relevant recent messages. ## Provider setup The built-in agent is powered by Anthropic's Claude Managed Agents. To enable the agent in a self-hosted SuperPlane deployment, an administrator must configure the following environment variables: - `ANTHROPIC_API_KEY`: Your Anthropic API key. - `ANTHROPIC_AGENT_ID`: The ID of your managed Anthropic agent. - `ANTHROPIC_ENVIRONMENT_ID`: The ID of your Anthropic environment. If these variables are not set, the agent interface remains disabled. #### Sharing apps Source URL: https://docs.superplane.com/concepts/sharing-apps A SuperPlane app is backed by a Git repository. You can export that repository, push it to GitHub, and let others install the app into their own organization with a single click. Install parameters let you customize the app at install time without editing YAML by hand. ## How app sharing works An app's [canvas](/concepts/canvas), [console](/concepts/console), scripts, and helper files form a complete, portable package. To share an app: 1. Export the app files from the **Files** tab or the CLI. 2. Push them to a public GitHub repository. 3. Add a **Launch in SuperPlane** badge to the README. 4. Optionally, add a `params.json` file to make the app configurable at install time. When someone clicks the badge, SuperPlane reads the repository, copies all files into the new app (scripts, READMEs, helper files), detects which integrations the app needs, and walks the user through naming the app, connecting integrations, and filling in any parameters before creating it. ## Repository structure A shareable app repository contains at minimum a `canvas.yaml`. Everything else is optional. | File | Required | Purpose | | ---- | -------- | ------- | | `canvas.yaml` | Yes | Workflow definition: nodes, connections, and configuration | | `console.yaml` | No | Console layout and panels | | `params.json` | No | Install parameters shown in the install wizard | | Other files | No | Scripts, READMEs, agent instructions, or any file your workflows reference | During install, SuperPlane copies every file from the repository into the new app's git repository — except `canvas.yaml`, `console.yaml`, and `params.json`, which are handled separately. This means helper scripts, documentation, and agent instruction files are available to the app from the start. ## Install parameters Install parameters let users customize an app when they install it. For example, a monitoring app might ask for an SSH host address, or a deploy pipeline might ask which repository to watch. ### Defining parameters Create a `params.json` file in the root of your repository: ```json { "install_params": [ { "name": "ssh_host", "label": "SSH Host", "type": "string", "placeholder": "192.168.1.100", "description": "IP address of the server to monitor", "required": true }, { "name": "deploy_region", "label": "Region", "type": "string", "default": "nyc1", "description": "Cloud region for new deployments", "required": false } ] } ``` Each parameter has these fields: | Field | Required | Description | | ----- | -------- | ----------- | | `name` | Yes | Identifier used in `{{ install_params. }}` placeholders across all files | | `label` | Yes | Display label shown in the install wizard | | `type` | Yes | `string`, `secret_picker`, or `integration-resource` | | `placeholder` | No | Hint text shown in the input field | | `description` | No | Help text shown below the input | | `default` | No | Pre-filled value (user can override) | | `required` | Yes | Whether the user must provide a value | ### Parameter types **`string`** — A plain text input. Use for hosts, names, regions, or any free-form value. **`secret_picker`** — Lets the user select an existing [secret](/security/secrets) from their organization. SuperPlane validates that the selected secret exists before completing the install. Use for credentials, API keys, or SSH keys that should not be stored in plain text. **`integration-resource`** — Lets the user pick a resource from a connected integration. Requires two additional fields: ```json { "name": "droplet_region", "label": "Droplet Region", "type": "integration-resource", "integration": "digitalocean", "resourceType": "region", "required": true } ``` | Field | Description | | ----- | ----------- | | `integration` | Integration type name (e.g., `digitalocean`, `github`) | | `resourceType` | Resource type to list (e.g., `region`, `size`, `image`, `repository`) | | `useNameAsValue` | When `true`, substitute the resource display name instead of its ID. Use this when the component expects a name (e.g., GitHub repository name) rather than a numeric ID. Optional, defaults to `false`. | ### Using parameters in canvas.yaml and files Reference parameters in your `canvas.yaml` and any other files using the `{{ install_params. }}` syntax. SuperPlane substitutes placeholders in both the canvas definition and all repository files (scripts, READMEs, etc.) during install. ```yaml - component: ssh configuration: host: {{ install_params.ssh_host }} port: 22 username: {{ install_params.ssh_user }} authentication: authMethod: password password: key: pw secret: {{ install_params.ssh_secret_name }} ``` At install time, SuperPlane replaces every `{{ install_params. }}` placeholder with the value the user provided before parsing the YAML. Write placeholders without quotes — the substituted value appears as-is in the file. If a parameter has a default and the user does not override it, the default value is used. ## Launch in SuperPlane badge Add this badge to your README so users can install the app with one click: ```markdown [![Launch in SuperPlane](https://superplane.com/badges/launch-in-superplane.svg)](https://app.superplane.com/install?repo=github.com//) ``` Replace `/` with your GitHub repository path. When a user clicks the badge, SuperPlane opens the install wizard, which: 1. Reads `canvas.yaml` from the repository. 2. Lets the user name the app (pre-filled from the template). 3. Detects which integrations the app uses and asks the user to connect them. 4. Reads `params.json` (if present) and shows the parameter form. 5. Creates the app with all placeholders resolved and all repository files copied in. ## Exporting an existing app To export an app you have already built: **From the UI:** 1. Open the app and go to the **Files** tab. 2. Download `canvas.yaml`, `console.yaml`, and any scripts or helper files. **From the CLI:** ```bash # Export the canvas superplane apps canvas get -o yaml > canvas.yaml # Export the console superplane apps console get -o yaml > console.yaml # List all files in the app repository superplane apps files tree ``` To turn the export into a shareable template: 1. Remove hardcoded values (secrets, repo names, hostnames) and replace them with `{{ install_params. }}` placeholders. 2. Create a `params.json` to define the install parameters. 3. Add a `README.md` with a Launch in SuperPlane badge and setup instructions. 4. Push everything to a GitHub repository. ## Best practices **Write a clear README.** Explain what the app does, list prerequisites, and describe how to customize it after install. Include the Launch in SuperPlane badge so users can install with one click. **Parameterize your app.** Even though `params.json` is optional, it makes installing the app much easier. Users should not have to open canvas nodes and update hardcoded values. Anything that varies between installations — repository names, secrets, regions, hostnames — should be a parameter. **Include an AGENTS.md.** The [built-in agent](/concepts/agent) and external agents (like Cursor) can read this file to understand how your canvas works. Document the main flows, what is safe to change, what should not be touched, and common issues. This helps agents give accurate advice instead of guessing. **Add annotations to the canvas.** Use notes on the canvas to explain key sections, especially parts that users will need to customize. For example, an annotation above an SSH node can explain which secret it expects and how to update the setup script. Annotations make the canvas self-documenting for both humans and agents. ## Examples | App | Description | Repository | | --- | ----------- | ---------- | | Preview Environments on DigitalOcean | Spin up ephemeral preview environments for GitHub PRs using DigitalOcean droplets | [superplanehq/app_preview-env-digitalocean](https://github.com/superplanehq/app_preview-env-digitalocean) | ### Workflow Orchestration #### Overview Source URL: https://docs.superplane.com/concepts/data-flow SuperPlane has an event-driven workflow model. Every node on the canvas emits a payload, and other nodes subscribe to these events to create workflows. This model enables flexible, composable automation pipelines. ## How It Works When an external event occurs (like a GitHub push), it triggers a node on your canvas. That node processes the event, emits a payload, and downstream nodes that subscribe to it receive the data and continue the chain. ```mermaid flowchart LR External[External Event] --> Trigger[Trigger Node] Trigger -->|payload| Action[Action Node] Action -->|payload| Next[Next Node] ``` Each node in the workflow: 1. **Receives** an event from its subscribed sources 2. **Processes** the event (executes an action, transforms data, etc.) 3. **Emits** a payload for downstream nodes As the workflow executes, payloads from each node accumulate into a message chain. Any node can access data from any upstream node in this chain using expressions. ## Runs and Run Items Understanding how SuperPlane tracks execution helps when working with data flow. ### Run Items A **run item** is a single execution within a single node: - For **trigger nodes**: a single received event (e.g., a GitHub push event) - For **action nodes**: a single execution (e.g., running a GitHub workflow) Each run item produces a payload that downstream nodes can access. ### Runs A **run** is a collection of run items and the dependencies between them. It represents a complete workflow execution from start to finish. - Starts with a **root event** — the first event that triggered the workflow (usually from a trigger node) - Grows as the workflow executes and each node adds its run item to the chain - Tracks the full execution history and data flow ```mermaid flowchart LR Root[Root Event] --> Item1[Run Item 1] Item1 --> Item2[Run Item 2] Item2 --> Item3[Run Item 3] Item1 --> Item4[Run Item 4] Item4 --> Item3 ``` ## The Message Chain As a run executes, each node's output is added to a **message chain**. This chain is accessible via the `$` variable — think of it as a message bus that streams all outputs to your current node. ### How It Works Consider this workflow: ```mermaid flowchart LR GitHub[GitHub onPush] --> Filter[Filter] --> Deploy[Deployment] ``` When the workflow executes, each node adds its output to `$`: ```json { "GitHub onPush": { "type": "github.push", "timestamp": "...", "data": { "ref": "refs/heads/main", "commit": "abc123" } }, "Filter": { "type": "filter.passed", "timestamp": "...", "data": { "passed": true } }, "Deployment": { "type": "deployment.finished", "timestamp": "...", "data": { "status": "success", "url": "https://app.example.com" } } } ``` From the Deployment node, you can access any upstream output via `.data`: ``` $['GitHub onPush'].data.ref // "refs/heads/main" $['Filter'].data.passed // true ``` Wrap expressions in `{{ }}` to insert values into text fields; in condition fields (If / Filter) write them bare. Each node also exposes `.config` (resolved settings at run time). See [Expressions](/concepts/expressions). ## Exploring Runs on the Canvas The workflow you see on the canvas is dynamic — it's not a single run, but a live view where multiple runs can execute simultaneously. ### Node Status Each node on the canvas shows a quick overview of its current or most recent run item. ![Node with run item status](../../../assets/data-flow-node-status.png) ### Run History Click on any node to open the sidebar. The sidebar shows the run history — all executions or events that have passed through this node, along with each execution's result. ![Run history sidebar](../../../assets/data-flow-run-history.png) ### Run Chain Click on any item in the run history to see the full run chain. This shows all run items from all nodes that executed as part of that particular run. ![Run chain view](../../../assets/data-flow-run-chain.png) ### Inspecting Run Items In the run chain view, the node you were inspecting is preselected. You can click on any other run item in the chain to explore its details and payload. ![Run item details expanded](../../../assets/data-flow-run-details.png) ## Payloads Every node emits a **payload**. Each run item also records a `.config` snapshot (visible in the **Config** tab). ### Trigger Components Trigger components listen to external resources and emit the event data as their payload. - Connect to external systems via webhooks or integrations - Emit events when something happens externally - Payload contains the raw event data from the external system **Examples:** [GitHub onPush](/components/github/#on-push), [GitHub onRelease](/components/github/#on-release), [Slack onAppMention](/components/slack/#on-app-mention) ### Action Components Action components execute operations and emit execution results as their payload. - Subscribe to events from upstream nodes - Execute operations on external systems - Payload contains execution results and any returned data **Examples:** [GitHub runWorkflow](/components/github/#run-workflow), [Slack sendMessage](/components/slack/#send-text-message), [HTTP request](/components/core/#http-request) ### Output Channels Nodes can emit through one or multiple output channels. Channels let you route data based on different outcomes. **Example: Pass/Fail Routing** ![Output channels](../../../assets/data-flow-output-channels.png) Subscribe to the `passed` channel to continue on success, or the `failed` channel to handle errors. **Output channels example** | Component | Channels | Description | | ----------------------- | ------------------------------- | ------------------------------------------- | | GitHub runWorkflow | `passed`, `failed` | Routes based on workflow success or failure | | Approval | `approved`, `rejected` | Routes based on approval decision | | Merge | `success`, `fail`, `timeout` | Routes based on merge outcome | | Dash0 listIssues | `clear`, `degraded`, `critical` | Routes based on issue severity | | PagerDuty listIncidents | `clear`, `low`, `high` | Routes based on incident urgency | ### Execution result vs. output channel Each execution carries **two independent** outcome fields. They report different things and should not be conflated: | Field | What it means | Values | | --- | --- | --- | | `result` | **Runtime health** — did the action run to completion without crashing? | `RESULT_PASSED`, `RESULT_FAILED`, `RESULT_CANCELLED`, `RESULT_UNKNOWN` | | `outputs` (keys) | **Semantic routing** — which logical output the action chose | Component-defined channel names (`success`, `failure`, `approved`, `rejected`, `true`, `false`, `not_found`, …) | **Example.** An HTTP node that receives a `500` status records `result: RESULT_PASSED` (the request was made, the response was parsed, the node finished cleanly) **and** emits on its `failure` channel (the response was a 5xx, so it routed onto the failure output). Both fields are correct. **Failure-class channels.** Only these channel names — case-insensitive — denote a semantic failure: `failure`, `failed`, `fail`, `timeout`. Other channels such as `rejected` (Approval), `not_found` (Memory), `false` (If), `degraded`, `low`, etc. are normal alternate routing outcomes, not failures. **Querying "failed runs".** If you want every run that did not take the happy path, filter on **both** axes — `result == RESULT_FAILED` **or** `outputs` contains a key in the failure-class set. `result` alone misses semantic failures routed via channels; channel alone misses runtime crashes that never emitted any output. #### Runs Source URL: https://docs.superplane.com/concepts/runs A **run** is a single, end-to-end execution of a SuperPlane app. It begins when a trigger receives an event and ends when all connected actions have finished processing. ## App run identity Every run has a unique identity (a Run ID) that ties together all the activity triggered by a specific event. Instead of hunting through disparate logs, you can view a run as a single cohesive trace. A run tracks the initial payload, the path taken through the canvas, and the exact inputs and outputs of every node along the way. ## Durable execution SuperPlane uses a **durable execution** model. This means that workflow state is preserved across steps. If a node crashes, times out, or the system restarts, the run does not lose its progress. Because every node's payload is saved to the message chain, a workflow can safely pause and resume. This is critical for workflows that: - Wait for human approval (which could take days). - Call flaky external APIs that might need to be retried. - Run long-running scripts on remote runners. You don't need to write custom retry logic or state-saving code; durable execution is built into the platform. ## Run vs. node execution vs. queue item To understand how SuperPlane processes work, it helps to distinguish between runs, node executions, and queue items: - **Run**: The overarching execution of the entire canvas, triggered by a single event. - **Node execution**: A specific action or trigger firing within the run. A single run contains many node executions. - **Queue item**: The pending work for a node execution. When a node finishes, it pushes queue items to downstream nodes. SuperPlane workers pull these items from the queue to start the next node executions. ## Version attachment Every run is permanently attached to the **canvas version** that was active when the run started. If you publish a new version of your app while a long-running workflow is still executing, the existing run will continue using the old version. This guarantees that workflows execute predictably, exactly as they were defined when the triggering event occurred. ## State and result filters Runs move through different states and conclude with a final result. **States**: - `STATE_STARTED`: The run is currently executing. - `STATE_FINISHED`: The run has completed (regardless of success or failure). **Results**: - `RESULT_PASSED`: All node executions completed successfully. - `RESULT_FAILED`: One or more node executions failed, and the run could not proceed. - `RESULT_CANCELLED`: The run was manually aborted. You can filter runs by these states and results in the UI or via the CLI to quickly find ongoing work or investigate failures. ## Run inspection UI The SuperPlane UI provides a dedicated view for inspecting runs. When you open an app, you can switch to the **Runs** tab to see a chronological list of all executions. ### Bottom panel Clicking on a specific run opens the **bottom panel**. This panel provides a detailed drill-down into the run's history: - **Timeline**: A chronological list of every node execution. - **Payloads**: The exact JSON input and output for each step. - **Logs**: Standard output and error logs generated by the nodes. You can click on any node in the canvas while a run is selected to instantly filter the bottom panel to that specific node's execution history. ## Failure and error resolution When a run fails (`RESULT_FAILED`), it stops executing downstream nodes. To resolve a failure: 1. Open the failed run in the UI. 2. Use the bottom panel to locate the specific node execution that failed. 3. Inspect the error logs and the input payload to determine why it failed (e.g., a bad API key, a malformed payload, or a network timeout). 4. Once you fix the underlying issue (e.g., updating a secret or fixing a bug in the canvas), you can often replay the failed node or restart the run, depending on the node's configuration. ## CLI and API usage You can inspect runs directly from your terminal using the [SuperPlane CLI](/cli/runs). List runs for an app: ```sh superplane runs list --app-id ``` Filter runs by state or result to find failures: ```sh superplane runs list --app-id --state STATE_STARTED --result RESULT_FAILED ``` Show full details for a specific run, including its node executions: ```sh superplane runs describe --app-id ``` These commands wrap the SuperPlane API, which you can also call directly to integrate run monitoring into your own internal tools. #### Component Nodes Source URL: https://docs.superplane.com/concepts/component-nodes **Components** are available building blocks that define capabilities in SuperPlane. A **component node** is one instance of a component on the canvas. When you add a component to your canvas, it becomes a node that can receive events, perform work, and emit payloads. ## Components vs Component Nodes - **Component**: The building block definition — what it does, what configuration it needs, what it emits - **Component Node**: A single instance of a component placed on your canvas with specific configuration Think of it like this: a component is the reusable definition, and a component node is one concrete instance with its own settings and name. ## Component Types There are two types of **executable** components (nodes that participate in runs): ### Trigger Components **Trigger components** start workflow executions. They listen for external events or can be invoked manually. **Examples:** Webhook, Schedule, Manual Run, GitHub onPush, Slack onAppMention ### Action Components **Action components** execute operations in response to upstream events. They subscribe to events, perform operations, and emit payloads for downstream nodes. **Examples:** HTTP Request, Filter, Approval, GitHub runWorkflow, Slack sendMessage ## Adding Component Nodes to the Canvas New component nodes can be added to the Canvas in two ways: ### From the Components Menu 1. Click the **"+ Components"** button in the top right of the canvas 2. Select a component from the list of available components 3. Drag it onto the canvas where you want it The component is now a node on your canvas, ready to be configured and connected. ### From Output Channels You can also drag an output channel from an existing node to an empty space on the canvas. This creates a new component node and automatically subscribes it to that output channel, making it faster to model workflows. ## Node Overview on Canvas Each component node on the canvas displays key information and provides interactive elements: ![Component node on canvas](../../../assets/component-nodes-node.png) 1. **Input channel** — Drag to subscribe to events from other nodes (Action nodes only). 2. **Configuration overview** — Quick summary of key settings for this node. 3. **Latest Run Item** — Shows the last run executed or event emitted. 4. **Action menu** — On hover: manually emit, copy, collapse/expand, or delete. 5. **Output channels** — Subscribe other nodes or drag to create new components. ## Pausing and resuming nodes You can **pause** a component node so it stops dequeuing new work. Events can still arrive and **queue**; they are processed again after you **resume** the node. Use this for maintenance, incident response, or debugging. Paused nodes are skipped until resumed (from the node menu where available, or via the API). ## Component Node Sidebar Clicking on a component node selects it and opens a component node sidebar. ![Component node sidebar](../../../assets/component-nodes-sidebar.png) 1. **Click to open** — You can click on a node to open the sidebar. 2. **Resizable sidebar** — Sidebar is resizable and contains node details. 3. **Latest runs section** — Recent executions with event ID, timestamp, and status. 4. **Configuration tab** — Node settings. Fields support expressions — see [Expressions](/concepts/expressions). 5. **Action menu for run item** — Cancel or push through running items. 6. **Queue** — Items waiting to execute (FIFO order). ## Single Run Chain Select a run from the list to see the full chain of nodes it went through. ![Single run chain view](../../../assets/component-nodes-single-run.png) 1. **Run chain** — Shows all nodes in the run with current node preselected. 2. **Dimmed nodes** — Nodes not included in the run are dimmed on the canvas. 3. **Expandable details** — Expand other nodes in the chain to view their payloads. 4. **Details tab** — Execution info: start/finish time, result, duration. 5. **Payload tab** — The data this node emitted for downstream nodes. 6. **Config tab** — Resolved configuration for this run (same as `$['Node Name'].config` in expressions). See [Expressions](/concepts/expressions). ## Component Availability Components are provided by **integrations**. SuperPlane includes: - **Core components**: Built-in components like Webhook, Filter, HTTP Request - **Integration components**: Components from integrations like GitHub, Slack, PagerDuty To use integration components, you may need to configure authentication or connection settings for that integration first. Browse the [Components](/components/core) section to see all available components and their documentation. ## Best Practices When working with component nodes: - **Choose the right component**: Understand what each component does before using it - **Use expressions**: Make configurations dynamic by referencing upstream data - **Name nodes clearly**: Use descriptive names that indicate purpose - **Test incrementally**: Verify component behavior before building complex workflows - **Monitor run history**: Check execution history to understand behavior and debug issues For more details on how component nodes connect and how data flows between them, see [Data Flow](/concepts/data-flow). For information about the canvas where you work with component nodes, see [Canvas](/concepts/canvas). #### Expressions Source URL: https://docs.superplane.com/concepts/expressions SuperPlane uses [Expr](https://expr-lang.org) for expressions. Expressions let you reference data from upstream nodes, transform values, and control workflow logic. **Don't want to write expressions by hand?** - **Ask the agent**: You can ask the built-in AI agent to write expressions for you. Just describe what you want to extract or calculate in the chat. - **Use the Preview tool**: When typing `{{` in a text field or `$` in a condition field, the Canvas editing UI provides an autocomplete dropdown based on actual payload data from previous runs. You can also use the **Preview** tab in the node configuration to test your expressions against real data before running the workflow. ## The message chain (`$`) As a run executes, each node's output is added to the message chain. Access it through `$`, referencing nodes by **display name**: ``` {{$['Node Name'].data.field}} {{$['Node Name'].data.nested.field}} {{$['Node Name'].data.array[0].value}} ``` Every entry also includes a **`.config`** property — the node's resolved configuration at run time: ``` {{$['HTTP Request'].config.url}} {{$['HTTP Request'].config.method}} ``` ### `root()` and `previous()` | Function | Returns | | -------- | ------- | | `root()` | The payload that started the run (the trigger event). | | `previous()` | The immediate upstream node's payload. | | `previous(n)` | Walk **n** levels upstream. | ``` {{root().data.ref}} {{previous().data.status}} ``` `previous()` is not available when a node has multiple inputs (e.g. after a Merge). Use `$['Node Name']` instead. --- ## Syntax: text fields vs conditions Expressions appear in two contexts with slightly different syntax: **Text fields** (URLs, message bodies, labels) — wrap each expression in `{{ }}`: ``` Deployment of {{$['Release'].data.name}} failed. See: {{$['Deploy'].data.workflow_run.html_url}} ``` **Condition fields** (If, Filter) — the entire field is one bare expression that must return `true` or `false`: ``` $['Get cat fact'].data.body.length <= 160 && $['Health Check'].data.body.healthy ``` --- ## Operators Beyond standard arithmetic (`+`, `-`, `*`, `/`, `%`, `**`) and comparison (`==`, `!=`, `<`, `>`, `<=`, `>=`): | Operator | What it does | Example | | -------- | ------------ | ------- | | `&&` `\|\|` `!` | Logical (aliases: `and`, `or`, `not`) | `{{$['a'].data.ok && !$['b'].data.failed}}` | | `contains` | String contains substring | `{{$['node'].data.body contains "error"}}` | | `startsWith` | String prefix check | `{{$['node'].data.ref startsWith "refs/heads/"}}` | | `endsWith` | String suffix check | `{{$['node'].data.branch endsWith "-hotfix"}}` | | `matches` | Regex match ([RE2](https://github.com/google/re2/wiki/Syntax)) | `{{$['node'].data.msg matches "^fix\\(.*\\)"}}` | | `in` / `not in` | Membership test | `{{$['node'].data.env in ["staging", "prod"]}}` | | `??` | Nil coalescing (fallback) | `{{$['node'].data.label ?? "default"}}` | | `? :` | Ternary | `{{$['node'].data.ok ? "pass" : "fail"}}` | | `?.` | Optional chaining | `{{$['node'].data?.user?.name}}` | --- ## Closures (`#`) Array functions accept a closure where **`#`** is the current element: ``` {{filter($['node'].data.items, # > 10)}} {{map($['node'].data.users, #.name)}} {{any($['node'].data.tags, # == "critical")}} {{sortBy($['node'].data.alerts, #.severity, "desc")}} ``` `reduce()` adds **`#acc`** for the accumulator: ``` {{reduce($['node'].data.items, #acc + #.price, 0)}} ``` --- ## Common patterns **Fallback for missing fields:** ``` {{$['Webhook'].data.user.name ?? "unknown"}} ``` **Ternary in a text field:** ``` Status: {{$['Deploy'].data.success ? "Deployed" : "Failed"}} ``` **Check array membership:** ``` {{"production" in $['node'].data.environments}} ``` **Filter and join:** ``` {{join(filter($['node'].data.tags, # startsWith "env:"), ", ")}} ``` **Date comparison (event in the last hour):** ``` {{now().Sub(date($['node'].data.timestamp)).Hours() < 1}} ``` **Build a JSON string:** ``` {{toJSON({status: $['Deploy'].data.result, ref: root().data.ref})}} ``` --- ## Function reference SuperPlane expressions have access to the full set of Expr built-in functions for strings, arrays, dates, math, and type conversion. See the [Expression Functions Reference](/concepts/expression-functions) for the complete list with signatures and examples. For the Expr language specification, see the [Expr documentation](https://expr-lang.org/docs/language-definition). #### Expression Functions Source URL: https://docs.superplane.com/concepts/expression-functions This page lists every function available in SuperPlane expressions. For an introduction to how expressions work, see [Expressions](/concepts/expressions). --- ## SuperPlane | Function | Description | Example | | -------- | ----------- | ------- | | `root()` | Root payload that started the run | `root().data.ref` | | `previous()` | Immediate upstream node's payload | `previous().data.status` | | `previous(n)` | Walk n levels upstream | `previous(2).data.version` | --- ## String | Function | Description | Example | | -------- | ----------- | ------- | | `trim(str)` | Remove whitespace from both ends | `trim(" hello ") == "hello"` | | `trim(str, chars)` | Remove specific characters | `trim("xxhelloxx", "x") == "hello"` | | `trimPrefix(str, prefix)` | Remove prefix if present | `trimPrefix("HelloWorld", "Hello") == "World"` | | `trimSuffix(str, suffix)` | Remove suffix if present | `trimSuffix("HelloWorld", "World") == "Hello"` | | `upper(str)` | Convert to uppercase | `upper("hello") == "HELLO"` | | `lower(str)` | Convert to lowercase | `lower("HELLO") == "hello"` | | `split(str, delim)` | Split into array | `split("a,b,c", ",") == ["a", "b", "c"]` | | `split(str, delim, n)` | Split with limit | `split("a,b,c", ",", 2) == ["a", "b,c"]` | | `splitAfter(str, delim)` | Split keeping delimiters | `splitAfter("a,b,c", ",") == ["a,", "b,", "c"]` | | `replace(str, old, new)` | Replace all occurrences | `replace("hello world", "world", "there")` | | `repeat(str, n)` | Repeat n times | `repeat("ab", 3) == "ababab"` | | `indexOf(str, sub)` | First occurrence index (-1 if missing) | `indexOf("apple pie", "pie") == 6` | | `lastIndexOf(str, sub)` | Last occurrence index (-1 if missing) | `lastIndexOf("abab", "ab") == 2` | | `hasPrefix(str, prefix)` | Starts with prefix? | `hasPrefix("hello", "he") == true` | | `hasSuffix(str, suffix)` | Ends with suffix? | `hasSuffix("hello", "lo") == true` | --- ## Number | Function | Description | Example | | -------- | ----------- | ------- | | `max(a, b)` | Larger of two numbers | `max(5, 7) == 7` | | `min(a, b)` | Smaller of two numbers | `min(5, 7) == 5` | | `abs(n)` | Absolute value | `abs(-5) == 5` | | `ceil(n)` | Round up | `ceil(1.2) == 2.0` | | `floor(n)` | Round down | `floor(1.8) == 1.0` | | `round(n)` | Round to nearest integer | `round(1.5) == 2.0` | --- ## Array Array functions that accept a predicate use `#` for the current element. See [Closures](/concepts/expressions#closures-). | Function | Description | Example | | -------- | ----------- | ------- | | `all(arr, pred)` | True if all elements match | `all([1, 2, 3], # > 0) == true` | | `any(arr, pred)` | True if any element matches | `any([1, 2, 3], # > 2) == true` | | `one(arr, pred)` | True if exactly one matches | `one([1, 2, 3], # == 2) == true` | | `none(arr, pred)` | True if no elements match | `none([1, 2, 3], # > 5) == true` | | `map(arr, pred)` | Transform each element | `map([1, 2, 3], # * 2) == [2, 4, 6]` | | `filter(arr, pred)` | Keep matching elements | `filter([1, 2, 3], # > 1) == [2, 3]` | | `find(arr, pred)` | First matching element | `find([1, 2, 3], # > 1) == 2` | | `findIndex(arr, pred)` | Index of first match | `findIndex([1, 2, 3], # > 1) == 1` | | `findLast(arr, pred)` | Last matching element | `findLast([1, 2, 3], # > 1) == 3` | | `findLastIndex(arr, pred)` | Index of last match | `findLastIndex([1, 2, 3], # > 1) == 2` | | `groupBy(arr, pred)` | Group elements by key | `groupBy(users, #.role)` | | `count(arr, pred)` | Count matching elements | `count([1, 2, 3], # > 1) == 2` | | `reduce(arr, pred, init)` | Reduce to single value (`#acc` + `#`) | `reduce([1, 2, 3], #acc + #, 0) == 6` | | `sum(arr)` | Sum of numbers | `sum([1, 2, 3]) == 6` | | `mean(arr)` | Average | `mean([1, 2, 3]) == 2.0` | | `median(arr)` | Median value | `median([1, 2, 3]) == 2.0` | | `first(arr)` | First element (nil if empty) | `first([1, 2, 3]) == 1` | | `last(arr)` | Last element (nil if empty) | `last([1, 2, 3]) == 3` | | `take(arr, n)` | First n elements | `take([1, 2, 3, 4], 2) == [1, 2]` | | `reverse(arr)` | Reverse order | `reverse([1, 2, 3]) == [3, 2, 1]` | | `sort(arr)` | Sort ascending | `sort([3, 1, 2]) == [1, 2, 3]` | | `sort(arr, "desc")` | Sort descending | `sort([1, 2, 3], "desc") == [3, 2, 1]` | | `sortBy(arr, pred)` | Sort by predicate | `sortBy(users, #.age, "desc")` | | `concat(arr1, arr2, ...)` | Concatenate arrays | `concat([1, 2], [3, 4]) == [1, 2, 3, 4]` | | `flatten(arr)` | Flatten nested arrays | `flatten([[1, 2], [3]]) == [1, 2, 3]` | | `uniq(arr)` | Remove duplicates | `uniq([1, 2, 2, 3]) == [1, 2, 3]` | | `join(arr, delim)` | Join into string | `join(["a", "b"], ",") == "a,b"` | --- ## Map | Function | Description | Example | | -------- | ----------- | ------- | | `keys(map)` | Array of keys | `keys({a: 1, b: 2}) == ["a", "b"]` | | `values(map)` | Array of values | `values({a: 1, b: 2}) == [1, 2]` | | `toPairs(map)` | Map to key-value pairs | `toPairs({a: 1}) == [["a", 1]]` | | `fromPairs(arr)` | Key-value pairs to map | `fromPairs([["a", 1]]) == {a: 1}` | --- ## Date and time | Function | Description | Example | | -------- | ----------- | ------- | | `now()` | Current time (UTC) | `now().Year()` | | `date(str)` | Parse a date string | `date("2024-08-14")` | | `date(str, tz)` | Parse with timezone | `date("2024-08-14", "America/New_York")` | | `date(unix)` | Parse a Unix timestamp | `date(1700000000)` | | `duration(str)` | Parse a duration string | `duration("1h30m")` | | `timezone(str)` | Get a timezone by name | `timezone("Europe/Zurich")` | Duration units: `ns`, `us`, `ms`, `s`, `m`, `h`. Date strings are parsed as RFC 3339 or `YYYY-MM-DD`. Numeric timestamps are auto-detected as seconds, milliseconds, microseconds, or nanoseconds. ### Date methods `now()` and `date()` return a time value with these chainable methods: | Method | Returns | Example | | ------ | ------- | ------- | | `.Year()` | Year (e.g. 2024) | `now().Year()` | | `.Month()` | Month (1-12) | `now().Month()` | | `.Day()` | Day of month (1-31) | `now().Day()` | | `.Hour()` | Hour (0-23) | `now().Hour()` | | `.Minute()` | Minute (0-59) | `now().Minute()` | | `.Second()` | Second (0-59) | `now().Second()` | | `.Weekday()` | Day of week (0 = Sunday) | `now().Weekday()` | | `.YearDay()` | Day of year (1-366) | `now().YearDay()` | | `.Unix()` | Unix timestamp (seconds) | `now().Unix()` | | `.UnixMilli()` | Unix timestamp (ms) | `now().UnixMilli()` | | `.Format(layout)` | Format using Go layout | `now().Format("2006-01-02")` | | `.Add(dur)` | Add a duration | `now().Add(duration("1h"))` | | `.Sub(time)` | Duration between two times | `now().Sub(date("2024-01-01"))` | | `.Before(time)` | True if before | `date("2024-01-01").Before(now())` | | `.After(time)` | True if after | `now().After(date("2024-01-01"))` | | `.In(tz)` | Convert to timezone | `now().In(timezone("US/Eastern"))` | | `.UTC()` | Convert to UTC | `date("...").UTC()` | | `.Round(dur)` | Round to nearest duration | `now().Round(duration("1h"))` | | `.Truncate(dur)` | Truncate to duration | `now().Truncate(duration("24h"))` | | `.IsZero()` | True if zero value | `date("...").IsZero()` | ### Duration methods | Method | Returns | Example | | ------ | ------- | ------- | | `.Hours()` | Float hours | `duration("90m").Hours() == 1.5` | | `.Minutes()` | Float minutes | `duration("1h").Minutes() == 60.0` | | `.Seconds()` | Float seconds | `duration("1m30s").Seconds() == 90.0` | | `.Milliseconds()` | Integer ms | `duration("1s").Milliseconds() == 1000` | | `.Microseconds()` | Integer us | `duration("1ms").Microseconds() == 1000` | | `.Nanoseconds()` | Integer ns | `duration("1us").Nanoseconds() == 1000` | --- ## Type and conversion | Function | Description | Example | | -------- | ----------- | ------- | | `type(v)` | Type name as string | `type(42) == "int"` | | `int(v)` | Convert to integer | `int("123") == 123` | | `float(v)` | Convert to float | `float("1.5") == 1.5` | | `string(v)` | Convert to string | `string(123) == "123"` | | `toJSON(v)` | Serialize to JSON string | `toJSON({a: 1})` | | `fromJSON(str)` | Parse JSON string | `fromJSON("{\"a\":1}")` | | `toBase64(str)` | Base64 encode | `toBase64("hello")` | | `fromBase64(str)` | Base64 decode | `fromBase64("aGVsbG8=") == "hello"` | | `len(v)` | Length of string, array, or map | `len("hello") == 5` | | `get(v, key)` | Safe index/key access (nil if missing) | `get([1, 2], 5) == nil` | --- For the Expr language specification, see the [Expr documentation](https://expr-lang.org/docs/language-definition). #### Runners Source URL: https://docs.superplane.com/concepts/runners **Runners** are worker machines that execute custom scripts from your workflows. SuperPlane provides components for executing shell commands, bash scripts, JavaScript, and Python scripts. - [Running Shell Commands](#running-shell-commands) - [Running Bash Scripts](#running-bash-scripts) - [Running JavaScript](#running-javascript) - [Running Python](#running-python) ## When to use runners Use runner components when a workflow step needs code or shell that SuperPlane integrations do not cover: - Run build scripts, linters, or custom tooling on dedicated machines - Transform upstream payload data with JavaScript or Python and pass structured output downstream - Execute in a specific container image without managing SSH or long-lived hosts - Provide sandboxed compute for coding agents and AI workflows For remote commands on a host you manage directly, consider [SSH Command](/components/core/#ssh-command) instead. For HTTP or API calls, use [HTTP Request](/components/core/#http-request). ## Running Shell Commands Runs shell commands on a runner machine. Commands execute in order. The task succeeds when the last command exits with code **0**, or fails if any command exits with a non-zero code. Example: ```sh git clone https://github.com/example/repo.git cd repo docker build -t example-image . docker push example-image ``` ### Passing output to the next node To pass output from the commands to the next node on the canvas, write valid JSON to the **`$SUPERPLANE_RESULT_FILE`** file — the path the runner sets for your task. ```sh git clone https://github.com/example/repo.git cd repo export IMAGE_TAG=example-image-$(git rev-parse HEAD) docker build -t $IMAGE_TAG . docker push $IMAGE_TAG echo "{\"image\": \"$IMAGE_TAG\"}" > $SUPERPLANE_RESULT_FILE ``` ## Running Bash Scripts Runs a Bash script on a runner machine. The task succeeds when the script exits with code **0**, or fails if the script exits with a non-zero code. Example: ```sh #!/bin/bash set -euo pipefail for i in {1..10}; do echo "Hello, world! $i" done ``` ### Passing output to the next node To pass output from the script to the next node on the canvas, write valid JSON to the **`$SUPERPLANE_RESULT_FILE`** file — the path the runner sets for your task. ```sh #!/bin/bash set -euo pipefail git clone https://github.com/example/repo.git cd repo docker build -t example-image . docker push example-image export IMAGE_TAG=example-image-$(git rev-parse HEAD) docker build -t $IMAGE_TAG . docker push $IMAGE_TAG echo "{\"message\":\"Hello, world!\"}" > $SUPERPLANE_RESULT_FILE ``` ## Running JavaScript Runs a JavaScript script on a runner machine. Example: ```javascript function main() { return { message: "Hello, world!" }; } ``` ### Reading payloads from previous nodes The script can read payloads from previous nodes using the `$` object. Example: ```javascript function main() { const commitSHA = $["On Git Push"].data.after; const commitMessage = $["On Git Push"].data.message; const imageTag = `example-image-${commitSHA}`; return { imageTag: imageTag }; } ``` ### Passing output to the next node The script returns a JSON object that is passed to the next node on the canvas. ```javascript function main() { return { message: "Hello, world!" }; } ``` ### Installing node packages Before executing the script, the runner can install node packages using the `npm install` command as part of the setup commands. Setup commands: ```bash npm install @octokit/rest ``` Script: ```javascript function main() { const octokit = new Octokit({ auth: process.env.GITHUB_TOKEN, }); const response = await octokit.request('GET /repos/{owner}/{repo}/contents/{path}', { owner: 'octokit', repo: 'octokit.js', path: 'README.md', }); return { contents: response.data }; } ``` ## Running Python Runs a Python script on a runner machine. Example: ```python def main(): return { message: "Hello, world!" } ``` ### Reading payloads from previous nodes The script can read payloads from previous nodes using the `$` object. Example: ```python def main(): const commitSHA = $["On Git Push"].data.after; const commitMessage = $["On Git Push"].data.message; const imageTag = `example-image-${commitSHA}`; return { imageTag: imageTag }; } ``` ### Passing output to the next node The script returns a JSON object that is passed to the next node on the canvas. ```python def main(): return { message: "Hello, world!" } ``` ### Installing Python packages Before executing the script, the runner can install Python packages using the `pip install` command as part of the setup commands. Setup commands: ```bash pip install @octokit/rest ``` Script: ```python import octokit def main(): octokit = octokit.Octokit({ auth: process.env.GITHUB_TOKEN, }) response = await octokit.request('GET /repos/{owner}/{repo}/contents/{path}', { owner: 'octokit', repo: 'octokit.js', path: 'README.md', }) return { contents: response.data } ``` ## Machine types Every runner node requires a **machine type** that will run your script. Pick one that matches the architecture and size your workload needs. | Machine type | Architecture | vCPUs | Memory | | ---------------- | ------------ | ----- | ------ | | `e1-large-amd64` | AMD64 | 4 | 16GB | | `e1-large-arm64` | ARM64 | 4 | 16GB | | `e1-tiny-amd64` | AMD64 | 0.5 | 1GB | | `e1-tiny-arm64` | ARM64 | 0.5 | 1GB | ## Host and Docker modes Every task runs in one of two execution modes: | Execution mode | Where work runs | | -------------- | ---------------------------------------- | | **Host** | Directly on the runner machine (default) | | **Docker** | Inside a container image you choose | Use **Docker** when you need an isolated environment or a specific toolchain image. ### Docker Image Selection When using Docker mode, you can select a container image in the UI in two ways: - **Preset**: Choose from a dropdown of commonly used, pre-configured images (e.g., `node:22-slim`, `python:3.12-slim`). - **Custom**: Select "Custom image" and type the exact image reference (e.g., `registry.example.com/my-tools:1.2.3`). ## Environment Variables You can pass environment variables to your runner scripts using the **Environment Variables** section in the node configuration. These variables are securely injected into the execution environment (both Host and Docker modes) and are available to your shell commands or scripts via standard environment variable syntax (e.g., `$MY_VAR` in Bash, `process.env.MY_VAR` in Node.js, `os.environ.get('MY_VAR')` in Python). ## Pre-installed software on the host machine The runner machine comes with the following pre-installed software. | Software | Version | | -------------- | --------- | | Ubuntu | 24.04 LTS | | Bash | 5.2 | | Docker CE | 29.5.3 | | Docker Buildx | 0.34.1 | | Docker Compose | 5.1.4 | | Node.js | 22.22 | | Python | 3.12.3 | | AWS CLI | 2.34 | Use these directly in shell commands, Bash scripts, and setup commands. ## Operator Details Runners are **Generally Available (GA)** for production workloads. ### Task Lifecycle A runner task progresses through the following states: 1. **Queued**: The task is waiting for an available runner machine in the fleet. 2. **Claimed**: A runner machine has picked up the task and is preparing the environment (e.g., pulling Docker images). 3. **Running**: The script or commands are currently executing. 4. **Succeeded** / **Failed** / **Canceled**: The terminal state of the task. ### Live Logs While a task is executing, you can view its live output directly from the Canvas. Click the **View logs** button on the running node to open a streaming log viewer. This helps you monitor long-running builds or scripts in real-time. ### Cancellation You can cancel a running task at any time. When you cancel a run from the Canvas UI or via the API, SuperPlane sends a cancellation signal to the task broker, which terminates the process on the runner machine and marks the task as **Canceled**. ### Runner Task Admin Panel Instance administrators can view all active runner tasks across the entire system. Navigate to the **Admin Panel** > **Runner Tasks** to see a live table of tasks that are currently queued or claimed. This view includes the task ID, status, fleet ID, runner ID, execution mode, and lifecycle timestamps. ### Operational Troubleshooting If a task is not progressing as expected: - **Stuck in Queued**: Check if your runner fleet has available machines or if the machines are offline. - **Fails immediately**: Check the run history or live logs. Common issues include syntax errors in the script, missing environment variables, or an invalid custom Docker image reference. - **Hangs in Running**: Ensure your script does not contain infinite loops or wait for interactive input. You can configure an execution timeout on the node to automatically kill hanging tasks. For more on how payloads flow between nodes, see [Data Flow](/concepts/data-flow). For expression syntax inside runner scripts and node configuration, see [Expressions](/concepts/expressions). ### Security #### Authentication & Accounts Source URL: https://docs.superplane.com/security/authentication This page explains how to authenticate with SuperPlane as a human user or an automated system. It covers UI login methods, account management, API tokens, and CLI authentication. ## Log in to the UI When logging into the SuperPlane UI, choose between the following methods (depending on your organization's configuration): - **Single Sign-On (SSO)**: Log in securely using your Google or GitHub account. - **Email and password**: Standard login using your registered email and password. - **Passwordless sign-in**: Log in without a password by requesting a magic link or access code sent to your email. Use this if you forget your password or prefer not to use one. The login screen remembers your last-used login method to speed up future sign-ins. ## Manage your account Access your **Profile** settings in the UI to manage your account details: - **Change your password**: Update your password at any time. - **Manage API tokens**: Generate and revoke personal API tokens. ## Create personal API tokens Personal API tokens are tied to your user account and inherit your permissions. Use them to authenticate the SuperPlane CLI or make direct API requests on your behalf. To create a personal token: 1. Go to **Profile > API token** in the SuperPlane UI. 2. Click **Generate Token** (or **Regenerate Token** if you already have one). 3. Copy the token immediately. It will not be shown again. **Note:** If you need a token for an automated script or integration that shouldn't be tied to a specific human user, use a [Service account](/security/service-accounts) instead. ## Session expiration When you log in to the UI, your session remains active as long as you continue to use SuperPlane. Your session token validity is automatically extended in the background with your activity. If you are inactive for an extended period, you will be prompted to log in again. ## Authenticate the CLI The SuperPlane CLI requires an API token to communicate with your organization. Authenticate using either a personal API token or a service account token. Choose between interactive login or environment variables. ### Connect interactively Run the `connect` command and follow the prompts: ```sh superplane connect ``` This saves your credentials locally and sets up your CLI context. ### Use environment variables For automated environments like CI/CD pipelines, authenticate the CLI via environment variables without running `superplane connect`. Set the following variables in your environment: ```sh export SUPERPLANE_URL="https://app.superplane.com" export SUPERPLANE_TOKEN="your-api-token" ``` When these variables are present, the CLI automatically uses them for all commands. ## Authenticate automated systems For programmatic access by external systems, scripts, or integrations, use service accounts. Service accounts are non-human identities that you can assign specific roles via RBAC. See the [Service accounts](/security/service-accounts) documentation for more details. #### Secrets Source URL: https://docs.superplane.com/security/secrets Secrets let you securely store sensitive credentials like API keys, passwords, and tokens for use in component configurations. ## How It Works Secrets are key-value stores scoped to your organization. Each secret contains one or more named keys that hold sensitive values. - **Organization-scoped**: Accessible to all workflows in the organization - **Encrypted at rest**: Secret data is encrypted before storage - **Referenced in configurations**: Components reference secrets by name and key, not by value - **Resolved at runtime**: Secret values are decrypted and resolved when components execute ## Creating Secrets Create secrets in **Organization Settings > Secrets**. **Example secret structure:** A secret named `production-ssh-keys` containing: - `private_key` = `-----BEGIN OPENSSH PRIVATE KEY-----...` - `passphrase` = `my-passphrase` Each secret can contain multiple key-value pairs. ## Using Secrets in Components In the **core** component set, organization secrets are used by the **SSH Command** component for authentication (SSH key or password). Select a secret and key from your organization's secrets when configuring SSH. Integrations may store their own credentials separately from organization secrets. If a component supports organization secrets in the future, it will be called out in that component’s documentation. ## Secret Resolution During workflow execution, SuperPlane: 1. **Looks up the secret** by name in the organization 2. **Decrypts the secret data** using the encryption key 3. **Extracts the specific key** from the secret's key-value pairs 4. **Provides the value** to the component for execution If a secret or key doesn't exist, the component execution fails with an error. ## Best Practices - **Use descriptive names**: Name secrets clearly (e.g. `production-keys` and `staging-keys`) - **Organize by service**: Group related credentials in a single secret with multiple keys - **Rotate regularly**: Update secret values when credentials change - **Don't hardcode**: Always use secret key fields instead of entering values directly ## Permissions Secret management requires specific permissions: - `secrets.read` - View organization secrets (but not their values) - `secrets.create` - Create new secrets - `secrets.update` - Update existing secrets - `secrets.delete` - Delete secrets By default, only `Admin` and `Owner` roles have these permissions. See [Access Control](/security/access-control) for details. #### RBAC Source URL: https://docs.superplane.com/security/access-control **Overview** SuperPlane uses organization-scoped role-based access control (RBAC) to decide who can do what in an organization. Today, RBAC is only defined at the organization level. **RBAC Sections** - [Roles](#roles) - [Groups](#groups) - [Members](#members) - [Permissions Reference](#permissions-reference) **Role Model** - A member has one direct organization role at a time. Assigning a new role replaces the previous direct role. - Group membership can add additional roles. Effective permissions are the union of direct role, group roles, and inherited roles. - Default roles are `Owner`, `Admin`, and `Viewer`. They are read-only in the UI. - To change the permissions of a default role, create a custom role and assign it instead. **Role Inheritance** ```mermaid graph TD Owner --> Admin Admin --> Viewer ``` **Default Roles** | Role | Inherits | Summary | | --- | --- | --- | | Owner | Admin | Full admin access plus manage organization settings and deletion. | | Admin | Viewer | Manage members, groups, roles, canvases, integrations, secrets, and custom components (if enabled). | | Viewer | - | Read-only access to org settings, roles, groups, members, canvases, and custom components (if enabled). | New members are assigned the `Viewer` role by default. **Default Role Permissions** Viewer permissions: - `org.read` - `roles.read` - `groups.read` - `members.read` - `canvases.read` - `service_accounts.read` - `agents.read` Admin permissions: - All Viewer permissions. - `canvases.create` - `canvases.update` - `canvases.delete` - `members.create` - `members.update` - `members.delete` - `groups.create` - `groups.update` - `groups.delete` - `integrations.create` - `integrations.read` - `integrations.update` - `integrations.delete` - `secrets.create` - `secrets.read` - `secrets.update` - `secrets.delete` - `roles.create` - `roles.update` - `roles.delete` - `service_accounts.create` - `service_accounts.update` - `service_accounts.delete` - `agents.create` Owner permissions: - All Admin permissions. - `org.update` - `org.delete` ## Permissions Reference Permissions are defined as resource/action pairs (for example, `members.create`). Use this list when building custom roles. **General** - `org.read` - View organization details and settings. - `org.update` - Update organization settings and configuration. - `org.delete` - Delete the organization (dangerous). **People & Groups** - `members.read` - View organization members and their details. - `members.create` - Invite or add members to the organization. - `members.update` - Update member roles and permissions. - `members.delete` - Remove members from the organization. - `groups.read` - View organization groups and their members. - `groups.create` - Create new groups within the organization. - `groups.update` - Update group settings and membership. - `groups.delete` - Delete groups from the organization. **Roles & Permissions** - `roles.read` - View organization roles and their permissions. - `roles.create` - Create new roles within the organization. - `roles.update` - Update role permissions and settings. - `roles.delete` - Delete roles from the organization. **Canvases** - `canvases.read` - View organization canvases. - `canvases.create` - Create new canvases within the organization. - `canvases.update` - Update canvas settings and configuration. - `canvases.delete` - Delete canvases from the organization. **Integrations** - `integrations.read` - View organization integrations. - `integrations.create` - Create new integrations. - `integrations.update` - Update integration settings and configuration. - `integrations.delete` - Delete integrations from the organization. **Secrets** - `secrets.read` - View organization secrets. - `secrets.create` - Create new secrets. - `secrets.update` - Update secrets. - `secrets.delete` - Delete secrets from the organization **Service accounts** - `service_accounts.read` - View service accounts (not secret token values). - `service_accounts.create` - Create service accounts. - `service_accounts.update` - Update service accounts and rotate tokens. - `service_accounts.delete` - Delete service accounts. **Agents** - `agents.read` - View agent chats and messages. - `agents.create` - Start or resume agent chats. ## Roles Use **Organization Settings > Roles** to review roles and create custom roles. - Default roles are marked as **Default Role** and are read-only. - Custom roles can be created, edited, and deleted if you have `roles.*` permissions. ![Roles page](../../../assets/rbac-roles.png) The Create Role page lets you pick permissions by category. ![Create role page](../../../assets/rbac-create-role.png) ## Groups Groups map to a single role. When a user is added to a group, they inherit that role in addition to any direct role assignment. - Create groups in **Organization Settings > Groups**. - Change a group role from the Groups list; all group members inherit the new role immediately. ![Groups page](../../../assets/rbac-groups.png) ![Groups creation page](../../../assets/rbac-create-group.png) ## Members The Members page is where you assign a member's direct role and manage invite links. - New members start as `Viewer` by default. - Assigning a role replaces the previous direct role. - You must keep at least one `Owner` in the organization. ![Members page](../../../assets/rbac-members.png) #### Service accounts Source URL: https://docs.superplane.com/security/service-accounts Service accounts are non-human identities for API access. Use them for scripts and integrations that need a dedicated set of permissions. ## When to use - **Scripts**: Call the SuperPlane API from automation. - **Integrations**: Let external systems call the SuperPlane API with their own identity and role. ## Create a service account and token 1. In the SuperPlane UI, go to **Organization Settings > Service accounts**. 2. Create a service account and assign it a role. 3. Generate an API token and copy it (it is shown only once). ## Use the token to configure the SuperPlane CLI ```sh superplane connect ``` ## Permissions The token can only do what the service account’s role allows. Permissions are organization-scoped and governed by [RBAC](/security/access-control). - **Viewer**: Read-only (e.g. list canvases, read run history). - **Admin** or custom roles: Create or update canvases, integrations, or secrets when required. ## Best practices - **One service account per external system**: Create a dedicated service account per integration or script so you can revoke access or rotate credentials without impacting others. - **Rotate**: Regenerate tokens periodically and update any stored copies. - **Least privilege**: Use the minimum role that satisfies the use case (e.g. Viewer for read-only). ### Installation #### Overview Source URL: https://docs.superplane.com/installation/overview SuperPlane can be installed in a few different ways depending on the level of scale and operational control you need. ## Try it on your computer Choose this if you want to quickly try SuperPlane on your local machine without setting up cloud resources or Kubernetes. - [Try it on your computer](/installation/local) ## Single-host installation Choose this if you want a production-like setup without Kubernetes. Single-host installs are simpler to operate and are ideal for smaller teams or early deployments. - [EC2 on AWS](/installation/single-host/aws-ec2) - [Compute Engine on GCP](/installation/single-host/gcp-compute-engine) - [Hetzner](/installation/single-host/hetzner) - [DigitalOcean](/installation/single-host/digitalocean) - [Linode](/installation/single-host/linode) - [Generic server](/installation/single-host/generic-server) ## Kubernetes Choose this if you want a scalable, production instance of SuperPlane. - [Google Kubernetes Engine](/installation/kubernetes/gke) - [Amazon Kubernetes (EKS)](/installation/kubernetes/amazon-eks) ## Updating SuperPlane Each installation method has its own upgrade process. See the upgrade section in your installation method's documentation: - [Local installation](/installation/local#upgrading) - Single-host installations: - [EC2 on AWS](/installation/single-host/aws-ec2#upgrading) - [Compute Engine on GCP](/installation/single-host/gcp-compute-engine#upgrading) - [Hetzner](/installation/single-host/hetzner#upgrading) - [DigitalOcean](/installation/single-host/digitalocean#upgrading) - [Linode](/installation/single-host/linode#upgrading) - [Generic server](/installation/single-host/generic-server#upgrading) - Kubernetes installations: - [Google Kubernetes Engine](/installation/kubernetes/gke#upgrading) - [Amazon Kubernetes (EKS)](/installation/kubernetes/amazon-eks#upgrading) #### Try it on your computer Source URL: https://docs.superplane.com/installation/local The fastest way to try SuperPlane is to run the latest version of the SuperPlane Docker container on your own machine. You'll have a working SuperPlane instance in less than a minute, without provisioning any cloud infrastructure. ## Prerequisites To run SuperPlane, you need: - [Docker installed and running][docker-install] (for example Docker Desktop on macOS/Windows, or Docker Engine on Linux). - A stable internet connection (SuperPlane opens a tunnel for incoming webhooks). ## Starting SuperPlane Run the latest stable SuperPlane Docker container: ```bash docker pull ghcr.io/superplanehq/superplane-demo:stable docker run --rm -p 3000:3000 -v spdata:/app/data -ti ghcr.io/superplanehq/superplane-demo:stable ``` This pulls the stable image and starts SuperPlane in your terminal. ### Public access and localtunnel SuperPlane needs to be reachable from the public internet to receive incoming webhooks. When you run the container, it automatically starts a [localtunnel][localtunnel] to expose your local instance through a public URL for incoming webhooks. This is convenient for quick trials, but it also means: - Your local SuperPlane instance becomes accessible from the internet via the tunnel URL. - You should **not** use this setup with sensitive data, secrets, or production systems. Use this setup for exploration and evaluation only. For more controlled, production-like deployments, use one of the single-host or Kubernetes installation options instead. ## Try the beta channel To try the latest features before they land in stable, use the beta tag: ```bash docker run -ti --rm ghcr.io/superplanehq/superplane-demo:beta ``` Beta images may change more frequently and can be less stable than the `stable` channel. ## Pin a specific version If you want to run a particular version, you can pin it explicitly: ```bash docker run -ti --rm ghcr.io/superplanehq/superplane-demo:v0.4 ``` Replace `v0.4` with the version you want to run. ## Updating SuperPlane To update to the latest version, run docker pull and restart the container: ``` docker pull ghcr.io/superplanehq/superplane-demo:stable docker run --rm -p 3000:3000 -v spdata:/app/data -ti ghcr.io/superplanehq/superplane-demo:stable ``` Replace `stable` with the specific version tag if needed. ## Removing SuperPlane To completely remove SuperPlane, remove the data volume and Docker images: ```bash docker volume rm spdata docker rmi ghcr.io/superplanehq/superplane-demo:stable ``` If you've used other tags (like `beta` or specific versions), remove those images as well: ```bash docker rmi ghcr.io/superplanehq/superplane-demo:beta docker rmi ghcr.io/superplanehq/superplane-demo:v0.4 ``` [localtunnel]: https://github.com/localtunnel/localtunnel [docker-install]: https://docs.docker.com/get-docker/ #### EC2 on AWS Source URL: https://docs.superplane.com/installation/single-host/aws-ec2 This guide walks you through setting up a new Amazon EC2 instance from scratch and installing SuperPlane using the single-host installer. ## 1. Create an EC2 instance 1. Sign in to the [AWS Management Console](https://console.aws.amazon.com/). 2. Open the **EC2** service. 3. Click **Launch instance**. 4. Configure your instance: - Give it a name (for example `superplane-single-host`). - Under **Application and OS Images**, choose an Ubuntu LTS image (for example Ubuntu Server 22.04 LTS). - Choose an instance type such as `t3.medium` (2 vCPUs, 4 GiB memory). - Select or create an SSH key pair so you can log in securely. 5. Under **Network settings**, either create a new security group or use an existing one with inbound rules that allow: - TCP port 22 (SSH) from your IP. - TCP port 80 (HTTP) from the internet. - TCP port 443 (HTTPS) from the internet. 6. Launch the instance and note its public IPv4 address or DNS name. At this point you have a Linux server that is reachable from the internet. ## 2. Point your domain to the instance 1. In your DNS provider (Route 53 or another provider), create an `A` record for your domain or subdomain (for example `superplane.example.com`). 2. Point the `A` record to the public IP address of your EC2 instance. 3. Wait for DNS to propagate (usually a few minutes). SuperPlane will use this domain to issue and maintain an SSL certificate. Optionally, you can allocate an Elastic IP and associate it with your instance so its public IP does not change. ## 3. Verify security group rules In the EC2 console: 1. Go to **Instances** and select your SuperPlane instance. 2. In the **Security** tab, click the attached security group. 3. Under **Inbound rules**, ensure the following rules exist: - SSH (TCP 22) from your IP. - HTTP (TCP 80) from `0.0.0.0/0`. - HTTPS (TCP 443) from `0.0.0.0/0`. Save any changes you make to the security group. ## 4. Install Docker and Docker Compose SSH into your EC2 instance using the public DNS name or IP. For Ubuntu images, the default user is usually `ubuntu`: ```bash ssh -i /path/to/your-key.pem ubuntu@your-ec2-public-dns ``` On the instance, install Docker and Docker Compose. For example, on Ubuntu: ```bash sudo apt update sudo apt install -y ca-certificates curl gnupg sudo install -m 0755 -d /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \ sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg sudo chmod a+r /etc/apt/keyrings/docker.gpg echo \ "deb [arch=$(dpkg --print-architecture) \ signed-by=/etc/apt/keyrings/docker.gpg] \ https://download.docker.com/linux/ubuntu \ $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \ sudo tee /etc/apt/sources.list.d/docker.list > /dev/null sudo apt update sudo apt install -y docker-ce docker-ce-cli containerd.io \ docker-buildx-plugin docker-compose-plugin sudo systemctl enable --now docker sudo usermod -aG docker ubuntu newgrp docker ``` You now have an EC2 instance with Docker and Docker Compose installed, reachable from the internet at your chosen domain. ## 5. Install SuperPlane With Docker set up, install SuperPlane using the single-host installer. First, download and unpack the installer: ```bash wget -q https://install.superplane.com/superplane-single-host.tar.gz tar -xf superplane-single-host.tar.gz cd superplane ``` Then run the installer: ```bash ./install.sh ``` This downloads the single-host bundle, extracts it, and runs the installer. The installer sets up the Docker Compose stack and starts SuperPlane on your instance. ## SSL certificates and public access Because SuperPlane needs to connect to external integrations and receive webhooks, your instance must be reachable from the public internet. During installation, SuperPlane automatically: - Issues an SSL certificate for your configured domain. - Renews the certificate so HTTPS continues to work over time. Ensure your security group allows inbound traffic on ports 80 and 443 so certificate issuance and HTTPS access can succeed. ## 6. Enable EBS snapshots To protect your SuperPlane instance, create regular snapshots of the root EBS volume. In the EC2 console: 1. Go to **Instances** and select your SuperPlane instance. 2. Open the **Storage** tab and note the root volume ID. 3. Click the volume ID to open it in the **Volumes** view. 4. Click **Actions → Create snapshot** to create a snapshot of the volume. You can use these snapshots to restore the volume, or create a new instance with the same data if something goes wrong. ## Updating SuperPlane 1. Check the [GitHub releases][github-releases] for the latest version tag. 2. Edit `docker-compose.yml` and update the `image` field with the new tag. 3. Restart the stack: ``` docker compose pull docker compose up -d ``` [github-releases]: https://github.com/superplanehq/superplane/releases [github-releases]: https://github.com/superplanehq/superplane/releases #### Compute Engine on GCP Source URL: https://docs.superplane.com/installation/single-host/gcp-compute-engine This guide walks you through setting up a new Google Compute Engine virtual machine from scratch and installing SuperPlane using the single-host installer. ## 1. Create a Compute Engine VM 1. Sign in to the [Google Cloud Console](https://console.cloud.google.com/). 2. Select or create a project. 3. Go to **Compute Engine → VM instances** and click **Create instance**. 4. Configure your VM: - Choose a region and zone close to you. - Under **Machine configuration**, pick a machine type such as `e2-medium` (2 vCPUs, 4 GB memory). - Under **Boot disk**, select an Ubuntu LTS image (for example Ubuntu 22.04 LTS). - Under **Firewall**, check **Allow HTTP traffic** and **Allow HTTPS traffic**. 5. Click **Create** and note the external IP address of the VM. At this point you have a Linux server that is reachable from the internet. ## 2. Point your domain to the VM 1. In your DNS provider (Cloud DNS or another provider), create an `A` record for your domain or subdomain (for example `superplane.example.com`). 2. Point the `A` record to the external IP of your VM. 3. Wait for DNS to propagate (usually a few minutes). SuperPlane will use this domain to issue and maintain an SSL certificate. ## 3. Verify firewall rules In the Google Cloud Console: 1. Go to **VPC network → Firewall**. 2. Ensure there are rules that allow: - TCP port 22 (SSH) to your VM. - TCP port 80 (HTTP) to your VM. - TCP port 443 (HTTPS) to your VM. The **Allow HTTP traffic** and **Allow HTTPS traffic** options you selected when creating the VM typically create these rules automatically. ## 4. Install Docker and Docker Compose SSH into your VM using the external IP or domain. For Ubuntu images, the default user is usually `ubuntu`: ```bash gcloud compute ssh your-instance-name --zone your-zone ``` or using plain SSH: ```bash ssh ubuntu@your-vm-external-ip-or-domain ``` On the VM, install Docker and Docker Compose. For example, on Ubuntu: ```bash sudo apt update sudo apt install -y ca-certificates curl gnupg sudo install -m 0755 -d /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \ sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg sudo chmod a+r /etc/apt/keyrings/docker.gpg echo \ "deb [arch=$(dpkg --print-architecture) \ signed-by=/etc/apt/keyrings/docker.gpg] \ https://download.docker.com/linux/ubuntu \ $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \ sudo tee /etc/apt/sources.list.d/docker.list > /dev/null sudo apt update sudo apt install -y docker-ce docker-ce-cli containerd.io \ docker-buildx-plugin docker-compose-plugin sudo systemctl enable --now docker sudo usermod -aG docker ubuntu newgrp docker ``` You now have a Compute Engine VM with Docker and Docker Compose installed, reachable from the internet at your chosen domain. ## 5. Install SuperPlane With Docker set up, install SuperPlane using the single-host installer. First, download and unpack the installer: ```bash wget -q https://install.superplane.com/superplane-single-host.tar.gz tar -xf superplane-single-host.tar.gz cd superplane ``` Then run the installer: ```bash ./install.sh ``` This downloads the single-host bundle, extracts it, and runs the installer. The installer sets up the Docker Compose stack and starts SuperPlane on your VM. ## SSL certificates and public access Because SuperPlane needs to connect to external integrations and receive webhooks, your VM must be reachable from the public internet. During installation, SuperPlane automatically: - Issues an SSL certificate for your configured domain. - Renews the certificate so HTTPS continues to work over time. Ensure your firewall allows inbound traffic on ports 80 and 443 so certificate issuance and HTTPS access can succeed. ## 6. Enable disk snapshots To protect your SuperPlane instance, create regular snapshots of the boot disk. In the Google Cloud Console: 1. Go to **Compute Engine → Disks**. 2. Find the boot disk attached to your SuperPlane VM. 3. Click the disk name to open its details. 4. Click **Create snapshot** to create a snapshot of the disk. You can use these snapshots to restore the disk, or create a new VM with the same data if something goes wrong. ## Updating SuperPlane 1. Check the [GitHub releases][github-releases] for the latest version tag. 2. Edit `docker-compose.yml` and update the `image` field with the new tag. 3. Restart the stack: ``` docker compose pull docker compose up -d ``` [github-releases]: https://github.com/superplanehq/superplane/releases [github-releases]: https://github.com/superplanehq/superplane/releases #### Hetzner Source URL: https://docs.superplane.com/installation/single-host/hetzner This guide walks you through setting up a new Hetzner cloud server from scratch and installing SuperPlane using the single‑host installer. ## 1. Create a Hetzner cloud server 1. Sign in to the [Hetzner Cloud Console](https://console.hetzner.cloud/). 2. Create a new project (or use an existing one). 3. Create a server: - Choose a location close to you. - Select an Ubuntu LTS image (for example Ubuntu 22.04). - Pick a shared CPU type with 2 CPU and 4 GB RAM. - Add SSH keys so you can log in securely. 4. Note the server’s public IPv4 address. At this point you have a Linux server that is reachable from the internet. ## 2. Point your domain to the server 1. In your DNS provider, create an `A` record for your domain or subdomain (for example `superplane.example.com`). 2. Point the `A` record to the public IP of your Hetzner server. 3. Wait for DNS to propagate (usually a few minutes). SuperPlane will use this domain to issue and maintain an SSL certificate. ## 3. Open required ports In the Hetzner Cloud Console: 1. Open your project and go to the **Servers** view. 2. Click your SuperPlane server to open its details. 3. Go to the **Networking** tab. 4. Under **Firewalls**, either create a new firewall or edit the one attached to the server. 5. Add inbound rules that allow: - TCP port 22 (SSH) - TCP port 80 (HTTP, for certificate issuance) - TCP port 443 (HTTPS, for SuperPlane) 6. Apply the firewall to your server if it is not already attached. ## 4. Install Docker and Docker Compose SSH into your Hetzner server using the IP or domain: ```bash ssh root@your-server-ip-or-domain ``` On the server, install Docker and Docker Compose. For example, on Ubuntu: ```bash apt update apt install -y ca-certificates curl gnupg install -m 0755 -d /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \ gpg --dearmor -o /etc/apt/keyrings/docker.gpg chmod a+r /etc/apt/keyrings/docker.gpg echo \ "deb [arch=$(dpkg --print-architecture) \ signed-by=/etc/apt/keyrings/docker.gpg] \ https://download.docker.com/linux/ubuntu \ $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \ tee /etc/apt/sources.list.d/docker.list > /dev/null apt update apt install -y docker-ce docker-ce-cli containerd.io \ docker-buildx-plugin docker-compose-plugin systemctl enable --now docker ``` You now have a Hetzner Linux server with Docker and Docker Compose installed, reachable from the internet at your chosen domain. ## 5. Install SuperPlane With Docker set up, install SuperPlane using the single‑host installer. First, download and unpack the installer: ```bash wget -q https://install.superplane.com/superplane-single-host.tar.gz tar -xf superplane-single-host.tar.gz cd superplane ``` Then run the installer: ```bash ./install.sh ``` This downloads the single‑host bundle, extracts it, and runs the installer. The installer sets up the Docker Compose stack and starts SuperPlane on your server. ## SSL certificates and public access Because SuperPlane needs to connect to external integrations and receive webhooks, your server must be reachable from the public internet. During installation, SuperPlane automatically: - Issues an SSL certificate for your configured domain. - Renews the certificate so HTTPS continues to work over time. Ensure your firewall allows inbound traffic on ports 80 and 443 so certificate issuance and HTTPS access can succeed. ## 6. Set up full disk backups To protect your SuperPlane instance, enable full disk backups for your Hetzner server. In the Hetzner Cloud Console: 1. Open your project and go to the **Servers** view. 2. Click your SuperPlane server to open its details. 3. Go to the **Backups** section. 4. Enable backups for the server. Hetzner will now create regular full disk backups of your server's root volume. You can use these backups to restore the entire server to an earlier state if something goes wrong. ## Updating SuperPlane 1. Check the [GitHub releases][github-releases] for the latest version tag. 2. Edit `docker-compose.yml` and update the `image` field with the new tag. 3. Restart the stack: ``` docker compose pull docker compose up -d ``` [github-releases]: https://github.com/superplanehq/superplane/releases [github-releases]: https://github.com/superplanehq/superplane/releases #### DigitalOcean Source URL: https://docs.superplane.com/installation/single-host/digitalocean This guide walks you through setting up a new DigitalOcean Droplet from scratch and installing SuperPlane using the single-host installer. ## 1. Create a DigitalOcean Droplet 1. Sign in to the [DigitalOcean Control Panel](https://cloud.digitalocean.com/). 2. Click **Create → Droplets**. 3. Configure your Droplet: - Choose a region close to you. - Select an Ubuntu LTS image (for example Ubuntu 22.04). - Pick a Basic Droplet with 2 vCPUs and 4 GB RAM. - Add SSH keys so you can log in securely. 4. Create the Droplet and note its public IPv4 address. At this point you have a Linux server that is reachable from the internet. ## 2. Point your domain to the Droplet 1. In your DNS provider (DigitalOcean DNS or another provider), create an `A` record for your domain or subdomain (for example `superplane.example.com`). 2. Point the `A` record to the public IP of your Droplet. 3. Wait for DNS to propagate (usually a few minutes). SuperPlane will use this domain to issue and maintain an SSL certificate. ## 3. Open required ports with Cloud Firewalls In the DigitalOcean Control Panel: 1. Go to **Networking → Firewalls**. 2. Create a new firewall (or edit an existing one). 3. Under **Inbound rules**, allow: - TCP port 22 (SSH) - TCP port 80 (HTTP, for certificate issuance) - TCP port 443 (HTTPS, for SuperPlane) 4. Under **Apply to Droplets**, select your SuperPlane Droplet. 5. Save the firewall. ## 4. Install Docker and Docker Compose SSH into your Droplet using the IP or domain: ```bash ssh root@your-droplet-ip-or-domain ``` On the Droplet, install Docker and Docker Compose. For example, on Ubuntu: ```bash apt update apt install -y ca-certificates curl gnupg install -m 0755 -d /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \ gpg --dearmor -o /etc/apt/keyrings/docker.gpg chmod a+r /etc/apt/keyrings/docker.gpg echo \ "deb [arch=$(dpkg --print-architecture) \ signed-by=/etc/apt/keyrings/docker.gpg] \ https://download.docker.com/linux/ubuntu \ $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \ tee /etc/apt/sources.list.d/docker.list > /dev/null apt update apt install -y docker-ce docker-ce-cli containerd.io \ docker-buildx-plugin docker-compose-plugin systemctl enable --now docker ``` You now have a DigitalOcean Droplet with Docker and Docker Compose installed, reachable from the internet at your chosen domain. ## 5. Install SuperPlane With Docker set up, install SuperPlane using the single-host installer. First, download and unpack the installer: ```bash wget -q https://install.superplane.com/superplane-single-host.tar.gz tar -xf superplane-single-host.tar.gz cd superplane ``` Then run the installer: ```bash ./install.sh ``` This downloads the single-host bundle, extracts it, and runs the installer. The installer sets up the Docker Compose stack and starts SuperPlane on your Droplet. ## SSL certificates and public access Because SuperPlane needs to connect to external integrations and receive webhooks, your Droplet must be reachable from the public internet. During installation, SuperPlane automatically: - Issues an SSL certificate for your configured domain. - Renews the certificate so HTTPS continues to work over time. Ensure your firewall allows inbound traffic on ports 80 and 443 so certificate issuance and HTTPS access can succeed. ## 6. Enable automatic backups To protect your SuperPlane instance, enable automatic backups for your Droplet. In the DigitalOcean Control Panel: 1. Go to **Droplets** and click your SuperPlane Droplet. 2. Open the **Backups** tab. 3. Enable backups for the Droplet. DigitalOcean will now create regular full disk backups of your Droplet. You can use these backups to restore the entire Droplet to an earlier state if something goes wrong. ## Updating SuperPlane 1. Check the [GitHub releases][github-releases] for the latest version tag. 2. Edit `docker-compose.yml` and update the `image` field with the new tag. 3. Restart the stack: ``` docker compose pull docker compose up -d ``` [github-releases]: https://github.com/superplanehq/superplane/releases [github-releases]: https://github.com/superplanehq/superplane/releases #### Linode Source URL: https://docs.superplane.com/installation/single-host/linode This guide walks you through setting up a new Linode instance from scratch and installing SuperPlane using the single-host installer. ## 1. Create a Linode 1. Sign in to the [Linode Cloud Manager](https://cloud.linode.com/). 2. Click **Create → Linode**. 3. Configure your Linode: - Choose a region close to you. - Select an Ubuntu LTS image (for example Ubuntu 22.04 LTS). - Pick a shared CPU plan with 2 vCPUs and 4 GB RAM (for example **Linode 4GB**). - Add SSH keys so you can log in securely. 4. Create the Linode and note its public IPv4 address. At this point you have a Linux server that is reachable from the internet. ## 2. Point your domain to the Linode 1. In your DNS provider (Linode DNS or another provider), create an `A` record for your domain or subdomain (for example `superplane.example.com`). 2. Point the `A` record to the public IP of your Linode. 3. Wait for DNS to propagate (usually a few minutes). SuperPlane will use this domain to issue and maintain an SSL certificate. ## 3. Open required ports with Cloud Firewall In the Linode Cloud Manager: 1. Go to **Firewall**. 2. Create a new firewall (or edit an existing one). 3. Under **Inbound Rules**, allow: - TCP port 22 (SSH) - TCP port 80 (HTTP, for certificate issuance) - TCP port 443 (HTTPS, for SuperPlane) 4. Under **Linodes**, attach the firewall to your SuperPlane Linode. 5. Save the firewall. ## 4. Install Docker and Docker Compose SSH into your Linode using the IP or domain: ```bash ssh root@your-linode-ip-or-domain ``` On the Linode, install Docker and Docker Compose. For example, on Ubuntu: ```bash apt update apt install -y ca-certificates curl gnupg install -m 0755 -d /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \ gpg --dearmor -o /etc/apt/keyrings/docker.gpg chmod a+r /etc/apt/keyrings/docker.gpg echo \ "deb [arch=$(dpkg --print-architecture) \ signed-by=/etc/apt/keyrings/docker.gpg] \ https://download.docker.com/linux/ubuntu \ $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \ tee /etc/apt/sources.list.d/docker.list > /dev/null apt update apt install -y docker-ce docker-ce-cli containerd.io \ docker-buildx-plugin docker-compose-plugin systemctl enable --now docker ``` You now have a Linode with Docker and Docker Compose installed, reachable from the internet at your chosen domain. ## 5. Install SuperPlane With Docker set up, install SuperPlane using the single-host installer. First, download and unpack the installer: ```bash wget -q https://install.superplane.com/superplane-single-host.tar.gz tar -xf superplane-single-host.tar.gz cd superplane ``` Then run the installer: ```bash ./install.sh ``` This downloads the single-host bundle, extracts it, and runs the installer. The installer sets up the Docker Compose stack and starts SuperPlane on your Linode. ## SSL certificates and public access Because SuperPlane needs to connect to external integrations and receive webhooks, your Linode must be reachable from the public internet. During installation, SuperPlane automatically: - Issues an SSL certificate for your configured domain. - Renews the certificate so HTTPS continues to work over time. Ensure your firewall allows inbound traffic on ports 80 and 443 so certificate issuance and HTTPS access can succeed. ## 6. Enable backups To protect your SuperPlane instance, enable backups for your Linode. In the Linode Cloud Manager: 1. Go to **Linodes** and click your SuperPlane Linode. 2. Open the **Backups** tab. 3. Enable backups for the Linode. Linode will now create regular backups of your instance. You can use these backups to restore the Linode to an earlier state if something goes wrong. ## Updating SuperPlane 1. Check the [GitHub releases][github-releases] for the latest version tag. 2. Edit `docker-compose.yml` and update the `image` field with the new tag. 3. Restart the stack: ``` docker compose pull docker compose up -d ``` [github-releases]: https://github.com/superplanehq/superplane/releases #### Generic server Source URL: https://docs.superplane.com/installation/single-host/generic-server This guide describes how to install and run SuperPlane on a generic Linux server, such as a bare-metal host or virtual machine from any provider. ## Prerequisites Before you start, make sure you have: - A Linux server that is exposed to the internet (public IP or behind a public load balancer). - Docker and Docker Compose installed on the server. - A domain name that points to this server’s public IP. The single-host installation uses Docker Compose to run SuperPlane and its dependencies. It will also issue and maintain an SSL certificate for the domain you configure. ## Install Docker and Docker Compose Install Docker using Docker's official repository. On Ubuntu, run: ```bash apt update apt install -y ca-certificates curl gnupg install -m 0755 -d /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \ gpg --dearmor -o /etc/apt/keyrings/docker.gpg chmod a+r /etc/apt/keyrings/docker.gpg echo \ "deb [arch=$(dpkg --print-architecture) \ signed-by=/etc/apt/keyrings/docker.gpg] \ https://download.docker.com/linux/ubuntu \ $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \ tee /etc/apt/sources.list.d/docker.list > /dev/null apt update apt install -y docker-ce docker-ce-cli containerd.io \ docker-buildx-plugin docker-compose-plugin systemctl enable --now docker ``` ## Installation steps Run the following commands on your server to download and unpack the installer: ```bash wget -q https://install.superplane.com/superplane-single-host.tar.gz tar -xf superplane-single-host.tar.gz cd superplane ``` Then run the installer: ```bash ./install.sh ``` This downloads the single-host bundle, extracts it, and runs the installer. The installer sets up the Docker Compose stack and starts SuperPlane on your server. ## SSL certificates and public access Because SuperPlane needs to connect to external integrations and receive webhooks, your server must be reachable from the public internet. During installation, SuperPlane automatically: - Issues an SSL certificate for your configured domain. - Renews the certificate so HTTPS continues to work over time. Ensure your firewall or security group allows inbound traffic on ports 80 and 443 so certificate issuance and HTTPS access can succeed. ## Updating SuperPlane 1. Check the [GitHub releases][github-releases] for the latest version tag. 2. Edit `docker-compose.yml` and update the `image` field with the new tag. 3. Restart the stack: ``` docker compose pull docker compose up -d ``` [github-releases]: https://github.com/superplanehq/superplane/releases #### Google Kubernetes Engine Source URL: https://docs.superplane.com/installation/kubernetes/gke This guide describes how to deploy SuperPlane to Google Kubernetes Engine (GKE) using Terraform. ## Prerequisites - A GCP project with billing enabled - [Terraform][terraform-install] >= 1.5.0 - [`gcloud` CLI][gcloud-install] installed and authenticated - [`kubectl`][kubectl-install] installed ## Step 1: Authenticate with GCP ```bash gcloud auth application-default login gcloud config set project YOUR_PROJECT_ID ``` ## Step 2: Create Static IP Address Create a global static IP address for the ingress: ```bash gcloud compute addresses create superplane-ip --global --ip-version=IPV4 ``` Get the reserved IP address: ```bash gcloud compute addresses describe superplane-ip --global --format='get(address)' ``` ## Step 3: Configure DNS Create an A record in your DNS provider pointing to the static IP: - **Type:** A - **Name:** Your subdomain (e.g., `superplane`) - **Value:** The static IP address from Step 2 Wait for DNS propagation and verify: ```bash dig superplane.example.com +short ``` ## Step 4: Clone and Configure Terraform ```bash git clone https://github.com/superplanehq/superplane-terraform cd superplane-terraform/gke cp terraform.tfvars.example terraform.tfvars ``` Edit `terraform.tfvars`: ```hcl project_id = "my-gcp-project" domain_name = "superplane.example.com" static_ip_name = "superplane-ip" letsencrypt_email = "admin@example.com" ``` ### Configuration Options | Variable | Description | Default | | ---------------------------- | ------------------------------------- | --------------- | | `project_id` | GCP project ID | (required) | | `domain_name` | Domain name for SuperPlane | (required) | | `static_ip_name` | Name of pre-created static IP | (required) | | `letsencrypt_email` | Email for Let's Encrypt | (required) | | `region` | GCP region | `us-central1` | | `zone` | GCP zone | `us-central1-a` | | `cluster_name` | GKE cluster name | `superplane` | | `node_count` | Number of GKE nodes | `2` | | `machine_type` | GKE node machine type | `e2-medium` | | `superplane_image_tag` | SuperPlane image tag | `stable` | | `installation.beaconEnabled` | Enable anonymized beacon telemetry | `true` | ## Step 5: Deploy ```bash terraform init terraform apply ``` The deployment takes 15-20 minutes and creates: - GKE cluster - Cloud SQL PostgreSQL instance with VPC peering - Kubernetes secrets - cert-manager with Let's Encrypt - SuperPlane deployment ## Step 6: Verify Configure kubectl: ```bash gcloud container clusters get-credentials superplane --zone=us-central1-a \ --project=YOUR_PROJECT_ID ``` Check pods and ingress: ```bash kubectl get pods -n superplane kubectl get ingress -n superplane ``` Check SSL certificate status: ```bash kubectl get certificate -n superplane ``` Once the certificate shows `Ready`, access SuperPlane at `https://your-domain.com`. ## Updating SuperPlane 1. Check the [GitHub releases][github-releases] for the latest version tag. 2. Update `superplane_image_tag` in `terraform.tfvars` with the new tag. 3. Apply the changes: ``` terraform apply ``` ## Uninstalling ```bash # Disable deletion protection for the database and the cluster terraform apply \ -var="gke_deletion_protection=false" \ -var="sql_deletion_protection=false" # Then destroy all resources terraform destroy \ -var="gke_deletion_protection=false" \ -var="sql_deletion_protection=false" # Delete the static IP gcloud compute addresses delete superplane-ip --global ``` [terraform-install]: https://www.terraform.io/downloads [kubectl-install]: https://kubernetes.io/docs/tasks/tools/ [gcloud-install]: https://cloud.google.com/sdk/docs/install [github-releases]: https://github.com/superplanehq/superplane/releases #### Amazon Kubernetes (EKS) Source URL: https://docs.superplane.com/installation/kubernetes/amazon-eks This guide describes how to deploy SuperPlane to Amazon EKS using Terraform. ## Prerequisites - An AWS account with permissions to create EKS, RDS, and VPC resources - [Terraform][terraform-install] >= 1.5.0 - [AWS CLI][aws-cli-install] installed - [`kubectl`][kubectl-install] installed ## Step 1: Configure AWS CLI Configure the AWS CLI with your credentials: ```bash aws configure ``` You will be prompted to enter: - **AWS Access Key ID:** Your access key - **AWS Secret Access Key:** Your secret key - **Default region name:** e.g., `us-east-1` - **Default output format:** `json` (recommended) Verify the configuration: ```bash aws sts get-caller-identity ``` ## Step 2: Clone and Configure Terraform If you already have the SuperPlane repo checked out, the Terraform configuration lives in `superplane-terraform/eks`. Otherwise, clone it: ```bash git clone https://github.com/superplanehq/superplane-terraform ``` Then: ```bash cd superplane-terraform/eks cp terraform.tfvars.example terraform.tfvars ``` Edit `terraform.tfvars`: ```hcl domain_name = "superplane.example.com" letsencrypt_email = "admin@example.com" ``` ### Configuration Options | Variable | Description | Default | | ---------------------------- | ---------------------------------- | -------------- | | `domain_name` | Domain name for SuperPlane | (required) | | `letsencrypt_email` | Email for Let's Encrypt | (required) | | `region` | AWS region | `us-east-1` | | `cluster_name` | EKS cluster name | `superplane` | | `node_count` | Number of EKS nodes | `2` | | `instance_type` | EKS node instance type | `t3.medium` | | `db_instance_class` | RDS instance class | `db.t3.medium` | | `superplane_image_tag` | SuperPlane image tag | `stable` | | `installation.beaconEnabled` | Enable anonymized beacon telemetry | `true` | ## Step 3: Deploy ```bash terraform init terraform apply ``` The deployment takes 15-20 minutes and creates: - VPC with public and private subnets - EKS cluster with node group - RDS PostgreSQL instance - Network Load Balancer - cert-manager with Let's Encrypt - SuperPlane deployment ## Step 4: Configure kubectl ```bash aws eks update-kubeconfig --region us-east-1 --name superplane ``` ## Step 5: Configure DNS Get the Load Balancer hostname: ```bash kubectl get svc -n ingress-nginx ingress-nginx-controller \ -o jsonpath='{.status.loadBalancer.ingress[0].hostname}' ``` Create a CNAME record in your DNS provider: - **Type:** CNAME - **Name:** Your subdomain (e.g., `superplane`) - **Value:** The hostname from the command above Wait for DNS propagation: ```bash dig superplane.example.com +short ``` ## Step 6: Verify Check pods and certificate status: ```bash kubectl get pods -n superplane kubectl get certificate -n superplane ``` Once the certificate shows `Ready`, access SuperPlane at `https://your-domain.com`. Note: Certificate issuance may take 5-10 minutes after DNS propagation completes. ## Updating SuperPlane 1. Check the [GitHub releases][github-releases] for the latest version tag. 2. Update `superplane_image_tag` in `terraform.tfvars` with the new tag. 3. Apply the changes: ``` terraform apply ``` ## Uninstalling ```bash # Disable deletion protection on the database aws rds modify-db-instance \ --db-instance-identifier superplane-db \ --no-deletion-protection \ --apply-immediately # Wait for modification to complete aws rds wait db-instance-available --db-instance-identifier superplane-db # Destroy all resources terraform destroy ``` [terraform-install]: https://www.terraform.io/downloads [kubectl-install]: https://kubernetes.io/docs/tasks/tools/ [aws-cli-install]: https://aws.amazon.com/cli/ [github-releases]: https://github.com/superplanehq/superplane/releases #### Beacon Source URL: https://docs.superplane.com/installation/beacon SuperPlane includes a lightweight beacon that sends a periodic ping to help the team understand installation volume and deployment types. ## What the beacon sends The beacon sends a JSON payload with: - `installation_type`: The installation type (for example `demo`, `single-host`, or `kubernetes`). - `installation_id`: A randomly generated UUID stored in the SuperPlane database No user data, workflow payloads, or secrets are included. The data is anonymized. ## How to disable the beacon You can disable the beacon by setting `SUPERPLANE_BEACON_ENABLED=no` and restarting SuperPlane. ### Local demo container Set the environment variable when starting the container: ```bash docker run --rm -p 3000:3000 -v spdata:/app/data \ -e SUPERPLANE_BEACON_ENABLED=no \ -ti ghcr.io/superplanehq/superplane-demo:stable ``` If you already have a data volume, you can also edit `/app/data/superplane.env` in that volume and restart the container. ### Single-host installer Edit `superplane.env` in the installation directory and set: ```bash SUPERPLANE_BEACON_ENABLED=no ``` Then restart the stack: ```bash docker compose up -d ``` ### Kubernetes (Helm) Set the Helm value and upgrade: ```yaml installation: beaconEnabled: false ``` Or with `--set`: ```bash helm upgrade superplane ./superplane-helm-chart \ --set installation.beaconEnabled=false ``` ### Command Line Interface (CLI) #### Overview & Installation Source URL: https://docs.superplane.com/cli/overview import { Aside } from "@astrojs/starlight/components"; Use the SuperPlane CLI to connect to your organization and manage workflows from your terminal. ## Installation ### Direct download Get the latest binary for your operating system and architecture: ```sh curl -fsSL https://install.superplane.com/install.sh | sh ``` Older versions can be found in our [GitHub Releases page](https://github.com/superplanehq/superplane/releases). ### APT (Debian and Ubuntu) On Debian-based distributions you can install and upgrade the CLI through `apt`. Trust the SuperPlane signing key, add the repository, and install: ```sh sudo install -d -m 0755 /etc/apt/keyrings curl -fsSL https://s3.amazonaws.com/apt.superplane.com/gpg.key \ | sudo gpg --dearmor -o /etc/apt/keyrings/superplane.gpg echo "deb [signed-by=/etc/apt/keyrings/superplane.gpg] https://s3.amazonaws.com/apt.superplane.com stable main" \ | sudo tee /etc/apt/sources.list.d/superplane.list sudo apt-get update sudo apt-get install -y superplane-cli ``` The repo serves both `amd64` and `arm64` packages; `apt` picks the right one automatically. ## Authentication The SuperPlane CLI uses API tokens for authentication. For a full overview of authentication methods, see [Authentication and accounts](/security/authentication). You can use: - **Service account token** (recommended for scripts and integrations): see [Service accounts](/security/service-accounts). - **Personal token** (tied to your user): go to **Profile > API token** in the SuperPlane UI. You can authenticate in two ways: ### Environment variables (recommended for CI/CD) Set the following environment variables to authenticate automatically without running `superplane connect`: ```sh export SUPERPLANE_URL="https://app.superplane.com" export SUPERPLANE_TOKEN="your-api-token" ``` ### Interactive connect Connect to a SuperPlane organization interactively: ```sh superplane connect ``` Show your identity for the current context: ```sh superplane whoami ``` ### Multiple organizations You can connect to multiple SuperPlane organizations at the same time. Each connection will become a CLI context. You can list contexts and switch interactively: ```sh superplane contexts ``` Switch directly with a context selector: ```sh superplane contexts / ``` ## Output formats All commands support `--output` (or `-o`) to choose the response format. Possible values are: - `text` (default) - `json` - `yaml` Examples: ```sh superplane apps list --output text superplane apps list -o json superplane apps canvas get -o yaml ``` ## Updating the CLI If a newer version is available the CLI prints an upgrade notice after every command. You can update in place with: ```sh superplane upgrade ``` `superplane self-update` is an alias for the same command. Self-update is available on macOS and Linux for release-built binaries; dev builds and Windows are not supported. If you installed via `apt`, upgrade through the package manager instead: ```sh sudo apt-get update sudo apt-get install --only-upgrade superplane-cli ``` First-time install uses `install.sh` or a manual binary from [Installation](#installation). To reinstall or pin a version, run `install.sh` again. #### Managing Apps Source URL: https://docs.superplane.com/cli/apps An app is the primary unit you manage from the CLI. Each app contains a canvas, console, and files. ## Generate a starter canvas YAML Print a blank canvas YAML skeleton to stdout: ```sh superplane apps canvas init ``` Start from an existing template: ```sh superplane apps canvas init --template health-check-monitor ``` List available templates: ```sh superplane apps canvas init --list-templates ``` Write directly to a file instead of stdout: ```sh superplane apps canvas init --output-file canvas.yaml ``` ## Create an app ```sh superplane apps create ``` You can also create an app from a canvas YAML file: ```sh superplane apps create --canvas-file my_canvas.yaml ``` `superplane apps create` accepts canvas-specific auto-layout flags when creating from a file: ```sh superplane apps create --canvas-file my_canvas.yaml --canvas-auto-layout horizontal ``` ## Describe an app canvas ```sh superplane apps canvas get ``` ## List apps ```sh superplane apps list ``` ## Delete an app ```sh superplane apps delete ``` ## Set active app Since you're mostly working on a single app at a time, you can set the active app with: ```sh superplane apps active ``` This allows you to omit the app argument on app-scoped commands. Runtime commands that require an explicit identifier use `--app-id`. The older `--canvas-id` flag is still accepted as a deprecated alias. ## Update an app canvas Export the existing canvas, edit it, then apply your changes: ```sh superplane apps canvas get > my_canvas.yaml # update your YAML to reflect the changes you want to make superplane apps canvas update -f my_canvas.yaml ``` `superplane apps canvas update` applies auto layout by default. Use explicit auto-layout flags only when you need to control scope or seed nodes. ### Check whether versioning is enabled Check the canvas metadata directly: ```sh superplane apps canvas get -o json | jq '.metadata.versioningEnabled' ``` Expected values: - `true`: effective versioning enabled for this app. Use `superplane apps canvas update --draft-id -f ...`. - `false`: effective versioning disabled for this app. Use `superplane apps canvas update -f ...` (no `--draft-id`). Quick behavior-based check: - If `superplane apps canvas update --draft-id ...` returns `--draft-id cannot be used when effective canvas versioning is disabled`, versioning is disabled for this app. - If `superplane apps canvas update ...` (without `--draft-id`) returns `effective canvas versioning is enabled for this canvas; use --draft-id`, versioning is enabled for this app. ## App versioning (drafts) Canvas update behavior depends on effective app mode: - Organization-level versioning ON forces effective versioning ON for all apps. - Organization-level versioning OFF allows each app to toggle versioning independently. - If app versioning is enabled, `superplane apps canvas update` must use `--draft-id`. - If app versioning is disabled, do not use `--draft-id`; updates apply directly. Draft workflow (versioning enabled): ```sh # List available drafts superplane apps drafts list # Write changes to a specific draft version superplane apps canvas update --draft-id -f my_canvas.yaml ``` If you already set an active app with `superplane apps active `, you can omit `` in `superplane apps drafts list`. ### Draft lifecycle actions When versioning is enabled, use `apps drafts` to manage your drafts: ```sh # List drafts for an app (or active app) superplane apps drafts list # Create a new draft superplane apps drafts create --name "Add incident routing path" # Delete a draft superplane apps drafts delete ``` ### Repository-backed staging When versioning is enabled, edits to `canvas.yaml` and `console.yaml` are written to a **staging** layer on your draft. These staged changes must be committed before they become part of the draft version. ```sh # Stage changes to canvas.yaml superplane apps canvas update --draft-id -f my_canvas.yaml ``` You can view a visual diff of staged changes and commit or discard them using the SuperPlane UI or API. ### Publish a draft Once your draft is ready and all changes are committed, you can publish it to make it the live version using the SuperPlane UI or API. ## Canvas YAML shape (minimal working example) When updating canvases via YAML, action and trigger nodes must use the API field names. This example connects a `schedule` trigger to an `http` action that sends a keepalive request every minute: ```yaml apiVersion: v1 kind: Canvas metadata: id: name: Store app spec: edges: - sourceId: schedule-schedule-w3mak1 targetId: http-keepalive-ping channel: default nodes: - id: schedule-schedule-w3mak1 name: schedule type: TYPE_TRIGGER component: schedule paused: false position: x: 144 y: 0 configuration: type: minutes minutesInterval: 1 customName: Keepalive {{ now() }} - id: http-keepalive-ping name: http type: TYPE_ACTION component: http paused: false position: x: 456 y: 0 configuration: method: GET url: https://store-app-c6nr.examplepaas.com/ customName: PaaS keepalive ``` Notes: - For action nodes, `type` must be `TYPE_ACTION` and `component` is required. - For trigger nodes, use `type: TYPE_TRIGGER` and `component`. - Edge fields are `sourceId`, `targetId`, and optional `channel`. - Use `superplane index actions` to find action keys (for example, `http`, `if`, `noop`). - Positioning guideline for agents: - Keep downstream nodes on the same row by default (`y` unchanged). - Use `x = upstream.x + 480` as the default spacing for new connected nodes. - Avoid changing positions of existing nodes unless explicitly requested. - If overlap still appears in UI, apply a small horizontal nudge (`x +/- 80..120`) before changing `y`. ## Managing console YAML The console is part of an app. Use `apps console` to read or replace its YAML. ```sh # Print the live console superplane apps console get -o yaml # Print your draft console superplane apps console get --draft-id -o yaml # Replace the console from a file superplane apps console set console.yaml # Replace the draft console when versioning is enabled superplane apps console set console.yaml --draft-id ``` If you already set an active app with `superplane apps active `, omit `` and pass the file with `--file`: ```sh superplane apps console set --file console.yaml ``` ## Managing app memory List memory records stored by an app: ```sh superplane apps memory list ``` Filter memory records by a specific namespace: ```sh superplane apps memory list --namespace "my-namespace" ``` If you already set an active app, the app argument is optional. ## Reading app files Use `apps files` to inspect the git repository attached to an app. ```sh # List files for an app superplane apps files tree # Print one file superplane apps files show canvas.yaml ``` If you already set an active app, the app argument is optional. #### Runs & Executions Source URL: https://docs.superplane.com/cli/runs ## Runtime operations List runs for an app: ```sh superplane runs list --app-id ``` Filter runs by state or result: ```sh superplane runs list --app-id --state STATE_STARTED --result RESULT_FAILED ``` Show full details for a specific run: ```sh superplane runs describe --app-id ``` ## Legacy runtime operations (deprecated) The following commands interact with lower-level execution primitives. They are deprecated in favor of the `runs` commands above. List node executions: ```sh superplane executions list --app-id --node-id ``` Cancel a node execution: ```sh superplane executions cancel --app-id --execution-id ``` List queue items for a node: ```sh superplane queue list --app-id --node-id ``` Delete a queue item: ```sh superplane queue delete --app-id --node-id --item-id ``` #### Integrations & Secrets Source URL: https://docs.superplane.com/cli/resources ## Managing organizations Get details for the current organization: ```sh superplane organizations get ``` Update the current organization's name or description: ```sh superplane organizations update --name "New Name" --description "New description" ``` ## Managing integrations List connected integrations: ```sh superplane integrations list ``` Get details for one connected integration: ```sh superplane integrations get ``` List resources available from a connected integration: ```sh superplane integrations list-resources --id --type ``` You can pass additional query parameters when needed: ```sh superplane integrations list-resources \ --id \ --type \ --parameters key=value,key2=value2 ``` ## Managing secrets List secrets: ```sh superplane secrets list ``` Create a secret from a file: ```sh superplane secrets create --file my_secret.yaml ``` Update a secret from a file: ```sh superplane secrets update --file my_secret.yaml ``` Delete a secret: ```sh superplane secrets delete ``` #### Discovery Index Source URL: https://docs.superplane.com/cli/discovery Use `index` to discover available integration definitions, triggers, and actions. ```sh superplane index integrations ``` Describe one integration definition: ```sh superplane index integrations --name ``` List core actions: ```sh superplane index actions ``` List actions from an integration definition: ```sh superplane index actions --from ``` Describe one action: ```sh superplane index actions --name ``` List triggers from an integration definition: ```sh superplane index triggers --from ``` Describe one trigger: ```sh superplane index triggers --name ``` List available UI widgets: ```sh superplane index widgets ``` Download the full registry (integrations, actions, triggers, and widgets) to a local JSON file: ```sh superplane index dump ``` By default the file is written to `/tmp/superplane-index.json`. Use `--file` to choose a different path: ```sh superplane index dump --file registry.json ``` ### Reference #### Public API Reference Source URL: https://docs.superplane.com/concepts/api-reference SuperPlane exposes a REST API covering all resources (canvases, integrations, secrets, service accounts, and more). The interactive docs list every route and schema. The full API reference is available as an interactive Swagger document at: **[https://app.superplane.com/api/v1/docs](https://app.superplane.com/api/v1/docs)** ## Authentication All API requests require a valid API token sent in the `Authorization` header: ``` Authorization: Bearer ``` For a full overview of authentication methods, see [Authentication and accounts](/security/authentication). You can obtain a token in two ways: - **Service account token** (recommended for scripts and integrations): see [Service accounts](/security/service-accounts). - **Personal token** (tied to your user): go to **Profile > API token** in the SuperPlane UI. ## Quick example ```sh curl -s https://app.superplane.com/api/v1/canvases \ -H "Authorization: Bearer " | jq ``` ## Using with the CLI The [SuperPlane CLI](/cli/overview) wraps the same API. If you prefer a terminal-based workflow, the CLI handles authentication and formatting for you. #### Glossary Source URL: https://docs.superplane.com/concepts/glossary This page defines the core terms used throughout the SuperPlane documentation. ## SuperPlane Apps A **SuperPlane app** is a control plane for long-lived, event-driven software engineering workflows across your existing tools. See [Overview](/concepts/superplane-apps). ## Canvas A **canvas** is the workspace where you design and run workflows. It is a graph of nodes connected by subscriptions that define how events flow between nodes. A canvas usually represents multiple possible workflows. ## Workflow A **workflow** is the behavior expressed by a canvas: what should happen when an event occurs, which steps run, and how data moves between steps. ## Node A **node** is a single step on a canvas. Triggers and actions execute. ## Note A **note** is a sticky note on the canvas for documentation. Notes do not run in workflows or emit payloads. ## Console A **console** is a per-app operational view: a grid of panels for status, runbooks, and live data from memory, executions, or runs. See [Console](/concepts/console). ## Memory **Memory** is persistent, app-scoped storage for JSON data, organized by namespace. Workflows can read and write it using the memory components. See [Memory](/concepts/canvas-memory). ## Execution config (Config tab) The **execution config** is a snapshot of a node's resolved configuration at execution time. Shown in the **Config** tab and accessible as `.config` in expressions. ## Component A **component** is the “type” of a node (for example, **Webhook**, **Manual Run**, **Filter**, or a GitHub action). Components define what configuration a node needs and what it emits. ## Trigger A **trigger** is a component that starts a workflow execution. Triggers typically receive external events (webhooks, schedules) or start runs manually. ## Action An **action** is a component that runs in response to an upstream event. Actions can call external systems, transform data, route events, or wait for human input. ## Integration An **integration** connects SuperPlane to an external system (for example GitHub, Slack, PagerDuty). Integrations provide triggers and actions you can use as nodes on the canvas. ## Event An **event** is the unit of work that flows between nodes. Events carry data (the payload) and are delivered to any downstream nodes that subscribe to them. ## Payload A **payload** is the JSON data associated with an event or a node execution. Payloads are what you inspect in run history and what you reference in expressions. ## Output channel (channel) A **channel** is a named output a node can emit on (for example `passed`/`failed`, `approved`/`rejected`). Channels let you route events to different downstream paths based on outcomes. ## Subscription A **subscription** is the connection from one node’s output (optionally a specific channel) to another node’s input. A canvas is essentially a graph of subscriptions. ## Run A **run** is a single end-to-end workflow execution, from the first triggering event through all downstream work it causes. Runs are what you use to debug “what happened?” across many steps. ## Run item A **run item** is the execution record for a single node within a run. A run is composed of many run items. ## Run history **Run history** is the UI view that lists past executions for a node or a canvas. It’s where you inspect payloads, timestamps, statuses, and errors. ## Message chain The **message chain** is the accumulated outputs from upstream nodes within a run. It allows downstream nodes to access and combine data from earlier steps. ## Expression An **expression** is a small program used to read and transform payload data (for example to build a message, compute a condition, or select an output path). See the [Expressions](/concepts/expressions) page for more details. ## Service account A **service account** is a non-human identity used to call the SuperPlane API from scripts and external systems. Access is governed by [RBAC](/concepts/access-control). See [Service accounts](/security/service-accounts) for details. ### Components #### AWS Source URL: https://docs.superplane.com/components/aws Manage resources and execute AWS commands in workflows import { CardGrid, LinkCard } from "@astrojs/starlight/components"; ## Triggers ## Actions ## Instructions Initially, you can leave the **"IAM Role ARN"** field empty, as you will be guided through the identity provider and IAM role creation process. ## CloudWatch • On Alarm **Trigger key:** `aws.cloudwatch.onAlarm` The On Alarm trigger starts a workflow execution when a CloudWatch alarm transitions to the ALARM state. ### Use Cases - **Incident response**: Notify responders and open incidents when alarms fire - **Auto-remediation**: Execute rollback or recovery workflows immediately - **Audit and reporting**: Track alarm transitions over time ### Configuration - **Region**: AWS region where alarms are evaluated - **Alarms**: Optional alarm name filters (supports equals, not-equals, and regex matches) - **State**: Only trigger for alarms in the specified state (OK, ALARM, or INSUFFICIENT_DATA) ### Event Data Each alarm event includes: - **detail.alarmName**: CloudWatch alarm name - **detail.state.value**: Current alarm state - **detail.previousState.value**: Previous alarm state ### Example Data ```json { "data": { "account": "123456789012", "detail": { "alarmName": "HighCPUUtilization", "previousState": { "reason": "Threshold Crossed: 1 datapoint [35.0 (20/11/24 20:29:00)] was not greater than or equal to the threshold (90.0).", "timestamp": "2024-11-20T20:30:33.000+0000", "value": "OK" }, "state": { "reason": "Threshold Crossed: 1 datapoint [95.0 (20/11/24 20:34:00)] was greater than or equal to the threshold (90.0).", "timestamp": "2024-11-20T20:35:33.000+0000", "value": "ALARM" } }, "detail-type": "CloudWatch Alarm State Change", "id": "2f1ecf5c-8bc9-4b7d-9e76-8df420e8e1a7", "region": "us-east-1", "resources": [ "arn:aws:cloudwatch:us-east-1:123456789012:alarm:HighCPUUtilization" ], "source": "aws.cloudwatch", "time": "2024-11-20T20:35:33Z", "version": "0" }, "timestamp": "2026-02-10T12:00:00Z", "type": "aws.cloudwatch.alarm" } ``` ## CodeArtifact • On Package Version **Trigger key:** `aws.codeArtifact.onPackageVersion` The On Package Version trigger starts a workflow execution when a package version is created, modified, or deleted in AWS CodeArtifact. ### Use Cases - **Release automation**: Trigger downstream workflows when a new package version is published - **Dependency monitoring**: Notify teams about changes to shared libraries - **Compliance checks**: Validate artifacts before promotion ### Example Data ```json { "data": { "account": "123456789012", "detail": { "changes": { "assetsAdded": 1, "assetsRemoved": 0, "assetsUpdated": 0, "metadataUpdated": false, "statusChanged": true }, "domainName": "example-domain", "domainOwner": "123456789012", "eventDeduplicationId": "5f87d1a3-2c1f-4ab0-8f55-8f4c2b4a5c76", "operationType": "Created", "packageFormat": "npm", "packageName": "@scope/example-package", "packageNamespace": null, "packageVersion": "1.2.3", "packageVersionRevision": "E30D52B451F42F41", "packageVersionState": "Published", "repositoryAdministrator": "arn:aws:sts::123456789012:assumed-role/ExampleRole/example-user", "repositoryName": "example-repo", "sequenceNumber": 1 }, "detail-type": "CodeArtifact Package Version State Change", "id": "d9e9ff4a-3514-3d2c-b6b8-1fb5e0b9d3b2", "region": "us-east-1", "resources": [ "arn:aws:codeartifact:us-east-1:123456789012:repository/example-domain/example-repo" ], "source": "aws.codeartifact", "time": "2024-11-20T20:35:33Z", "version": "0" }, "timestamp": "2026-03-10T14:25:30.31254162Z", "type": "aws.codeartifact.package.version" } ``` ## CodePipeline • On Pipeline **Trigger key:** `aws.codepipeline.onPipeline` The On Pipeline trigger starts a workflow execution when AWS CodePipeline emits a pipeline execution state change event. ### Use Cases - **Deployment visibility**: Start workflows whenever pipeline state changes - **Incident response**: Notify teams when a pipeline fails or is canceled - **Workflow orchestration**: Trigger follow-up automations on specific pipeline states ### Configuration - **Region**: AWS region where pipeline execution events are observed - **Pipelines**: Optional pipeline name filters (supports equals, not-equals, and regex matches) - **Pipeline States**: Optional list of states to match (for example STARTED, SUCCEEDED, FAILED) ### Event Data Each event includes: - **detail.pipeline**: CodePipeline pipeline name - **detail.execution-id**: Pipeline execution ID - **detail.state**: Pipeline execution state ### Example Data ```json { "data": { "account": "123456789012", "detail": { "execution-id": "00000000-0000-0000-0000-000000000001", "execution-trigger": { "trigger-detail": "arn:aws:sts::123456789012:assumed-role/superplane-demo-role/SuperPlane-00000000-0000-0000-0000-000000000000", "trigger-type": "StartPipelineExecution" }, "pipeline": "demo-pipeline", "pipeline-execution-attempt": 1, "start-time": "2026-02-24T15:21:42.016Z", "state": "STARTED", "version": 1 }, "detail-type": "CodePipeline Pipeline Execution State Change", "id": "00000000-0000-0000-0000-000000000002", "region": "us-east-1", "resources": [ "arn:aws:codepipeline:us-east-1:123456789012:demo-pipeline" ], "source": "aws.codepipeline", "time": "2026-02-24T15:21:42Z", "version": "0" }, "timestamp": "2026-02-24T15:21:52.212Z", "type": "aws.codepipeline.pipeline" } ``` ## EC2 • On Alarm **Trigger key:** `aws.ec2.onAlarm` The On Alarm trigger starts a workflow execution when a CloudWatch alarm attached to a specific EC2 instance transitions to the configured state. ### Use Cases - **Incident response**: Trigger remediation workflows when a CPU, network, or status-check alarm fires - **Auto-scaling**: React to alarms on individual instances without polling - **Audit**: Record alarm state transitions for specific instances over time ### Configuration - **Region**: AWS region where the instance and alarms reside - **Instance**: EC2 instance whose alarms to monitor (required) - **Alarm State**: Only trigger for a specific state: ALARM, OK, or INSUFFICIENT_DATA (required) - **Alarm**: Optionally restrict to a single alarm selected from the alarms attached to the chosen instance; leave empty to trigger on any alarm for that instance ### Event Data Each matched event includes the full EventBridge payload: - **detail.alarmName**: CloudWatch alarm name - **detail.state.value**: Current alarm state (ALARM / OK / INSUFFICIENT_DATA) - **detail.previousState.value**: Previous alarm state - **detail.configuration**: Full alarm configuration including metric, threshold, and dimensions - **region**, **account**, **time**: Event envelope fields ### Example Data ```json { "data": { "account": "123456789012", "detail": { "alarmName": "high cpu usage", "configuration": { "description": "The alarm", "metrics": [ { "id": "56cf46e9-e800-a52b-b55b-7f3c770c24ef", "metricStat": { "metric": { "dimensions": { "InstanceId": "i-1234567890abcdef0" }, "name": "CPUUtilization", "namespace": "AWS/EC2" }, "period": 30, "stat": "Average" }, "returnData": true } ] }, "previousState": { "reason": "Threshold Crossed: 1 datapoint [0.3166666666666666 (03/06/26 14:15:00)] was not greater than the threshold (20.0).", "reasonData": "{\"version\":\"1.0\",\"queryDate\":\"2026-06-03T14:15:45.660+0000\",\"startDate\":\"2026-06-03T14:15:00.000+0000\",\"statistic\":\"Average\",\"period\":30,\"recentDatapoints\":[0.3166666666666666],\"threshold\":20.0,\"evaluatedDatapoints\":[{\"timestamp\":\"2026-06-03T14:15:00.000+0000\",\"sampleCount\":1.0,\"value\":0.3166666666666666}]}", "timestamp": "2026-06-03T14:15:45.663+0000", "value": "OK" }, "state": { "reason": "Threshold Crossed: 1 datapoint [31.3283485070315 (03/06/26 15:45:00)] was greater than the threshold (20.0).", "reasonData": "{\"version\":\"1.0\",\"queryDate\":\"2026-06-03T15:46:15.660+0000\",\"startDate\":\"2026-06-03T15:45:00.000+0000\",\"statistic\":\"Average\",\"period\":30,\"recentDatapoints\":[31.3283485070315],\"threshold\":20.0,\"evaluatedDatapoints\":[{\"timestamp\":\"2026-06-03T15:45:00.000+0000\",\"sampleCount\":2.0,\"value\":31.3283485070315}]}", "timestamp": "2026-06-03T15:46:15.662+0000", "value": "ALARM" } }, "detail-type": "CloudWatch Alarm State Change", "id": "ccc0350a-524d-2f57-068b-1cebb2a4b6c0", "region": "us-east-1", "resources": [ "arn:aws:cloudwatch:us-east-1:123456789012:alarm:high cpu usage" ], "source": "aws.cloudwatch", "time": "2026-06-03T15:46:15Z", "version": "0" }, "timestamp": "2026-06-03T15:46:16.233981639Z", "type": "aws.ec2.alarm" } ``` ## EC2 • On Image **Trigger key:** `aws.ec2.onImage` The On Image trigger starts a workflow execution when an EC2 AMI changes state. ### Use Cases - **Image pipeline orchestration**: Continue workflows when a new AMI becomes available - **Failure handling**: Alert and remediate when AMI creation fails - **Compliance workflows**: Run validation and distribution after image creation ### Configuration - **Region**: AWS region where AMI state changes are monitored - **Image State**: State to trigger on (pending, available, failed) ### Event Data Each AMI state event includes: - **detail.ImageId**: AMI ID (for example: ami-1234567890abcdef0) - **detail.State**: AMI state - **detail.ErrorMessage**: Error message for failed states (if available) ### Example Data ```json { "data": { "account": "123456789012", "detail": { "ImageId": "ami-07f0e4f3e9c123abc", "State": "available" }, "detail-type": "EC2 AMI State Change", "id": "f74f3de5-f9b7-4f3d-909a-531fc3ff2f14", "region": "us-east-1", "resources": [ "arn:aws:ec2:us-east-1::image/ami-07f0e4f3e9c123abc" ], "source": "aws.ec2", "time": "2026-02-10T12:10:00Z", "version": "0" }, "timestamp": "2026-02-10T12:10:01Z", "type": "aws.ec2.image" } ``` ## ECR • On Image Push **Trigger key:** `aws.ecr.onImagePush` The On Image Push trigger starts a workflow execution when an image is pushed to an ECR repository. ### Use Cases - **Build pipelines**: Trigger builds and deployments on container pushes - **Security automation**: Kick off scans or alerts for newly pushed images - **Release workflows**: Promote artifacts when a tag is published ### Configuration - **Repositories**: Optional filters for ECR repository names - **Image Tags**: Optional filters for image tags (for example: `latest` or `^v[0-9]+`) ### Event Data Each image push event includes: - **detail.repository-name**: ECR repository name - **detail.image-tag**: Tag that was pushed - **detail.image-digest**: Digest of the image ### Example Data ```json { "data": { "account": "123456789012", "detail": { "action-type": "PUSH", "image-digest": "sha256:2c26b46b68ffc68ff99b453c1d30413413422f1642f0e2b8c7b8a0b8a96a909e", "image-tag": "latest", "repository-arn": "arn:aws:ecr:us-east-1:123456789012:repository/my-repo", "repository-name": "my-repo", "result": "SUCCESS" }, "detail-type": "ECR Image Action", "id": "c1b45a2c-9c3f-4c52-bc98-5ea31ce17692", "region": "us-east-1", "resources": [ "arn:aws:ecr:us-east-1:123456789012:repository/my-repo" ], "source": "aws.ecr", "time": "2024-01-01T12:00:00Z", "version": "0" }, "timestamp": "2026-02-03T12:00:00Z", "type": "aws.ecr.image.push" } ``` ## ECR • On Image Scan **Trigger key:** `aws.ecr.onImageScan` The On Image Scan trigger starts a workflow execution when an ECR image scan completes. ### Use Cases - **Security automation**: Notify teams or open issues on new findings - **Compliance checks**: Gate promotions based on severity thresholds - **Reporting**: Aggregate scan findings across repositories ### Configuration - **Repositories**: Optional filters for ECR repository names ### Notes - **Enhanced scanning**: Enhanced scanning events are sent by Amazon Inspector (aws.inspector2) ### Event Data Each image scan event includes: - **detail.scan-status**: Scan status (for example: COMPLETE) - **detail.repository-name**: ECR repository name - **detail.image-digest**: Digest of the image - **detail.image-tags**: Tags associated with the image - **detail.finding-severity-counts**: Counts per severity level (if any) ### Example Data ```json { "data": { "account": "123456789012", "detail": { "finding-severity-counts": { "CRITICAL": 10, "MEDIUM": 9 }, "image-digest": "sha256:7f5b2640fe6fb4f46592dfd3410c4a79dac4f89e4782432e0378abcd1234", "image-tags": [], "repository-name": "my-repo", "scan-status": "COMPLETE" }, "detail-type": "ECR Image Scan", "id": "df8b66c7-62c7-4b8a-9a6b-6ad7d6d8b3a2", "region": "us-east-1", "resources": [ "arn:aws:ecr:us-east-1:123456789012:repository/my-repo" ], "source": "aws.ecr", "time": "2024-01-01T12:00:00Z", "version": "0" }, "timestamp": "2026-03-10T14:25:30.31254162Z", "type": "aws.ecr.image.scan" } ``` ## SNS • On Topic Message **Trigger key:** `aws.sns.onTopicMessage` The On Topic Message trigger starts a workflow execution when a message is published to an AWS SNS topic. ### Use Cases - **Event-driven automation**: React to messages published by external systems - **Notification processing**: Handle SNS payloads in workflow steps - **Routing and enrichment**: Trigger downstream workflows based on topic activity ### How it works During setup, SuperPlane creates a webhook endpoint for this trigger and subscribes it to the selected SNS topic using HTTPS. SNS sends notification payloads to the webhook endpoint, which then emits workflow events. ### Example Data ```json { "data": { "account": "123456789012", "detail": { "message": "{\"orderId\":\"ord_123\",\"status\":\"created\"}", "messageId": "95df01b4-ee98-5cb9-9903-4c221d41eb5e", "subject": "order.created", "timestamp": "2026-01-10T10:00:00Z", "topicArn": "arn:aws:sns:us-east-1:123456789012:orders-events" }, "message": "{\"orderId\":\"ord_123\",\"status\":\"created\"}", "messageAttributes": { "eventType": { "Type": "String", "Value": "order.created" } }, "messageId": "95df01b4-ee98-5cb9-9903-4c221d41eb5e", "region": "us-east-1", "subject": "order.created", "timestamp": "2026-01-10T10:00:00Z", "topicArn": "arn:aws:sns:us-east-1:123456789012:orders-events", "type": "Notification" }, "timestamp": "2026-01-10T10:00:02.000000000Z", "type": "aws.sns.topic.message" } ``` ## CodeArtifact • Copy Package Versions **Component key:** `aws.codeArtifact.copyPackageVersions` The Copy Package Versions component copies one or more package versions from a source repository to a destination repository in the same domain. ### Use Cases - **Promotion**: Copy approved versions from staging to production - **Replication**: Mirror packages across repositories - **Migration**: Move versions between repos in the same domain ### Example Output ```json { "data": { "failedVersions": {}, "successfulVersions": { "1.0.0": { "revision": "REVISION1", "status": "Published" }, "1.0.1": { "revision": "REVISION2", "status": "Published" } } }, "timestamp": "2026-03-26T19:29:35.841265352Z", "type": "aws.codeartifact.package.versions.copied" } ``` ## CodeArtifact • Create Repository **Component key:** `aws.codeArtifact.createRepository` The Create Repository component creates a new repository in an AWS CodeArtifact domain. ### Use Cases - **Automated setup**: Create repositories as part of onboarding or pipeline setup - **Environment replication**: Mirror repository structure across domains - **Workflow provisioning**: Create a destination repository before copying packages ### Example Output ```json { "data": { "repository": { "administratorAccount": "123456789012", "arn": "arn:aws:codeartifact:us-east-1:123456789012:repository/example-domain/my-repo", "createdTime": 1706961600, "description": "Example repository created by workflow", "domainName": "example-domain", "domainOwner": "123456789012", "name": "my-repo" } }, "timestamp": "2026-03-26T19:29:35.841265352Z", "type": "aws.codeartifact.repository" } ``` ## CodeArtifact • Delete Package Versions **Component key:** `aws.codeArtifact.deletePackageVersions` The Delete Package Versions component permanently removes package versions and their assets. Deleted versions cannot be restored. To remove from view but keep the option to restore later, use Update Package Versions Status to set status to Archived instead. ### Use Cases - **Cleanup**: Remove obsolete or invalid versions - **Compliance**: Permanently remove versions that must not be retained - **Storage**: Free space by deleting unused versions ### Example Output ```json { "data": { "failedVersions": {}, "successfulVersions": { "1.0.0": { "revision": "REVISION1", "status": "Deleted" } } }, "timestamp": "2026-03-26T19:29:35.841265352Z", "type": "aws.codeartifact.packageVersions" } ``` ## CodeArtifact • Delete Repository **Component key:** `aws.codeArtifact.deleteRepository` The Delete Repository component deletes a repository from an AWS CodeArtifact domain. ### Use Cases - **Cleanup**: Remove repositories after migration or deprecation - **Environment teardown**: Delete temporary repositories created by workflows - **Lifecycle management**: Enforce retention by deleting old repositories ### Example Output ```json { "data": { "repository": { "administratorAccount": "123456789012", "arn": "arn:aws:codeartifact:us-east-1:123456789012:repository/example-domain/my-repo", "createdTime": 1706961600, "description": "Deleted repository", "domainName": "example-domain", "domainOwner": "123456789012", "name": "my-repo" } }, "timestamp": "2026-03-26T19:29:35.841265352Z", "type": "aws.codeartifact.repository" } ``` ## CodeArtifact • Dispose Package Versions **Component key:** `aws.codeArtifact.disposePackageVersions` The Dispose Package Versions component deletes the assets of package versions and sets their status to Disposed. The version record remains so you can still see it in ListPackageVersions with status Disposed; assets cannot be restored. ### Use Cases - **Retention**: Keep version metadata for audit while removing binary assets - **Storage**: Free asset storage while preserving version history - **Lifecycle**: Mark versions as disposed after a retention period ### Example Output ```json { "data": { "failedVersions": {}, "successfulVersions": { "1.0.0": { "revision": "REVISION1", "status": "Disposed" } } }, "timestamp": "2026-03-26T19:29:35.841265352Z", "type": "aws.codeartifact.packageVersions" } ``` ## CodeArtifact • Get Package Version **Component key:** `aws.codeArtifact.getPackageVersion` The Get Package Version component retrieves metadata for a specific package version in AWS CodeArtifact. ### Use Cases - **Release automation**: Resolve package metadata before promotion - **Audit trails**: Capture version details for reporting - **Dependency checks**: Validate status and origin of package versions ### Example Output ```json { "data": { "assets": [ { "hashes": { "sha256": "1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef" }, "name": "example-package-1.2.3.tgz", "size": 1234567890 } ], "package": { "displayName": "example-package", "format": "npm", "homePage": "https://example.com/example-package", "licenses": [ { "name": "MIT", "url": "https://opensource.org/licenses/MIT" } ], "namespace": "@scope", "origin": { "domainEntryPoint": { "externalConnectionName": "npmjs", "repositoryName": "example-repo" }, "originType": "EXTERNAL" }, "packageName": "@scope/example-package", "revision": "E30D52B451F42F41", "sourceCodeRepository": "https://github.com/example/example-package", "status": "Published", "summary": "Example package for demonstration.", "version": "1.2.3" } }, "timestamp": "2026-02-03T12:00:00Z", "type": "aws.codeartifact.package.version" } ``` ## CodeArtifact • Update Package Versions Status **Component key:** `aws.codeArtifact.updatePackageVersionsStatus` The Update Package Versions Status component sets the status of package versions to Archived, Published, or Unlisted. ### Use Cases - **Lifecycle management**: Archive old versions or publish after validation - **Visibility**: Unlist versions without deleting them - **Compliance**: Align version status with release policies ### Example Output ```json { "data": { "failedVersions": {}, "successfulVersions": { "1.0.0": { "revision": "REVISION1", "status": "Archived" }, "1.0.1": { "revision": "REVISION2", "status": "Archived" } } }, "timestamp": "2026-03-26T19:29:35.841265352Z", "type": "aws.codeartifact.packageVersions" } ``` ## CodePipeline • Get Pipeline **Component key:** `aws.codepipeline.getPipeline` The Get Pipeline component retrieves the full definition of an AWS CodePipeline pipeline. ### Use Cases - **Pipeline inspection**: Fetch pipeline stages, actions, and configuration - **Workflow branching**: Route workflow based on pipeline structure or version - **Audit and compliance**: Retrieve pipeline definitions for auditing purposes ### Configuration - **Region**: AWS region where the pipeline exists - **Pipeline**: Pipeline name to retrieve ### Output Emits the full pipeline definition including: - Pipeline name, version, and role ARN - All stages and their actions - Pipeline metadata (ARN, creation date, last updated date) ### Example Output ```json { "data": { "metadata": { "created": "2025-01-15T10:30:00Z", "pipelineArn": "arn:aws:codepipeline:us-east-1:123456789012:my-deploy-pipeline", "updated": "2026-02-20T14:00:00Z" }, "pipeline": { "name": "my-deploy-pipeline", "roleArn": "arn:aws:iam::123456789012:role/pipeline-role", "stages": [ { "actions": [ { "actionTypeId": { "category": "Source", "owner": "AWS", "provider": "CodeStarSourceConnection", "version": "1" }, "name": "SourceAction" } ], "name": "Source" }, { "actions": [ { "actionTypeId": { "category": "Deploy", "owner": "AWS", "provider": "CodeDeploy", "version": "1" }, "name": "DeployAction" } ], "name": "Deploy" } ], "version": 3 } }, "timestamp": "2026-02-22T10:00:00.000000000Z", "type": "aws.codepipeline.pipeline" } ``` ## CodePipeline • Get Pipeline Execution **Component key:** `aws.codepipeline.getPipelineExecution` The Get Pipeline Execution component retrieves the details of a specific AWS CodePipeline execution. ### Use Cases - **Execution inspection**: Fetch the status, trigger, and artifact revisions of a pipeline run - **Post-deploy checks**: After a RunPipeline component, fetch details of that execution for logging - **Workflow branching**: Route workflow based on execution status or trigger type - **Audit and compliance**: Retrieve execution details for auditing purposes ### Configuration - **Region**: AWS region where the pipeline exists - **Pipeline**: Pipeline name - **Execution ID**: The ID of the specific execution to retrieve ### Output Emits the full pipeline execution details including: - Execution ID, status, and status summary - Pipeline name and version - Trigger type and detail - Artifact revisions (source code revisions involved) - Execution mode and type ### Example Output ```json { "data": { "artifactRevisions": [ { "name": "SourceArtifact", "revisionChangeIdentifier": "abc123def456789", "revisionId": "abc123def456789", "revisionSummary": "Merge pull request #42 from feature/add-auth", "revisionUrl": "https://github.com/example/repo/commit/abc123def456789" } ], "executionMode": "SUPERSEDED", "executionType": "STANDARD", "pipelineExecutionId": "a1b2c3d4-5678-90ab-cdef-111122223333", "pipelineName": "my-deploy-pipeline", "pipelineVersion": 3, "status": "Succeeded", "statusSummary": "Pipeline completed successfully", "trigger": { "triggerDetail": "arn:aws:iam::123456789012:user/developer", "triggerType": "StartPipelineExecution" } }, "timestamp": "2026-02-23T10:00:00.000000000Z", "type": "aws.codepipeline.pipeline.execution" } ``` ## CodePipeline • Retry Stage Execution **Component key:** `aws.codepipeline.retryStageExecution` The Retry Stage Execution component retries a stage within an existing AWS CodePipeline execution. ### Use Cases - **Recover failed deployments**: Retry only failed actions in a failed stage - **Re-run full stage**: Retry all actions for a stage when needed - **Workflow recovery**: Continue orchestration after a transient failure ### Configuration - **Region**: AWS region where the pipeline exists - **Pipeline**: Pipeline name - **Stage**: Stage name to retry - **Pipeline Execution**: Source execution to retry from - **Retry Mode**: Choose between failed actions only or all actions ### Output Emits retry result metadata including: - Pipeline name and stage - Selected retry mode - Source execution ID - New execution ID created by the retry ### Example Output ```json { "data": { "pipeline": { "name": "my-pipeline", "newExecutionId": "4444-5555-6666", "retryMode": "FAILED_ACTIONS", "sourceExecutionId": "1111-2222-3333", "stage": "Deploy" } }, "timestamp": "2026-02-23T10:00:00.000000000Z", "type": "aws.codepipeline.stage.retry" } ``` ## CodePipeline • Run Pipeline **Component key:** `aws.codepipeline.runPipeline` The Run Pipeline component triggers an AWS CodePipeline execution and waits for it to complete. ### Use Cases - **CI/CD orchestration**: Trigger deployments from SuperPlane workflows - **Pipeline automation**: Run CodePipeline pipelines as part of workflow automation - **Multi-stage deployments**: Coordinate complex deployment pipelines - **Workflow chaining**: Chain multiple CodePipeline pipelines together ### How It Works 1. Starts a CodePipeline execution with the specified pipeline name 2. Waits for the pipeline to complete (monitored via EventBridge webhook and polling) 3. Routes execution based on pipeline result: - **Passed channel**: Pipeline completed successfully - **Failed channel**: Pipeline failed or was cancelled ### Configuration - **Region**: AWS region where the pipeline exists - **Pipeline**: Pipeline name or ARN to execute ### Output Channels - **Passed**: Emitted when pipeline completes successfully - **Failed**: Emitted when pipeline fails or is cancelled ### Notes - The component automatically sets up EventBridge monitoring for pipeline completion - Falls back to polling if webhook doesn't arrive - Can be cancelled, which will stop the running pipeline execution ### Example Output ```json { "data": { "detail": { "execution-id": "a1b2c3d4-5678-90ab-cdef-111122223333", "pipeline": "my-deploy-pipeline", "state": "SUCCEEDED", "version": 1 }, "pipeline": { "executionId": "a1b2c3d4-5678-90ab-cdef-111122223333", "name": "my-deploy-pipeline", "state": "SUCCEEDED", "status": "Succeeded" } }, "timestamp": "2026-02-10T14:35:22.518372841Z", "type": "aws.codepipeline.pipeline.finished" } ``` ## EC2 • Allocate Elastic IP **Component key:** `aws.ec2.allocateElasticIP` The Allocate Elastic IP component allocates a new Elastic IP address to your AWS account in the selected region. ### Use Cases - **Static public IPs**: Reserve a public IPv4 address before launching or exposing a service - **Failover workflows**: Allocate a replacement Elastic IP during disaster recovery - **Pre-provisioning**: Reserve an address ahead of association with an instance or network interface - **BYOIP and IPAM**: Allocate from your own address pools or VPC IPAM pools ### Configuration - **Region**: AWS region where the Elastic IP will be allocated - **IP source**: Where the address comes from: - **Amazon's pool**: Default public IPv4 address from AWS - **BYOIP pool**: Address from a public IPv4 pool you brought to your account - **Customer-owned pool**: Address from an on-premises pool for use with an Outpost - **IPAM pool**: Address from a VPC IPAM pool with a public IPv4 CIDR - **Pool**: Required when using BYOIP, customer-owned, or IPAM sources (searchable pickers scoped to the selected region) - **Address** (optional): Request a specific IPv4 address from the selected pool - **Tags** (optional): Key/value tags applied to the Elastic IP at allocation time ### Output Emits the allocated Elastic IP details on the default output channel: - `allocationId`, `publicIp`, `domain`, `region` ### Important Notes - Elastic IPs are allocated to your account and incur charges when not associated with a running instance - The address is allocated for use in a VPC (`domain: vpc`) - BYOIP, customer-owned, and IPAM pools must already exist in the target region ### Example Output ```json { "data": { "allocationId": "eipalloc-0abc1234567890def", "domain": "vpc", "publicIp": "203.0.113.10", "region": "us-east-1" }, "timestamp": "2026-05-21T12:01:00Z", "type": "aws.ec2.elastic-ip.allocated" } ``` ## EC2 • Copy Image **Component key:** `aws.ec2.copyImage` The Copy Image component copies an AMI to another AWS region. ### Use Cases - **Multi-region rollouts**: Replicate golden images to deployment regions - **Disaster recovery**: Keep AMI backups in secondary regions - **Promotion workflows**: Copy validated images across environments ### Configuration - **Destination Region**: AWS region where the copied AMI is created - **Source Region**: AWS region where the source AMI exists - **Source Image ID**: AMI ID to copy - **Image Name**: Name for the copied AMI - **Description**: Optional AMI description ### Completion behavior - The component waits for EventBridge `EC2 AMI State Change` events for the copied AMI. - It completes when the AMI state becomes `available`. - It fails if the AMI state becomes `failed`. ### Example Output ```json { "data": { "image": { "architecture": "x86_64", "creationDate": "2026-02-19T09:00:00.000Z", "description": "Copied for disaster recovery", "hypervisor": "xen", "imageId": "ami-0c0ffee1234567890", "imageType": "machine", "name": "my-app-2026-02-19", "ownerId": "123456789012", "region": "us-west-2", "rootDeviceName": "/dev/xvda", "rootDeviceType": "ebs", "state": "available", "virtualizationType": "hvm" } }, "timestamp": "2026-02-19T09:00:00Z", "type": "aws.ec2.image" } ``` ## EC2 • Create Alarm **Component key:** `aws.ec2.createAlarm` The Create Alarm component creates a CloudWatch metric alarm targeting a specific EC2 instance. ### Use Cases - **Proactive monitoring**: Set up CPU or network alarms as part of an instance provisioning workflow - **Auto-remediation**: Create alarms that trigger downstream workflows when thresholds are crossed - **Compliance**: Ensure every new instance has required alarms configured automatically ### Configuration - **Region**: AWS region where the EC2 instance and alarm reside - **Instance**: EC2 instance to monitor - **Alarm Name**: Unique name for the CloudWatch alarm - **Metric Name**: EC2 CloudWatch metric to monitor (CPU, disk, network, status checks) - **Statistic**: Aggregation function applied over the evaluation period (Average, Sum, Min, Max, SampleCount) - **Comparison Operator**: How the metric is compared to the threshold (e.g. GreaterThanThreshold) - **Threshold**: Numeric value to compare the metric against - **Period**: Evaluation window in seconds (default: 300) - **Evaluation Periods**: Number of consecutive periods that must breach the threshold before the alarm fires (default: 1) - **Alarm Description**: Optional free-text description - **Treat Missing Data**: How to treat missing data points (missing, ignore, breaching, notBreaching) - **Alarm Action** *(toggleable)*: EC2 automation action to execute when the alarm enters ALARM state — Recover, Reboot, Stop, or Terminate - **SNS Topic (on alarm)** *(toggleable)*: SNS topic ARN to publish a notification to when the alarm enters ALARM state ### Output Emits the created alarm details on the default output channel: - `alarmName`, `alarmArn`, `namespace`, `metricName` - `statistic`, `threshold`, `comparisonOperator`, `stateValue` - `period`, `evaluationPeriods`, `dimensions`, `region` ### Example Output ```json { "data": { "alarmArn": "arn:aws:cloudwatch:us-east-1:123456789012:alarm:cpuUsage", "alarmDescription": "Cpu alarm", "alarmName": "cpuUsage", "comparisonOperator": "GreaterThanThreshold", "dimensions": [ { "name": "InstanceId", "value": "i-1234567890abcdef0" } ], "evaluationPeriods": 1, "metricName": "CPUUtilization", "namespace": "AWS/EC2", "period": 120, "region": "us-east-1", "stateReason": "Unchecked: Initial alarm creation", "stateValue": "INSUFFICIENT_DATA", "statistic": "Average", "threshold": 80, "treatMissingData": "ignore" }, "timestamp": "2026-06-03T16:36:13.985915034Z", "type": "aws.ec2.alarm" } ``` ## EC2 • Create Image **Component key:** `aws.ec2.createImage` The Create Image component creates a new Amazon Machine Image (AMI) from an EC2 instance. ### Use Cases - **Golden image pipelines**: Build immutable infrastructure images from validated instances - **Backup workflows**: Snapshot instance state before deployments or migrations - **Release automation**: Produce versioned AMIs as part of CI/CD ### Configuration - **Region**: AWS region where the instance runs - **Instance**: EC2 instance ID to create an image from - **Image Name**: Name for the AMI - **Description**: Optional image description - **No Reboot**: If enabled, create the image without rebooting the instance ### Completion behavior - The component waits for EventBridge `EC2 AMI State Change` events for the created AMI. - It completes when the AMI state becomes `available`. - It fails if the AMI state becomes `failed`. ### Example Output ```json { "data": { "image": { "architecture": "x86_64", "creationDate": "2026-02-18T12:00:00.000Z", "description": "Golden image for production", "hypervisor": "xen", "imageId": "ami-07f0e4f3e9c123abc", "imageType": "machine", "name": "my-app-2026-02-18", "ownerId": "123456789012", "region": "us-east-1", "rootDeviceName": "/dev/xvda", "rootDeviceType": "ebs", "state": "available", "virtualizationType": "hvm" } }, "timestamp": "2026-02-18T12:00:00Z", "type": "aws.ec2.image" } ``` ## EC2 • Create Instance **Component key:** `aws.ec2.createInstance` The Create Instance component launches a new Amazon EC2 instance and waits until it reaches **running** state before emitting. ### Use Cases - **Ephemeral compute**: Provision temporary VMs for tests, builds, or automation - **Environment provisioning**: Launch instances as part of deployment workflows - **On-demand capacity**: Create additional compute when triggered by events ### Configuration - **Name**: Required value for the `Name` tag - **Region**: AWS region where the instance will be launched - **Operating System**: Quick Start operating system family, similar to the AWS launch wizard - **Image**: Public AMI for the selected operating system. These are filtered to only show currently available images in the selected region for the chosen OS family - **Instance Type**: EC2 instance type from the current generation catalog - **Subnet**: VPC subnet for the primary network interface - **Firewall**: Create a launch security group (like the AWS launch wizard) or use an existing one - **Allow SSH/HTTP/HTTPS from the internet**: Ingress rules when creating a new security group - **Configure Root Volume** (optional): Override the AMI root volume size and type - **Key Pair** (optional): EC2 key pair for SSH access. These are filtered to show only key pairs available in the selected region - **User Data** (optional): Shell script or cloud-init payload executed at launch - **Associate Public IP Address**: Assign a public IPv4 address when the subnet supports it ### Output Emits instance details on the default output channel, including: - `instanceId` — EC2 instance ID - `state` — should be `running` - `publicIpAddress` / `privateIpAddress` — network addresses when available - `publicDnsName` / `privateDnsName` — DNS names when available ### Example Output ```json { "data": { "imageId": "ami-07f0e4f3e9c123abc", "instanceId": "i-0abc1234567890def", "instanceType": "t3.micro", "keyName": "my-key", "launchTime": "2026-05-21T12:00:00.000Z", "name": "ephemeral-builder", "privateDnsName": "ip-10-0-1-25.ec2.internal", "privateIpAddress": "10.0.1.25", "publicDnsName": "ec2-54-198-10-42.compute-1.amazonaws.com", "publicIpAddress": "54.198.10.42", "region": "us-east-1", "state": "running", "subnetId": "subnet-0abc1234567890def", "vpcId": "vpc-0abc1234567890def" }, "timestamp": "2026-05-21T12:01:00Z", "type": "aws.ec2.instance" } ``` ## EC2 • Delete Instance **Component key:** `aws.ec2.deleteInstance` The Delete Instance component terminates an Amazon EC2 instance and waits until AWS reports it as **terminated**. ### Use Cases - **Ephemeral cleanup**: Tear down temporary instances after a workflow finishes - **Cost controls**: Delete unused instances from automation - **Incident remediation**: Terminate unhealthy instances after replacement capacity exists ### Configuration - **Region**: AWS region where the instance runs - **Instance**: EC2 instance ID to terminate ### Output Emits a deletion payload on the default output channel: - `state` — `terminated` ### Example Output ```json { "data": { "instanceId": "i-0abc1234567890def", "state": "terminated" }, "timestamp": "2026-05-21T12:05:00Z", "type": "aws.ec2.instance.deleted" } ``` ## EC2 • Deregister Image **Component key:** `aws.ec2.deregisterImage` The Deregister Image component removes an AMI from your account in a region. ### Use Cases - **Image lifecycle cleanup**: Remove unused AMIs after promotion - **Compliance operations**: Retire images that should no longer be launched - **Automation rollback**: Clean up AMIs created by failed workflows ### Configuration - **Region**: AWS region where the AMI exists - **Image ID**: AMI ID to deregister - **Delete Snapshots**: If enabled, delete the snapshots associated with the AMI ### Example Output ```json { "data": { "deregistered": true, "imageId": "ami-07f0e4f3e9c123abc", "region": "us-east-1", "requestId": "req-deregister" }, "timestamp": "2026-02-19T09:10:00Z", "type": "aws.ec2.image.deregistered" } ``` ## EC2 • Disable Image **Component key:** `aws.ec2.disableImage` The Disable Image component disables an AMI so it cannot be launched. ### Use Cases - **Risk containment**: Prevent new launches from vulnerable images - **Release control**: Temporarily block image usage during maintenance - **Lifecycle governance**: Enforce policies before image retirement ### Configuration - **Region**: AWS region where the AMI exists - **Image ID**: AMI ID to disable ### Example Output ```json { "data": { "disabled": true, "imageId": "ami-07f0e4f3e9c123abc", "region": "us-east-1", "requestId": "req-disable" }, "timestamp": "2026-02-19T09:30:00Z", "type": "aws.ec2.image.disabled" } ``` ## EC2 • Disable Image Deprecation **Component key:** `aws.ec2.disableImageDeprecation` The Disable Image Deprecation component removes the deprecation schedule from an AMI. ### Use Cases - **Release extension**: Keep an image available longer than planned - **Rollback support**: Reopen older images for temporary use - **Policy exceptions**: Remove deprecation when operational needs change ### Configuration - **Region**: AWS region where the AMI exists - **Image ID**: AMI ID to remove deprecation from ### Example Output ```json { "data": { "deprecationEnabled": false, "imageId": "ami-07f0e4f3e9c123abc", "region": "us-east-1", "requestId": "req-disable-deprecation" }, "timestamp": "2026-02-19T09:50:00Z", "type": "aws.ec2.image.deprecationDisabled" } ``` ## EC2 • Enable Image **Component key:** `aws.ec2.enableImage` The Enable Image component enables a previously disabled AMI. ### Use Cases - **Release promotion**: Re-enable AMIs after staged validation - **Operational recovery**: Restore image availability after temporary restrictions - **Lifecycle workflows**: Toggle image launchability based on policy checks ### Configuration - **Region**: AWS region where the AMI exists - **Image ID**: AMI ID to enable ### Example Output ```json { "data": { "enabled": true, "imageId": "ami-07f0e4f3e9c123abc", "region": "us-east-1", "requestId": "req-enable" }, "timestamp": "2026-02-19T09:20:00Z", "type": "aws.ec2.image.enabled" } ``` ## EC2 • Enable Image Deprecation **Component key:** `aws.ec2.enableImageDeprecation` The Enable Image Deprecation component sets a deprecation time for an AMI. ### Use Cases - **Release lifecycle**: Schedule AMI retirement dates - **Compliance enforcement**: Ensure images expire on policy deadlines - **Operational hygiene**: Phase out outdated images in a controlled window ### Configuration - **Region**: AWS region where the AMI exists - **Image ID**: AMI ID to deprecate - **Deprecate At**: RFC3339 timestamp when deprecation takes effect ### Example Output ```json { "data": { "deprecateAt": "2026-04-01T00:00:00Z", "deprecationEnabled": true, "imageId": "ami-07f0e4f3e9c123abc", "region": "us-east-1", "requestId": "req-enable-deprecation" }, "timestamp": "2026-02-19T09:40:00Z", "type": "aws.ec2.image.deprecationEnabled" } ``` ## EC2 • Get Alarm **Component key:** `aws.ec2.getAlarm` The Get Alarm component describes a CloudWatch alarm and emits its current details. ### Use Cases - **State inspection**: Check whether an alarm is in ALARM, OK, or INSUFFICIENT_DATA state before taking action - **Alarm metadata lookup**: Retrieve threshold, metric, and dimension details mid-workflow - **Audit**: Record alarm configuration at a point in time ### Configuration - **Region**: AWS region where the alarm resides - **Alarm**: CloudWatch alarm to describe, selected from all alarms in the chosen region (`ec2.alarm` resource picker) ### Output Emits the alarm details on the default output channel: - `alarmName`, `alarmArn`, `namespace`, `metricName` - `statistic`, `threshold`, `comparisonOperator`, `stateValue` - `period`, `evaluationPeriods`, `dimensions`, `region` ### Example Output ```json { "data": { "alarmArn": "arn:aws:cloudwatch:us-east-1:123456789012:alarm:cpuUsage", "alarmDescription": "Cpu alarm", "alarmName": "cpuUsage", "comparisonOperator": "GreaterThanThreshold", "dimensions": [ { "name": "InstanceId", "value": "i-1234567890abcdef0" } ], "evaluationPeriods": 1, "metricName": "CPUUtilization", "namespace": "AWS/EC2", "period": 120, "region": "us-east-1", "stateReason": "Unchecked: Initial alarm creation", "stateValue": "INSUFFICIENT_DATA", "statistic": "Average", "threshold": 80, "treatMissingData": "ignore" }, "timestamp": "2026-06-03T16:37:20.636935245Z", "type": "aws.ec2.alarm" } ``` ## EC2 • Get Image **Component key:** `aws.ec2.getImage` The Get Image component retrieves metadata for an EC2 AMI. ### Use Cases - **Release automation**: Validate AMI metadata before deployment - **Operational checks**: Inspect AMI state and ownership in workflows - **Traceability**: Resolve AMI details by image ID ### Configuration - **Region**: AWS region of the AMI - **Image ID**: AMI ID (for example: ami-1234567890abcdef0) ### Example Output ```json { "data": { "image": { "architecture": "x86_64", "creationDate": "2026-02-18T12:00:00.000Z", "description": "Golden image for production", "hypervisor": "xen", "imageId": "ami-1234567890abcdef0", "imageType": "machine", "name": "my-app-2026-02-18", "ownerId": "123456789012", "region": "us-east-1", "rootDeviceName": "/dev/xvda", "rootDeviceType": "ebs", "state": "available", "virtualizationType": "hvm" } }, "timestamp": "2026-02-18T12:00:00Z", "type": "aws.ec2.image" } ``` ## EC2 • Get Instance **Component key:** `aws.ec2.getInstance` The Get Instance component describes an EC2 instance and emits its current details. ### Use Cases - **State inspection**: Check whether an instance is running or stopped before taking action - **IP resolution**: Retrieve the public or private IP address of an instance at runtime - **Metadata lookup**: Fetch instance type, AMI, VPC, and tags mid-workflow ### Configuration - **Region**: AWS region where the instance runs - **Instance**: EC2 instance to describe ### Output Emits the instance details on the default output channel: - `instanceId`, `state`, `instanceType`, `imageId` - `publicIpAddress`, `privateIpAddress`, `publicDnsName`, `privateDnsName` - `subnetId`, `vpcId`, `region`, `name`, `launchTime` ### Example Output ```json { "data": { "imageId": "ami-07f0e4f3e9c123abc", "instanceId": "i-0abc1234567890def", "instanceType": "t3.micro", "keyName": "my-key", "launchTime": "2026-05-21T12:00:00.000Z", "name": "my-server", "privateDnsName": "ip-10-0-1-25.ec2.internal", "privateIpAddress": "10.0.1.25", "publicDnsName": "ec2-54-198-10-42.compute-1.amazonaws.com", "publicIpAddress": "54.198.10.42", "region": "us-east-1", "state": "running", "subnetId": "subnet-0abc1234567890def", "vpcId": "vpc-0abc1234567890def" }, "timestamp": "2026-05-21T12:01:00Z", "type": "aws.ec2.instance" } ``` ## EC2 • Get Instance Metrics **Component key:** `aws.ec2.getInstanceMetrics` The Get Instance Metrics component retrieves CloudWatch metrics for an EC2 instance over a configurable lookback window. > **Note:** CPU and network metrics are available for all instances. Memory metrics require the **CloudWatch Agent** to be installed and running on the instance. ### Use Cases - **Performance monitoring**: Sample CPU and network utilisation before making scaling decisions - **Incident investigation**: Pull recent metrics when responding to an alert - **Capacity planning**: Gather trend data to inform right-sizing - **Automated scaling**: Use metric outputs to conditionally trigger resize or power operations ### Configuration - **Region**: AWS region where the instance runs - **Instance**: EC2 instance to query metrics for - **Lookback Period**: How far back to retrieve metrics — 1h, 6h, 24h, 7d, or 14d - **Include Memory**: Fetch memory usage (requires the CloudWatch Agent on the instance) ### Output Returns averaged and aggregated metrics over the lookback window: - `instanceId`, `region`, `lookbackPeriod`, `start`, `end` - `avgCpuUsagePercent`: Average CPU utilisation percentage (null when CloudWatch returns no datapoints for the window) - `totalNetworkInBytes`: Total inbound network bytes over the window - `totalNetworkOutBytes`: Total outbound network bytes over the window - `avgNetworkInBytesPerSec`: Average inbound bytes per second - `avgNetworkOutBytesPerSec`: Average outbound bytes per second - `avgMemoryUsagePercent`: Average memory utilisation (null when the CloudWatch Agent is unavailable, returns no datapoints, or the memory request fails) ### Important Notes - CPU and network metrics use **basic monitoring** (5-minute resolution) by default; enable **detailed monitoring** on the instance for 1-minute resolution - Memory metrics require the [CloudWatch Agent](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Install-CloudWatch-Agent.html) to be installed on the instance - All metric values are rounded to two decimal places ### Example Output ```json { "data": { "avgCpuUsagePercent": 0.18, "avgNetworkInBytesPerSec": 107.25, "avgNetworkOutBytesPerSec": 11.63, "end": "2026-05-29T08:50:49Z", "instanceId": "i-0abc1234567890def", "lookbackPeriod": "7d", "region": "eu-north-1", "start": "2026-05-22T08:50:49Z", "totalNetworkInBytes": 64866070, "totalNetworkOutBytes": 7032351 }, "timestamp": "2026-05-29T08:50:50.657831534Z", "type": "aws.ec2.instance.metrics" } ``` ## EC2 • Manage Elastic IP **Component key:** `aws.ec2.manageElasticIP` The Manage Elastic IP component associates or disassociates an Elastic IP address with an EC2 instance. ### Use Cases - **Static addressing**: Attach a reserved Elastic IP to an instance after launch - **Failover**: Re-associate an Elastic IP to a replacement instance - **Cleanup**: Disassociate an Elastic IP before releasing it ### Configuration - **Region**: AWS region where the Elastic IP and instance reside - **Operation**: Choose **Associate** or **Disassociate** - **Elastic IP** (associate only): The allocated Elastic IP to attach - **Instance** (associate only): EC2 instance to associate the Elastic IP with - **Association** (disassociate only): The active Elastic IP association to remove ### Output Emits operation-specific details on the default output channel: - **Associate**: `associationId`, `allocationId`, `instanceId`, `region` - **Disassociate**: `associationId`, `region` ### Important Notes - The Elastic IP must be allocated before it can be associated - Disassociating is required before releasing an Elastic IP - Re-association to a different instance is allowed when the address is already associated elsewhere ### Example Output ```json { "data": { "allocationId": "eipalloc-0abc1234567890def", "associationId": "eipassoc-0abc1234567890def", "instanceId": "i-0abc1234567890def", "region": "us-east-1" }, "timestamp": "2026-05-21T12:03:00Z", "type": "aws.ec2.elastic-ip.associated" } ``` ## EC2 • Manage Instance Power **Component key:** `aws.ec2.manageInstancePower` The Manage Instance Power component performs power management operations on an EC2 instance. ### Use Cases - **Scheduled workloads**: Start or stop instances on demand from a workflow - **Cost optimisation**: Stop or hibernate non-production instances outside business hours - **Maintenance workflows**: Stop an instance before resizing or patching, start it after - **Recovery**: Reboot an instance experiencing issues ### Configuration - **Region**: AWS region where the instance runs - **Instance**: EC2 instance to manage - **Operation**: The power operation to perform: - **Start**: Start a stopped instance and wait for it to reach running state - **Stop**: Gracefully stop a running instance and wait for stopped state - **Reboot**: Reboot a running instance (completes once the reboot signal is sent) - **Hibernate**: Stop an instance and save RAM to disk (instance must have hibernation enabled) ### Output Emits instance details on the default output channel once the operation completes: - `instanceId`, `state`, `region` - `publicIpAddress`, `privateIpAddress` (start only) ### Important Notes - **Hibernate** requires the instance to have been launched with hibernation enabled - **Reboot** emits immediately after the reboot signal is accepted; it does not wait for the OS to come back online ### Example Output ```json { "data": { "imageId": "ami-0215d085326c25744", "instanceId": "i-0abc1234567890def", "instanceType": "t3.micro", "launchTime": "2026-05-28T09:41:14.000Z", "name": "preview-pr-5", "privateDnsName": "ip-10.0.1.25.eu-north-1.compute.internal", "privateIpAddress": "10.0.1.25", "publicDnsName": "ec2-54-198-10-42.eu-north-1.compute.amazonaws.com", "publicIpAddress": "54.198.10.42", "region": "eu-north-1", "state": "running", "subnetId": "subnet-0e7c8aa9b0a82aec5", "vpcId": "vpc-0049650f5a479c14b" }, "timestamp": "2026-05-28T09:41:26.29656651Z", "type": "aws.ec2.instance.power.started" } ``` ## EC2 • Release Elastic IP **Component key:** `aws.ec2.releaseElasticIP` The Release Elastic IP component releases an allocated Elastic IP address from your AWS account. ### Use Cases - **Cost optimisation**: Release unused Elastic IPs to avoid idle charges - **Cleanup workflows**: Remove temporary addresses after a workflow completes - **Decommissioning**: Release addresses when tearing down infrastructure ### Configuration - **Region**: AWS region where the Elastic IP was allocated - **Elastic IP**: The allocated Elastic IP to release ### Output Emits a release confirmation on the default output channel: - `allocationId`, `region` ### Important Notes - The Elastic IP must be disassociated before it can be released - Released addresses may be allocated to another AWS account and cannot always be recovered ### Example Output ```json { "data": { "allocationId": "eipalloc-0abc1234567890def", "region": "us-east-1" }, "timestamp": "2026-05-21T12:02:00Z", "type": "aws.ec2.elastic-ip.released" } ``` ## EC2 • Update Instance **Component key:** `aws.ec2.updateInstance` The Update Instance component resizes an EC2 instance to a new instance type and/or updates its security groups. ### Use Cases - **Right-sizing**: Scale an instance up or down based on observed utilisation - **Automated resizing**: Use the output of Get Instance Metrics to conditionally resize - **Security posture updates**: Replace the security groups attached to a running instance ### Configuration - **Region**: AWS region where the instance runs - **Instance**: EC2 instance to update - **New Instance Type**: Target instance type (e.g. `t3.medium`). The instance is stopped automatically, resized, and restarted. At least one of this field or Security Groups must be set. - **Security Group**: Replace the instance's security group. Takes effect immediately for VPC instances; does not require a stop/start cycle. - **Restart After Resize**: Whether to start the instance after changing its type (default true). If unchecked the instance remains stopped after the type change. ### Instance Type Change Lifecycle 1. The component records the current state of the instance. 2. If the instance is running it is stopped automatically. 3. Once stopped, `ModifyInstanceAttribute` is called with the new instance type. 4. If the instance was originally running and **Restart After Resize** is enabled, the instance is started again and the component waits for it to reach `running` state. ### Output Emits updated instance details on the default output channel: - `instanceId`, `instanceType`, `state`, `region` - `publicIpAddress`, `privateIpAddress`, `name` ### Example Output ```json { "data": { "imageId": "ami-0215d085326c25744", "instanceId": "i-03976dc68f19ba526", "instanceType": "t3.micro", "keyName": "my-key", "launchTime": "2026-05-29T08:52:02.000Z", "name": "ephemeral-builder", "privateDnsName": "ip-10-0-1-25.ec2.internal", "privateIpAddress": "10.0.1.25", "publicDnsName": "ec2-54-198-10-42.compute-1.amazonaws.com", "publicIpAddress": "54.198.10.42", "region": "eu-north-1", "state": "running", "subnetId": "subnet-0e7c8aa9b0a82aec5", "vpcId": "vpc-0049650f5a479c14b" }, "timestamp": "2026-05-29T08:52:13.71956816Z", "type": "aws.ec2.instance.updated" } ``` ## ECR • Get Image **Component key:** `aws.ecr.getImage` The Get Image component retrieves image metadata from an ECR repository by digest, tag, or both. ### Use Cases - **Release automation**: Fetch image details before deployment - **Audit trails**: Resolve digests and tags for traceability - **Security workflows**: Enrich findings with image metadata ### Configuration - **Region**: AWS region of the ECR repository - **Repository**: ECR repository name or ARN - **Image Digest**: Digest of the image (optional) - **Image Tag**: Tag of the image (optional) At least one of **Image Digest** or **Image Tag** is required. If both are provided, the request includes both. ### Example Output ```json { "data": { "artifactMediaType": "application/vnd.docker.container.image.v1+json", "imageDigest": "sha256:8f1d3e4f5a6b7c8d9e0f11121314151617181920212223242526272829303132", "imageManifestMediaType": "application/vnd.docker.distribution.manifest.v2+json", "imagePushedAt": "2026-02-03T12:00:00Z", "imageSizeInBytes": 48273912, "imageTags": [ "latest", "v1.2.3" ], "registryId": "123456789012", "repositoryName": "my-repo" }, "timestamp": "2026-02-03T12:00:00Z", "type": "aws.ecr.image" } ``` ## ECR • Get Image Scan Findings **Component key:** `aws.ecr.getImageScanFindings` The Get Image Scan Findings component retrieves vulnerability scan results for an ECR image. ### Use Cases - **Security automation**: Pull scan findings to drive alerting or approvals - **Compliance checks**: Validate images against severity thresholds - **Reporting**: Capture scan summaries and findings for audits ### Configuration - **Region**: AWS region of the ECR repository - **Repository**: ECR repository name or ARN - **Image Digest**: Digest of the image (optional) - **Image Tag**: Tag of the image (optional) At least one of **Image Digest** or **Image Tag** is required. If both are provided, the request includes both. ### Example Output ```json { "data": { "imageId": { "imageDigest": "sha256:8f1d3e4f5a6b7c8d9e0f11121314151617181920212223242526272829303132", "imageTag": "latest" }, "imageScanFindings": { "findingSeverityCounts": { "HIGH": 1 }, "findings": [ { "attributes": [ { "key": "package_name", "value": "openssl" }, { "key": "package_version", "value": "1.1.1k" } ], "description": "Example vulnerability in a package.", "name": "CVE-2024-12345", "severity": "HIGH", "uri": "https://example.com/cve-2024-12345" } ], "imageScanCompletedAt": "2026-02-03T12:05:00Z", "vulnerabilitySourceUpdatedAt": "2026-02-03T00:00:00Z" }, "imageScanStatus": { "description": "Scan completed", "status": "COMPLETE" }, "registryId": "123456789012", "repositoryName": "my-repo" }, "timestamp": "2026-02-03T12:05:00Z", "type": "aws.ecr.image.scanFindings" } ``` ## ECR • Scan Image **Component key:** `aws.ecr.scanImage` The Scan Image component scans an ECR image for vulnerabilities. ### Use Cases - **Security automation**: Scan images for vulnerabilities - **Compliance checks**: Validate images against severity thresholds - **Reporting**: Capture scan summaries and findings for audits ### Configuration - **Region**: AWS region of the ECR repository - **Repository**: ECR repository name or ARN - **Image Digest**: Digest of the image (optional) - **Image Tag**: Tag of the image (optional) At least one of **Image Digest** or **Image Tag** is required. If both are provided, the request includes both. ### Example Output ```json { "data": { "imageId": { "imageDigest": "sha256:8f1d3e4f5a6b7c8d9e0f11121314151617181920212223242526272829303132", "imageTag": "latest" }, "imageScanFindings": { "findingSeverityCounts": { "HIGH": 1 }, "findings": [ { "attributes": [ { "key": "package_name", "value": "openssl" }, { "key": "package_version", "value": "1.1.1k" } ], "description": "Example vulnerability in a package.", "name": "CVE-2024-12345", "severity": "HIGH", "uri": "https://example.com/cve-2024-12345" } ], "imageScanCompletedAt": "2026-02-03T12:05:00Z", "vulnerabilitySourceUpdatedAt": "2026-02-03T00:00:00Z" }, "imageScanStatus": { "description": "Scan completed", "status": "COMPLETE" }, "registryId": "123456789012", "repositoryName": "my-repo" }, "timestamp": "2026-02-03T12:05:00Z", "type": "aws.ecr.image.scanFindings" } ``` ## ECS • Create Service **Component key:** `aws.ecs.createService` The Create Service component creates a new ECS service in a cluster. ### Use Cases - **Provisioning workflows**: Create a service during environment setup - **Deployment automation**: Roll out new workloads from workflows - **Infrastructure orchestration**: Configure ECS service settings as part of release pipelines ### Notes - You can pass advanced ECS CreateService fields through **Additional ECS API Arguments**. - Do not combine **Launch Type** with **Capacity Provider Strategy**. ### Example Output ```json { "data": { "service": { "clusterArn": "arn:aws:ecs:us-east-1:111122223333:cluster/superplane-demo-cluster", "createdAt": "2026-02-12T08:15:10Z", "desiredCount": 2, "enableExecuteCommand": true, "launchType": "FARGATE", "pendingCount": 0, "platformVersion": "1.4.0", "propagateTags": "SERVICE", "runningCount": 2, "schedulingStrategy": "REPLICA", "serviceArn": "arn:aws:ecs:us-east-1:111122223333:service/superplane-demo-cluster/superplane-api", "serviceName": "superplane-api", "status": "ACTIVE", "taskDefinition": "arn:aws:ecs:us-east-1:111122223333:task-definition/superplane-api:5", "taskSets": [] } }, "timestamp": "2026-02-12T08:15:32.101112131Z", "type": "aws.ecs.service" } ``` ## ECS • Describe Service **Component key:** `aws.ecs.describeService` The Describe Service component fetches details about a single ECS service. ### Use Cases - **Deployment checks**: Inspect running/desired task counts before or after deployment - **Operational visibility**: Fetch service status and task definition details in workflows - **Automation branching**: Route workflow execution based on ECS service state ### Example Output ```json { "data": { "service": { "clusterArn": "arn:aws:ecs:us-west-1:123456789012:cluster/production-cluster-alpha", "createdAt": "2026-01-20T10:12:33Z", "deployments": [ { "createdAt": "2026-01-20T10:12:33Z", "desiredCount": 3, "id": "ecs-svc/8473629182736450912", "pendingCount": 0, "runningCount": 3, "status": "PRIMARY", "taskDefinition": "arn:aws:ecs:us-west-1:123456789012:task-definition/api-gateway-service:7", "updatedAt": "2026-01-20T10:18:11Z" } ], "desiredCount": 3, "enableExecuteCommand": true, "events": [ { "createdAt": "2026-01-20T10:18:11Z", "id": "d91b5e4a-7a5f-4b1d-bdb4-3d4f8f8a9912", "message": "(service api-gateway-service-prod) has reached a steady state." }, { "createdAt": "2026-01-20T10:17:02Z", "id": "a12f9c47-92c3-4c9f-8d12-88d6ab3f8e72", "message": "(service api-gateway-service-prod) (deployment ecs-svc/8473629182736450912) deployment completed." }, { "createdAt": "2026-01-20T10:13:05Z", "id": "c7a8e3b1-11f2-4fbc-9d8e-2194bb0eaf55", "message": "(service api-gateway-service-prod) has started 3 tasks: (task 9f8e7d6c5b4a3210e1f2a3b4c5d6e7f8)." } ], "launchType": "FARGATE", "networkConfiguration": { "awsvpcConfiguration": { "assignPublicIp": "DISABLED", "securityGroups": [ "sg-0a1b2c3d4e5f6a7b8", "sg-1b2c3d4e5f6a7b8c9" ], "subnets": [ "subnet-01a2b3c4d5e6f7a8b", "subnet-09f8e7d6c5b4a3210" ] } }, "pendingCount": 0, "platformVersion": "1.4.0", "propagateTags": "SERVICE", "runningCount": 3, "schedulingStrategy": "REPLICA", "serviceArn": "arn:aws:ecs:us-west-1:123456789012:service/production-cluster-alpha/api-gateway-service-prod", "serviceName": "api-gateway-service-prod", "status": "ACTIVE", "taskDefinition": "arn:aws:ecs:us-west-1:123456789012:task-definition/api-gateway-service:7", "taskSets": [] } }, "timestamp": "2026-01-20T12:45:09.123456789Z", "type": "aws.ecs.service" } ``` ## ECS • Execute Command **Component key:** `aws.ecs.executeCommand` The Execute Command component runs ECS Exec against a running task container. ### Use Cases - **Operational debugging**: Run diagnostics inside a live task - **Runtime inspection**: Check process state or config from workflows - **Automated remediation**: Trigger one-off commands in containerized services ### Notes - ECS Exec must be enabled and properly configured for the task/service. - Interactive mode opens an ECS session and returns session connection details. ### Example Output ```json { "data": { "command": { "clusterArn": "arn:aws:ecs:us-east-1:111122223333:cluster/superplane-demo-cluster", "containerArn": "arn:aws:ecs:us-east-1:111122223333:container/superplane-demo-cluster/aaaaaaaa11111111bbbbbbbb22222222/2d7f98c1e4d14f98a4d1f36e6f4f5d23", "containerName": "api", "interactive": false, "session": { "sessionId": "ecs-execute-command-0f2ea5a931534f9f8f37f7e706a2c100", "streamUrl": "wss://ssmmessages.us-east-1.amazonaws.com/v1/data-channel/ecs-execute-command-0f2ea5a931534f9f8f37f7e706a2c100?role=publish_subscribe", "tokenValue": "AQoDYXdzEJr//////////wEaDAi4cUd2QqXQwq2NAiD3rWkK9mYc9..." }, "taskArn": "arn:aws:ecs:us-east-1:111122223333:task/superplane-demo-cluster/aaaaaaaa11111111bbbbbbbb22222222" } }, "timestamp": "2026-02-12T09:10:21.445566778Z", "type": "aws.ecs.executeCommand" } ``` ## ECS • Run Task **Component key:** `aws.ecs.runTask` The Run Task component starts one or more ECS tasks and completes based on task lifecycle events. ### Use Cases - **One-off workloads**: Execute ad-hoc jobs on ECS - **Batch processing**: Trigger task runs from workflow events - **Operational automation**: Run remediation or maintenance tasks ### Completion behavior - Always waits for tasks to leave startup states (for example, PENDING) before completing. - If **Timeout (seconds)** is set, waits for all tracked tasks to reach STOPPED, or completes with timeout when that deadline is reached. ### Notes - For Fargate tasks, set **Network Configuration** using the ECS awsvpcConfiguration format. - Use **Capacity Provider Strategy** when you want ECS to choose capacity providers; it cannot be combined with **Launch Type**. ### Example Output ```json { "data": { "failures": [], "tasks": [ { "clusterArn": "arn:aws:ecs:us-east-1:111122223333:cluster/superplane-demo-cluster", "createdAt": "2026-02-10T14:30:01Z", "desiredStatus": "RUNNING", "group": "family:superplane-ecs-task", "lastStatus": "RUNNING", "launchType": "FARGATE", "platformVersion": "1.4.0", "startedBy": "", "stoppedReason": "", "taskArn": "arn:aws:ecs:us-east-1:111122223333:task/superplane-demo-cluster/aaaaaaaa11111111bbbbbbbb22222222", "taskDefinitionArn": "arn:aws:ecs:us-east-1:111122223333:task-definition/superplane-ecs-task:1" } ], "timedOut": false }, "timestamp": "2026-02-10T14:30:37.633534466Z", "type": "aws.ecs.task" } ``` ## ECS • Stop Task **Component key:** `aws.ecs.stopTask` The Stop Task component requests ECS to stop a running task and waits for the task to reach STOPPED. ### Use Cases - **Operational control**: Stop ad-hoc or long-running tasks from workflows - **Remediation**: Terminate unhealthy tasks during automated incident response - **Cost control**: Stop no-longer-needed background workloads ### Notes - ECS sends a SIGTERM signal and then force-stops the task if it does not exit gracefully. - **Reason** is optional and appears in ECS task stop metadata when provided. ### Example Output ```json { "data": { "task": { "clusterArn": "arn:aws:ecs:us-east-1:111122223333:cluster/superplane-demo-cluster", "createdAt": "2026-02-10T14:30:01Z", "desiredStatus": "STOPPED", "group": "family:superplane-ecs-task", "lastStatus": "STOPPED", "launchType": "FARGATE", "platformVersion": "1.4.0", "startedBy": "", "stoppedReason": "stopping", "taskArn": "arn:aws:ecs:us-east-1:111122223333:task/superplane-demo-cluster/aaaaaaaa11111111bbbbbbbb22222222", "taskDefinitionArn": "arn:aws:ecs:us-east-1:111122223333:task-definition/superplane-ecs-task:1" } }, "timestamp": "2026-02-10T14:31:19.987196041Z", "type": "aws.ecs.task" } ``` ## ECS • Update Service **Component key:** `aws.ecs.updateService` The Update Service component updates configuration for an existing ECS service. ### Use Cases - **Deployments**: Roll out a new task definition - **Scaling workflows**: Change desired count dynamically - **Operational tuning**: Update deployment, network, or tag behavior ### Notes - You can pass advanced ECS UpdateService fields through **Additional ECS API Arguments**. - Do not combine **Launch Type** with **Capacity Provider Strategy**. ### Example Output ```json { "data": { "service": { "clusterArn": "arn:aws:ecs:us-east-1:111122223333:cluster/superplane-demo-cluster", "createdAt": "2026-02-12T08:15:10Z", "desiredCount": 3, "enableExecuteCommand": true, "launchType": "FARGATE", "pendingCount": 1, "platformVersion": "1.4.0", "propagateTags": "SERVICE", "runningCount": 2, "schedulingStrategy": "REPLICA", "serviceArn": "arn:aws:ecs:us-east-1:111122223333:service/superplane-demo-cluster/superplane-api", "serviceName": "superplane-api", "status": "ACTIVE", "taskDefinition": "arn:aws:ecs:us-east-1:111122223333:task-definition/superplane-api:6", "taskSets": [] } }, "timestamp": "2026-02-12T09:00:03.987654321Z", "type": "aws.ecs.service" } ``` ## Lambda • Run Function **Component key:** `aws.lambda.runFunction` The Run Lambda component invokes a Lambda function. ### Use Cases - **Automated workflows**: Trigger Lambda functions from SuperPlane workflows - **Event processing**: Process events from other applications - **Data transformation**: Transform data in real-time - **API integrations**: Call Lambda functions from other applications ### How It Works 1. Invokes the specified Lambda function with the provided payload 2. Returns the function's response including status code, payload, and log output 3. Optionally creates a new Lambda function from inline JavaScript code ### Example Output ```json { "data": { "payload": { "message": "hello from lambda" }, "report": { "billedDuration": "100 ms", "duration": "89.81 ms", "initDuration": "160.97 ms", "maxMemoryUsed": "82 MB", "memorySize": "128 MB" }, "requestId": "9f8d2b5e-1c7a-4d62-8f1a-0f8b8e4f3a12" }, "timestamp": "2026-03-26T19:29:35.841265352Z", "type": "aws.lambda.run" } ``` ## Prometheus • Create Workspace **Component key:** `aws.prometheus.createWorkspace` The Create Workspace component creates an Amazon Managed Service for Prometheus workspace. ### Configuration - **Region**: AWS region for the workspace - **Alias**: Optional workspace alias - **KMS Key ARN**: Optional customer managed AWS KMS key ARN for encryption - **Client Token**: Optional idempotency token - **Tags**: Optional workspace tags ### Example Output ```json { "data": { "workspace": { "alias": "example-workspace-created", "arn": "arn:aws:aps:us-east-1:123456789012:workspace/ws-22222222-2222-4222-8222-222222222222", "status": { "statusCode": "CREATING" }, "tags": { "purpose": "example" }, "workspaceId": "ws-22222222-2222-4222-8222-222222222222" } }, "timestamp": "2026-01-01T00:10:00.000000000Z", "type": "aws.prometheus.workspace" } ``` ## Prometheus • Delete Workspace **Component key:** `aws.prometheus.deleteWorkspace` The Delete Workspace component deletes an Amazon Managed Service for Prometheus workspace. ### Notes AWS does not immediately delete metrics data that has already been ingested. It is permanently deleted within one month. ### Configuration - **Region**: AWS region of the workspace - **Workspace**: Target workspace - **Client Token**: Optional idempotency token ### Example Output ```json { "data": { "deleted": true, "workspaceId": "ws-11111111-1111-4111-8111-111111111111" }, "timestamp": "2026-01-01T00:15:00.000000000Z", "type": "aws.prometheus.workspace.deleted" } ``` ## Prometheus • Get Workspace **Component key:** `aws.prometheus.getWorkspace` The Get Workspace component retrieves details for an Amazon Managed Service for Prometheus workspace. ### Configuration - **Region**: AWS region of the workspace - **Workspace**: Target workspace ### Example Output ```json { "data": { "workspace": { "alias": "example-workspace", "arn": "arn:aws:aps:us-east-1:123456789012:workspace/ws-11111111-1111-4111-8111-111111111111", "createdAt": "2026-01-01T00:00:00Z", "prometheusEndpoint": "https://aps-workspaces.us-east-1.amazonaws.com/workspaces/ws-11111111-1111-4111-8111-111111111111/", "status": { "statusCode": "ACTIVE" }, "tags": { "environment": "example" }, "workspaceId": "ws-11111111-1111-4111-8111-111111111111" } }, "timestamp": "2026-01-01T00:05:00.000000000Z", "type": "aws.prometheus.workspace" } ``` ## Prometheus • Query **Component key:** `aws.prometheus.query` The Query component executes an instant PromQL query against an Amazon Managed Service for Prometheus workspace. ### Configuration - **Region**: AWS region of the workspace - **Workspace**: Target workspace - **Query**: Required PromQL expression to evaluate. Example: `up` - **Time**: Optional evaluation timestamp in RFC3339 or Unix format - **Timeout**: Optional query timeout duration - **Query sample thresholds**: Optional warning and error thresholds for query samples processed ### Output Emits one `aws.prometheus.query` payload with the result type and results. ### Example Output ```json { "data": { "result": [ { "metric": { "component": "run_promql_query", "instance": "host.docker.internal:8000" }, "value": [ 1781107045, "94.39090288589495" ] }, { "metric": { "component": "run_promql_range_query", "instance": "host.docker.internal:8000" }, "value": [ 1781107045, "72.52482929121066" ] } ], "resultType": "vector" }, "timestamp": "2026-01-01T00:05:00.000000000Z", "type": "aws.prometheus.query" } ``` ## Prometheus • Query Range **Component key:** `aws.prometheus.queryRange` The Query Range component executes a range PromQL query against an Amazon Managed Service for Prometheus workspace. ### Configuration - **Region**: AWS region of the workspace - **Workspace**: Target workspace - **Query**: Required PromQL expression to evaluate. Example: `up` - **Start**: Required start timestamp in RFC3339 or Unix format. Example: `2026-01-01T00:00:00Z` - **End**: Required end timestamp in RFC3339 or Unix format. Example: `2026-01-02T00:00:00Z` - **Step**: Required query resolution step. Example: `15s` - **Timeout**: Optional query timeout duration - **Query sample thresholds**: Optional warning and error thresholds for query samples processed ### Output Emits one `aws.prometheus.queryRange` payload with the result type and results. ### Example Output ```json { "data": { "result": [ { "metric": { "component": "run_promql_query" }, "values": [ [ 1781102220, "0.620012400248005" ], [ 1781102250, "0.5400108002160044" ], [ 1781105820, "0.48" ] ] } ], "resultType": "matrix" }, "timestamp": "2026-01-01T00:05:00.000000000Z", "type": "aws.prometheus.queryRange" } ``` ## Prometheus • Update Workspace **Component key:** `aws.prometheus.updateWorkspace` The Update Workspace component updates the alias for an Amazon Managed Service for Prometheus workspace. ### Configuration - **Region**: AWS region of the workspace - **Workspace**: Target workspace - **Alias**: New workspace alias - **Client Token**: Optional idempotency token ### Example Output ```json { "data": { "alias": "example-workspace-updated", "updated": true, "workspaceId": "ws-22222222-2222-4222-8222-222222222222" }, "timestamp": "2026-01-01T00:20:00.000000000Z", "type": "aws.prometheus.workspace.updated" } ``` ## Route 53 • Create DNS Record **Component key:** `aws.route53.createRecord` The Create DNS Record component creates a new DNS record in an AWS Route 53 hosted zone. ### Use Cases - **Domain management**: Create DNS records for new services or endpoints - **Automated provisioning**: Set up DNS entries as part of infrastructure workflows - **Multi-environment setup**: Create environment-specific DNS records automatically ### How It Works 1. Connects to AWS Route 53 using the integration credentials 2. Creates a new DNS record in the specified hosted zone 3. Returns the change status and submission timestamp ### Example Output ```json { "data": { "change": { "id": "/change/C1234567890ABC", "status": "INSYNC", "submittedAt": "2026-01-28T10:30:00.000Z" }, "record": { "name": "api.example.com", "type": "A" } }, "timestamp": "2026-01-28T10:30:00.000Z", "type": "aws.route53.change" } ``` ## Route 53 • Delete DNS Record **Component key:** `aws.route53.deleteRecord` The Delete DNS Record component deletes a DNS record from an AWS Route 53 hosted zone. ### Use Cases - **Cleanup**: Remove DNS records when decommissioning services - **Environment teardown**: Delete DNS entries for temporary environments - **Migration**: Remove old DNS records after migrating to new endpoints ### How It Works 1. Connects to AWS Route 53 using the integration credentials 2. Deletes the specified DNS record from the hosted zone 3. The record name, type, TTL, and values must match the existing record exactly 4. Returns the change status and submission timestamp ### Example Output ```json { "data": { "change": { "id": "/change/C5555555555GHI", "status": "INSYNC", "submittedAt": "2026-01-28T10:30:00.000Z" }, "record": { "name": "api.example.com", "type": "A" } }, "timestamp": "2026-01-28T10:30:00.000Z", "type": "aws.route53.change" } ``` ## Route 53 • Upsert DNS Record **Component key:** `aws.route53.upsertRecord` The Upsert DNS Record component creates or updates a DNS record in an AWS Route 53 hosted zone. ### Use Cases - **Idempotent updates**: Safely create or update DNS records without checking existence first - **Rolling deployments**: Update DNS records to point to new infrastructure - **Failover management**: Switch DNS records between primary and secondary endpoints ### How It Works 1. Connects to AWS Route 53 using the integration credentials 2. Creates the DNS record if it doesn't exist, or updates it if it does 3. Returns the change status and submission timestamp ### Example Output ```json { "data": { "change": { "id": "/change/C9876543210DEF", "status": "INSYNC", "submittedAt": "2026-01-28T10:30:00.000Z" }, "record": { "name": "api.example.com", "type": "A" } }, "timestamp": "2026-01-28T10:30:00.000Z", "type": "aws.route53.change" } ``` ## SNS • Create Topic **Component key:** `aws.sns.createTopic` The Create Topic component creates an AWS SNS topic and returns its metadata. ### Use Cases - **Provisioning workflows**: Create topics as part of environment setup - **Automation bootstrap**: Prepare topics before publishing messages - **Self-service operations**: Provision messaging resources on demand ### Example Output ```json { "data": { "attributes": { "DisplayName": "Orders Events", "Owner": "123456789012", "TopicArn": "arn:aws:sns:us-east-1:123456789012:orders-events" }, "contentBasedDeduplication": false, "displayName": "Orders Events", "fifoTopic": false, "name": "orders-events", "owner": "123456789012", "topicArn": "arn:aws:sns:us-east-1:123456789012:orders-events" }, "timestamp": "2026-01-10T10:00:02.000000000Z", "type": "aws.sns.topic" } ``` ## SNS • Delete Topic **Component key:** `aws.sns.deleteTopic` The Delete Topic component deletes an AWS SNS topic. ### Use Cases - **Cleanup workflows**: Remove temporary topics after execution - **Lifecycle management**: Decommission unused messaging resources - **Rollback automation**: Remove topics created in failed provisioning runs ### Example Output ```json { "data": { "deleted": true, "topicArn": "arn:aws:sns:us-east-1:123456789012:orders-events" }, "timestamp": "2026-01-10T10:00:02.000000000Z", "type": "aws.sns.topic.deleted" } ``` ## SNS • Get Subscription **Component key:** `aws.sns.getSubscription` The Get Subscription component retrieves metadata and attributes for an AWS SNS subscription. ### Use Cases - **Subscription audits**: Inspect endpoint and delivery configuration - **Workflow enrichment**: Load subscription metadata before downstream actions - **Validation**: Confirm subscription existence and protocol ### Example Output ```json { "data": { "attributes": { "Endpoint": "https://example.com/sns/events", "Protocol": "https", "RawMessageDelivery": "true", "TopicArn": "arn:aws:sns:us-east-1:123456789012:orders-events" }, "endpoint": "https://example.com/sns/events", "owner": "123456789012", "pendingConfirmation": false, "protocol": "https", "rawMessageDelivery": true, "subscriptionArn": "arn:aws:sns:us-east-1:123456789012:orders-events:7f8a3d50-f160-4d2d-8f8a-fb95d7f86a51", "topicArn": "arn:aws:sns:us-east-1:123456789012:orders-events" }, "timestamp": "2026-01-10T10:00:02.000000000Z", "type": "aws.sns.subscription" } ``` ## SNS • Get Topic **Component key:** `aws.sns.getTopic` The Get Topic component retrieves metadata and attributes for an AWS SNS topic. ### Use Cases - **Configuration audits**: Verify topic settings and attributes - **Workflow enrichment**: Load topic metadata before downstream actions - **Validation**: Confirm topic existence and ownership ### Example Output ```json { "data": { "attributes": { "DisplayName": "Orders Events", "Owner": "123456789012", "TopicArn": "arn:aws:sns:us-east-1:123456789012:orders-events" }, "contentBasedDeduplication": false, "displayName": "Orders Events", "fifoTopic": false, "name": "orders-events", "owner": "123456789012", "topicArn": "arn:aws:sns:us-east-1:123456789012:orders-events" }, "timestamp": "2026-01-10T10:00:02.000000000Z", "type": "aws.sns.topic" } ``` ## SNS • Publish Message **Component key:** `aws.sns.publishMessage` The Publish Message component sends a message to an AWS SNS topic. ### Use Cases - **Event fan-out**: Broadcast workflow results to multiple subscribers - **Notifications**: Send operational updates to users and systems - **Automation**: Trigger downstream subscribers through SNS delivery ### Example Output ```json { "data": { "messageId": "a730a53a-a86d-5fcb-9ad1-ff72b8d0f104", "topicArn": "arn:aws:sns:us-east-1:123456789012:orders-events" }, "timestamp": "2026-01-10T10:00:02.000000000Z", "type": "aws.sns.message.published" } ``` ## SQS • Create Queue **Component key:** `aws.sqs.createQueue` The Create Queue component creates a new AWS SQS queue. ### Configuration - **Region**: AWS region for the SQS queue - **Queue Name**: Name of the queue to create ### Example Output ```json { "data": { "queueName": "my-created-queue", "queueUrl": "https://sqs.us-east-1.amazonaws.com/123456789012/my-created-queue" }, "timestamp": "2026-02-11T12:00:00Z", "type": "aws.sqs.queue" } ``` ## SQS • Delete Queue **Component key:** `aws.sqs.deleteQueue` The Delete Queue component deletes an AWS SQS queue. ### Configuration - **Region**: AWS region of the SQS queue - **Queue**: Target SQS queue to delete ### Example Output ```json { "data": { "deleted": true, "queueUrl": "https://sqs.us-east-1.amazonaws.com/123456789012/my-queue" }, "timestamp": "2026-02-11T12:00:00Z", "type": "aws.sqs.queue.deleted" } ``` ## SQS • Get Queue **Component key:** `aws.sqs.getQueue` The Get Queue component retrieves metadata and attributes for an AWS SQS queue. ### Configuration - **Region**: AWS region of the SQS queue - **Queue**: Target SQS queue ### Example Output ```json { "data": { "attributes": { "DelaySeconds": "0", "MaximumMessageSize": "262144", "MessageRetentionPeriod": "345600", "QueueArn": "arn:aws:sqs:us-east-1:123456789012:my-queue", "ReceiveMessageWaitTimeSeconds": "0", "VisibilityTimeout": "30" }, "queueUrl": "https://sqs.us-east-1.amazonaws.com/123456789012/my-queue" }, "timestamp": "2026-02-11T12:00:00Z", "type": "aws.sqs.queue" } ``` ## SQS • Purge Queue **Component key:** `aws.sqs.purgeQueue` The Purge Queue component removes all messages from an AWS SQS queue. ### Configuration - **Region**: AWS region of the SQS queue - **Queue**: Target SQS queue to purge ### Example Output ```json { "data": { "purged": true, "queueUrl": "https://sqs.us-east-1.amazonaws.com/123456789012/my-queue" }, "timestamp": "2026-02-11T12:00:00Z", "type": "aws.sqs.queue.purged" } ``` ## SQS • Send Message **Component key:** `aws.sqs.sendMessage` The Send Message component publishes a message to an AWS SQS queue. ### Configuration - **Region**: AWS region of the SQS queue - **Queue**: Target SQS queue - **Message Body**: The message payload to send ### Example Output ```json { "data": { "messageId": "d84c1b4d-1f3b-4b6c-9d9f-5c3a2b1f9e7a", "queueUrl": "https://sqs.us-east-1.amazonaws.com/123456789012/my-queue" }, "timestamp": "2026-02-11T12:00:00Z", "type": "aws.sqs.message" } ``` #### Bitbucket Source URL: https://docs.superplane.com/components/bitbucket React to events in your Bitbucket repositories import { CardGrid, LinkCard } from "@astrojs/starlight/components"; ## Triggers ## Instructions To configure Bitbucket with SuperPlane: - **API Token mode**: - Go to **Atlassian Settings → Security → Create API token**. - Select **Bitbucket** App. - Create a token with admin:workspace:bitbucket scope. - **Workspace Access Token mode**: - Go to **Bitbucket Workspace Settings → Security → Access tokens**. - Create a workspace access token. - **Copy the token** and your workspace slug (for example: `my-workspace`) below. ## On Push **Trigger key:** `bitbucket.onPush` The On Push trigger starts a workflow execution when code is pushed to a Bitbucket repository. ### Use Cases - **CI/CD automation**: Trigger builds and deployments on code pushes - **Code quality checks**: Run linting and tests on every push - **Notification workflows**: Send notifications when code is pushed ### Configuration - **Repository**: Select the Bitbucket repository to monitor - **Refs**: Configure which branches to monitor (e.g., `refs/heads/main`) ### Event Data Each push event includes: - **repository**: Repository information - **push.changes**: Array of reference changes with new/old commit details - **actor**: Information about who pushed ### Webhook Setup This trigger automatically sets up a Bitbucket webhook when configured. The webhook is managed by SuperPlane and will be cleaned up when the trigger is removed. ### Example Data ```json { "data": { "actor": { "display_name": "John Doe", "links": { "avatar": { "href": "https://bitbucket.org/account/johndoe/avatar/" }, "html": { "href": "https://bitbucket.org/johndoe/" } }, "nickname": "johndoe", "type": "user", "uuid": "{d301aafa-d676-4ee0-a3f1-8b94c681feaa}" }, "push": { "changes": [ { "closed": false, "commits": [ { "author": { "raw": "John Doe \u003cjohn@example.com\u003e", "type": "author" }, "hash": "709d658dc5b6d6afcd46049c2f332ee3f515a67d", "links": { "html": { "href": "https://bitbucket.org/my-workspace/my-repo/commits/709d658dc5b6d6afcd46049c2f332ee3f515a67d" } }, "message": "Add new feature\n", "type": "commit" } ], "created": false, "forced": false, "new": { "name": "main", "target": { "author": { "raw": "John Doe \u003cjohn@example.com\u003e", "type": "author", "user": { "display_name": "John Doe", "type": "user", "uuid": "{d301aafa-d676-4ee0-a3f1-8b94c681feaa}" } }, "date": "2024-01-15T10:30:00+00:00", "hash": "709d658dc5b6d6afcd46049c2f332ee3f515a67d", "links": { "html": { "href": "https://bitbucket.org/my-workspace/my-repo/commits/709d658dc5b6d6afcd46049c2f332ee3f515a67d" } }, "message": "Add new feature\n", "type": "commit" }, "type": "branch" }, "old": { "name": "main", "target": { "author": { "raw": "John Doe \u003cjohn@example.com\u003e", "type": "author" }, "date": "2024-01-14T15:00:00+00:00", "hash": "1e65c05c1d5171631d92438a13901ca7dae9618c", "message": "Previous commit\n", "type": "commit" }, "type": "branch" }, "truncated": false } ] }, "repository": { "full_name": "my-workspace/my-repo", "links": { "html": { "href": "https://bitbucket.org/my-workspace/my-repo" } }, "name": "my-repo", "type": "repository", "uuid": "{b7f10c3a-2a1e-4c36-af54-7e818f3b6e1d}" } }, "timestamp": "2024-01-15T10:30:00Z", "type": "bitbucket.push" } ``` #### CircleCI Source URL: https://docs.superplane.com/components/circleci Trigger and monitor CircleCI pipelines import { CardGrid, LinkCard } from "@astrojs/starlight/components"; ## Triggers ## Actions ## Instructions Create a Personal API Token in CircleCI → User Settings → Personal API Tokens ## On Workflow Completed **Trigger key:** `circleci.onWorkflowCompleted` Triggers when a CircleCI workflow completes. ### Use Cases - **Workflow chaining**: Start SuperPlane workflows when CircleCI workflows complete - **Status monitoring**: Monitor CI/CD workflow results - **Notifications**: Send alerts when workflows succeed or fail - **Post-processing**: Process artifacts after workflow completion ### Configuration - **Project Slug**: The CircleCI project slug (e.g., gh/username/repo) ### Event Data Each workflow completion event includes: - **workflow**: Workflow information including ID, name, status, and URL - **pipeline**: Parent pipeline information including ID, number, and trigger details - **project**: Project information - **organization**: Organization information ### Webhook Setup This trigger automatically sets up a CircleCI webhook when configured. The webhook is managed by SuperPlane and cleaned up when the trigger is removed. ### Example Data ```json { "data": { "happened_at": "2021-09-01T22:49:34.317Z", "id": "3888f21b-eaa7-38e3-8f3d-75a63bba8895", "pipeline": { "created_at": "2021-09-01T22:49:03.544Z", "id": "1285fe1d-d3a6-44fc-8886-8979558254c4", "number": 130 }, "project": { "id": "84996744-a854-4f5e-aea3-04e2851dc1d2", "name": "repo", "slug": "github/username/repo" }, "type": "workflow-completed", "workflow": { "created_at": "2021-09-01T22:49:03.616Z", "id": "fda08377-fe7e-46b1-8992-3a7aaecac9c3", "name": "build-test-deploy", "status": "success", "stopped_at": "2021-09-01T22:49:34.170Z", "url": "https://app.circleci.com/pipelines/github/username/repo/130/workflows/fda08377-fe7e-46b1-8992-3a7aaecac9c3" } }, "timestamp": "2021-09-01T22:49:34.317Z", "type": "circleci.workflow.completed" } ``` ## Get Flaky Tests **Component key:** `circleci.getFlakyTests` The Get Flaky Tests component identifies flaky tests in a CircleCI project using the Insights API. ### Use Cases - **Test reliability**: Identify tests that pass and fail inconsistently - **CI stability**: Find flaky tests that cause unreliable builds - **Quality improvement**: Prioritize fixing flaky tests for better developer experience ### Configuration - **Project Slug**: CircleCI project slug (e.g., gh/username/repo) ### Output Emits a `circleci.flakyTests` payload with a list of flaky tests and their flakiness data. ### Example Output ```json { "data": { "flakyTests": [ { "classname": "auth_test.go", "file": "pkg/auth/auth_test.go", "jobName": "test", "pipelineName": "build-pipeline", "source": "go", "testName": "TestUserAuthentication", "timesFlaky": 8, "workflowName": "build-test-deploy" }, { "classname": "cache_test.go", "file": "pkg/cache/cache_test.go", "jobName": "test", "pipelineName": "build-pipeline", "source": "go", "testName": "TestCacheInvalidation", "timesFlaky": 3, "workflowName": "build-test-deploy" } ], "totalFlakyTests": 2 }, "timestamp": "2021-09-01T22:55:34.317Z", "type": "circleci.flakyTests" } ``` ## Get Last Workflow **Component key:** `circleci.getLastWorkflow` The Get Last Workflow component retrieves the most recent workflow for a CircleCI project. ### Use Cases - **Latest status check**: Get the most recent workflow to check project health - **Branch monitoring**: Monitor the latest workflow on a specific branch - **Status filtering**: Find the last workflow with a specific status (e.g., last successful build) ### How It Works 1. Fetches recent pipelines for the project (optionally filtered by branch) 2. Iterates through pipelines to find workflows 3. Returns the first workflow matching the optional status filter ### Configuration - **Project Slug**: CircleCI project slug (e.g., gh/username/repo) - **Branch**: Optional branch filter - **Status**: Optional workflow status filter (success, failed, etc.) ### Output Emits a `circleci.workflow` payload with the most recent matching workflow details. ### Example Output ```json { "data": { "createdAt": "2021-09-01T22:49:03.544Z", "id": "fda08377-fe7e-46b1-8992-3a7aaecac9c3", "name": "build-test-deploy", "pipelineId": "1285fe1d-d3a6-44fc-8886-8979558254c4", "status": "success", "stoppedAt": "2021-09-01T22:55:34.317Z" }, "timestamp": "2021-09-01T22:55:34.317Z", "type": "circleci.workflow" } ``` ## Get Recent Workflow Runs **Component key:** `circleci.getRecentWorkflowRuns` The Get Recent Workflow Runs component fetches recent individual runs for a named CircleCI workflow via the Insights API. ### Use Cases - **Workflow health monitoring**: See recent run statuses and durations at a glance - **Performance tracking**: Monitor how long workflow runs take over time - **Branch comparison**: Compare recent runs across branches ### How It Works 1. Calls the CircleCI Insights endpoint for the given project and workflow name 2. Returns a list of individual workflow runs (up to 90 days back) 3. Each run includes its status, duration, branch, timestamps, and credits used ### Configuration - **Project Slug**: CircleCI project slug (e.g., gh/username/repo) - **Workflow Name**: Name of the workflow to fetch runs for - **Branch**: Optional branch filter (defaults to the project's default branch) ### Output Emits a `circleci.workflowRuns` payload containing an array of recent workflow runs with fields like `id`, `status`, `duration`, `branch`, `createdAt`, `stoppedAt`, and `creditsUsed`. ### Example Output ```json { "data": { "runs": [ { "branch": "main", "createdAt": "2021-09-01T22:49:03.544Z", "creditsUsed": 150, "duration": 384, "id": "fda08377-fe7e-46b1-8992-3a7aaecac9c3", "isApproval": false, "status": "success", "stoppedAt": "2021-09-01T22:55:27.544Z" }, { "branch": "main", "createdAt": "2021-08-31T14:22:10.000Z", "creditsUsed": 160, "duration": 412, "id": "b2c3d4e5-f6a7-8901-bcde-f12345678901", "isApproval": false, "status": "failed", "stoppedAt": "2021-08-31T14:29:02.000Z" } ] }, "timestamp": "2021-09-01T22:55:34.317Z", "type": "circleci.workflowRuns" } ``` ## Get Test Metrics **Component key:** `circleci.getTestMetrics` The Get Test Metrics component fetches test performance data from the CircleCI Insights API. ### Use Cases - **Test health monitoring**: Track most failed and slowest tests - **CI optimization**: Identify tests that slow down your pipeline - **Quality tracking**: Monitor test success rates across runs ### Configuration - **Project Slug**: CircleCI project slug (e.g., gh/username/repo) - **Workflow Name**: Name of the workflow to get test metrics for ### Output Emits a `circleci.testMetrics` payload with most failed tests, slowest tests, and test run summaries. ### Example Output ```json { "data": { "mostFailedTests": [ { "classname": "auth_test.go", "failedRuns": 5, "flaky": true, "testName": "TestUserAuthentication", "totalRuns": 42 } ], "slowestTests": [ { "classname": "migration_test.go", "failedRuns": 1, "flaky": false, "p50DurationSecs": 12.5, "testName": "TestDatabaseMigration", "totalRuns": 42 } ], "testRuns": [ { "pipelineNumber": 130, "successRate": 0.95, "testCounts": { "error": 0, "failure": 2, "skipped": 1, "success": 38, "total": 41 }, "workflowId": "fda08377-fe7e-46b1-8992-3a7aaecac9c3" } ], "totalTestRuns": 42 }, "timestamp": "2021-09-01T22:55:34.317Z", "type": "circleci.testMetrics" } ``` ## Get Workflow **Component key:** `circleci.getWorkflow` The Get Workflow component fetches details for a CircleCI workflow. ### Use Cases - **Workflow inspection**: Fetch current workflow status, jobs, and metadata - **Workflow context**: Use workflow fields to drive branching decisions in later steps ### Configuration - **Workflow ID**: The ID of the CircleCI workflow to retrieve (supports expressions) ### Output Emits a `circleci.workflow` payload containing workflow fields like `id`, `name`, `status`, `createdAt`, and `stoppedAt`. ### Example Output ```json { "data": { "createdAt": "2021-09-01T22:49:03.544Z", "id": "fda08377-fe7e-46b1-8992-3a7aaecac9c3", "jobs": [ { "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "jobNumber": 42, "name": "build", "projectSlug": "gh/acme/my-app", "startedAt": "2021-09-01T22:49:05.000Z", "status": "success", "stoppedAt": "2021-09-01T22:52:10.000Z", "type": "build" }, { "id": "b2c3d4e5-f6a7-8901-bcde-f12345678901", "jobNumber": 43, "name": "test", "projectSlug": "gh/acme/my-app", "startedAt": "2021-09-01T22:52:15.000Z", "status": "success", "stoppedAt": "2021-09-01T22:54:30.000Z", "type": "build" } ], "name": "build-test-deploy", "status": "success", "stoppedAt": "2021-09-01T22:55:34.317Z" }, "timestamp": "2021-09-01T22:55:34.317Z", "type": "circleci.workflow" } ``` ## Run Pipeline **Component key:** `circleci.runPipeline` The Run Pipeline component starts a CircleCI pipeline and waits for it to complete. ### Use Cases - **CI/CD orchestration**: Trigger builds and deployments from SuperPlane workflows - **Pipeline automation**: Run CircleCI pipelines as part of workflow automation - **Multi-stage deployments**: Coordinate complex deployment pipelines - **Workflow chaining**: Chain multiple CircleCI workflows together ### How It Works 1. Triggers a CircleCI pipeline with the specified location (branch or tag) and parameters 2. Waits for all workflows in the pipeline to complete (monitored via webhook) 3. Routes execution based on workflow results: - **Success channel**: All workflows completed successfully - **Failed channel**: Any workflow failed or was cancelled ### Configuration - **Project Slug**: CircleCI project slug (e.g., gh/username/repo) - **Location**: Branch or tag to run the pipeline - **Pipeline definition ID**: Find in CircleCI: Project Settings → Project Setup. - **Parameters**: Optional pipeline parameters as key-value pairs (supports expressions) ### Output Channels - **Success**: Emitted when all workflows complete successfully - **Failed**: Emitted when any workflow fails or is cancelled ### Example Output ```json { "data": { "pipeline": { "created_at": "2021-09-01T22:49:03.544Z", "id": "1285fe1d-d3a6-44fc-8886-8979558254c4", "number": 130 }, "workflows": [ { "id": "fda08377-fe7e-46b1-8992-3a7aaecac9c3", "name": "build-test-deploy", "status": "success" } ] }, "timestamp": "2021-09-01T22:49:34.317Z", "type": "circleci.workflow.completed" } ``` #### Claude Source URL: https://docs.superplane.com/components/claude Use Claude models in workflows import { CardGrid, LinkCard } from "@astrojs/starlight/components"; ## Actions ## Instructions To get new Claude API key, go to [platform.claude.com](https://platform.claude.com). ## Run Claude Agent **Component key:** `claude.runAgent` The **Run Claude Agent** component uses [Claude Managed Agents](https://platform.claude.com/docs/en/managed-agents/overview) to start a **session** with a configured agent and environment, sends your task as a **user message**, and waits until the **session** reaches a terminal state (idle or terminated) by polling. Log streaming is not used. ### Prerequisites - A **Claude API key** on the integration. - An **agent** and **environment** already created in the Anthropic API (or Console). This step references them by ID. ### Configuration - **Agent ID** and optional **Version**: the Managed Agent to run (latest, or a pinned version if **Version** is set). - **Environment ID**: The environment the session runs in. - **Prompt**: The user message (task) sent to the agent. - **Vault IDs** (optional): For MCP tools that need vault-backed credentials. ### Output Emits a finished payload with **session** status, **session id**, and the final **agent message** when available so downstream steps can branch or consume the result. For failure cases the status is still emitted when the **session** is *terminated* or the step times out. ### Example Output ```json { "data": { "lastMessage": "Finished the requested task.", "messages": [ "Let me check the documentation...", "Finished the requested task." ], "sessionId": "sess_01ExampleManagedSession", "status": "idle" }, "timestamp": "2026-04-26T12:00:00Z", "type": "claude.runAgent.finished" } ``` ## Text Prompt **Component key:** `claude.textPrompt` The Text Prompt component uses Anthropic's Claude models to generate text responses. ### Use Cases - **Summarization**: Generate summaries of incidents or deployments. - **Code Analysis**: specific code review or PR comments. - **Content Generation**: Create documentation or drafting communications. ### Configuration - **Model**: The Claude model to use (e.g., claude-3-5-sonnet-latest). - **Prompt**: The main user message/instruction. - **System Message**: (Optional) Context to define the assistant's behavior or persona. - **Max Tokens**: (Optional) Limit the length of the generated response. - **Temperature**: (Optional) Control randomness (0.0 to 1.0). ### Output Returns a payload containing: - **text**: The content generated by Claude. - **usage**: Input and output token counts. - **stopReason**: Why the generation ended (e.g., "end_turn", "max_tokens"). - **model**: The specific model version used. ### Notes - Requires a valid Claude API key configured in integration - Response quality and speed depend on the selected model - Token usage is tracked and may incur costs based on your Claude plan ### Example Output ```json { "data": { "id": "msg_01X9JGt5...123456", "model": "claude-3-5-sonnet-latest", "response": { "content": [ { "text": "Here is the summary of the deployment logs you requested...", "type": "text" } ], "id": "msg_01X9JGt5...123456", "model": "claude-3-5-sonnet-latest", "role": "assistant", "stop_reason": "end_turn", "type": "message", "usage": { "input_tokens": 45, "output_tokens": 120 } }, "stopReason": "end_turn", "text": "Here is the summary of the deployment logs you requested...", "usage": { "input_tokens": 45, "output_tokens": 120 } }, "timestamp": "2026-02-06T12:00:00Z", "type": "claude.message" } ``` #### Cloudflare Source URL: https://docs.superplane.com/components/cloudflare Manage Cloudflare zones, rules, and DNS import { CardGrid, LinkCard } from "@astrojs/starlight/components"; ## Triggers ## Actions ## Instructions To connect Cloudflare to SuperPlane: 1. In the [Cloudflare dashboard](https://dash.cloudflare.com/), open the account you want to connect, then go to **Manage Account → Account API Tokens** and click **Create Token → Create Custom Token**. Creating an account-owned token requires **Super Administrator** access on the Cloudflare account. 2. Name the token and keep the first policy scoped to **Entire Account**. Select these permissions: - **Developer Platform** → **Workers KV Storage** → **Edit** - **Developer Platform** → **Workers Scripts** → **Edit** - **Developer Platform** → **Workers** → **Edit** - **Network Services** → **Account Load Balancers** → **Edit** - **Network Services** → **Load Balancing: Monitors and Pools** → **Edit** - **Account & Billing** → **Notifications** → **Edit** - **Account & Billing** → **Account Settings** → **Edit** - **Cloudflare One** → **Cloudflare Tunnel** → **Edit** 3. Click **Add policy**. In the new policy, change the scope dropdown from **Entire Account** to **All Domains** or **Specified Domains** for only the domains SuperPlane should manage. The DNS and zone rows below are only available after switching this policy to a domain scope: - **DNS & Zones** → **Zone** → **Read** - **DNS & Zones** → **DNS** → **Edit** - **Caching** → **Cache Purge** → **Purge** - **SSL and Certificates** → **SSL and Certificates** → **Edit** - **Rules & Configuration** → **Dynamic URL Redirects** → **Edit** - **Rules & Configuration** → **Origin** → **Edit** - **Developer Platform** → **Workers Routes** → **Edit** - **Network Services** → **Zone Load Balancers** → **Edit** 4. Optionally set an expiration date, review, create the token, and paste the generated token below. Cloudflare only shows the token once. 5. Copy the **Account ID** from the same account's home page right sidebar and paste it into **Account ID** below. ## On Load Balancing Health Alert **Trigger key:** `cloudflare.onLoadBalancingHealthAlert` The On Load Balancing Health Alert trigger starts a workflow from Cloudflare Load Balancing health notifications. ### Use Cases - **Pool unhealthy**: React when a load balancer pool becomes unhealthy - **Origin unhealthy**: Notify or remediate when an endpoint/origin fails health checks - **Failover awareness**: Detect health changes that cause Cloudflare to route traffic away from unhealthy pools ### Configuration - **Pool**: Optional pool filter. Leave empty to listen across pools available to the account. - **New Health**: Health states to listen for. Defaults to `Unhealthy`. - **Event Source**: Listen for pool events, origin events, or both. ### Webhook Setup SuperPlane automatically creates a Cloudflare Alerting webhook destination and notification policy for `load_balancing_health_alert`. Cloudflare signs requests with the generated webhook secret and SuperPlane verifies the `cf-webhook-auth` header before emitting an event. ### Workflow execution details In the workflow execution chain, the trigger's **Details** tab lists: - **Triggered At**: When SuperPlane recorded the webhook event. - **Alert Type**: For example `load_balancing_health_alert`. - **Event Source**: `pool` or `origin`. - **New Health**: The health state in the notification (for example `Unhealthy`). - **Pool**: Pool name when Cloudflare sends it; otherwise the pool ID. The trigger **title** still prefers an origin name, then pool name, then load balancer name when those fields are present in the payload. Use the **Payload** tab (or expressions such as `$.trigger.data`) for every field Cloudflare sends, including **origin name**, **load balancer id/name**, and **account id**. ### Example Data ```json { "data": { "account_id": "account_abc123", "alert_type": "load_balancing_health_alert", "event_source": "origin", "load_balancer_id": "lb_123", "load_balancer_name": "api.example.com", "new_health": "Unhealthy", "origin_name": "api-primary", "pool_id": "pool_xyz789", "pool_name": "Production pool" }, "timestamp": "2026-03-26T19:29:35.841265352Z", "type": "cloudflare.loadBalancing.healthAlert" } ``` ## On Tunnel Health **Trigger key:** `cloudflare.onTunnelHealth` The On Tunnel Health trigger starts a workflow from Cloudflare `tunnel_health_event` notifications (Cloudflare Tunnel / cloudflared). ### Use Cases - **Degraded or down**: React when tunnel connectivity drops below healthy thresholds - **Recovery**: Resume normal processing when the tunnel returns to a healthy state ### Configuration - **Tunnel**: Optional. SuperPlane adds this tunnel to the Cloudflare notification policy **and** requires the webhook payload's `tunnel_id` to match (case-insensitive), so a mis-scoped or forged request is less likely to start your workflow. Leave **Tunnel** empty to accept any tunnel on the account (policy and webhook checks both allow any tunnel id present in the payload). > **Note**: Cloudflare's **Send test** notification may include a sample `tunnel_id` that does not match your real tunnel. With a tunnel selected, that test delivery will not emit until you clear the tunnel filter or use a payload that matches your tunnel id. ### Webhook Setup SuperPlane provisions a Cloudflare Alerting webhook destination and a notification policy for `tunnel_health_event`. Cloudflare signs requests with the generated webhook secret and SuperPlane verifies the `cf-webhook-auth` header before emitting an event. ### Workflow execution details The trigger **Payload** tab (and expressions such as `$.trigger.data`) use a merged view of the webhook JSON: fields inside `data` are combined with top-level fields (for example `alert_type`, `account_id`) so everything is available in one object. ### Example Data ```json { "data": { "account_id": "90ddd046-218b-d375-f20e-9f9082cc0c6d", "alert_name": "tunnel_health_event", "alert_type": "tunnel_health_event", "dashboard_link": "dash.cloudflare.com/aBcD1234efgh567i890j1kl234567m89", "name": "SuperPlane Tunnel Health Alert", "new_status": "TUNNEL_STATUS_TYPE_DEGRADED", "policy_id": "fe9eda012119414084b1c9ffc9a1e2c9", "policy_name": "SuperPlane Tunnel Health Alert", "severity": "INFO", "status_reason": "status change", "text": "A Cloudflare Tunnel in your account has changed its connection status.\nTunnel: tunnel-name (aBcD1234efgh567i890j1kl234567m80) \nNew status: TUNNEL_STATUS_TYPE_DEGRADED (status change)", "timestamp": "2022-10-27T06:00:22Z", "ts": 1778597408, "tunnel_id": "aBcD1234efgh567i890j1kl234567m80", "tunnel_name": "tunnel-name" }, "timestamp": "2026-05-12T14:50:14.036687251Z", "type": "cloudflare.tunnel.healthEvent" } ``` ## Create DNS Record **Component key:** `cloudflare.createDnsRecord` The Create DNS Record component creates a DNS record in a Cloudflare zone. ### Use Cases - **Provisioning**: Add records when new environments are created - **Verification**: Create TXT or CNAME records for domain ownership checks - **Releases**: Add or update canary or migration records ### Configuration - **Zone**: Select the Cloudflare zone or enter a domain name - **Type**: DNS record type (A, AAAA, CNAME, MX, TXT, NS, etc.) - **Name**: Record name (e.g., `www`, `api`, or `@` for apex) - **Content**: Record value (IP, hostname, or text) - **TTL**: Time-to-live in seconds (use `1` for auto) - **Proxied**: Proxy through Cloudflare (A, AAAA, CNAME only) - **Priority**: Priority value (MX or SRV only) ### Output Emits the created DNS record on the default channel. If the zone is not found, the record is invalid, or a duplicate exists, the run fails. ### Example Output ```json { "data": { "content": "192.0.2.1", "id": "record_abc123", "name": "api.example.com", "proxied": false, "ttl": 1, "type": "A" }, "timestamp": "2026-03-26T19:29:35.841265352Z", "type": "cloudflare.dnsRecord" } ``` ## Create KV Namespace **Component key:** `cloudflare.createKVNamespace` The Create KV Namespace component creates a new Cloudflare Workers KV namespace. ### Use Cases - **Feature flags**: Provision a dedicated namespace to store feature flag state - **Session storage**: Create a namespace for application session data - **Configuration store**: Set up a namespace for dynamic configuration values ### Configuration - **Title**: A human-readable name for the namespace (must be unique per account) ### Output Returns the created namespace with its assigned ID and title. ### Example Output ```json { "data": { "accountId": "90ddd046218bd375f20e9f9082cc0c6d", "namespace": { "id": "0f2ac74b498b48028cb68387c421e279", "supports_url_encoding": true, "title": "my-kv-namespace" } }, "timestamp": "2026-05-05T06:54:57.198268018Z", "type": "cloudflare.kv.namespace.created" } ``` ## Create Load Balancer **Component key:** `cloudflare.createLoadBalancer` The Create Load Balancer component creates a new Cloudflare Load Balancer attached to a zone. ### Use Cases - **Traffic distribution**: Route traffic across multiple origin pools - **Blue/green deployments**: Create a load balancer backed by your new (green) pool - **Multi-region failover**: Define ordered pools with a fallback for automatic failover ### Configuration - **Zone**: The zone to attach the load balancer to - **Name**: The hostname of the load balancer (e.g. `lb.example.com`) - **Fallback Pool**: Pool to use when all default pools are unhealthy - **Default Pools**: Ordered list of pools to route traffic to - **Steering Policy**: How traffic is distributed across pools - **Session Affinity**: How client sessions are pinned to a pool - **Pool Weights**: Per-pool weights used when steering policy is set to Random ### Output Returns the created load balancer with its assigned ID and full configuration. ### Example Output ```json { "data": { "loadBalancer": { "default_pools": [ "64d858d71f1e9839fdfb0d2ca78951f5" ], "description": "description", "enabled": true, "fallback_pool": "64d858d71f1e9839fdfb0d2ca78951f5", "id": "f7adb491a20dcab2e29a3141f2f197f7", "name": "example.org", "networks": [ "cloudflare" ], "proxied": true, "random_steering": { "default_weight": 1 }, "session_affinity": "none", "session_affinity_attributes": { "samesite": "Auto", "secure": "Auto", "zero_downtime_failover": "none" }, "steering_policy": "random", "ttl": 30 }, "zoneId": "8132be7b33d9dc874ee6da0fa112945b" }, "timestamp": "2026-05-05T13:00:33.465739808Z", "type": "cloudflare.loadBalancer.created" } ``` ## Create Monitor **Component key:** `cloudflare.createMonitor` The Create Monitor component creates a Cloudflare Load Balancing health monitor. ### Use Cases - **Health checks**: Monitor HTTP, HTTPS, TCP, ICMP, UDP, or SMTP endpoints - **Failover**: Attach the new monitor to a pool so unhealthy origins are removed from load balancer rotation - **Release safety**: Create monitor definitions as part of load balancing setup automation ### Configuration - **Name / Type / Path / Port**: Basic monitor settings. Path is required for HTTP and HTTPS monitors. Port is required for HTTP, HTTPS, TCP, UDP ICMP, and SMTP monitors. - **Advanced Health Check Settings**: Optional method, expected response, headers, redirects, TLS, probe zone, **interval** and **timeout** (seconds; omit both to let Cloudflare pick plan defaults), **retries**, and consecutive thresholds. Plan minimum interval: Pro 60s, Business 15s, Enterprise 10s. - **Pool**: Optional pool to attach the created monitor to immediately. ### Output Emits the created monitor and, when configured, the attached pool. ### Example Output ```json { "data": { "accountId": "account_abc123", "monitor": { "consecutive_down": 3, "consecutive_up": 2, "description": "Login page monitor", "expected_codes": "2xx", "id": "monitor_abc123", "interval": 60, "method": "GET", "path": "/health", "retries": 0, "timeout": 5, "type": "https" }, "monitorId": "monitor_abc123", "pool": { "id": "pool_xyz789", "monitor": "monitor_abc123", "name": "Production pool" }, "poolId": "pool_xyz789" }, "timestamp": "2026-03-26T19:29:35.841265352Z", "type": "cloudflare.monitor.created" } ``` ## Create Origin Rule **Component key:** `cloudflare.createOriginRule` The Create Origin Rule component creates a Cloudflare origin rule that routes matching requests to a different origin server. ### Configuration - **Zone**: Select the Cloudflare zone where the rule should run - **Apply To**: Apply to all incoming requests or build a custom filter - **Match Rules**: Field/operator/value predicates used to build the Cloudflare expression - **DNS Record**: Optional hostname Cloudflare should resolve and route to - **Destination Port**: Optional destination port override - **Host Header**: Optional HTTP Host header override - **SNI**: Optional SNI override - **Enabled**: Whether the rule is active ### Output Emits the created origin rule on the default channel. ### Example Output ```json { "data": { "rule": { "action": "route", "action_parameters": { "host_header": "api.example.com", "origin": { "host": "api-origin.example.com", "port": 8443 } }, "description": "Route API requests", "enabled": true, "expression": "starts_with(http.request.uri.path, \"/api/\")", "id": "rule123" }, "zoneId": "zone123" }, "timestamp": "2026-05-06T12:00:00Z", "type": "cloudflare.createOriginRule" } ``` ## Create Pool **Component key:** `cloudflare.createPool` The Create Pool component creates a new Cloudflare Load Balancer origin pool. ### Use Cases - **Canary deployments**: Provision a new origin pool for a canary release - **Blue/green deployments**: Create the green pool before switching traffic - **Multi-region**: Add origin servers in new regions ### Configuration - **Name**: A unique, human-readable name for the pool - **Description**: Optional description - **Origins**: List of origin servers with name, address, enabled flag, weight, optional port, and optional coordinates - **Enabled**: Whether the pool is active - **Minimum Origins**: Minimum number of healthy origins before marking pool unhealthy - **Origin Steering Policy**: How requests are distributed across origins - **Monitor**: (Optional) Health monitor to use for origin health checks - **Load Shedding**: (Optional) Configure load shedding for the pool ### Output Returns the created origin pool with its assigned ID and full configuration. ### Example Output ```json { "data": { "accountId": "90ddd046218bd375f20e9f9082cc0c6d", "pool": { "description": "my pool", "enabled": true, "id": "483e85c07a861ae7a8813ef010be7036", "minimum_origins": 1, "name": "my-pool", "origin_steering": { "policy": "random" }, "origins": [ { "address": "192.0.2.1", "enabled": true, "name": "server-1", "port": 2013, "weight": 1 } ] } }, "timestamp": "2026-05-05T06:54:57.198268018Z", "type": "cloudflare.pool.created" } ``` ## Create Tunnel **Component key:** `cloudflare.createTunnel` The Create Tunnel component provisions a Cloudflare Tunnel under your account. ### Use Cases - **Expose internal services**: Pair with ingress rules so private origins are reachable through Cloudflare without opening inbound firewall ports - **Automation**: Create tunnels as part of environment provisioning ### Configuration - **Name**: A unique name for the tunnel - **Config source**: `cloudflare` (managed in Zero Trust) or `local` (managed via local cloudflared configuration) ### Output Returns the tunnel resource from the Cloudflare API, including its ID. When Cloudflare returns a connector token, it is included in the output (treat it as a secret). > **Note**: Deleting a tunnel does not automatically remove all public hostname routes; use Cloudflare Zero Trust or DNS workflows as needed. ### Example Output ```json { "data": { "accountId": "90ddd046218bd375f20e9f9082cc0c6d", "tunnel": { "account_tag": "90ddd046218bd375f20e9f9082cc0c6d", "config_src": "cloudflare", "created_at": "2026-05-12T14:40:05.379813Z", "id": "432c983d-7934-47a8-923f-bfa017eef9c4", "metadata": {}, "name": "my-test-tunnel", "status": "inactive", "token": "eyJhIjoiOTBkZGQwNDYyMThiZDM3NWYy...rTE0rM1hHaHhNMEVpa0QvK2RacE0xQUM1N1dHZEVHMHZxS1h4SHV1UER3PT0ifQ==" }, "tunnelId": "432c983d-7934-47a8-923f-bfa017eef9c4" }, "timestamp": "2026-05-12T14:40:06.391597638Z", "type": "cloudflare.tunnel.created" } ``` ## Delete Certificate Pack **Component key:** `cloudflare.deleteCertificatePack` The Delete Certificate Pack component removes a custom SSL/TLS certificate pack from a Cloudflare zone. ### Use Cases - **Environment teardown**: Remove certificates issued for preview environments when they are decommissioned - **Certificate rotation**: Delete old certificate packs as part of a renewal workflow - **Cleanup**: Remove certificates that failed validation or are no longer needed ### Configuration - **Certificate Pack**: The certificate pack to delete (shown as `zone/pack-id`). Can be set from a prior Order Certificate Pack component via an expression. ### Output Emits the deleted pack ID, resolved zone ID, zone name when known from integration metadata, certificate hostnames when returned by the Cloudflare API (before deletion), and `deleted: true`. ### Example Output ```json { "data": { "deleted": true, "hosts": [ "preview-123.example.com" ], "packId": "cc15b64a-e432-4210-a51d-b7042fd55ac0", "zoneId": "abc123def456abc123def456abc12345", "zoneName": "example.com" }, "timestamp": "2026-05-11T10:00:00.000000000Z", "type": "cloudflare.certificate_pack.deleted" } ``` ## Delete DNS Record **Component key:** `cloudflare.deleteDnsRecord` The Delete DNS Record component removes a DNS record from a Cloudflare zone. ### Use Cases - **Deprovisioning**: Remove DNS records when services or environments are torn down - **Cleanup**: Delete temporary verification records (e.g. migration or certificate validation) - **Maintenance**: Remove stale or incorrect records as part of workflow automation ### Configuration - **Record**: Select the DNS record to delete (e.g. zone-id/record-id or record name) ### Output Emits the deleted DNS record (zoneId, recordId, record) on the default channel. If the record is not found or deletion fails, the component goes to an error state and does not emit. ### Example Output ```json { "data": { "record": { "content": "example.com", "id": "record_abc123", "name": "app.example.com", "proxied": false, "ttl": 360, "type": "CNAME" }, "recordId": "record_abc123", "zoneId": "zone_xyz789" }, "timestamp": "2026-03-26T19:29:35.841265352Z", "type": "cloudflare.dnsRecord" } ``` ## Delete KV Namespace **Component key:** `cloudflare.deleteKVNamespace` The Delete KV Namespace component permanently removes a Cloudflare Workers KV namespace and all of its key-value pairs. ### Use Cases - **Environment teardown**: Remove namespaces as part of infrastructure cleanup - **Pipeline cleanup**: Delete temporary namespaces created during a workflow ### Configuration - **Namespace**: The KV namespace to delete ### Output Emits a confirmation with the account ID, namespace ID, and a deleted flag. > **Warning**: This operation is irreversible. All keys stored in the namespace will be permanently deleted. ### Example Output ```json { "data": { "accountId": "90ddd046218bd375f20e9f9082cc0c6d", "deleted": true, "namespace": { "id": "8cc7c421092f456389b23bac8c6b609c" } }, "timestamp": "2026-05-07T05:56:34.511115884Z", "type": "cloudflare.kv.namespace.deleted" } ``` ## Delete KV Value **Component key:** `cloudflare.deleteKVValue` The Delete KV Value component removes a key-value pair from a Cloudflare Workers KV namespace. ### Use Cases - **Cleanup**: Remove stale keys as part of a teardown workflow - **Feature flag rollback**: Delete a flag to revert to default behaviour - **Session invalidation**: Remove session keys to force re-authentication ### Configuration - **Namespace**: The ID of the KV namespace to delete from - **Key**: The key to delete ### Output Emits a confirmation with the account ID, namespace ID, and key that was deleted. > **Warning**: This operation is irreversible. The key and its value will be permanently removed. ### Example Output ```json { "data": { "accountId": "90ddd046218bd375f20e9f9082cc0c6d", "deleted": true, "key": "my-key", "namespaceId": "0f2ac74b498b48028cb68387c421e279" }, "timestamp": "2026-05-05T06:54:57.198268018Z", "type": "cloudflare.kv.value.deleted" } ``` ## Delete Load Balancer **Component key:** `cloudflare.deleteLoadBalancer` The Delete Load Balancer component permanently removes a Cloudflare Load Balancer from a zone. ### Use Cases - **Teardown**: Remove a load balancer as part of environment cleanup - **Blue/green decommission**: Delete the old load balancer after traffic has been fully migrated ### Configuration - **Load Balancer**: The load balancer to delete ### Output Emits a confirmation with the zone ID and load balancer ID of the deleted load balancer. > **Warning**: This operation is irreversible. Deleting the load balancer will immediately stop routing traffic through it. ### Example Output ```json { "data": { "deleted": true, "loadBalancerId": "699d98642c564d2e855e9661899b7252", "zoneId": "023e105f4ecef8ad9ca31a8372d0c353" }, "timestamp": "2026-05-05T06:54:57.198268018Z", "type": "cloudflare.loadBalancer.deleted" } ``` ## Delete Monitor **Component key:** `cloudflare.deleteMonitor` The Delete Monitor component removes a Cloudflare Load Balancing health monitor. ### Use Cases - **Cleanup**: Delete monitor definitions when load balancing resources are decommissioned - **Rollback**: Remove monitors created during test or migration workflows ### Configuration - **Monitor**: The monitor to delete. - **Force**: Delete even when Cloudflare reports that pools or other resources reference the monitor. ### Output Emits the deleted monitor ID and any references Cloudflare reported before deletion. ### Example Output ```json { "data": { "accountId": "account_abc123", "deleted": true, "monitorId": "monitor_abc123", "references": [] }, "timestamp": "2026-03-26T19:29:35.841265352Z", "type": "cloudflare.monitor.deleted" } ``` ## Delete Origin Rule **Component key:** `cloudflare.deleteOriginRule` The Delete Origin Rule component removes a Cloudflare origin rule from a zone. ### Configuration - **Rule**: Select the origin rule to delete ### Output Emits the deleted origin rule on the default channel. ### Example Output ```json { "data": { "rule": { "action": "route", "action_parameters": { "origin": { "host": "api-origin.example.com" } }, "description": "Route API requests", "enabled": true, "expression": "starts_with(http.request.uri.path, \"/api/\")", "id": "rule123" }, "zoneId": "zone123" }, "timestamp": "2026-05-06T12:00:00Z", "type": "cloudflare.deleteOriginRule" } ``` ## Delete Pool **Component key:** `cloudflare.deletePool` The Delete Pool component permanently removes a Cloudflare Load Balancer origin pool. ### Use Cases - **Blue/green deployments**: Clean up the old (blue) pool after traffic has shifted - **Environment teardown**: Remove pools as part of infrastructure cleanup ### Configuration - **Pool ID**: The origin pool to delete ### Output Emits a confirmation with the account ID and pool ID of the deleted pool. > **Warning**: This operation is irreversible. Ensure the pool is not attached to any load balancer before deleting. ### Example Output ```json { "data": { "accountId": "90ddd046218bd375f20e9f9082cc0c6d", "deleted": true, "poolId": "f7be7edc94014415ba06bca7b13c5c5a" }, "timestamp": "2026-05-05T05:59:02.93536262Z", "type": "cloudflare.pool.deleted" } ``` ## Delete Tunnel **Component key:** `cloudflare.deleteTunnel` The Delete Tunnel component permanently removes a Cloudflare Tunnel. ### Use Cases - **Teardown**: Remove tunnels when an environment is decommissioned - **Rotation**: Delete an old tunnel after migrating to a new one ### Configuration - **Tunnel**: The tunnel ID to delete ### Output Emits confirmation with the account ID and tunnel ID. > **Warning**: This operation is irreversible. Active traffic using the tunnel will fail until reconfigured. ### Example Output ```json { "data": { "accountId": "90ddd046218bd375f20e9f9082cc0c6d", "deleted": true, "tunnelId": "3c683924-6802-47c9-860a-f27a66e684a2" }, "timestamp": "2026-05-12T14:02:15.319225119Z", "type": "cloudflare.tunnel.deleted" } ``` ## Delete Worker **Component key:** `cloudflare.deleteWorker` The Delete Worker component removes a Worker script. ### Configuration - **Worker Script**: Worker to delete (picker lists scripts for the account). - **Force**: When enabled, Cloudflare deletes the script even when blocked by bindings (see Cloudflare API `force` query parameter). ### Output Emits the account ID and Worker Script that were deleted. > **Warning**: This operation is irreversible for the Worker script. ### Example Output ```json { "data": { "accountId": "90ddd046218bd375f20e9f9082cc0c6d", "deleted": true, "workerScript": "my-worker" }, "timestamp": "2026-05-05T12:00:00.000000000Z", "type": "cloudflare.worker.deleted" } ``` ## Deploy Worker **Component key:** `cloudflare.deployWorker` The Deploy Worker component uploads a single-module Worker (`worker.js`) to a **Worker script name** in your account. When **Provision Worker if missing** is enabled (default), it first calls Cloudflare's Create Worker API so a **new** name works without a separate step. After upload, SuperPlane always creates a **deployment** so the new version serves 100% of traffic (`cloudflare.worker.deployed`). ### Script source - **Inline**: paste the full contents of `worker.js` (ES module exporting `fetch`). - **URL**: provide an **https** URL that returns the script body (max 2 MiB). ### Configuration - **Worker script name**: Name of the Worker in your account (same name used in routes and the dashboard). Used for both provisioning and upload. - **Provision Worker if missing** (default on): Calls `POST .../workers/workers` with the optional metadata fields in **Provision settings** when that section is visible. If the Worker already exists, the error is ignored and upload continues. - **Provision settings** (optional): Tags, Logpush, Observability, Subdomain, Tail consumers — sent only on the provision step when it runs; omit toggles to leave those keys out of the API request. - **Compatibility date** (optional): Passed to the **script upload** metadata. If omitted, SuperPlane sends a recent default so Cloudflare treats the upload as a modern module Worker. - **Compatibility flags** (optional): comma- or newline-separated flags for the upload metadata. - **Deployment message** (optional): annotation stored on the deployment. ### Output Emits the account ID, script name, new version ID, and deployment object. ### Example Output ```json { "data": { "accountId": "90ddd046218bd375f20e9f9082cc0c6d", "deployment": { "created_on": "2026-05-05T12:00:00Z", "id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", "source": "api", "strategy": "percentage", "versions": [ { "percentage": 100, "version_id": "18f97339-c287-4872-9bdd-e2135c07ec12" } ] }, "scriptName": "my-worker", "versionId": "18f97339-c287-4872-9bdd-e2135c07ec12" }, "timestamp": "2026-05-05T12:00:00.000000000Z", "type": "cloudflare.worker.deployed" } ``` ## Get KV Value **Component key:** `cloudflare.getKVValue` The Get KV Value component reads a value by key from a Cloudflare Workers KV namespace. ### Use Cases - **Feature flag checks**: Read a feature flag value before proceeding - **Configuration lookup**: Retrieve dynamic configuration at workflow runtime - **Audit**: Capture the current value of a key as part of a pipeline snapshot ### Configuration - **Namespace**: The ID of the KV namespace to read from - **Key**: The key to retrieve ### Output Returns the account ID, namespace ID, key, and the retrieved value string. ### Example Output ```json { "data": { "accountId": "90ddd046218bd375f20e9f9082cc0c6d", "key": "my-key", "namespaceId": "0f2ac74b498b48028cb68387c421e279", "value": "my-value" }, "timestamp": "2026-05-05T06:54:57.198268018Z", "type": "cloudflare.kv.value.fetched" } ``` ## Get Load Balancer **Component key:** `cloudflare.getLoadBalancer` The Get Load Balancer component fetches the current state of a Cloudflare Load Balancer. ### Use Cases - **Pre-flight validation**: Confirm a load balancer exists before updating it - **Audit**: Capture a snapshot of the load balancer configuration at a point in time - **Conditional logic**: Branch a workflow based on the current steering policy or pool set ### Configuration - **Load Balancer**: The load balancer to retrieve ### Output Returns the full load balancer configuration including pools, steering policy, and session affinity settings. ### Example Output ```json { "data": { "loadBalancer": { "default_pools": [ "17b5962d775c646f3f9725cbc7a53df4" ], "description": "Example load balancer", "enabled": true, "fallback_pool": "17b5962d775c646f3f9725cbc7a53df4", "id": "699d98642c564d2e855e9661899b7252", "name": "lb.example.com", "proxied": true, "session_affinity": "none", "steering_policy": "random" }, "loadBalancerId": "699d98642c564d2e855e9661899b7252", "zoneId": "023e105f4ecef8ad9ca31a8372d0c353" }, "timestamp": "2026-05-05T06:54:57.198268018Z", "type": "cloudflare.loadBalancer.fetched" } ``` ## Get Monitor **Component key:** `cloudflare.getMonitor` The Get Monitor component fetches the current configuration of a Cloudflare Load Balancing health monitor. ### Use Cases - **Pre-flight validation**: Confirm a monitor exists and inspect its configuration before modifying it - **Audit**: Capture a snapshot of monitor settings at a point in time - **Workflow data**: Expose monitor configuration as payload data for downstream nodes ### Configuration - **Monitor**: The health monitor to retrieve ### Output Returns the full monitor configuration including type, path, port, intervals, and health thresholds. ### Example Output ```json { "data": { "accountId": "account_abc123", "monitor": { "consecutive_down": 3, "consecutive_up": 2, "description": "Login page monitor", "expected_codes": "2xx", "id": "monitor_abc123", "interval": 60, "method": "GET", "path": "/health", "port": 443, "retries": 0, "timeout": 5, "type": "https" }, "monitorId": "monitor_abc123" }, "timestamp": "2026-05-11T10:00:00.000000000Z", "type": "cloudflare.monitor.fetched" } ``` ## Get Pool **Component key:** `cloudflare.getPool` The Get Pool component fetches the current state of a Cloudflare Load Balancer origin pool. ### Use Cases - **Health checks**: Inspect origin health and pool status in a workflow - **Pre-flight validation**: Confirm a pool exists before updating it - **Audit**: Capture a snapshot of pool configuration at a point in time ### Configuration - **Pool ID**: The origin pool to retrieve ### Output Returns the full pool configuration including its origins, enabled state, and health monitor. ### Example Output ```json { "data": { "accountId": "90ddd046218bd375f20e9f9082cc0c6d", "pool": { "description": "my updated pool", "enabled": true, "id": "f7be7edc94014415ba06bca7b13c5c5a", "minimum_origins": 1, "name": "my-updated-pool", "origin_steering": { "policy": "random" }, "origins": [ { "address": "192.0.2.1:2015", "enabled": false, "name": "server-1", "weight": 1 } ] }, "poolId": "f7be7edc94014415ba06bca7b13c5c5a" }, "timestamp": "2026-05-05T05:58:40.060373991Z", "type": "cloudflare.pool.fetched" } ``` ## Get Tunnel **Component key:** `cloudflare.getTunnel` The Get Tunnel component fetches the current state of a Cloudflare Tunnel (cloudflared). ### Use Cases - **Health and status checks**: Inspect tunnel status in a workflow - **Validation**: Confirm a tunnel exists before updating routes or DNS ### Configuration - **Tunnel**: The tunnel ID to retrieve ### Output Returns the tunnel object from the Cloudflare API (ID, name, status, config source, timestamps, and related fields). ### Example Output ```json { "data": { "accountId": "90ddd046218bd375f20e9f9082cc0c6d", "tunnel": { "account_tag": "90ddd046218bd375f20e9f9082cc0c6d", "config_src": "local", "created_at": "2026-05-12T13:59:00.953876Z", "id": "3c683924-6802-47c9-860a-f27a66e684a2", "metadata": {}, "name": "my-test-tunnel", "status": "active" }, "tunnelId": "3c683924-6802-47c9-860a-f27a66e684a2" }, "timestamp": "2026-05-12T14:01:27.023693818Z", "type": "cloudflare.tunnel.fetched" } ``` ## Get Worker **Component key:** `cloudflare.getWorker` The Get Worker component loads Workers script **settings** (bindings, compatibility, usage model, etc.) and the list of **deployments** (newest first per Cloudflare). ### Configuration - **Worker Script**: The Worker script in your Cloudflare account (picker lists scripts for the account). ### Output Emits `settings` and `deployments` for use in later workflow steps. ### Example Output ```json { "data": { "accountId": "90ddd046218bd375f20e9f9082cc0c6d", "deployments": [ { "created_on": "2026-05-05T12:00:00Z", "id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", "source": "api", "strategy": "percentage", "versions": [ { "percentage": 100, "version_id": "18f97339-c287-4872-9bdd-e2135c07ec12" } ] } ], "settings": { "bindings": [], "compatibility_date": "2024-01-01", "usage_model": "standard" }, "workerScript": "my-worker" }, "timestamp": "2026-05-05T12:00:00.000000000Z", "type": "cloudflare.worker.fetched" } ``` ## Order Certificate Pack **Component key:** `cloudflare.orderCertificatePack` The Order Certificate Pack component orders an advanced SSL/TLS certificate pack for custom hostnames in a Cloudflare zone. ### Use Cases - **Preview environments**: Automatically provision SSL certificates for dynamically created preview subdomains - **Custom domains**: Issue certificates for customer-owned domains behind Cloudflare - **Wildcard coverage**: Order a certificate that covers both the apex and wildcard subdomains ### Configuration - **Zone**: The Cloudflare zone to issue the certificate in - **Hosts**: One or more hostnames the certificate should cover. Include both apex and wildcard variants (e.g., `example.com` and `*.example.com`) if needed. - **Certificate Authority**: The CA to use — Let's Encrypt (free, automated), Google, or SSL.com. - **Validation Method**: How domain ownership is verified — TXT record, HTTP file, or email. - **Certificate Validity Period**: How long the certificate should be valid. Available for Google and SSL.com certificates. - **Cloudflare Branding**: Whether to include Cloudflare branding on the certificate (optional). ### Output Emits the resolved zone ID, zone name when known from integration metadata, pack ID, and the ordered certificate pack object (including covered hostnames). Status will typically be `initializing` or `pending_validation` immediately after ordering. ### Example Output ```json { "data": { "pack": { "certificate_authority": "lets_encrypt", "hosts": [ "preview-123.example.com" ], "id": "cc15b64a-e432-4210-a51d-b7042fd55ac0", "status": "initializing", "type": "advanced", "validation_method": "txt" }, "packId": "cc15b64a-e432-4210-a51d-b7042fd55ac0", "zoneId": "abc123def456abc123def456abc12345", "zoneName": "example.com" }, "timestamp": "2026-05-11T10:00:00.000000000Z", "type": "cloudflare.certificate_pack.ordered" } ``` ## Purge Cache **Component key:** `cloudflare.purgeCache` The Purge Cache component clears cached content from the Cloudflare CDN. ### Use Cases - **Deployments**: Immediately serve fresh content after a release without waiting for TTL expiry - **Hotfixes**: Force CDN edge nodes to re-fetch updated assets after a critical fix - **Preview environments**: Clear cache for specific preview subdomain URLs ### Configuration - **Zone**: The Cloudflare zone whose cache to purge - **Mode**: - *Everything*: Purge all cached content in the zone (equivalent to "Purge Everything" in the dashboard). Use with care — this can spike origin traffic. - *Files*: Purge one or more specific URLs. Supports both plain URLs and URLs with custom cache headers. - *Tags*: Purge by Cache-Tag header values (Enterprise plan only). - *Hosts*: Purge all files cached under one or more hostnames (Enterprise plan only). - *Prefixes*: Purge all cached assets whose URL starts with one of the provided prefixes. ### Output Emits the Cloudflare purge result ID, zone ID, zone name (when known from integration metadata), and the purge scope (mode + items). ### Example Output ```json { "data": { "files": [ "https://example.com/assets/main.css", "https://example.com/assets/app.js" ], "id": "9a7806061c88ada191ed06f989cc3dac", "mode": "files", "zoneId": "abc123def456abc123def456abc12345", "zoneName": "example.com" }, "timestamp": "2026-05-11T10:00:00.000000000Z", "type": "cloudflare.cache.purged" } ``` ## Put KV Value **Component key:** `cloudflare.putKVValue` The Put KV Value component writes a key-value pair to a Cloudflare Workers KV namespace. ### Use Cases - **Feature flags**: Toggle features by writing flag values into KV storage - **Cache invalidation**: Store cache keys or version stamps - **Dynamic configuration**: Update runtime configuration values from a workflow ### Configuration - **Namespace**: The ID of the KV namespace to write to - **Key**: The key name (up to 512 bytes, printable non-whitespace characters) - **Value**: The value to store (up to 25 MiB) - **Expiration TTL**: (Optional) Number of seconds until the key expires (minimum 60) ### Output Emits a confirmation with the account ID, namespace ID, and key that was written. ### Example Output ```json { "data": { "accountId": "90ddd046218bd375f20e9f9082cc0c6d", "key": "my-key", "namespaceId": "0f2ac74b498b48028cb68387c421e279", "written": true }, "timestamp": "2026-05-05T06:54:57.198268018Z", "type": "cloudflare.kv.value.put" } ``` ## Update DNS Record **Component key:** `cloudflare.updateDNSRecord` The Update DNS Record component updates an existing DNS record in a Cloudflare zone. ### Use Cases - **Infrastructure changes**: Update record content when an IP or target changes - **Release automation**: Switch a record to proxied or adjust TTL during a migration - **Verification**: Update TXT records for ownership verification as part of workflows ### Configuration - **Record**: DNS record to update (e.g. zone-id/record-id or app.example.com) - **Content**: New record value - **TTL**: TTL in seconds (default 360) - **Proxied**: Whether Cloudflare should proxy traffic for this record ### Output Emits the updated DNS record (id, type, name, content, proxied, ttl) on the default channel. If the update fails (e.g. record not found, invalid update), the component goes to an error state and does not emit. ### Example Output ```json { "data": { "record": { "content": "203.0.113.10", "id": "record_abc123", "name": "app.example.com", "proxied": true, "ttl": 1, "type": "A" }, "recordId": "record_abc123", "zoneId": "zone_xyz789" }, "timestamp": "2026-03-26T19:29:35.841265352Z", "type": "cloudflare.dnsRecord" } ``` ## Update Load Balancer **Component key:** `cloudflare.updateLoadBalancer` The Update Load Balancer component modifies an existing Cloudflare Load Balancer. ### Use Cases - **Traffic shifting**: Change pool weights to shift traffic between canary and stable pools - **Blue/green cutover**: Switch default pools to point at the green pool - **Session affinity changes**: Enable or disable sticky sessions for a release - **Steering policy update**: Switch from random to geo or latency-based steering ### Configuration - **Load Balancer**: The load balancer to update - **Steering Policy**: (Optional) New distribution policy across pools - **Pool Weights**: (Optional) Per-pool weights for random steering - **Session Affinity**: (Optional) How client sessions are pinned to a specific pool - **Session Affinity TTL**: (Optional) Duration of session affinity in seconds - **Fallback Pool**: (Optional) New fallback pool - **Default Pools**: (Optional) New ordered list of active pools ### Output Returns the updated load balancer configuration. ### Example Output ```json { "data": { "loadBalancer": { "default_pools": [ "9290f38c5d07c2e2f4df57b1f61d4196", "17b5962d775c646f3f9725cbc7a53df4" ], "description": "Example load balancer", "enabled": true, "fallback_pool": "17b5962d775c646f3f9725cbc7a53df4", "id": "699d98642c564d2e855e9661899b7252", "name": "lb.example.com", "proxied": true, "random_steering": { "pool_weights": { "17b5962d775c646f3f9725cbc7a53df4": 0.1, "9290f38c5d07c2e2f4df57b1f61d4196": 0.9 } }, "session_affinity": "cookie", "session_affinity_ttl": 1800, "steering_policy": "random" }, "loadBalancerId": "699d98642c564d2e855e9661899b7252", "zoneId": "023e105f4ecef8ad9ca31a8372d0c353" }, "timestamp": "2026-05-05T06:54:57.198268018Z", "type": "cloudflare.loadBalancer.updated" } ``` ## Update Monitor **Component key:** `cloudflare.updateMonitor` The Update Monitor component modifies an existing Cloudflare Load Balancing health monitor. ### Use Cases - **Adjust thresholds**: Change health check intervals, timeouts, or consecutive up/down counts - **Change protocol**: Switch a monitor from HTTP to HTTPS or TCP - **Update endpoint**: Modify the path or port being checked - **Tune headers**: Add or remove request headers sent during health checks ### Configuration - **Monitor**: The health monitor to update (required) - **Type / Description / Path / Port**: Override basic monitor settings. Only toggled fields are applied. - **Advanced Health Check Settings**: Override method, expected response, headers, redirect, TLS, and timing thresholds. ### Output Returns the updated monitor configuration after the change is applied. ### Example Output ```json { "data": { "accountId": "account_abc123", "monitor": { "consecutive_down": 3, "consecutive_up": 2, "description": "Updated login page monitor", "expected_codes": "2xx", "id": "monitor_abc123", "interval": 30, "method": "GET", "path": "/healthz", "port": 443, "retries": 2, "timeout": 5, "type": "https" }, "monitorId": "monitor_abc123" }, "timestamp": "2026-05-11T10:00:00.000000000Z", "type": "cloudflare.monitor.updated" } ``` ## Update Origin Rule **Component key:** `cloudflare.updateOriginRule` The Update Origin Rule component updates a Cloudflare origin rule, such as changing the origin host for matching requests. ### Configuration - **Rule**: Select the origin rule to update - **Apply To**: Apply to all incoming requests or build a custom filter - **Match Rules**: Field/operator/value predicates used to build the Cloudflare expression - **DNS Record**: Optional hostname Cloudflare should resolve and route to - **Destination Port**: Optional destination port override - **Host Header**: Optional HTTP Host header override - **SNI**: Optional SNI override - **Enabled**: Whether the rule is active ### Output Emits the updated origin rule on the default channel. ### Example Output ```json { "data": { "rule": { "action": "route", "action_parameters": { "origin": { "host": "new-api-origin.example.com" } }, "description": "Route API requests", "enabled": true, "expression": "starts_with(http.request.uri.path, \"/api/\")", "id": "rule123" }, "zoneId": "zone123" }, "timestamp": "2026-05-06T12:00:00Z", "type": "cloudflare.updateOriginRule" } ``` ## Update Pool **Component key:** `cloudflare.updatePool` The Update Pool component modifies an existing Cloudflare Load Balancer origin pool. ### Use Cases - **Canary deployments**: Shift traffic weight from stable to canary origin - **Blue/green deployments**: Disable blue origins and enable green origins - **Scaling**: Add or remove origin servers dynamically - **Health management**: Enable or disable individual origins without removing them ### Configuration - **Pool ID**: The ID of the pool to update - **Origins**: Full list of origin servers with updated weights or enabled status - **Name**: Optional new name for the pool - **Description**: Optional new description - **Enabled**: Enable or disable the entire pool - **Minimum Origins**: Minimum number of healthy origins before pool is marked unhealthy - **Origin Steering Policy**: How requests are distributed across origins - **Monitor**: Health monitor ID for origin health checks - **Load Shedding**: Configure load shedding for the pool ### Output Returns the updated origin pool configuration. ### Example Output ```json { "data": { "accountId": "90ddd046218bd375f20e9f9082cc0c6d", "pool": { "description": "my updated pool", "enabled": true, "id": "f7be7edc94014415ba06bca7b13c5c5a", "minimum_origins": 1, "name": "my-updated-pool", "origin_steering": { "policy": "random" }, "origins": [ { "address": "192.0.2.1:2015", "enabled": false, "name": "server-1", "weight": 1 } ] }, "poolId": "f7be7edc94014415ba06bca7b13c5c5a" }, "timestamp": "2026-05-05T05:57:59.044021383Z", "type": "cloudflare.pool.updated" } ``` ## Update Redirect Rule **Component key:** `cloudflare.updateRedirectRule` The Update Redirect Rule component modifies an existing redirect rule in a Cloudflare zone. ### Use Cases - **URL management**: Update redirect rules dynamically based on workflow events - **A/B testing**: Switch redirect targets for testing purposes - **Maintenance**: Temporarily redirect traffic during maintenance - **Migration**: Update redirects as part of site migration workflows ### Configuration - **Zone**: Select the Cloudflare zone containing the redirect rule - **Rule ID**: The ID of the redirect rule to update - **Description**: Optional description for the rule - **Match Type**: How to match URLs (exact match or expression-based) - **Source URL Pattern**: URL pattern to match (for exact match type) - **Expression**: Cloudflare expression for matching (for expression type) - **Target URL**: The URL to redirect to (supports expressions) - **Status Code**: HTTP status code for redirect (301, 302, 307, 308) - **Preserve Query String**: Whether to preserve query parameters in redirect - **Enabled**: Whether the rule is active ### Output Returns the updated redirect rule with all current configuration. ### Example Output ```json { "data": { "enabled": true, "rule": { "action": "redirect", "action_parameters": { "from_value": { "preserve_query_string": false, "status_code": 301, "target_url": { "value": "https://example.com/new-path" } } }, "description": "Redirect old path to new path", "enabled": true, "expression": "http.request.uri.path eq \"/old-path\"", "id": "rule_abc123" }, "ruleId": "rule_abc123", "zoneId": "zone_xyz789" }, "timestamp": "2026-03-26T19:29:35.841265352Z", "type": "cloudflare.redirectRule" } ``` ## Update Worker Route **Component key:** `cloudflare.updateWorkerRoute` The Update Worker Route component manages **zone routes** for Workers. ### Create vs update - Leave **Route ID** empty to **create** a new route (`POST /zones/{zone}/workers/routes`). - Set **Route ID** to **update** an existing route (`PUT /zones/{zone}/workers/routes/{id}`). ### Configuration - **Zone**: Cloudflare zone for the route. - **Pattern**: URL pattern (for example `example.com/*`). - **Worker Script**: Worker script invoked for matching traffic (picker lists scripts for the account). ### Output Emits the route id, pattern, and script returned by the Cloudflare API. ### Example Output ```json { "data": { "accountId": "90ddd046218bd375f20e9f9082cc0c6d", "route": { "id": "023e105f4ecef8ad9ca31a8372d0c353", "pattern": "example.com/*", "script": "my-worker" }, "zoneId": "023e105f4ecef8ad9ca31a8372d0c353" }, "timestamp": "2026-05-05T12:00:00.000000000Z", "type": "cloudflare.workerRoute.created" } ``` #### Cloudsmith Source URL: https://docs.superplane.com/components/cloudsmith Automate repository, package, and artifact management on Cloudsmith import { CardGrid, LinkCard } from "@astrojs/starlight/components"; ## Triggers ## Actions ## Instructions ## Cloudsmith Service Account API Key SuperPlane authenticates to Cloudsmith using a service account API key, which is not tied to an individual user. 1. In the Cloudsmith web dashboard, go to the **Accounts** tab and click on **Services** 2. Click on **New Service**. Give the service a name like **Superplane** and optional description. Assign the **Manager** role to the service. 3. Click on **Create Service** and copy the generated API key. 4. Paste the API key below. 5. To give the service access to any repository, click on your Repository and then **Settings** → **Access control → Privileges for specific services**, and add the service with the **Admin** privilege. ## On Package Created **Trigger key:** `cloudsmith.onPackageCreated` The On Package Created trigger starts a workflow whenever a new package is uploaded to the selected repository. ### Use Cases - **Ingestion pipelines**: React to new artifacts as they land — promote, tag, or notify - **Auditing**: Record who uploaded which package and when - **Fan-out**: Kick off downstream checks (e.g. fetch repository details) for each new package ### Configuration - **Repository**: The repository to watch, in the form `owner/repository` (required) ### Webhook Setup This trigger provisions a Cloudsmith webhook automatically: on setup it registers SuperPlane's webhook URL on the selected repository for the `package.created` event, and removes it when the trigger is deleted. The Cloudsmith service account needs the **Admin** privilege on the repository for this. Each delivery is signed (HMAC-SHA1) with a per-node secret and verified on receipt, so forged or unsigned requests are rejected. ### Output Emits the new package's details: **namespace**, **repository**, **name**, **version**, **slug_perm**, **format**, **license**, **uploader**, **uploaded_at**, and **status**. ### Example Data ```json { "data": { "event": "package.created", "format": "npm", "license": "MIT", "name": "sp-compliance-mit", "namespace": "weskk", "repository": "superplane-compliance", "slug_perm": "wxu9RDqPfCj0", "status": "Completed", "uploaded_at": "2026-06-17T14:50:00.843111Z", "uploader": "superplane-dnig", "version": "1.0.0" }, "timestamp": "2026-06-17T14:50:00Z", "type": "cloudsmith.package.created" } ``` ## On Security Scan Completed **Trigger key:** `cloudsmith.onSecurityScanCompleted` The On Security Scan Completed trigger starts a workflow whenever Cloudsmith finishes scanning a package in the selected repository for vulnerabilities. ### Use Cases - **Block vulnerable packages**: Quarantine or reject a package when its scan finds High/Critical vulnerabilities - **Security alerts**: Notify a channel when vulnerabilities are detected - **Audit**: Record the scan outcome for every package ### Configuration - **Repository**: The repository to watch, in the form `owner/repository` (required) ### Webhook Setup This trigger provisions a Cloudsmith webhook automatically: on setup it registers SuperPlane's webhook URL on the selected repository for the `package.security_scanned` event, and removes it when the trigger is deleted. The Cloudsmith service account needs the **Admin** privilege on the repository for this. Each delivery is signed (HMAC-SHA1) with a per-node secret and verified on receipt, so forged or unsigned requests are rejected. ### Output Emits the package's identity (**namespace**, **repository**, **name**, **version**, **slug_perm**, **format**) and the scan results: **security_scan_status**, **has_vulnerabilities**, **max_severity**, **num_vulnerabilities**, and **vulnerability_scan_results_url**. Because this fires when the scan *completes*, the vulnerability fields are settled — filter downstream, e.g. only act when `max_severity` is High/Critical. ### Example Data ```json { "data": { "event": "package.security_scanned", "format": "npm", "has_vulnerabilities": true, "max_severity": "High", "name": "sp-compliance-gpl", "namespace": "weskk", "num_vulnerabilities": 2, "repository": "superplane-compliance", "security_scan_status": "2 Vulnerabilities Detected", "slug_perm": "f3XvJCI9ufJa", "version": "1.0.0", "vulnerability_scan_results_url": "https://api.cloudsmith.io/v1/vulnerabilities/weskk/superplane-compliance/f3XvJCI9ufJa/" }, "timestamp": "2026-06-18T14:17:58Z", "type": "cloudsmith.package.securityScanned" } ``` ## Get Package **Component key:** `cloudsmith.getPackage` The Get Package component retrieves complete metadata for a specific Cloudsmith package, including sync status, quarantine state, and security scan results. ### Use Cases - **Release gating**: Check that a package is Available and sync-completed before triggering downstream deployment steps - **Quarantine detection**: Detect when a package has been quarantined or has policy violations - **Audit trails**: Record full package metadata (checksums, format, upload time) for compliance - **Downstream enrichment**: Pass package details such as format or CDN URL to later workflow steps - **Checksum verification**: Retrieve SHA-256 or MD5 checksums to validate package integrity - **Security insights**: Check the security scan status and link to full vulnerability results ### Configuration - **Repository** (required): The repository containing the package, in the form `owner/repository`. - **Package** (required): The unique package identifier (`slug_perm`). Supports expressions — use `{{ $['On Package Uploaded'].package.slug_perm }}` to reference an upstream trigger. ### Output Returns the complete package object including: - **name** / **version**: Package name and version string - **format**: Package format (e.g., `python`, `debian`, `docker`, `maven`) - **status** / **status_str**: Overall status code and label (e.g. `Available`, `Quarantined`, `Failed`) - **stage** / **stage_str**: Processing stage (e.g. `Fully Synchronised`) - **sync_progress**: Sync completion percentage (0–100) - **is_sync_completed** / **is_sync_failed**: Final sync outcome flags - **is_quarantined**: Whether the package has been quarantined - **security_scan_status**: Result of the most recent security scan - **vulnerability_scan_results_url**: URL to full vulnerability scan results - **checksum_md5** / **checksum_sha1** / **checksum_sha256** / **checksum_sha512**: Package checksums - **size** / **size_str**: Package size in bytes and human-readable form - **cdn_url** / **self_html_url**: Download and web UI URLs - **uploaded_at**: ISO 8601 upload timestamp ### Example Output ```json { "data": { "cdn_url": "https://dl.cloudsmith.io/basic/example-owner/example-repo/docker/example-package-id.manifest.json", "checksum_md5": "00000000000000000000000000000000", "checksum_sha1": "0000000000000000000000000000000000000000", "checksum_sha256": "0000000000000000000000000000000000000000000000000000000000000000", "checksum_sha512": "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "description": "Example package payload", "display_name": "example-app", "filename": "example-app", "format": "docker", "is_quarantined": true, "is_sync_awaiting": false, "is_sync_completed": true, "is_sync_failed": false, "is_sync_in_flight": false, "is_sync_in_progress": false, "name": "example-app", "namespace": "example-owner", "policy_violated": false, "repository": "example-repo", "security_scan_completed_at": "2026-01-01T02:00:00Z", "security_scan_started_at": "2026-01-01T01:59:00Z", "security_scan_status": "Scan Detected Vulnerabilities", "self_html_url": "https://cloudsmith.io/~example-owner/repos/example-repo/packages/detail/docker/example-app/example-version/a=amd64;xpo=linux/", "self_url": "https://api.cloudsmith.io/v1/packages/example-owner/example-repo/example-package-id/", "self_webapp_url": "https://app.cloudsmith.com/example-owner/r/example-repo/docker/example-app/example-version/example-package-id", "size": 123456, "size_str": "", "slug": "example-app-abc1", "slug_perm": "example-package-id", "stage": 9, "stage_str": "Fully Synchronised", "stage_updated_at": "2026-01-01T01:58:00Z", "status": 7, "status_reason": "", "status_str": "Quarantined", "status_updated_at": "2026-01-01T02:05:00Z", "summary": "", "sync_finished_at": "2026-01-01T02:03:00Z", "sync_progress": 100, "tags": { "version": [ "latest" ] }, "tags_immutable": {}, "uploaded_at": "2026-01-01T01:55:00Z", "uploader": "example-user", "version": "example-version", "vulnerability_scan_results_url": "https://api.cloudsmith.io/v1/vulnerabilities/example-owner/example-repo/example-package-id/" }, "timestamp": "2026-01-01T02:06:00Z", "type": "cloudsmith.package.fetched" } ``` ## Get Repository **Component key:** `cloudsmith.getRepository` The Get Repository component retrieves detailed information about a specific Cloudsmith repository. ### Use Cases - **Status checks**: Verify a repository exists and is reachable before publishing or promoting packages - **Information retrieval**: Read repository visibility, namespace, and configuration - **Storage monitoring**: Track storage usage, package counts, and download metrics - **Compliance checks**: Inspect quarantined or policy-violating package counts before downstream actions ### Configuration - **Repository**: The repository to retrieve (required, supports expressions). The value is the repository identifier in the form `owner/repository`. ### Output Returns the repository object including: - **name**: A descriptive name for the repository - **slug**: The slug that identifies the repository in URIs - **namespace**: The namespace (owner) the repository belongs to - **repository_type_str**: The visibility of the repository (Public, Private, Open-Source) - **storage_region**: The Cloudsmith region in which package files are stored - **size** / **size_str**: The calculated storage size of the repository - **package_count**: The number of packages in the repository - **num_downloads**: The number of downloads for packages in the repository - **num_quarantined_packages**: The number of quarantined packages - **num_policy_violated_packages**: The number of packages with policy violations ### Example Output ```json { "data": { "cdn_url": "https://dl.cloudsmith.io/public/acme/production", "content_kind": "Standard", "created_at": "2026-01-15T09:42:11.123456Z", "description": "Production packages for the ACME platform", "is_open_source": false, "is_private": true, "is_public": false, "name": "Production", "namespace": "acme", "namespace_url": "https://api.cloudsmith.io/v1/namespaces/acme/", "num_downloads": 18234, "num_policy_violated_packages": 2, "num_quarantined_packages": 1, "package_count": 312, "package_group_count": 47, "repository_type_str": "Private", "self_html_url": "https://cloudsmith.io/~acme/repos/production/", "self_url": "https://api.cloudsmith.io/v1/repos/acme/production/", "self_webapp_url": "https://cloudsmith.io/~acme/repos/production/", "size": 524288000, "size_str": "500.0 MB", "slug": "production", "slug_perm": "abcdef123456", "storage_region": "us-ohio" }, "timestamp": "2026-03-12T21:13:32.946693411Z", "type": "cloudsmith.repository.fetched" } ``` #### Coolify Source URL: https://docs.superplane.com/components/coolify List and control Coolify applications and services, and trigger deployments import { CardGrid, LinkCard } from "@astrojs/starlight/components"; ## Actions ## Instructions **Setup steps:** 1. **Base URL:** Use your Coolify instance URL (for example `https://coolify.example.com` for self-hosted, or `https://app.coolify.io` for Coolify Cloud). 2. **API Token:** In Coolify, go to **Keys & Tokens → API tokens**, click **Create new token**, give it a name, select the required permissions (read + write), and copy the generated token. 3. The API token is **team-scoped** — SuperPlane will see all applications and services available to that team. ## Control Application **Component key:** `coolify.controlApplication` The Control Application component invokes a lifecycle operation on a Coolify application. ### How It Works 1. Calls `GET /api/v1/applications/{uuid}/{operation}` on the configured Coolify instance 2. Emits the API confirmation message on the default output channel ### Configuration - **Application**: The Coolify application to control - **Operation**: One of `start`, `stop`, or `restart` ### Example Output ```json { "data": { "applicationUuid": "abc123def456", "message": "Application restarting.", "operation": "restart" }, "timestamp": "2024-01-15T10:30:00Z", "type": "coolify.application.controlled" } ``` ## Control Service **Component key:** `coolify.controlService` The Control Service component invokes a lifecycle operation on a Coolify service (one-click or custom Docker Compose stack). ### How It Works 1. Calls `GET /api/v1/services/{uuid}/{operation}` on the configured Coolify instance 2. Emits the API confirmation message on the default output channel ### Configuration - **Service**: The Coolify service to control - **Operation**: One of `start`, `stop`, or `restart` ### Example Output ```json { "data": { "message": "Service restarting.", "operation": "restart", "serviceUuid": "svc111aaa222" }, "timestamp": "2024-01-15T10:30:00Z", "type": "coolify.service.controlled" } ``` ## Deploy Application **Component key:** `coolify.deployApplication` The Deploy Application component queues a deployment for a Coolify application. It does not wait for the deployment to finish — the execution emits as soon as Coolify acknowledges the request. ### How It Works 1. Calls `GET /api/v1/deploy?uuid={uuid}&force={force}` on the configured Coolify instance 2. Emits the queued deployment metadata (deployment UUID, message) on the default output channel and finishes immediately ### Configuration - **Application**: The Coolify application to deploy - **Force**: When enabled, Coolify rebuilds the image instead of redeploying the existing one (defaults to false) ### Output A `coolify.application.deploy.queued` payload with `applicationUuid`, `deploymentUuid` (when returned), and `message`. ### Example Output ```json { "data": { "applicationUuid": "abc123def456", "deploymentUuid": "deploy-uuid-xyz", "force": false, "message": "Deployment queued." }, "timestamp": "2024-01-15T10:30:00Z", "type": "coolify.application.deploy.queued" } ``` ## List Applications **Component key:** `coolify.listApplications` The List Applications component fetches every application available to the Coolify API token and emits the list on the default output channel. ### How It Works 1. Calls `GET /api/v1/applications` on the configured Coolify instance 2. Emits the array of applications, each with `uuid`, `name`, `status`, `fqdn`, `description`, `gitRepository`, and `gitBranch` ### Use Cases - Iterate over every application with a downstream `forEach` to act on each (e.g. restart all) - Filter applications by status before invoking lifecycle actions - Surface application details into other workflows ### Example Output ```json { "data": { "applications": [ { "description": "Marketing site", "fqdn": "https://app.example.com", "gitBranch": "main", "gitRepository": "https://github.com/example/frontend", "name": "frontend", "status": "running", "uuid": "abc123def456" }, { "fqdn": "https://api.example.com", "gitBranch": "main", "gitRepository": "https://github.com/example/api", "name": "api", "status": "exited", "uuid": "def456abc789" } ], "count": 2 }, "timestamp": "2024-01-15T10:30:00Z", "type": "coolify.applications.listed" } ``` ## List Services **Component key:** `coolify.listServices` The List Services component fetches every Coolify service (one-click and custom Docker Compose stacks) available to the API token and emits the list on the default output channel. ### How It Works 1. Calls `GET /api/v1/services` on the configured Coolify instance 2. Emits the array of services, each with `uuid`, `name`, `status`, `fqdn`, `description`, and `serverUuid` ### Use Cases - Iterate over every service with a downstream `forEach` to act on each - Filter services by status before invoking lifecycle actions - Inventory services across an environment ### Example Output ```json { "data": { "count": 2, "services": [ { "description": "Primary database", "name": "postgres", "serverUuid": "srv999zzz000", "status": "running", "uuid": "svc111aaa222" }, { "fqdn": "https://analytics.example.com", "name": "plausible", "serverUuid": "srv999zzz000", "status": "running", "uuid": "svc333bbb444" } ] }, "timestamp": "2024-01-15T10:30:00Z", "type": "coolify.services.listed" } ``` #### Core Source URL: https://docs.superplane.com/components/core Built-in SuperPlane components. import { CardGrid, LinkCard } from "@astrojs/starlight/components"; ## Triggers ## Actions ## On Error **Trigger key:** `onError` The On Error trigger reacts to unexpected failures anywhere in the canvas. ### How It Works Whenever any node in the same canvas finishes in the **error** state (it could not execute - e.g. a network failure, invalid credentials, or an unhandled exception), every On Error node in that canvas fires a new run. This happens independently of how your nodes are connected: On Error nodes do not need an incoming connection. If you place multiple On Error nodes on a canvas, all of them receive every error. > Note: this reacts to the **error** state, not the **failed** state. A component that > executed successfully but produced a failure outcome (e.g. an HTTP request returning > 404, or a rejected approval) does **not** trigger On Error. Use a Filter or the > component's failure output channel for those cases. ### Event Data Each emitted event carries: - `node`: the node that errored - its `id`, `name`, and `component` type - `error`: the failure `reason` and human-readable `message` - `run`: the `id` of the run that failed - `root`: the event that started the failed run - the originating `node` and its `payload` - `payloads`: the payloads emitted by every upstream node in the failed run, keyed by node name ### Examples - `$['On Error'].node.name`: the name of the node that errored - `$['On Error'].error.message`: the error message - `$['On Error'].root.payload.data.version`: data from the event that triggered the failed run - `$['On Error'].payloads['Build'].data.version`: data from an upstream node in the failed run ### Example Data ```json { "data": { "error": { "message": "request timeout after 30s", "reason": "error" }, "node": { "component": "http", "id": "http-deploy-to-prod-a1b2c3", "name": "Deploy to Prod" }, "payloads": { "Manual Run": { "data": { "version": "1.4.2" }, "type": "manual.run" } }, "root": { "node": { "component": "start", "id": "manual-run-9z8y7x", "name": "Manual Run" }, "payload": { "data": { "version": "1.4.2" }, "type": "manual.run" } }, "run": { "id": "8f1c2d3e-4a5b-6c7d-8e9f-0a1b2c3d4e5f" } }, "timestamp": "2024-01-01T09:00:00Z", "type": "onError.triggered" } ``` ## Schedule **Trigger key:** `schedule` The Schedule trigger starts workflow executions automatically based on a configured schedule. ### Use Cases - **Periodic tasks**: Run daily reports, backups, or maintenance tasks - **Data synchronization**: Regularly sync data between systems - **Monitoring**: Periodic health checks and monitoring - **Batch processing**: Process data on a recurring schedule ### Schedule Types - **Minutes**: Trigger every N minutes (1-59) - **Hours**: Trigger every N hours at a specific minute (1-23 hours) - **Days**: Trigger every N days at a specific time (1-31 days) - **Weeks**: Trigger every N weeks on specific weekdays at a specific time (1-52 weeks) - **Months**: Trigger every N months on a specific day and time (1-24 months) - **Cron**: Use a cron expression for advanced scheduling patterns ### Timezone Support For days, weeks, months, and cron schedules, you can specify a timezone to ensure triggers occur at the correct local time. ### Cron Expressions Supports both 5-field and 6-field cron expressions: - **5-field**: `minute hour day month dayofweek` (e.g., `30 14 * * MON-FRI`) - **6-field**: `second minute hour day month dayofweek` (e.g., `0 30 14 * * MON-FRI`) ### Event Data Each scheduled execution includes calendar information: - **calendar**: Year, month, day, hour, minute, second, week_day - **timezone**: Timezone information (for applicable schedule types) ### Examples - **Every 15 minutes**: Minutes schedule with 15-minute interval - **Daily at 9 AM**: Days schedule with hour=9, minute=0 - **Weekdays at 2 PM**: Weeks schedule with weekDays=[Monday-Friday], hour=14 - **First of every month**: Months schedule with dayOfMonth=1 ### Example Data ```json { "data": { "calendar": { "day": "1", "hour": "09", "minute": "00", "month": "January", "second": "00", "week_day": "Monday", "year": "2024" }, "timezone": "+00:00" }, "timestamp": "2024-01-01T09:00:00Z", "type": "scheduler.tick" } ``` ## Manual Run **Trigger key:** `start` The Manual Run trigger allows you to start workflow executions manually from the SuperPlane UI or CLI. ### Use Cases - **Testing workflows**: Manually trigger workflows during development and testing - **One-off tasks**: Run workflows on-demand for specific operations - **Debugging**: Manually execute workflows to debug issues - **Ad-hoc processing**: Process data when needed without automation ### How It Works 1. Add the Manual Run trigger as the starting node of your workflow 2. Configure one or more templates, each with a name, default payload, and optional parameters 3. Click the "Run" button in the workflow UI, or invoke the `run` hook via the API/CLI to start an execution 4. The workflow begins immediately with the configured payload for the selected template ### Configuration Each Manual Run trigger exposes a list of templates. A template has: - `name` (required): a label used as the run target (and the event channel) - `parameters` (optional): a list of typed parameters exposed to payload expressions as `parameters["name"]` and used by the run form - `payload` (required): a default JSON object emitted when the template is used. Supports expressions such as `{{ now() }}` and `{{ parameters["my parameter"] }}` in JSON values. Each parameter has a `name` (plain text), required `type` (`string`, `number`, `boolean`, or `select`), an optional `title` for the run form label (defaults to `name` when unset), and an optional default (`defaultString`, `defaultNumber`, or `defaultBoolean`) whose editor matches the selected type. Select parameters also require an `options` list of `label` / `value` pairs; run-time values use the option `value` strings. ### Event Data Manual runs emit an event with type `manual.run`. The data is the selected template's payload after expression resolution. ### Example Data ```json { "data": { "message": "Hello, World!" }, "timestamp": "2024-01-01T00:00:00Z", "type": "manual.run" } ``` ## Webhook **Trigger key:** `webhook` The Webhook trigger starts a new workflow execution when an HTTP request is received at the generated webhook URL. ### Use Cases - **External system integration**: Receive events from third-party services - **CI/CD pipelines**: Trigger workflows from build systems - **Form submissions**: Process data from web forms - **Event notifications**: Receive notifications from external applications ### How It Works 1. When you add a Webhook trigger to a workflow, SuperPlane generates a unique webhook URL 2. Configure the authentication method for the webhook 3. External systems can send HTTP requests to this URL 4. Each request starts a new workflow execution with the request data ### Authentication Methods - **Signature (HMAC)**: Verify requests using an HMAC-SHA256 signature - **Bearer Token**: Require a Bearer token in the `Authorization` header - **Header Token**: Require a raw token in a custom header (default: `X-Webhook-Token`) - **None (unsafe)**: No authentication (not recommended for production) ### Request Data The webhook payload includes: - **body**: Parsed request body (JSON if possible, otherwise raw data) - **headers**: All HTTP headers from the request ### Security - Each webhook has a unique secret key for authentication - Secrets can be reset using the "Reset Authentication" action - Maximum payload size: 64KB ### Example Usage Send a POST request to the webhook URL with your payload. The workflow will receive the data and start execution. ### Example Data ```json { "data": { "body": { "event": "push", "repository": "superplanehq/superplane" }, "headers": { "X-Event": [ "push" ] } }, "timestamp": "2026-01-19T12:00:00Z", "type": "webhook" } ``` ## Add Memory **Component key:** `addMemory` The Add Memory component appends one or more items to canvas-level memory storage. ### Use Cases - Persist identifiers for later cleanup paths - Store cross-run mappings (for example pull request to resource ID) - Keep structured operational context per canvas ### How It Works 1. Reads `namespace` and value fields from configuration 2. Appends a new memory row for the current canvas 3. Emits `memory.added` with the saved payload ### List Mode Enable "Input is a list" to add one memory row per element of a list expression. Configure `listSource` (the expression that yields the list) and `itemVariable` (the name to reference each element in field-value expressions, defaults to `item`). A single `memory.added` event is emitted with all written rows and the total `count`. ### Example Output ```json { "data": { "data": { "namespace": "machines", "values": { "creator": "alex", "id": "1", "pull_request": "123" } } }, "timestamp": "2026-01-19T12:00:00Z", "type": "memory.added" } ``` ## Approval **Component key:** `approval` The Approval component pauses workflow execution and waits for manual approval from specified users, groups, or roles before continuing. ### Use Cases - **Deployment approvals**: Require approval before deploying to production - **Financial transactions**: Get approval for high-value operations - **Content moderation**: Review content before publishing - **Compliance workflows**: Ensure regulatory approvals are obtained ### How It Works 1. When the Approval component executes, it creates approval requirements based on the configured approvers 2. The workflow pauses and waits for all required approvals 3. Approvers can approve or reject from the workflow UI 4. Once all approvals are collected, the workflow continues: - **Approved channel**: All required approvers approved - **Rejected channel**: At least one approver rejected ### Configuration - **Approvers**: List of users, groups, or roles who must approve - **Everyone**: Any authenticated user can approve - **Specific user**: Only the specified user can approve - **Group**: Any member of the specified group can approve - **Role**: Any user with the specified role can approve ### Output Channels - **Approved**: Emitted when all required approvers have approved - **Rejected**: Emitted when at least one approver rejects (after all have responded) ### Actions - **approve**: Approve a pending requirement (can include an optional comment) - **reject**: Reject a pending requirement (requires a reason) ### Example Output ```json { "data": { "records": [ { "approval": { "approvedAt": "2024-01-01T12:00:00Z", "comment": "Looks good" }, "index": 0, "state": "approved", "type": "user", "user": { "email": "alex@example.com", "id": "user_123", "name": "Alex Doe" } } ], "result": "approved" }, "timestamp": "2026-01-16T17:56:16.680755501Z", "type": "approval.finished" } ``` ## Delete Memory **Component key:** `deleteMemory` The Delete Memory component removes memory rows from canvas-level memory storage. ### Use Cases - Remove stale IDs after cleanup is complete - Keep memory stores bounded over time ### How It Works 1. Reads `namespace` and `matchList` from configuration 2. Deletes memory rows matching all configured key/value pairs 3. Emits `memory.deleted` to the `deleted` or `notFound` channel ### Output Channels - **Deleted**: At least one matching memory row was removed - **Not Found**: No matching memory rows were removed ### Example Output ```json { "data": { "data": { "count": 1, "deleted": [ { "creator": "igor", "pull_request": 123, "sandbox_id": "sbx-001" } ], "matches": { "creator": "igor", "pull_request": 123 }, "namespace": "machines" } }, "timestamp": "2026-02-28T00:00:00Z", "type": "memory.deleted" } ``` ## Display **Component key:** `display` The Display component displays a debug message from the latest execution. ### Use Cases - **Debugging**: Display a message from the latest execution to help debug the workflow. - **Notifications**: Display a message from the latest execution to notify the user. - **Logging**: Display a message from the latest execution to log the workflow. ### Example Output ```json { "data": { "message": "Hello, World!" }, "timestamp": "2026-01-16T17:56:16.680755501Z", "type": "display.executed" } ``` ## Filter **Component key:** `filter` The Filter component evaluates a boolean expression against incoming events and only forwards events that match the condition. ### Use Cases - **Data validation**: Only process events that meet certain criteria - **Event filtering**: Filter out unwanted events before processing - **Conditional routing**: Stop processing events that don't match requirements - **Data quality**: Ensure only valid data continues through the workflow ### How It Works 1. The Filter component evaluates a boolean expression against the incoming event data 2. If the expression evaluates to `true`, the event is emitted to the default output channel 3. If the expression evaluates to `false`, the execution passes without emitting (effectively filtering out the event) ### Expression Environment The expression has access to: - **$**: The run context data - **root()**: Access to the root event data - **previous()**: Access to previous node outputs (optionally with depth parameter) ### Examples - `$["Node Name"].status == "active"`: Only forward events where status is "active" - `$["Node Name"].amount > 1000`: Filter events with amount greater than 1000 - `$["Node Name"].user.role == "admin" && $["Node Name"].action == "delete"`: Complex condition checking multiple fields ### Example Output ```json { "data": {}, "timestamp": "2026-01-16T17:56:16.680755501Z", "type": "filter.executed" } ``` ## For Each **Component key:** `forEach` The For Each component reads an array from the upstream payload and emits one downstream event per element. ### Use Cases - Iterate over a list of results and process each one independently - Split runner output arrays into per-item workflow paths - Process each page, service, or record with the same downstream steps ### How It Works 1. Evaluates the configured array expression against the incoming event data 2. Emits one `foreach.item` event to the `item` channel for each element 3. If the array is empty, passes without emitting any events ### Limits - At most 100 items per execution. Larger arrays fail with an error. - Self-hosted deployments can raise this cap with the `SUPERPLANE_MAX_EMIT_COUNT` environment variable. ### Output Fields (per item) - **item**: The array element value - **index**: Zero-based index of the element - **totalCount**: Total number of items in the array ### Expression Environment - **$**: The run context data - **root()**: Access root event data - **previous()**: Access previous node outputs ### Example Output ```json { "data": { "index": 0, "item": { "cost_usd": 42.5, "service": "EC2" }, "totalCount": 3 }, "timestamp": "2026-01-16T17:56:16.680755501Z", "type": "foreach.item" } ``` ## GraphQL Request **Component key:** `graphql` The GraphQL component runs a GraphQL document against a URL using the standard **GraphQL over HTTP** JSON body shape. ### Request - **URL** — GraphQL HTTP endpoint (supports expressions) - **Query** — Multi-line GraphQL document (no JSON escaping in the canvas) - **Variables** — Key/value pairs merged into the request variables object - **Headers** — Request headers - **Authorization** — Optional bearer token stored in an organization Secret ### Response - **status** - Response status code - **headers** - Response headers - **body** - Response body converted to JSON ### Example Output ```json { "data": { "body": { "data": { "viewer": { "login": "octocat" } } }, "headers": { "Content-Type": [ "application/json" ] }, "status": 200 }, "timestamp": "2026-01-16T17:56:16.680755501Z", "type": "graphql.request.finished" } ``` ## HTTP Request **Component key:** `http` The HTTP component allows you to make HTTP requests to external APIs and services as part of your workflow. ### Use Cases - **API integration**: Call external REST APIs - **Webhook notifications**: Send notifications to external systems - **Data fetching**: Retrieve data from external services - **Service orchestration**: Coordinate with microservices ### Supported Methods - GET, POST, PUT, DELETE, PATCH, HEAD HEAD requests do not send a body and the response body is empty by design. Use HEAD for health checks, URL validation, or to inspect response headers and status without downloading the full response payload. ### Request Configuration - **URL**: The endpoint to call (supports expressions) - **Method**: HTTP method to use - **Query Parameters**: Optional URL query parameters - **Headers**: Custom HTTP headers (header names cannot use expressions) - **Authorization** (optional): Bearer Token, Basic Auth password, or custom header value - **Body**: Request body in various formats: - **JSON**: Structured JSON payload - **Form Data**: URL-encoded form data - **Plain Text**: Raw text content - **XML**: XML formatted content ### Response Handling The component emits the response with: - **status**: HTTP status code - **headers**: Response headers - **body**: Parsed response body (JSON if possible, otherwise string) ### Example Output ```json { "data": { "body": { "message": "ok" }, "error": "Error to read request body: EOF", "headers": { "Content-Type": [ "application/json" ] }, "status": 200 }, "timestamp": "2026-01-16T17:56:16.680755501Z", "type": "http.request.finished" } ``` ## If **Component key:** `if` The If component evaluates a boolean expression and routes events to different output channels based on the result. ### Use Cases - **Conditional branching**: Route events down different paths based on conditions - **Decision logic**: Implement if-then-else logic in workflows - **Data routing**: Send events to different processing paths - **Workflow control**: Control workflow flow based on event properties ### How It Works 1. The If component evaluates a boolean expression against the incoming event data 2. If the expression evaluates to `true`, the event is emitted to the "True" output channel 3. If the expression evaluates to `false`, the event is emitted to the "False" output channel ### Output Channels - **True**: Events where the expression evaluates to `true` - **False**: Events where the expression evaluates to `false` ### Expression Environment The expression has access to: - **$**: The run context data - **root()**: Access to the root event data - **previous()**: Access to previous node outputs (optionally with depth parameter) ### Examples - `$["Node Name"].status == "approved"`: Route approved items to True channel - `$["Node Name"].amount > 1000`: Route high-value items to True channel - `$["Node Name"].user.role == "admin"`: Route admin actions to True channel ### Example Output ```json { "data": {}, "timestamp": "2026-01-16T17:56:16.680755501Z", "type": "if.executed" } ``` ## Loop **Component key:** `loop` The Loop component runs downstream steps repeatedly until an exit condition becomes true. ### Use Cases - Poll an API until a resource reaches a ready state - Retry a workflow segment until validation passes - Paginate through results until all pages are processed - Run approval or review cycles until consensus is reached ### How It Works 1. On the first run, Loop emits to the **Next** channel and starts the loop session 2. Connect downstream nodes to the Next output and wire the last step back to Loop 3. When those steps finish, Loop evaluates the **Until Expression** 4. If the expression is `true`, Loop emits on **Done** and the loop ends 5. If the expression is `false`, Loop emits on **Next** again for another iteration ### Wiring ``` Trigger → Loop → Step A → Step B ──┐ ↑ │ └────────────────────┘ ``` Edges back into Loop are allowed so downstream steps can return control for the next condition check. ### Output Channels - **Done**: Emitted once when the loop stops. Payload is under `data.done` with `iterations`, `stopReason` (`conditionTrue` or `max_iterations`), and `elapsedMs` - **Next**: Emitted at the start of each iteration. Payload is under `data.next` with `iteration` and `maxIterations` ### Limits - **Max Iterations** caps how many iterations are allowed (default 10, maximum 100) - **Timeout** caps the total wall-clock time of a single run (default 3600s, maximum 86400s). If the loop is still running when the timeout elapses, the run fails. This prevents a stuck run (e.g. downstream never reports back) from blocking subsequent runs on the node. ### Delay Between Iterations Optionally wait before starting the next iteration. Uses the same fixed or exponential backoff strategies as the HTTP component retry settings. The first iteration always starts immediately; delays apply between subsequent iterations only. ### Expression Environment The until expression has access to: - **$**: The run context data, including outputs from the latest iteration - **root()**: Access root event data - **previous()**: Access previous node outputs ### Example Output ```json { "data": { "done": { "elapsedMs": 4521, "iterations": 3, "stopReason": "conditionTrue" } }, "timestamp": "2026-01-16T17:56:16.680755501Z", "type": "loop.done" } ``` ## Merge **Component key:** `merge` The Merge component waits for events from all upstream nodes before forwarding a combined result downstream. ### Use Cases - **Parallel processing**: Wait for multiple parallel operations to complete - **Data aggregation**: Combine results from multiple sources - **Synchronization**: Synchronize multiple workflow branches - **Fan-in patterns**: Collect outputs from multiple upstream nodes ### How It Works 1. The Merge component waits for events from all distinct upstream source nodes 2. Once all inputs are received, it emits the combined data to the Success channel 3. Optional timeout and conditional stop features allow early completion ### Configuration Options - **Enable Timeout**: Cancel merge after a specified time if not all inputs are received - **Enable Conditional Stop**: Stop waiting early when a condition is met (e.g., if one branch fails) ### Output Channels - **Success**: Emitted when all upstream inputs are received - **Timeout**: Emitted if the timeout is reached before all inputs are received - **Fail**: Emitted if the conditional stop expression evaluates to true ### Behavior - Tracks distinct source nodes (ignoring multiple channels from the same source) - Combines all received event data into the output - Supports timeout to prevent indefinite waiting - Supports conditional early stop based on expression evaluation ### Example Output ```json { "data": { "eventIDs": [ "event_1", "event_2" ], "groupKey": "merge-group-123", "sources": [ "node_a", "node_b" ], "stopEarly": false }, "timestamp": "2026-01-16T17:56:16.680755501Z", "type": "merge.finished" } ``` ## No Operation **Component key:** `noop` The No Operation component is a pass-through component that forwards events to downstream nodes without any modification or processing. ### Use Cases - **Testing workflows**: Use this component to test workflow connections and flow without side effects - **Placeholder nodes**: Temporarily replace components during workflow development - **Event forwarding**: Simply forward events when no processing is needed ### Behavior When executed, the No Operation component immediately emits the incoming event data to the default output channel without any transformation. It has no configuration options and requires no setup. ### Example Output ```json { "data": {}, "timestamp": "2026-01-16T17:56:16.680755501Z", "type": "noop.finished" } ``` ## Read Memory **Component key:** `readMemory` The Read Memory component looks up values from canvas-level memory storage. ### Use Cases - Retrieve previously stored IDs before cleanup actions - Check whether related data already exists - Rehydrate context from prior runs ### How It Works 1. Reads `namespace`, `resultMode`, `emitMode`, and `matchList` from configuration 2. Finds memory rows matching all configured key/value pairs 3. Emits `memory.read` to the `found` or `notFound` channel ### Output Channels - **Found**: At least one matching memory row was found - **Not Found**: No matching memory rows were found ### Limits - When **Emit Mode** is `oneByOne`, at most 100 events are emitted per execution. - Self-hosted deployments can raise this cap with the `SUPERPLANE_MAX_EMIT_COUNT` environment variable. ### Example Output ```json { "data": { "count": 1, "emitMode": "allAtOnce", "matches": { "creator": "igor", "pull_request": 123 }, "namespace": "machines", "resultMode": "latest", "values": [ { "creator": "igor", "pull_request": 123, "sandbox_id": "sbx-001" } ] }, "timestamp": "2026-02-28T00:00:00Z", "type": "memory.read" } ``` ## Run Shell Commands **Component key:** `runner` Runs shell commands on a fleet runner. ### Execution - **Host**: Commands run directly on the runner machine (Bash with a PTY). - **Docker**: Commands run inside a container started from **Docker image**. The runner pulls the image, starts a long-lived container, and executes your script via `docker exec`. The image must include a usable `sleep` (common base images do). ### Configuration - **Machine type**: Runner fleet registered on the task-broker (required). - **Execution mode**: Host (default) or Docker. - **Container base image**: Choose a common public image, or **Other (custom image)** to enter any OCI reference. - **Custom container image**: Shown only for **Other**; use a normal reference (`my.registry.example.com/org/repo:1.2.3` or `debian:bookworm-slim@sha256:…`). Private registries require the runner to be configured with registry credentials. - **Execution timeout**: Optional wall-clock limit in seconds (1–86400). Defaults to **3600** (1 hour) when unset or **0**. - **Commands**: One or more shell commands, one per line. - **Environment variables**: Optional key/value pairs available during command execution. Values can be literal strings (with expression support) or organization secret keys. ### Output channels - **Passed**: The commands finished with exit code **0**. - **Failed**: The commands finished with non-zero exit code. ### Structured result If the completed broker task includes valid JSON in **result**, SuperPlane includes it on the `runner.finished` event payload next to **status** and **exit_code** (the exact shape depends on your runner / task implementation). ### Example Output ```json { "data": [ { "exit_code": 0, "result": { "example": "value" }, "status": "succeeded" } ], "timestamp": "2026-01-16T17:56:16.680755501Z", "type": "runner.finished" } ``` ## Run Bash **Component key:** `runnerBash` Runs a Bash script on a fleet runner. ### Execution - **Host**: Script runs with Bash on the runner machine. - **Docker**: Script runs inside a container started from **Docker image**. Use an image that includes Bash (for example **Debian Bookworm (slim)**). ### Script contract Your script runs as-is. The runner sets: - `SUPERPLANE_PAYLOAD_FILE` — path to a JSON file with upstream canvas data (same shape as workflow expressions) - `SUPERPLANE_RESULT_FILE` — path where your script must write a JSON-serializable **result** Stdout and stderr (for example `echo`) stream to **View logs**. Write the structured **result** to `SUPERPLANE_RESULT_FILE`; it is emitted on the finished event as **result**. Example: ```bash ##!/usr/bin/env bash set -euo pipefail num=$(jq -r '."GitHub PR".data.number' "$SUPERPLANE_PAYLOAD_FILE") echo "Processing PR #$num" printf '{"pr":%s}\n' "$num" > "$SUPERPLANE_RESULT_FILE" ``` ### Configuration - **Machine type**: Runner fleet registered on the task-broker (required). - **Execution mode**: Host (default) or Docker. - **Container base image**: Defaults to a Debian image in Docker mode. - **Execution timeout**: Optional wall-clock limit in seconds (1–86400). Defaults to **3600** (1 hour) when unset or **0**. - **Script**: Bash source executed by the runner. - **Setup commands**: Optional shell commands (one per line) run before the script in the same environment and working directory. - **Environment variables**: Optional key/value pairs available during execution. ### Output channels - **Passed**: The script finished with exit code **0**. - **Failed**: The script finished with non-zero exit code. ### Example Output ```json { "data": [ { "exit_code": 0, "result": { "example": "value" }, "status": "succeeded" } ], "timestamp": "2026-01-16T17:56:16.680755501Z", "type": "runnerBash.finished" } ``` ## Run JavaScript **Component key:** `runnerJS` Runs JavaScript on a fleet runner. ### Execution - **Host**: Script runs with Node.js on the runner machine. - **Docker**: Script runs inside a container started from **Docker image**. Use a Node.js image (for example **Node.js 22 (Bookworm)**) so `node` is available. ### Script contract Your script must define `function main()`. The runner injects upstream canvas data as the global `$` object (same shape as workflow expressions). Return a JSON-serializable value from `main()`; it is emitted on the finished event as **result**. Example: ```javascript function main() { return { pr: $['GitHub PR'].data.number }; } ``` ### Configuration - **Machine type**: Runner fleet registered on the task-broker (required). - **Execution mode**: Host (default) or Docker. - **Container base image**: Defaults to a Node.js image in Docker mode. - **Execution timeout**: Optional wall-clock limit in seconds (1–86400). Defaults to **3600** (1 hour) when unset or **0**. - **Script**: JavaScript source executed by Node.js. - **Setup commands**: Optional shell commands (one per line) run before the script in the same environment and working directory. - **Environment variables**: Optional key/value pairs available during execution. ### Output channels - **Passed**: The script finished with exit code **0**. - **Failed**: The script finished with non-zero exit code. ### Example Output ```json { "data": [ { "exit_code": 0, "result": { "example": "value" }, "status": "succeeded" } ], "timestamp": "2026-01-16T17:56:16.680755501Z", "type": "runnerJS.finished" } ``` ## Run Python **Component key:** `runnerPython` Runs Python on a fleet runner. ### Execution - **Host**: Script runs with Python 3 on the runner machine. - **Docker**: Script runs inside a container started from **Docker image**. Use a Python image (for example **Python 3.12 (slim)**) so `python3` is available. ### Script contract Your script must define `def main(payload):`. The runner passes upstream canvas data as the `payload` argument (same shape as workflow expressions). Return a JSON-serializable value from `main()`; it is emitted on the finished event as **result**. Example: ```python def main(payload): return {"pr": payload["GitHub PR"]["data"]["number"]} ``` ### Configuration - **Machine type**: Runner fleet registered on the task-broker (required). - **Execution mode**: Host (default) or Docker. - **Container base image**: Defaults to a Python image in Docker mode. - **Execution timeout**: Optional wall-clock limit in seconds (1–86400). Defaults to **3600** (1 hour) when unset or **0**. - **Script**: Python source executed by Python 3. - **Setup commands**: Optional shell commands (one per line) run before the script in the same environment and working directory. - **Environment variables**: Optional key/value pairs available during execution. ### Output channels - **Passed**: The script finished with exit code **0**. - **Failed**: The script finished with non-zero exit code. ### Example Output ```json { "data": [ { "exit_code": 0, "result": { "example": "value" }, "status": "succeeded" } ], "timestamp": "2026-01-16T17:56:16.680755501Z", "type": "runnerPython.finished" } ``` ## Send Email Notification **Component key:** `sendEmail` The Send Email Notification component sends emails through the system's configured email provider (Resend or SMTP) without requiring a separate integration setup. ### Use Cases - **Notifications**: Send email notifications for workflow events - **Alerts**: Email alerts for errors or important conditions - **Status updates**: Notify stakeholders about workflow progress - **User communications**: Send emails to users as part of automated workflows ### Recipients Select recipients from your organization's users, groups, or roles. The system resolves the actual email addresses at send time. ### Configuration - **Recipients**: List of users, groups, or roles - **Subject**: Email subject line (supports expressions) - **Body**: Email body content (supports expressions) ### Output Emits the list of recipients and the subject to the default output channel. ### Example Output ```json { "data": { "groups": [], "roles": [], "subject": "Deployment completed", "to": [ "alice@example.com", "bob@example.com" ] }, "timestamp": "2026-03-19T12:00:00.000000000Z", "type": "sendEmail.sent" } ``` ## SSH Command **Component key:** `ssh` Run one or more commands on a remote host via SSH. ### Authentication Choose **SSH key** or **Password**, then select the organization Secret and the key name within that secret that holds the credential. - **SSH key**: Secret key containing the private key (PEM/OpenSSH). Optionally a second secret+key for passphrase if the key is encrypted. - **Password**: Secret key containing the password. ### Configuration - **Host**, **Port** (default 22), **Username**: Connection details. - **Command source**: Choose **Inline** to type commands directly, or **From file** to load them from a file in the app's repository (e.g. scripts/deploy.sh). - **Commands** (inline mode): One or more commands to run, one per line (supports expressions). Each non-empty line becomes a command joined with &&. The output payload is based on the last command. - **Command file** (file mode): Path to a file in the Files tab. - **Working directory**: Optional; Changes to this directory before running the command. - **Environment variables**: Optional list of key/value pairs available during command execution. - **Timeout (seconds)**: How long the command may run (default 60). - **Connection retry** (optional): Enable to retry connecting when the host is not reachable yet (e.g. server still booting). Set number of retries and interval between attempts. - **Execution retry** (optional): Enable to retry running the command when the exit status is not 0. Set number of retries and interval between attempts. ### Output - **success**: Exit code 0 - **failed**: Non-zero exit code ### Example Output ```json { "data": { "exitCode": 0, "stderr": "", "stdout": "Hello, World!\n" }, "timestamp": "2026-01-19T12:00:00Z", "type": "ssh.command.executed" } ``` ## Time Gate **Component key:** `timeGate` The Time Gate component delays event processing until the next valid day and time window, with optional excluded dates. ### Use Cases - **Business hours**: Only process events during business hours - **Scheduled releases**: Delay deployments until off-peak hours - **Holiday handling**: Exclude specific dates from processing - **Time-based routing**: Route events based on time of day or specific dates ### Configuration - **Active Days**: Days of the week when the gate can open - **Active Time**: Start and end times in HH:MM-HH:MM format (24-hour) - **Timezone**: Timezone offset for time calculations (default: current) - **Exclude Dates**: Specific MM/DD dates that override the rules above ### Behavior - Events wait until the next valid time window is reached - Exclude dates override the day/time rules - Can be manually pushed through using the "Push Through" action - Automatically schedules execution when the time window is reached ### Example Output ```json { "data": {}, "timestamp": "2026-01-16T17:56:16.680755501Z", "type": "timegate.finished" } ``` ## Update Memory **Component key:** `updateMemory` The Update Memory component updates matching rows in canvas-level memory storage. ### Use Cases - Patch stored records after external state changes - Enrich existing memory rows with additional fields - Keep identifiers and status data in sync ### How It Works 1. Reads `namespace`, `matchList`, and `valueList` from configuration 2. Updates all matching memory rows in a single SQL operation 3. Emits `memory.updated` to the `found` or `notFound` channel ### Output Channels - **Found**: At least one matching memory row was updated - **Not Found**: No matching memory rows were updated ### List Mode Enable "Input is a list" to iterate over a list expression and run one update per element. Both `matchList` and `valueList` field values are evaluated per element with the iteration variable in scope (defaults to `item`), so expressions like `item.uuid` resolve to the current element's value on every iteration. This means each item updates only its own matched row. All resulting updates are reported in a single `memory.updated` event. To use a single global match across iterations, write a `{{ ... }}` template (resolved before iteration starts) instead of a bare expression. ### Example Output ```json { "data": { "data": { "count": 1, "matches": { "creator": "igor", "pull_request": 123 }, "namespace": "machines", "updated": [ { "creator": "igor", "pull_request": 123, "sandbox_id": "sbx-001", "status": "running", "updated_by": "workflow" } ], "values": { "status": "running", "updated_by": "workflow" } } }, "timestamp": "2026-02-28T00:00:00Z", "type": "memory.updated" } ``` ## Upsert Memory **Component key:** `upsertMemory` The Upsert Memory component updates matching rows in canvas-level memory storage, and creates a new row when no matches are found. ### Use Cases - Keep one record per identifier (for example environment or pull request) - Replace ad-hoc update-then-add branching with one component - Persist latest status snapshots with stable matching keys ### How It Works 1. Reads `namespace`, `matchList`, and `valueList` from configuration 2. Attempts to update all matching memory rows 3. If no rows were updated, inserts a new memory row with the values 4. Emits `memory.upserted` to the default channel with `operation` set to `updated` or `created` ### Simplified Matching If `matchList` is empty, the component treats the namespace as a singleton record and upserts at namespace level. This lets you store just one field (for example `value`) without extra marker fields. ### Output Always emits to the default channel. Check `data.operation` to know whether the component updated existing rows or created a new row. ### List Mode Enable "Input is a list" to iterate over a list expression and run one upsert per element. Both `matchList` and `valueList` field values are evaluated per element with the iteration variable in scope (defaults to `item`), so expressions like `item.uuid` resolve to the current element's value on every iteration. This means each item upserts against its own matched row. All upserts are reported in a single `memory.upserted` event with per-item operation results. To use a single global match across iterations, write a `{{ ... }}` template (resolved before iteration starts) instead of a bare expression. ### Example Output ```json { "data": { "data": { "count": 1, "matches": { "environment": "production", "latest_deployment_source": "manual_run" }, "namespace": "deployments", "operation": "updated", "records": [ { "environment": "production", "latest_deployment": "v1.0.1", "latest_deployment_source": "manual_run" } ], "values": { "environment": "production", "latest_deployment": "v1.0.1", "latest_deployment_source": "manual_run" } } }, "timestamp": "2026-02-28T00:00:00Z", "type": "memory.upserted" } ``` ## Wait **Component key:** `wait` The Wait component pauses workflow execution for a specified duration or until a specific time is reached. ### Use Cases - **Rate limiting**: Add delays between API calls - **Scheduled execution**: Wait until a specific time before proceeding - **Retry delays**: Wait before retrying failed operations - **Time-based workflows**: Delay processing until a specific date/time ### Wait Modes - **Interval**: Wait for a fixed duration (seconds, minutes, or hours) - Supports expressions for dynamic wait times - Example: `{{$['Node Name'].data.retry_delay}}` or `{{$['Node Name'].data.status == "urgent" ? 0 : 30}}` - **Countdown**: Wait until a specific date/time is reached - Supports ISO 8601 date formats - Supports expressions for dynamic target times - Example: `{{$['Node Name'].data.release_date}}` or `{{$['Node Name'].data.run_time + duration("48h")}}` ### Behavior - Execution pauses until the wait period completes - Can be manually pushed through using the "Push Through" action - Automatically resumes when the wait time expires - Emits metadata including start time, finish time, and result ### Output The component emits a payload with: - **started_at**: When the wait began - **finished_at**: When the wait completed - **result**: Completion status (completed, cancelled) - **reason**: How it completed (timeout, manual_override, user_cancel) ### Example Output ```json { "data": { "actor": { "display_name": "Alex Doe", "email": "alex@example.com" }, "finished_at": "2024-01-01T12:05:00Z", "reason": "timeout", "result": "completed", "started_at": "2024-01-01T12:00:00Z" }, "timestamp": "2026-01-16T17:56:16.680755501Z", "type": "wait.finished" } ``` #### Cursor Source URL: https://docs.superplane.com/components/cursor Build workflows with Cursor AI Agents and track usage import { CardGrid, LinkCard } from "@astrojs/starlight/components"; ## Actions ## Instructions To get your API keys, visit the [Cursor Dashboard](https://cursor.com/dashboard). You may need separate keys for Agents and Admin features. ## Get Daily Usage Data **Component key:** `cursor.getDailyUsageData` The Get Daily Usage Data component fetches team usage metrics from Cursor's Admin API. ### Use Cases - **Usage reporting**: Track team productivity and AI usage patterns - **Cost tracking**: Monitor usage-based requests and subscription consumption - **Analytics dashboards**: Build custom dashboards with Cursor usage data ### How It Works 1. Fetches usage data for the specified date range from Cursor's Admin API 2. Returns detailed metrics per user including lines added/deleted, requests, and model usage ### Configuration - **Start Date**: Start of the date range (YYYY-MM-DD format, defaults to 7 days ago) - **End Date**: End of the date range (YYYY-MM-DD format, defaults to today) ### Output The output includes per-user daily metrics: - Lines added/deleted (total and accepted) - Tab completions shown/accepted - Composer, chat, and agent requests - Subscription vs usage-based request counts - Most used model and file extensions ### Notes - Requires a valid Cursor Admin API key configured in the integration - Only returns data for active users ### Example Output ```json { "data": { "data": [ { "acceptedLinesAdded": 1102, "acceptedLinesDeleted": 645, "agentRequests": 12, "chatRequests": 128, "composerRequests": 45, "date": 1710720000000, "email": "developer@company.com", "isActive": true, "mostUsedModel": "gpt-4", "subscriptionIncludedReqs": 180, "totalAccepts": 73, "totalApplies": 87, "totalLinesAdded": 1543, "totalLinesDeleted": 892, "totalRejects": 14, "totalTabsAccepted": 289, "totalTabsShown": 342, "usageBasedReqs": 5 } ], "period": { "endDate": 1710892800000, "startDate": 1710720000000 } }, "timestamp": "2026-03-26T19:29:35.841265352Z", "type": "cursor.getDailyUsageData.result" } ``` ## Get Last Message **Component key:** `cursor.getLastMessage` The Get Last Message component retrieves the last message from a Cursor Cloud Agent's conversation history. ### Use Cases - **Message tracking**: Get the latest response or prompt from an agent conversation - **Workflow automation**: Use the last message as input for downstream components - **Status monitoring**: Check what the agent last communicated ### How It Works 1. Fetches the conversation history for the specified agent ID 2. Extracts the last message from the conversation 3. Returns the message details including ID, type (user_message or assistant_message), and text ### Configuration - **Agent ID**: The unique identifier for the cloud agent (e.g., bc_abc123) ### Output The output includes: - **Agent ID**: The identifier of the agent - **Message**: The last message object containing: - **ID**: Unique message identifier - **Type**: Either "user_message" or "assistant_message" - **Text**: The message content ### Notes - Requires a valid Cursor Cloud Agent API key configured in the integration - If the agent has been deleted, the conversation cannot be accessed - Returns nil if the conversation has no messages ### Example Output ```json { "data": { "agentId": "bc_abc123", "message": { "id": "msg_005", "text": "I've added a troubleshooting section to the README.", "type": "assistant_message" } }, "timestamp": "2026-03-26T19:29:35.841265352Z", "type": "cursor.getLastMessage.result" } ``` ## Launch Cloud Agent **Component key:** `cursor.launchAgent` The Launch Cloud Agent component triggers a Cursor AI coding agent and waits for it to complete. ### Use Cases - **Automated code generation**: Generate code from natural language prompts - **PR fixes**: Automatically fix issues on existing pull requests - **Code refactoring**: Refactor code based on instructions - **Feature implementation**: Implement new features from specifications ### How It Works 1. Launches a Cursor Cloud Agent with the specified prompt and configuration 2. Waits for the agent to complete (monitored via webhook and polling) 3. Emits output with the agent result (success or failure) ### Example Output ```json { "data": { "agentId": "agent_12345", "branchName": "cursor/agent-550e8400", "prUrl": "https://github.com/org/repo/pull/42", "status": "FINISHED", "summary": "Refactored login logic." }, "timestamp": "2026-03-26T19:29:35.841265352Z", "type": "cursor.launchAgent.finished" } ``` #### Dash0 Source URL: https://docs.superplane.com/components/dash0 Connect to Dash0 to query data using Prometheus API import { CardGrid, LinkCard } from "@astrojs/starlight/components"; ## Triggers ## Actions ## Instructions To connect Dash0 to Superplane: 1. Go to **Settings → Auth Tokens → + Add** to create a new API token. 2. Give the token a name, grant it access to the Default or all Datasets, all Signal types, and all Permissions. 3. Click **Save** and copy the **Token** into the **API Token** field below. 4. Go to **Settings → Endpoints → Prometheus API** and copy the **Endpoint** into the **Prometheus API Base URL** field below. 5. Click **Connect** to finish setup. ## On Alert Notification **Trigger key:** `dash0.onAlertNotification` The On Alert Notification trigger starts a workflow execution when Dash0 sends an alert notification webhook. ### Setup Connect the Dash0 integration in SuperPlane. A webhook notification channel is created automatically in Dash0 with routing for all alert check notifications. Add this trigger to a workflow and publish the canvas to start receiving events. ### Event Data The trigger emits the full JSON payload received from Dash0 as `dash0.alertNotification`. ### Example Data ```json { "data": { "issue": { "checkrules": [ { "annotations": { "summary": "High error rate detected" }, "description": "Alert when API error rate is high", "expression": "sum(rate(http_requests_total{status=~\"5..\"}[5m])) \u003e 0.05", "for": "5m", "id": "check_456", "interval": "1m", "keepFiringFor": "10m", "labels": { "env": "prod", "service": "api" }, "name": "API availability", "thresholds": { "critical": 0.05 }, "url": "https://app.dash0.com/check-rules/check_456" } ], "dataset": "default", "description": "Error rate exceeded threshold for API availability check.", "end": "", "id": "issue_123", "issueIdentifier": "availability-api-high-error-rate", "labels": [ { "key": "service", "value": { "stringValue": "api" } }, { "key": "env", "value": { "stringValue": "prod" } } ], "start": "2026-02-20T12:00:00Z", "status": "critical", "summary": "High error rate on API availability check", "url": "https://app.dash0.com/issues/issue_123" } }, "timestamp": "2026-02-20T12:00:00Z", "type": "dash0.alertNotification" } ``` ## On Synthetic Check Notification **Trigger key:** `dash0.onSyntheticCheckNotification` The On Synthetic Check Notification trigger starts a workflow execution when Dash0 sends a synthetic check notification webhook. ### Setup Connect the Dash0 integration in SuperPlane. A webhook notification channel is created automatically in Dash0 with routing for all synthetic check notifications. Add this trigger to a workflow and publish the canvas to start receiving events. ### Event Data The trigger emits the full JSON payload received from Dash0 as `dash0.syntheticCheckNotification`. ### Labels Format Synthetic check notifications use a tuple-based label format where each label is an array of `[index, {key, value}]`. The trigger normalizes these labels into a flat `{key: value}` map in the emitted payload for easier downstream consumption. ### Example Data ```json { "data": { "issue": { "checkrules": [ { "annotations": { "summary": "API health check failure detected" }, "description": "Monitor API health endpoint availability", "expression": "", "for": "5m", "id": "check_101", "interval": "1m", "keepFiringFor": "10m", "labels": { "env": "prod", "service": "api" }, "name": "API Health Check", "thresholds": {}, "url": "https://app.dash0.com/check-rules/check_101" } ], "dataset": "default", "description": "Synthetic check detected failures for API health endpoint.", "end": "", "id": "issue_789", "issueIdentifier": "synthetic-check-api-health", "labels": [ [ "0", { "key": "dash0.resource.type", "value": { "stringValue": "synthetic" } } ], [ "1", { "key": "dash0.synthetic_check.attempt_id", "value": { "stringValue": "73768e2c" } } ], [ "2", { "key": "dash0.synthetic_check.failed_critical_assertions", "value": { "stringValue": "{\"be-brussels\":[{\"actualValue\":\"503\",\"assertion\":{\"kind\":\"status_code\",\"spec\":{\"operator\":\"is\",\"value\":\"200\"}},\"explanation\":\"Expected value to be 200, but got 503\"}]}" } } ], [ "3", { "key": "dash0.synthetic_check.id", "value": { "stringValue": "api-health-check" } } ], [ "4", { "key": "dash0.synthetic_check.name", "value": { "stringValue": "API Health Check" } } ] ], "start": "2026-02-20T12:00:00Z", "status": "critical", "summary": "Synthetic check failed: API Health Check", "url": "https://app.dash0.com/issues/issue_789" } }, "timestamp": "2026-02-20T12:00:00Z", "type": "dash0.syntheticCheckNotification" } ``` ## Create Check Rule **Component key:** `dash0.createCheckRule` The Create Check Rule component creates a Prometheus-style alert check rule in Dash0 to monitor metrics and trigger alerts based on PromQL expressions. ### Use Cases - **Service health monitoring**: Create alerts for service error rates, latency, or availability - **Resource monitoring**: Alert on high CPU, memory, or disk usage - **Business metrics**: Monitor key business metrics and trigger alerts when thresholds are exceeded - **SLO enforcement**: Create alerts based on Service Level Objectives (SLOs) ### Configuration #### Name & Expression - **Name**: Human-readable name for the check rule - **Expression**: PromQL expression to evaluate. Supports $__threshold variable for dynamic thresholding #### Thresholds - **Degraded**: Threshold value for degraded state (warning) - **Critical**: Threshold value for critical state (alert) - Required when using $__threshold in the expression #### Evaluation - **Interval**: How often to evaluate the expression (1m, 5m, 10m) - **For**: Grace period before triggering (pending duration) - **Keep Firing For**: Grace period before resolving (resolution duration) #### Metadata - **Summary**: Short templatable summary (max 255 chars) - **Description**: Detailed templatable description (max 2048 chars) - **Labels**: Prometheus labels for routing and grouping - **Annotations**: Prometheus annotations for additional context #### Control - **Enabled**: Whether the check rule is active - **Dataset**: Dash0 dataset to query (defaults to "default") ### Output Returns the created check rule details from the Dash0 API, including the rule ID and full configuration. ### Example Output ```json { "data": { "annotations": { "runbook": "https://wiki.example.com/runbooks/high-error-rate", "summary": "Error rate is {{ $value }} errors/sec" }, "dataset": "default", "description": "The error rate has exceeded the configured threshold", "enabled": true, "expression": "sum(rate(http_requests_total{status=~\"5..\"}[5m])) \u003e $__threshold", "for": "0s", "id": "high-error-rate-alert", "interval": "1m", "keepFiringFor": "0s", "labels": { "severity": "high", "team": "backend" }, "name": "High error rate alert", "summary": "Error rate is high", "thresholds": { "critical": 50, "degraded": 10 } }, "timestamp": "2026-03-06T12:00:00Z", "type": "dash0.checkRule.created" } ``` ## Create HTTP Synthetic Check **Component key:** `dash0.createHttpSyntheticCheck` The Create Synthetic Check component creates an HTTP synthetic check in Dash0 to monitor the availability and performance of your endpoints. ### Use Cases - **Uptime monitoring**: Create checks to monitor API endpoints and websites - **Performance validation**: Set response time thresholds to catch regressions - **Deployment verification**: Create synthetic checks after deployments to verify availability - **Multi-region monitoring**: Monitor endpoints from multiple global locations ### Configuration #### Name & Dataset - **Name**: Display name of the synthetic check - **Dataset**: The Dash0 dataset to create the check in (defaults to "default") #### Request - **URL**: Target URL to monitor - **Method**: HTTP method (GET, POST, PUT, PATCH, DELETE, HEAD) - **Redirects**: Whether to follow HTTP redirects - **Allow Insecure**: Skip TLS certificate validation (useful for staging environments) - **Headers**: Custom HTTP request headers - **Body**: Request body payload (for POST/PUT/PATCH) #### Schedule - **Interval**: How often the check runs (e.g. 30s, 1m, 5m, 1h, 2d) - **Locations**: Probe locations (Frankfurt, Oregon, North Virginia, London, Brussels, Melbourne) - **Strategy**: Execution strategy (all locations or round-robin) #### Assertions Each assertion has a kind, severity (critical or degraded), and kind-specific parameters: - **Status Code**: Validate the HTTP response status code - **Timing**: Set thresholds for response, request, SSL, connection, DNS, or total time - **Error Type**: Detect specific error types (DNS, connection, SSL, timeout) - **SSL Certificate Validity**: Enforce minimum days until certificate expiration - **Response Header**: Validate presence or value of a specific response header - **JSON Body**: Validate JSON response fields using JSONPath expressions - **Text Body**: Match plain-text response content #### Retries - **Attempts**: Number of retry attempts on failure - **Delay**: Delay between retries (e.g. 1s, 2s, 5s) ### Output Returns the created synthetic check details from the Dash0 API, including the check ID and full configuration. ### Example Output ```json { "data": { "kind": "Dash0SyntheticCheck", "metadata": { "annotations": {}, "labels": { "dash0.com/dataset": "default", "dash0.com/id": "64617368-3073-796e-7468-abc123def456", "dash0.com/origin": "api-abc12345-6789-0123-4567-890abcdef012", "dash0.com/version": "1" }, "name": "login-api-health-check" }, "spec": { "enabled": true, "plugin": { "display": { "name": "Login API health check" }, "kind": "http", "spec": { "assertions": { "criticalAssertions": [ { "kind": "status_code", "spec": { "operator": "is", "value": "200" } }, { "kind": "timing", "spec": { "operator": "lte", "type": "response", "value": "5000ms" } } ], "degradedAssertions": [ { "kind": "timing", "spec": { "operator": "lte", "type": "response", "value": "2000ms" } } ] }, "request": { "headers": [], "method": "get", "queryParameters": [], "redirects": "follow", "tls": { "allowInsecure": false }, "tracing": { "addTracingHeaders": true }, "url": "https://api.example.com/health" }, "retries": { "kind": "fixed", "spec": { "attempts": 3, "delay": "1s" } } } }, "schedule": { "interval": "1m", "locations": [ "de-frankfurt", "us-oregon" ], "strategy": "all_locations" } } }, "timestamp": "2026-01-19T12:00:00Z", "type": "dash0.syntheticCheck.created" } ``` ## Delete Check Rule **Component key:** `dash0.deleteCheckRule` The Delete Check Rule component removes a check rule (Prometheus alert rule) from Dash0 by its ID or origin. Use the check rule ID from a Create/Get/Update output or from the Dash0 dashboard. ### Use Cases - **Cleanup**: Remove obsolete or test check rules - **Automation**: Delete check rules as part of automated workflows - **Resource management**: Clean up check rules when services are decommissioned ### Configuration - **Check Rule**: The Dash0 check rule ID or origin to delete (required) - **Dataset**: The dataset the check rule belongs to (defaults to "default") ### Output Returns a confirmation payload indicating successful deletion. ### Example Output ```json { "data": { "deleted": true, "id": "api-b8dad545-7920-49f9-96be-df053cda312d" }, "timestamp": "2026-03-06T12:00:00Z", "type": "dash0.checkRule.deleted" } ``` ## Delete HTTP Synthetic Check **Component key:** `dash0.deleteHttpSyntheticCheck` The Delete HTTP Synthetic Check component removes a synthetic check from Dash0 by its ID. Use the check ID from a Create/Get/Update output (e.g. metadata.labels["dash0.com/id"]) or from the Dash0 dashboard. ### Configuration - **Check ID**: The Dash0 synthetic check ID to delete (required). - **Dataset**: The dataset the check belongs to (defaults to "default"). ### Output Returns a confirmation payload (e.g. deleted id). ### Example Output ```json { "data": { "deleted": true, "id": "64617368-3073-796e-7468-abc123def456" }, "timestamp": "2026-01-19T12:00:00Z", "type": "dash0.syntheticCheck.deleted" } ``` ## Get Check Rule **Component key:** `dash0.getCheckRule` The Get Check Rule component retrieves the full configuration of an existing check rule (Prometheus alert rule) from Dash0. ### Use Cases - **Configuration review**: Fetch current check rule settings for audit or documentation - **Workflow integration**: Retrieve check rule details to use in subsequent workflow steps - **Health monitoring**: Check if alert rules are properly configured ### Configuration - **Check Rule**: The ID or origin of the check rule to retrieve (from Dash0) - **Dataset**: The Dash0 dataset the check rule belongs to (defaults to "default") ### Output Returns the complete check rule configuration from the Dash0 API, including: - Name and expression (PromQL query) - Thresholds (degraded and critical) - Evaluation settings (interval, for, keepFiringFor) - Labels and annotations - Enabled status ### Example Output ```json { "data": { "annotations": { "runbook": "https://wiki.example.com/runbooks/high-error-rate", "summary": "Error rate is {{ $value }} errors/sec" }, "dataset": "default", "description": "The error rate has exceeded the configured threshold", "enabled": true, "expression": "sum(rate(http_requests_total{status=~\"5..\"}[5m])) \u003e $__threshold", "for": "0s", "id": "high-error-rate-alert", "interval": "1m", "keepFiringFor": "0s", "labels": { "severity": "high", "team": "backend" }, "name": "High error rate alert", "summary": "Error rate is high", "thresholds": { "critical": 50, "degraded": 10 } }, "timestamp": "2026-03-06T12:00:00Z", "type": "dash0.checkRule.fetched" } ``` ## Get HTTP Synthetic Check **Component key:** `dash0.getHttpSyntheticCheck` The Get HTTP Synthetic Check component retrieves the full configuration and operational metrics of an existing HTTP synthetic check from Dash0. ### Use Cases - **Health dashboards**: Fetch current uptime and performance metrics for display in workflows - **Audit and reporting**: Retrieve check configurations for compliance or documentation - **Incident response**: Quickly gather check status and recent performance data during incidents ### Configuration - **Check ID**: The ID of the synthetic check to retrieve (from Dash0) - **Dataset**: The Dash0 dataset the check belongs to (defaults to "default") ### Output Channels - **Healthy**: The check is passing — the most recent run outcome is "Healthy" - **Degraded**: The check is degraded — the most recent run outcome is "Degraded" - **Critical**: The check is failing — the most recent run outcome is "Critical" ### Output Returns a combined payload with: #### Configuration The full synthetic check configuration from the Dash0 API, including: - Name, URL, HTTP method - Schedule (interval, locations, strategy) - Assertions (critical and degraded thresholds) - Retry settings #### Metrics Operational metrics from the Dash0 Prometheus API: - **Healthy Runs (24h/7d)**: Number of successful check runs - **Critical Runs (24h/7d)**: Number of failed check runs - **Total Runs (24h/7d)**: Total number of check runs - **Avg Duration (24h/7d)**: Mean end-to-end response time (in milliseconds) - **Last Outcome**: Most recent run outcome (Healthy or Critical) Note: Metrics are fetched on a best-effort basis. If Prometheus metrics are unavailable for a check, the configuration is still returned with null metric values. ### Example Output ```json { "data": { "configuration": { "kind": "Dash0SyntheticCheck", "metadata": { "annotations": {}, "description": "", "labels": { "dash0.com/dataset": "default", "dash0.com/id": "64617368-3073-796e-7468-73599f287bf4", "dash0.com/origin": "", "dash0.com/version": "21" }, "name": "New synthetic check" }, "spec": { "display": { "name": "New synthetic check" }, "enabled": true, "labels": {}, "notifications": { "channels": [], "onlyCriticalChannels": [] }, "plugin": { "kind": "http", "spec": { "assertions": { "criticalAssertions": [ { "kind": "status_code", "spec": { "operator": "is", "value": "200" } } ], "degradedAssertions": [ { "kind": "timing", "spec": { "operator": "lte", "type": "total", "value": "2000ms" } } ] }, "request": { "headers": [], "method": "get", "queryParameters": [], "redirects": "follow", "tls": { "allowInsecure": false }, "tracing": { "addTracingHeaders": true }, "url": "https://example.com/health" } } }, "retries": { "kind": "off", "spec": {} }, "schedule": { "interval": "1m", "locations": [ "be-brussels" ], "strategy": "all_locations" } } }, "metrics": { "avgDuration24hMs": 1004, "avgDuration7dMs": 1004, "criticalRuns24h": 2275, "criticalRuns7d": 2438, "healthyRuns24h": 6, "healthyRuns7d": 37, "lastOutcome": "Healthy", "totalRuns24h": 2281, "totalRuns7d": 2475 } }, "timestamp": "2026-03-03T11:00:00Z", "type": "dash0.syntheticCheck.fetched" } ``` ## List Issues **Component key:** `dash0.listIssues` The List Issues component queries Dash0 to retrieve all current issues and routes execution based on issue severity. ### Use Cases - **Health monitoring**: Check system health and route based on issue severity - **Alert routing**: Route alerts to different channels based on issue status - **Issue tracking**: Monitor and process active issues - **Automated remediation**: Trigger remediation workflows based on issues ### Configuration - **Check Rules**: Optional list of check rules to filter issues (leave empty to get all issues) ### Output Channels - **Clear**: No active issues detected - **Degraded**: One or more degraded issues detected - **Critical**: One or more critical issues detected ### Output Returns a list of issues with: - **check_rule**: The check rule that generated the issue - **status**: Issue status (clear, degraded, critical) - **labels**: Metric labels associated with the issue - **metadata**: Additional issue metadata ### Example Output ```json { "data": { "data": { "result": [ { "metric": { "service_name": "test" }, "value": [ 1234567890, "1" ], "values": [ [ 1234567890, "1" ], [ 1234567900, "2" ] ] } ], "resultType": "vector" }, "status": "success" }, "timestamp": "2026-01-19T12:00:00Z", "type": "dash0.issues.list" } ``` ## Query Prometheus **Component key:** `dash0.queryPrometheus` The Query Prometheus component executes PromQL queries against the Dash0 Prometheus API. ### Use Cases - **Metrics monitoring**: Query application and infrastructure metrics - **Alerting**: Check metric thresholds and trigger alerts - **Data analysis**: Analyze time-series data from your applications - **Performance monitoring**: Monitor system performance metrics ### Configuration - **PromQL Query**: The Prometheus Query Language query to execute (supports expressions) - **Dataset**: The dataset to query (default: "default") - **Query Type**: - **Instant**: Query a single point in time - **Range**: Query a time range with optional start, end, and step parameters ### Output Returns the Prometheus query response including: - **status**: Query status (success or error) - **data**: Query results with metric labels and values - **dataType**: Result type (vector, matrix, scalar, or string) ### Notes - Requires Dash0 API token and base URL configured in application settings - Supports all standard PromQL functions and operators - Range queries require start, end, and step parameters ### Example Output ```json { "data": { "data": { "result": [ { "metric": { "service_name": "test" }, "value": [ 1234567890, "1" ], "values": [ [ 1234567890, "1" ], [ 1234567900, "2" ] ] } ], "resultType": "vector" }, "status": "success" }, "timestamp": "2026-01-19T12:00:00Z", "type": "dash0.prometheus.response" } ``` ## Send Log Event **Component key:** `dash0.sendLogEvent` The Send Log Event component sends log records from workflows to Dash0 via OTLP HTTP ingestion. ### Use Cases - **Audit trails**: Record workflow events (deployments, approvals, alerts) as log lines - **Observability correlation**: Tie workflow activity to traces and metrics in Dash0 - **Event tracking**: Create searchable log entries for workflow milestones - **Debugging**: Send diagnostic information from workflows to Dash0 Logs Explorer ### Configuration - **Severity**: Log severity level (TRACE, DEBUG, INFO, WARN, ERROR, FATAL) - **Event Name**: Optional name for this log event (e.g. deployment.completed) - **Service Name**: Optional service identifier (becomes OTLP resource attribute 'service.name') - **Body**: The log message content (plain text or JSON string) - **Attributes**: Optional key-value pairs for additional log metadata - **Dataset**: Optional dataset name for log organization (defaults to "default") ### Output Returns a confirmation that the log was sent along with the log record details: - **sent**: Boolean indicating success - **severityText**: The log severity level - **body**: The log message content - **eventName**: The event name (if provided) - **serviceName**: The service name (if provided) - **attributes**: Additional metadata (if provided) - **dataset**: The dataset name - **timestamp**: When the log was sent ### Notes - Requires Dash0 API token and base URL configured in application settings - Logs appear in Dash0 Logs Explorer and can be correlated with traces and metrics - Use INFO severity for normal workflow events, WARN/ERROR for issues ### Example Output ```json { "data": { "attributes": { "env": "production" }, "body": "Deployment started", "dataset": "default", "eventName": "deployment.created", "sent": true, "serviceName": "api-gateway", "severityText": "INFO" }, "timestamp": "2026-03-11T16:05:54.753430237Z", "type": "dash0.log.sent" } ``` ## Update Check Rule **Component key:** `dash0.updateCheckRule` The Update Check Rule component updates an existing check rule (Prometheus alert rule) in Dash0. Use the check rule ID from a previous Create Check Rule output or from the Dash0 dashboard. ### Use Cases - **Threshold adjustment**: Update alert thresholds based on changing conditions - **Expression refinement**: Modify the PromQL query to better detect issues - **Notification changes**: Update labels and annotations for better routing - **Enable/disable**: Temporarily disable check rules during maintenance ### Configuration - **Check Rule**: The Dash0 check rule ID to update (required) - **Dataset**: The dataset the check rule belongs to (defaults to "default") - **Name**, **Expression**, **Thresholds**, **Interval**, etc.: Same as Create Check Rule; the full spec is sent to replace the existing check rule ### Output Returns the updated check rule details from the Dash0 API, including the rule ID and full configuration. ### Example Output ```json { "data": { "annotations": { "runbook": "https://wiki.example.com/runbooks/high-error-rate", "summary": "Error rate is {{ $value }} errors/sec" }, "dataset": "default", "description": "The error rate has exceeded the configured threshold", "enabled": true, "expression": "sum(rate(http_requests_total{status=~\"5..\"}[5m])) \u003e $__threshold", "for": "30s", "id": "high-error-rate-alert", "interval": "1m", "keepFiringFor": "5m", "labels": { "severity": "high", "team": "backend" }, "name": "High error rate alert", "summary": "Error rate is high", "thresholds": { "critical": 75, "degraded": 15 } }, "timestamp": "2026-03-06T12:00:00Z", "type": "dash0.checkRule.updated" } ``` ## Update HTTP Synthetic Check **Component key:** `dash0.updateHttpSyntheticCheck` The Update HTTP Synthetic Check component updates an existing synthetic check in Dash0. Use the check ID from a previous Create HTTP Synthetic Check output (e.g. metadata.labels["dash0.com/id"]) or from the Dash0 dashboard. ### Configuration - **Check ID**: The Dash0 synthetic check ID to update (required). - **Dataset**: The dataset the check belongs to (defaults to "default"). - **Name**, **Request**, **Schedule**, **Assertions**, **Retries**: Same as Create HTTP Synthetic Check; the full spec is sent to replace the existing check. ### Example Output ```json { "data": { "kind": "Dash0SyntheticCheck", "metadata": { "annotations": {}, "labels": { "dash0.com/dataset": "default", "dash0.com/id": "64617368-3073-796e-7468-abc123def456", "dash0.com/origin": "api-abc12345-6789-0123-4567-890abcdef012", "dash0.com/version": "2" }, "name": "login-api-health-check" }, "spec": { "enabled": true, "plugin": { "display": { "name": "Login API health check" }, "kind": "http", "spec": { "assertions": { "criticalAssertions": [ { "kind": "status_code", "spec": { "operator": "is", "value": "200" } } ], "degradedAssertions": [] }, "request": { "headers": [], "method": "get", "queryParameters": [], "redirects": "follow", "tls": { "allowInsecure": false }, "tracing": { "addTracingHeaders": true }, "url": "https://api.example.com/health" }, "retries": { "kind": "fixed", "spec": { "attempts": 3, "delay": "1s" } } } }, "schedule": { "interval": "1m", "locations": [ "de-frankfurt", "us-oregon" ], "strategy": "all_locations" } } }, "timestamp": "2026-01-19T12:00:00Z", "type": "dash0.syntheticCheck.updated" } ``` #### Datadog Source URL: https://docs.superplane.com/components/datadog Create events in Datadog import { CardGrid, LinkCard } from "@astrojs/starlight/components"; ## Actions ## Instructions To configure Datadog to work with SuperPlane: 1. **Get API Keys**: In Datadog, go to Organization Settings > API Keys to get your API Key 2. **Get Application Key**: Go to Organization Settings > Application Keys to create an Application Key 3. **Select Site**: Choose the Datadog site that matches your account (US1, US3, US5, EU, or AP1) 4. **Enter Credentials**: Provide your API Key, Application Key, and Site in the integration configuration ## Create Event **Component key:** `datadog.createEvent` The Create Event component creates a new event in Datadog. ### Use Cases - **Deployment tracking**: Log deployment events to correlate with metrics - **Incident annotation**: Add context to incidents with custom events - **Workflow notifications**: Create events to track workflow execution milestones ### Outputs The component emits an event containing: - `id`: The unique identifier of the created event - `title`: The event title - `text`: The event body - `date_happened`: Unix timestamp when the event occurred - `alert_type`: The severity level (info, warning, error, success) - `priority`: Event priority (normal, low) - `tags`: Array of tags attached to the event - `url`: Link to view the event in Datadog ### Example Output ```json { "data": { "alert_type": "info", "date_happened": 1704067200, "id": 1234567890, "priority": "normal", "tags": [ "env:prod", "service:web" ], "text": "Application v1.2.3 has been deployed successfully", "title": "Deployment completed", "url": "https://app.datadoghq.com/event/event?id=1234567890" }, "timestamp": "2026-01-19T12:00:00Z", "type": "datadog.event" } ``` #### Daytona Source URL: https://docs.superplane.com/components/daytona Execute code in isolated sandbox environments import { CardGrid, LinkCard } from "@astrojs/starlight/components"; ## Actions ## Create Repository Sandbox **Component key:** `daytona.createRepositorySandbox` The Create Repository Sandbox component creates a new Daytona sandbox, clones a repository, and runs a bootstrap script. ### Use Cases - **Ephemeral dev environments**: Spin up a fresh environment for a repository on demand - **CI-like workflows**: Clone code and run setup scripts before downstream tasks - **Automated validation**: Prepare repository state before executing tests or commands ### Notes - The component waits for the sandbox to reach the "started" state - Clone and bootstrap run sequentially in the same session - If clone or bootstrap fails, the component returns an error ### Example Output ```json { "data": { "bootstrap": { "from": "file", "path": "scripts/bootstrap.sh" }, "directory": "/home/daytona/example-app", "repository": "https://github.com/superplanehq/example-app.git", "sandboxId": "sandbox-abc123def456", "sandboxStartedAt": "2026-01-19T12:00:00Z", "secrets": [ { "name": "API_KEY", "type": "env", "value": { "key": "API_KEY", "secret": "api-key-secret" } } ], "timeout": 300 }, "timestamp": "2026-01-19T12:00:00Z", "type": "daytona.repository.sandbox" } ``` ## Create Sandbox **Component key:** `daytona.createSandbox` The Create Sandbox component creates an isolated environment for executing code safely. ### Use Cases - **AI code execution**: Run AI-generated code in a secure sandbox - **Code testing**: Test untrusted code without affecting your infrastructure - **Development environments**: Create ephemeral development environments ### Common Pattern Use this pattern when you want to create a sandbox, run one or more commands in it, and delete it when the flow is done. 1. Add a **Create Sandbox** node. Its output includes the sandbox ID that downstream nodes need: ```json { "data": { "id": "sandbox-abc123def456", "state": "started" }, "type": "daytona.sandbox" } ``` 2. Connect an **Execute Command** node immediately after **Create Sandbox** and set **Sandbox** to: ```text {{ previous().data.id }} ``` 3. **Execute Command** returns the command result, not the sandbox ID: ```json { "data": { "exitCode": 0, "result": "npm test\nPASS\n", "timeout": false }, "type": "daytona.command.response" } ``` 4. If you add more command nodes, reference the original create node by name so every command uses the same sandbox: ```text {{ $["Create Sandbox"].data.id }} ``` 5. Add **Delete Sandbox** at the end of the flow and use the same sandbox reference: ```text {{ $["Create Sandbox"].data.id }} ``` ### Configuration - **Snapshot**: Base environment snapshot (optional, uses default if not specified) - **Target**: Target region for the sandbox (optional) - **Auto Stop Interval**: Time in minutes before the sandbox auto-stops - **Environment Variables**: Key-value pairs to set as environment variables in the sandbox ### Output Returns the sandbox information including: - **id**: The unique sandbox identifier (use this in subsequent execute/delete operations) - **state**: The current state of the sandbox (e.g., "started") ### Notes - The component polls the sandbox state until it reaches "started" - Each sandbox is fully isolated - Remember to delete sandboxes when done to free resources ### Example Output ```json { "data": { "id": "sandbox-abc123def456", "state": "started" }, "timestamp": "2026-01-19T12:00:00Z", "type": "daytona.sandbox" } ``` ## Delete Sandbox **Component key:** `daytona.deleteSandbox` The Delete Sandbox component removes an existing Daytona sandbox. ### Use Cases - **Resource cleanup**: Delete sandboxes after code execution is complete - **Cost management**: Remove unused sandboxes to free resources - **Workflow cleanup**: Clean up sandboxes at the end of automation workflows ### Configuration - **Sandbox**: The ID or name of the sandbox to delete. If this node runs immediately after **Create Sandbox**, use `{{ previous().data.id }}`. If it runs after one or more command nodes, use `{{ $["Create Sandbox"].data.id }}` so the cleanup step still points to the original sandbox. - **Force**: Optional flag to force deletion even if sandbox is running ### Output Returns deletion confirmation including: - **deleted**: Boolean indicating successful deletion - **id**: The ID of the deleted sandbox ### Notes - Always delete sandboxes when they are no longer needed - Sandboxes will auto-stop after the configured interval, but explicit deletion frees resources immediately ### Example Output ```json { "data": { "deleted": true, "id": "sandbox-abc123def456" }, "timestamp": "2026-01-19T12:00:00Z", "type": "daytona.delete.response" } ``` ## Execute Code **Component key:** `daytona.executeCode` The Execute Code component runs code in an existing Daytona sandbox. ### Use Cases - **AI code execution**: Run AI-generated code safely - **Code testing**: Execute untrusted code in isolation - **Script automation**: Run Python, TypeScript, or JavaScript scripts - **Data processing**: Execute data transformation scripts ### Configuration - **Sandbox**: The sandbox ID to execute code in (from Create Sandbox or Create Repository Sandbox output). Supports expressions, e.g. `{{ previous().data.id }}` or `{{ $["Create Repository Sandbox"].data.sandboxId }}` - **Code**: The code to execute (supports expressions) - **Language**: The programming language (python, typescript, javascript) - **Timeout**: Optional execution timeout in milliseconds ### Output Returns the execution result including: - **exitCode**: The process exit code (0 for success) - **result**: The stdout/output from the code execution ### Notes - The sandbox must be created first using createSandbox - Code output is captured from stdout - Non-zero exit codes indicate execution errors ### Example Output ```json { "data": { "exitCode": 0, "result": "Hello, World!\n" }, "timestamp": "2026-01-19T12:00:00Z", "type": "daytona.execute.response" } ``` ## Execute Command **Component key:** `daytona.executeCommand` The Execute Command component runs shell commands in an existing Daytona sandbox. ### Use Cases - **Package installation**: Install dependencies (pip install, npm install) - **File operations**: Create, move, or delete files in the sandbox - **System commands**: Run any shell command in the isolated environment - **Build processes**: Execute build scripts or compilation commands ### Configuration - **Sandbox**: The sandbox ID to run commands in (from **Create Sandbox** or **Create Repository Sandbox** output). Supports expressions, e.g. `{{ previous().data.id }}` or `{{ $["Create Repository Sandbox"].data.sandboxId }}` - **Command**: The shell command to execute - **Working Directory**: Optional working directory for the command - **Environment Variables**: Optional key-value pairs exported before command execution - **Timeout**: Optional execution timeout in seconds ### Common Patterns When **Execute Command** runs immediately after **Create Sandbox**, set **Sandbox** to: ```text {{ previous().data.id }} ``` If you want to run a second or third command in the same sandbox, keep referencing the original create node by name: ```text {{ $["Create Sandbox"].data.id }} ``` This is more reliable than `previous()` once the previous node is another **Execute Command** node. ### Output Routes to one of two channels: - **success**: Exit code is 0 - **failed**: Exit code is non-zero The payload includes: - **exitCode**: The process exit code (0 for success) - **timeout**: Whether the command timed out - **result**: The stdout/output from the command execution ### Notes - The sandbox must be created first using createSandbox - Commands run in a shell environment - Non-zero exit codes indicate command failures ### Example Output ```json { "data": { "exitCode": 0, "result": "Successfully installed requests-2.31.0\n", "timeout": false }, "timestamp": "2026-01-19T12:00:00Z", "type": "daytona.command.response" } ``` ## Get Preview URL **Component key:** `daytona.getPreviewUrl` The Get Preview URL component generates a Daytona preview URL for a specific sandbox port. ### Use Cases - **Open sandbox web apps**: Access a web app running in a sandbox from a browser - **Share previews**: Generate signed URLs that can be opened without custom headers - **Automation**: Generate preview links for downstream steps and notifications ### Configuration - **Sandbox**: Sandbox to generate the preview URL for - **Port**: Sandbox port to preview (default: 3000) - **Signed URL**: Whether to generate a signed preview URL (default: true) - **Expires In Seconds**: Signed URL expiration in seconds (default: 60, max: 86400) ### URL Formats - **Standard URL** (`signed=false`): `https://{port}-{sandboxId}.{daytonaProxyDomain}` Requires `x-daytona-preview-token` header with the returned token - **Signed URL** (`signed=true`): `https://{port}-{token}.{daytonaProxyDomain}` Authentication is embedded in the URL, no custom header required ### Output Returns preview URL information including: - **sandbox**: The sandbox ID used in the request - **port**: The target sandbox port - **signed**: Whether the generated URL is signed - **url**: Generated preview URL - **token**: Preview token (embedded token for signed URLs, header token for standard URLs) - **expiresInSeconds**: Expiration for signed URLs ### Notes - The target port must be serving HTTP traffic in the sandbox, otherwise preview access may fail - Signed URLs can be opened directly in browsers - Standard URLs require `x-daytona-preview-token` header for private sandboxes ### Example Output ```json { "data": { "expiresInSeconds": 3600, "port": 3000, "sandbox": "sandbox-abc123def456", "signed": true, "token": "signed-token-abc123", "url": "https://3000-signed-token-abc123.preview.daytona.app" }, "timestamp": "2026-01-19T12:00:00Z", "type": "daytona.preview.response" } ``` #### DigitalOcean Source URL: https://docs.superplane.com/components/digitalocean Manage and monitor your DigitalOcean infrastructure import { CardGrid, LinkCard } from "@astrojs/starlight/components"; ## Actions ## Instructions ## DigitalOcean Personal Access Token Generate a [DigitalOcean Personal Access Token](https://cloud.digitalocean.com/account/api/tokens) and copy it. - Token name: `SuperPlane Integration` - Expiration: **No expiry** (or choose an appropriate expiration) - Scopes: **Full Access** (or customize as needed) ## Access Key (optional) Only required for **Spaces Object Storage** components. Create an [Access Key ID & Secret Access Key](https://cloud.digitalocean.com/spaces/access_keys) and copy the generated pair. - Scope: **Full Access** (all buckets) or **Limited Access** (specific buckets) > **Note:** The Personal Access Token and Secret Access Key are shown only once — store them somewhere safe before continuing. ## Add Data Source **Component key:** `digitalocean.addDataSource` The Add Data Source component adds a new data source to an existing knowledge base on the DigitalOcean Gradient AI Platform. ### How it works Adds a single data source — either a Spaces bucket or a web/sitemap URL — to a knowledge base. When **Index after adding** is enabled (the default), the component also starts an indexing job and waits for it to complete before emitting the output. ### Data Source Types - **Spaces Bucket or Folder** — indexes all supported files in a DigitalOcean Spaces bucket or folder - **Web or Sitemap URL** — crawls a public website (seed URL) or a list of URLs from a sitemap ### Chunking Strategies Each data source has its own independent chunking configuration: - **Section-based** (default) — splits on structural elements like headings and paragraphs; fast and low-cost - **Semantic** — groups sentences by meaning; slower but context-aware - **Hierarchical** — creates parent (context) and child (retrieval) chunk pairs - **Fixed-length** — splits strictly by token count; best for logs and unstructured text ### Indexing When **Index after adding** is enabled, the component starts an indexing job scoped **only to the newly added data source** and polls every 30 seconds until the job completes. Other existing data sources in the knowledge base are not re-indexed. Disable it if you want to add multiple data sources first and index them all at once using the Index Knowledge Base component. ### Output Returns the added data source details: - **dataSourceUUID**: UUID of the newly added data source - **knowledgeBaseUUID**: UUID of the knowledge base - **knowledgeBaseName**: Name of the knowledge base When indexing is enabled, the output also includes: - **indexingJob**: Full indexing job details (status, totalTokens, completedDataSources, totalDataSources, startedAt, finishedAt) ### Example Output ```json { "data": { "dataSourceName": "https://example.com/", "dataSourceUUID": "e374bb5e-33e6-11f1-b074-4e01edede4", "indexingJob": { "completedDataSources": 1, "finishedAt": "2026-04-09T07:37:51Z", "startedAt": "2026-04-09T07:36:58Z", "status": "INDEX_JOB_STATUS_COMPLETED", "totalDataSources": 1, "totalTokens": "21" }, "knowledgeBaseName": "ecommerce-knowledge-base", "knowledgeBaseUUID": "3b88fe18-31bb-11f1-b074-4e013hhjte4" }, "timestamp": "2026-04-09T07:38:01.304486131Z", "type": "digitalocean.data_source.added" } ``` ## Assign Reserved IP **Component key:** `digitalocean.assignReservedIP` The Assign Reserved IP component assigns or unassigns a DigitalOcean Reserved IP to a droplet. ### Use Cases - **Blue/green deployments**: Reassign a reserved IP to the new deployment with zero downtime - **Failover**: Quickly reassign a reserved IP from a failed droplet to a healthy replacement - **Maintenance**: Temporarily unassign a reserved IP while a droplet is being serviced ### Configuration - **Reserved IP**: The reserved IP address to manage (required) - **Action**: The operation to perform: assign or unassign (required) - **Droplet ID**: The target droplet for the assignment (required when action is assign) ### Output Returns the action result including: - **id**: Action ID - **status**: Final action status (completed) - **type**: Type of action performed (assign or unassign) - **started_at**: When the action started - **completed_at**: When the action completed - **resource_id**: Reserved IP resource identifier ### Important Notes - The component polls until the action completes - For **assign**, the reserved IP will be unassigned from any current droplet first - For **unassign**, the **Droplet ID** field is ignored ### Example Output ```json { "data": { "completed_at": "2026-03-13T10:10:05Z", "id": 2048576123, "region_slug": "nyc3", "resource_id": 2335912909, "resource_type": "floating_ip", "started_at": "2026-03-13T10:10:00Z", "status": "completed", "type": "assign_ip" }, "timestamp": "2026-03-13T10:10:08.000000000Z", "type": "digitalocean.reservedip.assign" } ``` ## Attach Knowledge Base **Component key:** `digitalocean.attachKnowledgeBase` The Attach Knowledge Base component connects a knowledge base to an existing Gradient AI agent, enabling the agent to use it for retrieval-augmented generation (RAG). ### Use Cases - **Post-creation wiring**: After creating a new knowledge base, attach it to an agent to make it immediately available - **Blue/green KB deployment**: Attach a newly indexed knowledge base to an agent as part of a promotion pipeline - **Multi-KB agents**: Add additional knowledge bases to an agent that already has others attached ### Configuration - **Agent**: The agent to attach the knowledge base to (required) - **Knowledge Base**: The knowledge base to attach — only shows knowledge bases not already attached to the selected agent (required) ### Output Returns confirmation of the attachment including: - **agentUUID**: UUID of the agent - **knowledgeBaseUUID**: UUID of the attached knowledge base ### Example Output ```json { "data": { "agentUUID": "20cd8434-6ea1-11f0-bf8f-4e013e2ddde4", "knowledgeBaseUUID": "a1b2c3d4-0000-0000-0000-000000000001" }, "timestamp": "2025-01-01T00:00:00Z", "type": "digitalocean.knowledge_base.attached" } ``` ## Copy Object **Component key:** `digitalocean.copyObject` The Copy Object component copies an object from one location to another within DigitalOcean Spaces. When **Delete Source** is enabled, the source object is deleted after a successful copy, effectively moving the object. ### Prerequisites Spaces Access Key ID and Secret Access Key must be configured in the DigitalOcean integration settings. ### Configuration - **Source Bucket**: The bucket containing the object to copy - **Source File Path**: The path to the source object (e.g. reports/daily.csv). Supports expressions. - **Destination Bucket**: The bucket to copy the object into (can be the same bucket) - **Destination File Path**: The path for the copied object (e.g. archive/2026/daily.csv). Supports expressions. - **Visibility**: Access control for the destination object — Private (default) or Public - **Delete Source**: When enabled, the source object is deleted after a successful copy (move operation) ### Output - **sourceBucket**: The source bucket name - **sourceFilePath**: The source object path - **destinationBucket**: The destination bucket name - **destinationFilePath**: The destination object path - **endpoint**: The full Spaces URL of the copied object - **eTag**: MD5 hash of the copied object - **moved**: `true` if the source was deleted, `false` otherwise ### Notes - Both buckets must be in the same region - Copying an object to the same path overwrites it - Metadata and tags are copied from the source object by default ### Use Cases - **Archiving**: Move processed files to an archive bucket or folder - **Promotion**: Copy an artifact from a staging bucket to production - **Backup**: Duplicate a file before modifying it - **Renaming**: Move a file to a new path within the same bucket ### Example Output ```json { "data": { "destinationBucket": "my-company-archive", "destinationFilePath": "archive/2026/daily.csv", "eTag": "a1b2c3d4ef567890a1b2c3d4ef567890", "endpoint": "https://my-company-archive.fra1.digitaloceanspaces.com/archive/2026/daily.csv", "moved": false, "sourceBucket": "my-company-assets", "sourceFilePath": "reports/daily.csv" }, "timestamp": "2026-03-25T09:00:00Z", "type": "digitalocean.spaces.object.copied" } ``` ## Create Alert Policy **Component key:** `digitalocean.createAlertPolicy` The Create Alert Policy component creates a monitoring alert policy that triggers notifications when droplet metrics cross defined thresholds. > **Note:** Monitoring is only available for droplets that had monitoring enabled during creation. Droplets created without monitoring will not report metrics or trigger alerts. ### Use Cases - **Capacity management**: Get notified when CPU or memory usage consistently exceeds a safe operating level - **Performance monitoring**: Detect and respond to high load averages or network saturation - **Automated workflows**: Chain downstream actions when infrastructure metrics breach limits ### Configuration - **Description**: Human-readable name for the alert policy (required) - **Metric Type**: The droplet metric to monitor, such as CPU Usage or Memory Usage (required) - **Comparison**: Alert when the value is GreaterThan or LessThan the threshold (required) - **Threshold Value**: The numeric threshold that triggers the alert (required) - **Evaluation Window**: The rolling time window over which the metric is averaged (required) - **Droplets**: Specific droplets to scope the policy to (optional) - **Tags**: Monitor all droplets with matching tags (optional) - **Enabled**: Whether the alert policy is immediately active (default: true) - **Email Notifications**: Email addresses to notify when the alert fires (optional) - **Slack Channel**: Slack channel to post alerts to, e.g. #alerts (optional) - **Slack Webhook URL**: Incoming webhook URL for the Slack workspace (required when Slack Channel is set) ### Output Returns the created alert policy including: - **uuid**: Alert policy UUID for use in Get/Delete operations - **description**: Human-readable description - **type**: Metric type being monitored - **compare**: Comparison operator (GreaterThan/LessThan) - **value**: Threshold value - **window**: Evaluation window - **enabled**: Whether the policy is active - **alerts**: Configured notification channels (email and/or Slack) ### Important Notes - At least one notification channel (email or Slack) is required - **Slack Channel** and **Slack Webhook URL** must be provided together - Scoping by **Droplets** and **Tags** are independent — you can use either, both, or neither (applies to all droplets) ### Example Output ```json { "data": { "alerts": { "email": [ "sammy@digitalocean.com" ] }, "compare": "GreaterThan", "description": "High CPU Usage", "enabled": true, "entities": [ "558899681" ], "tags": [], "type": "v1/insights/droplet/cpu", "uuid": "ffcaf816-f6a5-4b4a-b4c4-e84532755e82", "value": 20, "window": "5m" }, "timestamp": "2026-03-18T09:29:00.308296519Z", "type": "digitalocean.alertpolicy.created" } ``` ## Create App **Component key:** `digitalocean.createApp` The Create App component provisions a new application on DigitalOcean's App Platform from a GitHub, GitLab, or Bitbucket repository. The component requires that you have connected your Git provider in your DigitalOcean account and granted access to the repository you want to deploy. You can do so by creating a sample app in the DigitalOcean control panel as illustrated here: https://docs.digitalocean.com/products/app-platform/getting-started/deploy-sample-apps/ ### Use Cases - **Deploy web services**: Provision web services and APIs with configurable instance sizes and HTTP ports - **Deploy static sites**: Host static websites and single-page applications with custom build and output directories - **Deploy workers**: Run background workers for processing tasks - **Deploy jobs**: Run one-off or scheduled jobs (pre-deploy, post-deploy, or failed-deploy) - **Automated provisioning**: Create app instances as part of infrastructure automation workflows - **Multi-environment setup**: Deploy separate app instances for dev, staging, and production ### Configuration - **Name**: The name for the app (required) - **Region**: The region to deploy the app in (required) - **Component Type**: The type of component - Service, Static Site, Worker, or Job (required, defaults to Service) - **Source Provider**: The source code provider - GitHub, GitLab, or Bitbucket (required) - **Repository**: The repository in owner/repo format (required, shown based on selected provider) - **Branch**: The branch to deploy from (defaults to "main", shown based on selected provider) - **Deploy on Push**: Automatically deploy when code is pushed to the branch (default: true) - **Environment Slug**: The runtime environment/buildpack (e.g., go, node-js, python, html) - **Build Command**: Custom build command (e.g., npm install && npm run build) - **Run Command**: Custom run command for services, workers, and jobs (e.g., npm start) - **Source Directory**: Path to the source code within the repository (defaults to /) - **HTTP Port**: The port the service listens on (services only) - **Instance Size**: The instance size slug (e.g., apps-s-1vcpu-1gb) for services, workers, and jobs - **Instance Count**: Number of instances to run (services, workers, and jobs) - **Output Directory**: Build output directory for static sites (e.g., build, dist, public) - **Index Document**: Index document for static sites (defaults to index.html) - **Error Document**: Custom error document for static sites (e.g., 404.html) - **Catchall Document**: Catchall document for single-page applications (e.g., index.html) - **Environment Variables**: Key-value pairs for environment variables (optional) #### Ingress Configuration - **Ingress Path**: Path prefix for routing traffic to the component (e.g., /api for services, / for static sites) - **CORS Allow Origins**: Origins allowed for Cross-Origin Resource Sharing (e.g., https://example.com) - **CORS Allow Methods**: HTTP methods allowed for CORS requests (e.g., GET, POST, PUT) #### Database Configuration - **Add Database**: Attach a database to the app - **Database Component Name**: Name used to reference the database in env vars (e.g., ${db.DATABASE_URL}) - **Database Engine**: PostgreSQL, MySQL, Redis, or MongoDB - **Database Version**: Engine version (e.g., 16 for PostgreSQL) - **Use Managed Database**: Connect to an existing DigitalOcean Managed Database cluster instead of a dev database - **Database Cluster Name**: Name of the existing managed database cluster (required for managed databases) - **Database Name / User**: Optional database name and user for managed database connections #### VPC Configuration - **VPC**: ID of the VPC to deploy into. Apps in a VPC can communicate with other resources over the private network. ### Output Returns the created app including: - **id**: The unique app ID - **name**: The app name - **default_ingress**: The default ingress URL - **live_url**: The live URL for the app - **region**: The region where the app is deployed - **active_deployment**: Information about the active deployment ### Notes - The app will be created with a single component of the selected type - Deployments are asynchronous and may take several minutes to complete - The component emits an output once the deployment reaches ACTIVE status - If the deployment fails, the component will report the failure - Dev databases are free and suitable for development; use managed databases for production - Use bindable variables (e.g., ${db.DATABASE_URL}) to reference database connection details in environment variables ### Example Output ```json { "data": { "defaultIngress": "https://my-app-22-b6v8c.ondigitalocean.app", "id": "6d8abe1c-7cc5-4db3-b1aa-d9cdd1c127e7", "liveURL": "https://my-app-22-b6v8c.ondigitalocean.app", "name": "my-app-22", "region": { "continent": "Asia", "data_centers": [ "blr1" ], "flag": "india", "label": "Bangalore", "slug": "blr" } }, "timestamp": "2026-03-24T07:01:24.678254095Z", "type": "digitalocean.app.created" } ``` ## Create DNS Record **Component key:** `digitalocean.createDNSRecord` The Create DNS Record component creates a new DNS record for a domain managed by DigitalOcean. ### Use Cases - **Service discovery**: Add A or CNAME records when provisioning new services - **Email routing**: Create MX records for custom mail delivery - **Verification**: Add TXT records for domain ownership verification - **Subdomain management**: Dynamically create subdomains as part of provisioning workflows ### Configuration - **Domain**: The DigitalOcean-managed domain to add the record to (required) - **Type**: The DNS record type (required): A, AAAA, CNAME, MX, NS, TXT, SRV, CAA - **Name**: The subdomain name for the record (required, use @ for root) - **Data**: The record value, e.g. an IP address or hostname (required, supports expressions) - **TTL**: Time-to-live in seconds (optional, defaults to 1800) - **Priority**: Record priority for MX/SRV records (optional) - **Port**: Port number for SRV records (optional) - **Weight**: Weight for SRV records (optional) ### Output Returns the created DNS record including: - **id**: Record ID - **type**: Record type - **name**: Subdomain name - **data**: Record value - **ttl**: Time-to-live - **priority**: Priority (for MX/SRV) - **port**: Port (for SRV) - **weight**: Weight (for SRV) ### Example Output ```json { "data": { "data": "167.71.224.221.felixgateru2.com", "id": 1812548333, "name": "_sip._tcp", "port": 8000, "priority": 1, "ttl": 1800, "type": "SRV", "weight": 1 }, "timestamp": "2026-03-16T09:50:03.222782653Z", "type": "digitalocean.dns.record.created" } ``` ## Create Database **Component key:** `digitalocean.createDatabase` The Create Database component adds a new database to an existing DigitalOcean Managed Database cluster. ### Use Cases - **Application bootstrap**: Create an application-specific database as part of environment setup - **Tenant provisioning**: Add a dedicated database for a new customer or workspace - **Migration workflows**: Prepare a destination database before importing data ### Configuration - **Database Cluster**: The managed database cluster that will contain the new database (required) - **Database Name**: The name of the database to create (required, supports expressions) ### Output Returns the created database including: - **name**: The created database name - **databaseClusterId**: The cluster UUID - **databaseClusterName**: The cluster name ### Important Notes - If you use custom token scopes, this action requires `database:create` and `database:read` - Database management is not supported for Caching or Valkey clusters ### Example Output ```json { "data": { "databaseClusterId": "9cc10173-e9ea-4176-9dbc-a4cee4c4ff30", "databaseClusterName": "primary-postgres", "name": "app_db" }, "timestamp": "2026-03-27T09:15:00Z", "type": "digitalocean.database.created" } ``` ## Create Database Cluster **Component key:** `digitalocean.createDatabaseCluster` The Create Database Cluster component provisions a new DigitalOcean Managed Database cluster and waits until it is online. ### Use Cases - **Environment bootstrap**: Provision a managed database cluster before creating apps or databases - **Platform setup**: Create a dedicated cluster for a service, team, or customer environment - **Migration workflows**: Stand up a new cluster before importing data or cutover ### Configuration - **Name**: The database cluster name (required) - **Engine**: The database engine to provision, such as PostgreSQL or MySQL (required) - **Version**: The engine version to provision (required) - **Region**: The DigitalOcean region for the cluster (required) - **Size**: The node size slug for the cluster, for example `db-s-1vcpu-1gb` (required) - **Node Count**: The number of nodes in the cluster (required) ### Output Returns the created database cluster including: - **id**: The cluster UUID - **name**: The cluster name - **engine**: The provisioned engine - **version**: The engine version - **region**: The cluster region - **size**: The selected node size slug - **num_nodes**: The number of nodes - **status**: The current cluster status - **connection**: Connection information when available ### Important Notes - If you use custom token scopes, this action requires `database:create` and `database:read` - Valid versions, sizes, and node counts depend on the selected engine. Use the DigitalOcean Database Options API or dashboard values when configuring this component - The component polls until the cluster status becomes `online` ### Example Output ```json { "data": { "connection": { "host": "superplane-db-do-user-123456-0.j.db.ondigitalocean.com", "port": 25060, "ssl": true, "uri": "postgres://doadmin:[email protected]:25060/defaultdb?sslmode=require", "user": "doadmin" }, "created_at": "2026-03-27T13:00:00Z", "engine": "pg", "id": "65b497a5-1674-4b1a-a122-01aebe761ef7", "name": "superplane-db", "num_nodes": 1, "private_network_uuid": "7e6d2691-182b-4dd1-8452-529f88feb996", "region": "nyc1", "size": "db-s-1vcpu-1gb", "status": "online", "version": "18.0" }, "timestamp": "2026-03-27T13:00:05Z", "type": "digitalocean.database.cluster.created" } ``` ## Create Droplet **Component key:** `digitalocean.createDroplet` The Create Droplet component creates a new droplet in DigitalOcean. ### Use Cases - **Infrastructure provisioning**: Automatically provision droplets from workflow events - **Scaling**: Create new instances in response to load or alerts - **Environment setup**: Spin up droplets for testing or staging environments ### Configuration - **Name**: The hostname for the droplet (required, supports expressions) - **Region**: Region slug where the droplet will be created (required) - **Size**: Size slug for the droplet (required) - **Image**: Image slug or ID for the droplet OS (required) - **SSH Keys**: SSH keys to add to the droplet. Must have been added to the DigitalOcean team. (optional) - **Tags**: Tags to apply to the droplet (optional) - **User Data**: Cloud-init user data script (optional) - **Backups**: Enable automated backups for the droplet (optional) - **IPv6**: Enable IPv6 networking on the droplet (optional) - **Monitoring**: Enable DigitalOcean monitoring agent on the droplet (optional) - **VPC UUID**: UUID of the VPC to create the droplet in (optional) ### Output Returns the created droplet object including: - **id**: Droplet ID - **name**: Droplet hostname - **status**: Current droplet status - **region**: Region information - **networks**: Network information including IP addresses ### Example Output ```json { "data": { "disk": 25, "id": 98765432, "image": { "id": 12345, "name": "Ubuntu 24.04 (LTS) x64", "slug": "ubuntu-24-04-x64" }, "memory": 1024, "name": "my-droplet", "networks": { "v4": [ { "ip_address": "104.131.186.241", "type": "public" } ] }, "region": { "name": "New York 3", "slug": "nyc3" }, "size_slug": "s-1vcpu-1gb", "status": "new", "tags": [ "web" ], "vcpus": 1 }, "timestamp": "2026-03-12T21:10:00.000000000Z", "type": "digitalocean.droplet.created" } ``` ## Create GPU Droplet **Component key:** `digitalocean.createGPUDroplet` The Create GPU Droplet component creates a new GPU-powered droplet in DigitalOcean. ### Use Cases - **AI/ML workloads**: Provision GPU-powered instances for training and inference - **High-performance computing**: Spin up GPU instances for compute-intensive tasks - **Rendering workloads**: Create GPU droplets for 3D rendering pipelines ### Configuration - **Name**: The hostname for the GPU droplet (required, supports expressions) - **Region**: Region slug where the GPU droplet will be created (required, only shows GPU-capable regions) - **Size**: GPU size slug for the droplet (required, only shows GPU sizes) - **Image Type**: Choose between a pre-configured one-click application or a base OS image (required) - **One-Click Application**: Pre-configured GPU-optimized applications like ML-in-a-Box (with PyTorch, TensorFlow, CUDA), CUDA Toolkit, and other marketplace apps (shown when Image Type is "One-Click Application") - **Base OS Image**: GPU-compatible base operating systems including Ubuntu, Debian, Rocky Linux, and Fedora (shown when Image Type is "Base OS Image") - **SSH Keys**: SSH keys to add to the droplet. Must have been added to the DigitalOcean team. (optional) - **Tags**: Tags to apply to the droplet (optional) - **User Data**: Cloud-init user data script (optional) - **Backups**: Enable automated backups for the droplet (optional) - **IPv6**: Enable IPv6 networking on the droplet (optional) - **Monitoring**: Enable DigitalOcean monitoring agent on the droplet (optional) - **VPC**: UUID of the VPC to create the droplet in (optional) ### Output Returns the created GPU droplet object including: - **id**: Droplet ID - **name**: Droplet hostname - **status**: Current droplet status - **region**: Region information - **size_slug**: GPU size identifier - **networks**: Network information including IP addresses ### Example Output ```json { "data": { "disk": 720, "id": 412345678, "image": { "id": 98765, "name": "GPU H100 Base - Ubuntu 22.04", "slug": "gpu-h100-base-ubuntu-22-04" }, "memory": 245760, "name": "my-gpu-droplet", "networks": { "v4": [ { "ip_address": "143.198.100.50", "type": "public" } ] }, "region": { "name": "Toronto 1", "slug": "tor1" }, "size_slug": "gpu-h100x1-80gb", "status": "active", "tags": [ "gpu", "ml-training" ], "vcpus": 20 }, "timestamp": "2026-03-12T21:10:00.000000000Z", "type": "digitalocean.gpuDroplet.created" } ``` ## Create Knowledge Base **Component key:** `digitalocean.createKnowledgeBase` The Create Knowledge Base component creates a new knowledge base on the DigitalOcean Gradient AI Platform, ready for use with AI agents via retrieval-augmented generation (RAG). ### How it works A knowledge base converts your data sources into vector embeddings using the selected embedding model. Those embeddings are stored in an OpenSearch database — either a newly provisioned one or one you already have. Once created, the knowledge base can be attached to any Gradient AI agent. ### Data Sources You can add multiple data sources of different types: - **Spaces Bucket or Folder** — indexes all supported files in a DigitalOcean Spaces bucket or folder - **Web or Sitemap URL** — crawls a public website (seed URL) or a list of URLs from a sitemap Each data source has its own independent chunking strategy. ### Chunking Strategies - **Section-based** (default) — splits on structural elements like headings and paragraphs; fast and low-cost - **Semantic** — groups sentences by meaning; slower but context-aware - **Hierarchical** — creates parent (context) and child (retrieval) chunk pairs - **Fixed-length** — splits strictly by token count; best for logs and unstructured text ### OpenSearch Database The knowledge base requires an OpenSearch database to store the vector embeddings: - **Create new** — provisions a new database automatically sized to your data - **Use existing** — connects to a database you already have by providing its ID ### Output Returns the created knowledge base including: - **uuid**: Knowledge base UUID for use in downstream components - **name**: Name of the knowledge base - **region**: Datacenter region - **embeddingModelUUID**: UUID of the embedding model used - **projectId**: Associated project ID - **databaseId**: UUID of the OpenSearch database (populated after provisioning completes for new databases) - **createdAt**: Creation timestamp ### Example Output ```json { "data": { "createdAt": "2025-01-01T00:00:00Z", "databaseId": "abf1055a-745d-4c24-a1db-1959ea819264", "embeddingModelUUID": "05700391-7aa8-11ef-bf8f-4e013e2ddde4", "name": "my-knowledge-base", "projectId": "37455431-84bd-4fa2-94cf-e8486f8f8c5e", "region": "tor1", "tags": [ "docs", "production" ], "uuid": "20cd8434-6ea1-11f0-bf8f-4e013e2ddde4" }, "timestamp": "2025-01-01T00:00:00Z", "type": "digitalocean.knowledge_base.created" } ``` ## Create Load Balancer **Component key:** `digitalocean.createLoadBalancer` The Create Load Balancer component creates a new load balancer in DigitalOcean and waits until it is active. ### Use Cases - **Traffic distribution**: Distribute incoming requests across multiple droplets - **High availability**: Ensure zero-downtime deployments by routing traffic across instances - **Scalable infrastructure**: Provision load balancers as part of automated environment setup ### Configuration - **Name**: The name of the load balancer (required, only letters, numbers, and hyphens) - **Region**: Region where the load balancer will be created (required) - **Forwarding Rules**: One or more forwarding rules specifying entry/target protocol, port, and optional TLS passthrough (required) - **Droplets**: The droplets to add as targets — must be in the same region as the load balancer (optional, mutually exclusive with Tag) - **Tag**: Tag used to dynamically target droplets (optional, mutually exclusive with Droplets) ### Output Returns the created load balancer object including: - **id**: Load balancer ID (UUID) - **name**: Load balancer name - **ip**: Assigned public IP address - **status**: Current status (active) - **region**: Region information - **forwarding_rules**: Configured forwarding rules - **droplet_ids**: Targeted droplet IDs ### Important Notes - The component polls until the load balancer status becomes **active** - Specify either **Droplet IDs** or **Tag** to define targets, not both - The load balancer name must contain only letters, numbers, and hyphens - All specified droplets must be in the same region as the load balancer ### Example Output ```json { "data": { "algorithm": "round_robin", "created_at": "2026-03-13T10:00:00Z", "droplet_ids": [ 98765432, 98765433 ], "forwarding_rules": [ { "entry_port": 80, "entry_protocol": "http", "target_port": 80, "target_protocol": "http" } ], "id": "4de7ac8b-495b-4884-9a69-1050c6793cd6", "ip": "104.131.186.241", "name": "my-load-balancer", "region": { "name": "New York 3", "slug": "nyc3" }, "status": "active", "tag": "" }, "timestamp": "2026-03-13T10:01:15.000000000Z", "type": "digitalocean.loadbalancer.created" } ``` ## Create Snapshot **Component key:** `digitalocean.createSnapshot` The Create Snapshot component creates a point-in-time snapshot of a DigitalOcean Droplet. ### Use Cases - **Backup**: Create a backup before performing risky operations on a droplet - **Image creation**: Create a custom image from an existing droplet for reuse - **Migration**: Snapshot a droplet before migrating to a different region or size ### Configuration - **Droplet**: The ID of the droplet to snapshot (required) - **Name**: A human-readable name for the snapshot (required) ### Output Returns the snapshot details including: - **id**: Snapshot ID - **name**: Snapshot name - **created_at**: When the snapshot was created - **resource_id**: The ID of the droplet that was snapshotted - **regions**: Regions where the snapshot is available - **min_disk_size**: Minimum disk size required to use this snapshot - **size_gigabytes**: Size of the snapshot in GB ### Example Output ```json { "data": { "created_at": "2026-03-13T13:35:43Z", "id": 220464921, "min_disk_size": 10, "name": "superplane-1773328904", "regions": [ "blr1" ], "resource_id": "98145763", "resource_type": "droplet", "size_gigabytes": 2.04 }, "timestamp": "2026-03-13T13:36:14.803060936Z", "type": "digitalocean.snapshot.created" } ``` ## Delete Alert Policy **Component key:** `digitalocean.deleteAlertPolicy` The Delete Alert Policy component permanently removes a monitoring alert policy from your DigitalOcean account. ### Use Cases - **Cleanup**: Remove alert policies that are no longer needed - **Policy rotation**: Delete old policies as part of a replace workflow - **Automated teardown**: Remove monitoring policies when decommissioning environments ### Configuration - **Alert Policy**: The alert policy to delete (required, supports expressions) ### Output Returns information about the deleted policy: - **alertPolicyUuid**: The UUID of the alert policy that was deleted ### Important Notes - This operation is **permanent** and cannot be undone - If the policy does not exist (already deleted), the component completes successfully (idempotent) ### Example Output ```json { "data": { "alertPolicyUuid": "669adfc8-d72b-4d2d-80ed-bea78d6e1562" }, "timestamp": "2026-03-17T10:00:00Z", "type": "digitalocean.alertpolicy.deleted" } ``` ## Delete App **Component key:** `digitalocean.deleteApp` The Delete App component removes a DigitalOcean App Platform application. ### Use Cases - **Cleanup**: Remove applications that are no longer needed - **Environment teardown**: Delete temporary or test app instances - **Resource management**: Free up resources by deleting unused apps ### Configuration - **App**: The app to delete (required) ### Output Returns confirmation of the deleted app including: - **appId**: The ID of the deleted app ### Notes - This operation is idempotent - deleting an already deleted app will succeed - All deployments and associated resources will be removed - This action cannot be undone ### Example Output ```json { "data": { "appId": "20e27025-f9c1-4da4-bfc4-00a13eb9ff42" }, "timestamp": "2026-03-24T05:59:24.092664924Z", "type": "digitalocean.app.deleted" } ``` ## Delete DNS Record **Component key:** `digitalocean.deleteDNSRecord` The Delete DNS Record component permanently removes a DNS record from a DigitalOcean-managed domain. ### Use Cases - **Cleanup**: Remove DNS records for decommissioned services - **Rotation**: Delete old records as part of a DNS rotation workflow - **Automated teardown**: Remove service discovery records when tearing down infrastructure ### Configuration - **Domain**: The DigitalOcean-managed domain containing the record (required) - **Record ID**: The ID of the DNS record to delete (required, supports expressions) ### Output Returns information about the deleted record: - **recordId**: The ID of the record that was deleted - **domain**: The domain the record belonged to ### Important Notes - This operation is **permanent** and cannot be undone - Deleting a record that does not exist is treated as a success (idempotent) - Record IDs can be obtained from the output of createDNSRecord or upsertDNSRecord ### Example Output ```json { "data": { "deleted": true, "domain": "example.com", "recordId": 12345678 }, "timestamp": "2026-03-13T10:05:00.000000000Z", "type": "digitalocean.dns.record.deleted" } ``` ## Delete Data Source **Component key:** `digitalocean.deleteDataSource` The Delete Data Source component removes a data source from an existing knowledge base on the DigitalOcean Gradient AI Platform. ### How it works Deletes a single data source from a knowledge base. DigitalOcean automatically triggers a re-indexing job after every deletion to clean up stale embeddings from the OpenSearch database. The component waits for that job to complete before emitting the output. ### Output Returns the deleted data source details: - **dataSourceUUID**: UUID of the deleted data source - **knowledgeBaseUUID**: UUID of the knowledge base - **knowledgeBaseName**: Name of the knowledge base ### Example Output ```json { "data": { "dataSourceUUID": "650d31b0-3338-11f1-b074-4e013e2bere4", "indexingJob": { "completedDataSources": 1, "finishedAt": "2026-04-09T10:29:39Z", "startedAt": "2026-04-09T10:28:58Z", "status": "INDEX_JOB_STATUS_COMPLETED", "totalDataSources": 1, "totalTokens": "" }, "knowledgeBaseName": "ecommerce-knowledge-base-v2", "knowledgeBaseUUID": "3f3d8984-32a2-11f1-b074-4e01dffdde4" }, "timestamp": "2026-04-09T10:29:59.190938313Z", "type": "digitalocean.data_source.deleted" } ``` ## Delete Database **Component key:** `digitalocean.deleteDatabase` The Delete Database component permanently removes a database from a DigitalOcean Managed Database cluster. ### Use Cases - **Cleanup**: Remove databases that are no longer needed after a workflow completes - **Environment teardown**: Delete temporary or preview-environment databases - **Tenant offboarding**: Remove customer-specific databases during deprovisioning ### Configuration - **Database Cluster**: The managed database cluster containing the database (required) - **Database**: The database to delete (required) ### Output Returns information about the deleted database: - **name**: The deleted database name - **databaseClusterId**: The cluster UUID - **databaseClusterName**: The cluster name - **deleted**: Whether the delete request succeeded ### Important Notes - If you use custom token scopes, this action requires `database:delete` and `database:read` - Database management is not supported for Caching or Valkey clusters - Deleting a database that no longer exists is treated as a success ### Example Output ```json { "data": { "databaseClusterId": "9cc10173-e9ea-4176-9dbc-a4cee4c4ff30", "databaseClusterName": "primary-postgres", "deleted": true, "name": "app_db" }, "timestamp": "2026-03-27T09:20:00Z", "type": "digitalocean.database.deleted" } ``` ## Delete Droplet **Component key:** `digitalocean.deleteDroplet` The Delete Droplet component permanently deletes a droplet from your DigitalOcean account. ### Use Cases - **Cleanup**: Remove temporary or test droplets after use - **Cost optimization**: Automatically tear down unused infrastructure - **Automated workflows**: Delete droplets as part of deployment rollback or cleanup processes - **Environment management**: Remove ephemeral environments after testing ### Configuration - **Droplet**: The droplet to delete (required, supports expressions) ### Output Returns information about the deleted droplet: - **dropletId**: The ID of the droplet that was deleted ### Important Notes - This operation is **permanent** and cannot be undone - All data on the droplet will be lost - The droplet will be shut down if it's running before deletion - Any snapshots of the droplet will remain in your account ### Example Output ```json { "data": { "dropletId": 557784760 }, "timestamp": "2026-03-12T21:25:45.688697002Z", "type": "digitalocean.droplet.deleted" } ``` ## Delete GPU Droplet **Component key:** `digitalocean.deleteGPUDroplet` The Delete GPU Droplet component permanently deletes a GPU droplet from your DigitalOcean account. ### Use Cases - **Cleanup**: Remove temporary GPU droplets after training or inference tasks - **Cost optimization**: Automatically tear down expensive GPU infrastructure when not in use - **Automated workflows**: Delete GPU droplets as part of ML pipeline cleanup - **Environment management**: Remove ephemeral GPU environments after testing ### Configuration - **Droplet**: The GPU droplet to delete (required, supports expressions) ### Output Returns information about the deleted GPU droplet: - **dropletId**: The ID of the GPU droplet that was deleted ### Important Notes - This operation is **permanent** and cannot be undone - All data on the GPU droplet will be lost - The droplet will be shut down if it's running before deletion - Any snapshots of the GPU droplet will remain in your account ### Example Output ```json { "data": { "dropletId": 957784760 }, "timestamp": "2026-03-12T21:25:45.688697002Z", "type": "digitalocean.gpuDroplet.deleted" } ``` ## Delete Knowledge Base **Component key:** `digitalocean.deleteKnowledgeBase` The Delete Knowledge Base component removes a knowledge base from the DigitalOcean Gradient AI Platform. ### How it works Deletes the specified knowledge base. Optionally, you can also delete the associated OpenSearch database that stores the vector embeddings. ### Use Cases - **Cleanup**: Remove knowledge bases that are no longer needed - **Resource management**: Free up resources by deleting unused knowledge bases and their databases - **Rotation**: Delete an old knowledge base after a new one has been verified and attached ### Configuration - **Knowledge Base**: The knowledge base to delete (required) - **Delete OpenSearch Database**: Whether to also delete the associated OpenSearch database (optional, defaults to off) ### Output Returns confirmation of the deletion including: - **knowledgeBaseUUID**: UUID of the deleted knowledge base - **databaseDeleted**: Whether the OpenSearch database was also deleted - **databaseId**: UUID of the deleted database (included when the database was deleted) - **databaseName**: Name of the deleted database (included when the database was deleted) ### Notes - If the knowledge base is currently attached to any agents, it will automatically be removed from those agents upon deletion. Consider using the Detach Knowledge Base component first if you need more control over the detachment process. - Deleting the OpenSearch database is irreversible and will remove all vector embeddings ### Example Output ```json { "data": { "databaseDeleted": true, "databaseId": "9cc10173-e9ea-4176-9dbc-a4cee4c4ff30", "databaseName": "my-knowledge-base-os", "knowledgeBaseUUID": "a1b2c3d4-0000-0000-0000-000000000001" }, "timestamp": "2025-01-01T00:00:00Z", "type": "digitalocean.knowledge_base.deleted" } ``` ## Delete Load Balancer **Component key:** `digitalocean.deleteLoadBalancer` The Delete Load Balancer component permanently deletes a load balancer from your DigitalOcean account. ### Use Cases - **Cleanup**: Remove load balancers after decommissioning a service - **Cost optimization**: Automatically tear down unused load balancers - **Environment management**: Delete load balancers as part of environment teardown workflows ### Configuration - **Load Balancer**: The load balancer to delete (required, supports expressions) ### Output Returns information about the deleted load balancer: - **loadBalancerID**: The UUID of the load balancer that was deleted ### Important Notes - This operation is **permanent** and cannot be undone - Deleting a load balancer does not delete the targeted droplets - If the load balancer does not exist (404), the component emits success (idempotent) ### Example Output ```json { "data": { "loadBalancerID": "4de7ac8b-495b-4884-9a69-1050c6793cd6" }, "timestamp": "2026-03-13T10:05:30.000000000Z", "type": "digitalocean.loadbalancer.deleted" } ``` ## Delete Object **Component key:** `digitalocean.deleteObject` The Delete Object component permanently removes an object from a DigitalOcean Spaces bucket. ### Prerequisites Spaces Access Key ID and Secret Access Key must be configured in the DigitalOcean integration settings. ### Configuration - **Bucket**: The Spaces bucket containing the object. The dropdown lists all buckets — the region is determined automatically. - **File Path**: The full path to the object within the bucket (e.g. reports/daily.csv). Supports expressions to reference a path from an upstream component. ### Output - **bucket**: The bucket name - **filePath**: The path of the deleted object - **deleted**: Always `true` on success ### Notes - This operation is **permanent** and cannot be undone - The operation succeeds even if the object does not exist (idempotent) ### Use Cases - **Cleanup**: Remove temporary or processed files after a workflow completes - **Rotation**: Delete old reports or artifacts as part of a file rotation policy - **Pipeline teardown**: Remove objects created during a pipeline run ### Example Output ```json { "data": { "bucket": "my-company-assets", "deleted": true, "filePath": "reports/daily.csv" }, "timestamp": "2026-03-25T09:00:00Z", "type": "digitalocean.spaces.object.deleted" } ``` ## Delete Snapshot **Component key:** `digitalocean.deleteSnapshot` The Delete Snapshot component deletes a DigitalOcean snapshot image. ### Use Cases - **Cleanup**: Remove old snapshots to free up storage and reduce costs - **Lifecycle management**: Automatically delete snapshots after they are no longer needed - **Rotation**: Delete older snapshots as part of a snapshot rotation policy ### Configuration - **Snapshot**: The snapshot to delete (required) ### Output Returns confirmation of the deleted snapshot including: - **snapshotId**: The ID of the deleted snapshot - **deleted**: Confirmation that the snapshot was deleted ### Example Output ```json { "data": { "deleted": true, "snapshotId": "220431883" }, "timestamp": "2026-03-13T06:27:06.208635289Z", "type": "digitalocean.snapshot.deleted" } ``` ## Detach Knowledge Base **Component key:** `digitalocean.detachKnowledgeBase` The Detach Knowledge Base component removes a knowledge base from an existing Gradient AI agent. ### Use Cases - **Rollback**: Remove a knowledge base that is causing poor agent responses - **Cleanup**: Detach an outdated knowledge base before attaching a freshly indexed one - **Rotation**: As part of a blue/green pipeline, detach the old knowledge base after the new one is verified ### Configuration - **Agent**: The agent to detach the knowledge base from (required) - **Knowledge Base**: The knowledge base to detach — only shows knowledge bases currently attached to the selected agent (required) ### Output Returns confirmation of the detachment including: - **agentUUID**: UUID of the agent - **knowledgeBaseUUID**: UUID of the detached knowledge base ### Example Output ```json { "data": { "agentUUID": "20cd8434-6ea1-11f0-bf8f-4e013e2ddde4", "knowledgeBaseUUID": "a1b2c3d4-0000-0000-0000-000000000001" }, "timestamp": "2025-01-01T00:00:00Z", "type": "digitalocean.knowledge_base.detached" } ``` ## Get Alert Policy **Component key:** `digitalocean.getAlertPolicy` The Get Alert Policy component retrieves the full details of a monitoring alert policy. ### Use Cases - **Policy inspection**: Verify the current configuration of an alert policy - **Conditional logic**: Check whether a policy is enabled before modifying it downstream - **Audit workflows**: Retrieve alert policy details as part of a compliance or reporting pipeline ### Configuration - **Alert Policy**: The alert policy to retrieve (required, supports expressions) ### Output Returns the alert policy object including: - **uuid**: Alert policy UUID - **description**: Human-readable description - **type**: Metric type being monitored (e.g. v1/insights/droplet/cpu) - **compare**: Comparison operator (GreaterThan/LessThan) - **value**: Threshold value - **window**: Evaluation window (5m, 10m, 30m, 1h) - **entities**: Scoped droplet IDs - **tags**: Scoped droplet tags - **enabled**: Whether the policy is active - **alerts**: Configured notification channels ### Example Output ```json { "data": { "alerts": { "email": [ "sammy@digitalocean.com" ] }, "compare": "GreaterThan", "description": "High CPU Usage", "enabled": true, "entities": [ "558899681" ], "tags": [], "type": "v1/insights/droplet/cpu", "uuid": "ffcaf816-f6a5-4b4a-b4c4-e84532755e82", "value": 20, "window": "5m" }, "timestamp": "2026-03-18T09:54:58.914731251Z", "type": "digitalocean.alertpolicy.fetched" } ``` ## Get App **Component key:** `digitalocean.getApp` The Get App component retrieves detailed information about a specific DigitalOcean App Platform application. ### Use Cases - **Status checks**: Verify app state and deployment status before performing operations - **Information retrieval**: Get current app configuration, URLs, and deployment details - **Pre-flight validation**: Check app exists before operations like update or delete - **Monitoring**: Track app configuration, active deployments, and ingress URLs - **Integration workflows**: Retrieve app details for use in downstream workflow steps ### Configuration - **App ID**: The unique identifier of the app to retrieve (required) ### Output Returns the app object including: - **id**: The unique app ID - **name**: The app name - **default_ingress**: The default ingress URL - **live_url**: The live URL for the app - **region**: The region where the app is deployed - **active_deployment**: Information about the active deployment - **in_progress_deployment**: Information about any in-progress deployment - **spec**: Complete app specification including services, workers, jobs, static sites, databases, and configuration ### Notes - The app ID can be obtained from the output of the Create App component or from the DigitalOcean dashboard - The component returns the current state of the app, including all deployed components - Use this component to verify deployment status before performing updates or other operations ### Example Output ```json { "data": { "active_deployment": { "cause": "initial deployment", "created_at": "2026-03-24T10:17:51Z", "id": "a5ad056d-523a-48e2-9715-76db183f5a15", "phase": "ACTIVE", "progress": { "steps": [ { "ended_at": "2026-03-24T10:18:56.473548704Z", "name": "build", "started_at": "2026-03-24T10:17:57.360621633Z", "status": "SUCCESS", "steps": [ { "ended_at": "2026-03-24T10:18:23.527631658Z", "name": "initialize", "started_at": "2026-03-24T10:17:57.360716517Z", "status": "SUCCESS" }, { "ended_at": "2026-03-24T10:18:54.938686340Z", "name": "components", "started_at": "2026-03-24T10:18:23.527664326Z", "status": "SUCCESS", "steps": [ { "name": "my-app", "status": "SUCCESS" } ] } ] }, { "ended_at": "2026-03-24T10:19:06.689255599Z", "name": "deploy", "started_at": "2026-03-24T10:19:02.998040282Z", "status": "SUCCESS", "steps": [ { "ended_at": "2026-03-24T10:19:04.851886393Z", "name": "initialize", "started_at": "2026-03-24T10:19:02.998063884Z", "status": "SUCCESS" }, { "ended_at": "2026-03-24T10:19:04.851934987Z", "name": "components", "started_at": "2026-03-24T10:19:04.851916324Z", "status": "SUCCESS" }, { "ended_at": "2026-03-24T10:19:06.689152591Z", "name": "finalize", "started_at": "2026-03-24T10:19:04.852021129Z", "status": "SUCCESS" } ] } ], "success_steps": 5, "total_steps": 5 }, "spec": { "ingress": { "rules": [ { "component": { "name": "my-app" }, "match": { "path": { "prefix": "/" } } } ] }, "name": "my-app", "region": "blr", "static_sites": [ { "github": { "branch": "main", "deploy_on_push": true, "repo": "digitalocean/hello-world" }, "name": "my-app" } ] }, "static_sites": [ { "name": "my-app", "source_commit_hash": "8ac84464242f1b430147319deb28abb5a20049b8" } ], "updated_at": "2026-03-24T10:19:07Z" }, "created_at": "2026-03-24T10:17:51Z", "default_ingress": "https://my-app-ixj6x.ondigitalocean.app", "id": "eb0fc7fa-8294-48c5-8a48-77d47fc6c89e", "last_deployment_created_at": "2026-03-24T10:17:51Z", "live_domain": "my-app-ixj6x.ondigitalocean.app", "live_url": "https://my-app-ixj6x.ondigitalocean.app", "live_url_base": "https://my-app-ixj6x.ondigitalocean.app", "pending_deployment": { "id": "" }, "region": { "continent": "Asia", "data_centers": [ "blr1" ], "flag": "india", "label": "Bangalore", "slug": "blr" }, "spec": { "ingress": { "rules": [ { "component": { "name": "my-app" }, "match": { "path": { "prefix": "/" } } } ] }, "name": "my-app", "region": "blr", "static_sites": [ { "github": { "branch": "main", "deploy_on_push": true, "repo": "digitalocean/hello-world" }, "name": "my-app" } ] }, "updated_at": "2026-03-24T10:19:13Z" }, "timestamp": "2026-03-26T08:21:30.077395918Z", "type": "digitalocean.app.fetched" } ``` ## Get Cluster Configuration **Component key:** `digitalocean.getClusterConfiguration` The Get Cluster Configuration component retrieves the active configuration for a DigitalOcean Managed Database cluster. ### Use Cases - **Audit workflows**: Inspect the active cluster configuration for reporting or compliance checks - **Validation**: Compare the current cluster configuration before updates or maintenance - **Operational visibility**: Retrieve engine-specific settings that affect behavior and performance ### Configuration - **Database Cluster**: The managed database cluster to inspect (required) ### Output Returns the cluster configuration including: - **databaseClusterId**: The cluster UUID - **databaseClusterName**: The cluster name - **config**: The configuration object returned by the DigitalOcean API ### Important Notes - If you use custom token scopes, this action requires `database:read` - The keys inside `config` vary by database engine ### Example Output ```json { "data": { "config": { "autovacuum_naptime": 60, "backtrack_commit_timeout": 30, "default_toast_compression": "pglz", "idle_in_transaction_session_timeout": 0, "jit": true, "max_parallel_workers": 8 }, "databaseClusterId": "65b497a5-1674-4b1a-a122-01aebe761ef7", "databaseClusterName": "superplane-db-test" }, "timestamp": "2026-03-27T11:10:00.000000000Z", "type": "digitalocean.database.cluster.config.fetched" } ``` ## Get Database **Component key:** `digitalocean.getDatabase` The Get Database component retrieves a managed database from a DigitalOcean cluster and enriches it with cluster context. ### Use Cases - **Routing decisions**: Inspect the database and cluster state before directing traffic or jobs - **Operational checks**: Review engine, region, and connection details before maintenance steps - **Audit workflows**: Retrieve the current database and cluster context for reporting or validation ### Configuration - **Database Cluster**: The managed database cluster containing the database (required) - **Database**: The database to retrieve (required) ### Output Returns the requested database enriched with cluster details, including: - **name**: The database name - **databaseClusterId**: The cluster UUID - **databaseClusterName**: The cluster name - **engine**: The cluster engine - **version**: The cluster engine version - **region**: The cluster region - **status**: The cluster status - **connection**: Connection information when available - **database**: The raw database object returned by the API ### Important Notes - If you use custom token scopes, this action requires `database:read` - Database management is not supported for Caching or Valkey clusters ### Example Output ```json { "data": { "connection": { "database": "defaultdb", "host": "superplane-db-test-do-user-1234567-0.j.db.ondigitalocean.com", "port": 25060, "ssl": true, "uri": "postgresql://doadmin@superplane-db-test-do-user-1234567-0.j.db.ondigitalocean.com:25060/defaultdb?sslmode=require", "user": "doadmin" }, "database": { "name": "app_db" }, "databaseClusterId": "65b497a5-1674-4b1a-a122-01aebe761ef7", "databaseClusterName": "superplane-db-test", "engine": "pg", "name": "app_db", "region": "nyc1", "status": "online", "version": "17" }, "timestamp": "2026-03-27T11:12:00.000000000Z", "type": "digitalocean.database.fetched" } ``` ## Get Database Cluster **Component key:** `digitalocean.getDatabaseCluster` The Get Database Cluster component retrieves the details of an existing DigitalOcean Managed Database cluster. ### Use Cases - **Status checks**: Verify a cluster is online before creating databases or users - **Information retrieval**: Fetch connection details, sizing, engine, and region information - **Pre-flight validation**: Confirm a cluster exists before downstream operations ### Configuration - **Database Cluster**: The managed database cluster to retrieve (required) ### Output Returns the database cluster including: - **id**: The cluster UUID - **name**: The cluster name - **engine**: The configured engine - **version**: The engine version - **region**: The cluster region - **size**: The node size slug - **num_nodes**: The number of nodes - **status**: The cluster status - **connection**: Connection information when available ### Important Notes - If you use custom token scopes, this action requires `database:read` - The returned connection information depends on the cluster type and provisioning state. ### Example Output ```json { "data": { "connection": { "host": "superplane-db-do-user-123456-0.j.db.ondigitalocean.com", "port": 25060, "ssl": true, "uri": "postgres://doadmin:[email protected]:25060/defaultdb?sslmode=require", "user": "doadmin" }, "created_at": "2026-03-27T13:00:00Z", "engine": "pg", "id": "65b497a5-1674-4b1a-a122-01aebe761ef7", "name": "superplane-db", "num_nodes": 1, "private_network_uuid": "7e6d2691-182b-4dd1-8452-529f88feb996", "region": "nyc1", "size": "db-s-1vcpu-1gb", "status": "online", "version": "18.0" }, "timestamp": "2026-03-27T13:05:00Z", "type": "digitalocean.database.cluster.fetched" } ``` ## Get Droplet **Component key:** `digitalocean.getDroplet` The Get Droplet component retrieves detailed information about a specific droplet. ### Use Cases - **Status checks**: Verify droplet state before performing operations - **Information retrieval**: Get current IP addresses, configuration, and status - **Pre-flight validation**: Check droplet exists before operations like snapshot or power management - **Monitoring**: Track droplet configuration and network details ### Configuration - **Droplet**: The droplet to retrieve (required, supports expressions) ### Output Returns the droplet object including: - **id**: Droplet ID - **name**: Droplet hostname - **status**: Current droplet status (new, active, off, archive) - **memory**: RAM in MB - **vcpus**: Number of virtual CPUs - **disk**: Disk size in GB - **region**: Region information - **image**: Image information - **size_slug**: Size identifier - **networks**: Network information including IP addresses - **tags**: Applied tags ### Example Output ```json { "data": { "disk": 25, "id": 557784760, "image": { "id": 220345895, "name": "superplane-1773328904", "slug": "" }, "memory": 1024, "name": "superplane-1773328904-s-1vcpu-1gb-nyc3-01", "networks": { "v4": [ { "ip_address": "192.0.2.1", "type": "public" }, { "ip_address": "10.108.0.3", "type": "private" } ] }, "region": { "name": "New York 3", "slug": "nyc3" }, "size_slug": "s-1vcpu-1gb", "status": "active", "tags": [], "vcpus": 1 }, "timestamp": "2026-03-12T21:13:32.946693411Z", "type": "digitalocean.droplet.fetched" } ``` ## Get Droplet Metrics **Component key:** `digitalocean.getDropletMetrics` The Get Droplet Metrics component retrieves CPU usage, memory utilization, and network bandwidth metrics for a droplet over a specified lookback window. > **Note:** Monitoring is only available for droplets that had monitoring enabled during creation. Droplets created without monitoring will not report metrics. ### Use Cases - **Performance monitoring**: Sample current resource utilization before scaling decisions - **Incident investigation**: Pull recent metrics when responding to an alert - **Capacity planning**: Gather trend data to inform right-sizing of infrastructure - **Automated scaling**: Use metric outputs to conditionally trigger resize or power operations ### Configuration - **Droplet**: The droplet to fetch metrics for (required, supports expressions) - **Lookback Period**: How far back to retrieve metrics — 1h, 6h, 24h, 7d, or 14d (required) ### Output Returns a combined metrics payload with averaged values over the lookback window: - **dropletId**: The ID of the queried droplet - **start**: ISO 8601 timestamp of the start of the metrics window - **end**: ISO 8601 timestamp of the end of the metrics window - **lookbackPeriod**: The selected lookback period - **avgCpuUsagePercent**: Average CPU usage percentage over the window - **avgMemoryUsagePercent**: Average memory utilization percentage, computed from (total − available) / total × 100 - **avgPublicOutboundBandwidthMbps**: Average public outbound bandwidth in Mbps (as reported by the DigitalOcean API) - **avgPublicInboundBandwidthMbps**: Average public inbound bandwidth in Mbps (as reported by the DigitalOcean API) All metric values are rounded to two decimal places. ### Important Notes - Metrics are only available for droplets with the DigitalOcean Monitoring Agent installed - The Monitoring Agent is pre-installed on droplets using official DigitalOcean images created after 2018 - Data point resolution varies by window: shorter windows return finer-grained data ### Example Output ```json { "data": { "avgCpuUsagePercent": 0.18, "avgMemoryUsagePercent": 34.39, "avgPublicInboundBandwidthMbps": 0.36, "avgPublicOutboundBandwidthMbps": 0.15, "dropletId": "559378149", "end": "2026-03-19T08:36:34Z", "lookbackPeriod": "1h", "start": "2026-03-19T07:36:34Z" }, "timestamp": "2026-03-19T08:36:37.115389929Z", "type": "digitalocean.droplet.metrics" } ``` ## Get GPU Droplet **Component key:** `digitalocean.getGPUDroplet` The Get GPU Droplet component retrieves detailed information about a specific GPU droplet. ### Use Cases - **Status checks**: Verify GPU droplet state before performing operations - **Information retrieval**: Get current IP addresses, GPU configuration, and status - **Pre-flight validation**: Check GPU droplet exists before operations like snapshot or power management - **Monitoring**: Track GPU droplet configuration and network details ### Configuration - **Droplet**: The GPU droplet to retrieve (required, supports expressions) ### Output Returns the GPU droplet object including: - **id**: Droplet ID - **name**: Droplet hostname - **status**: Current droplet status (new, active, off, archive) - **memory**: RAM in MB - **vcpus**: Number of virtual CPUs - **disk**: Disk size in GB - **region**: Region information - **image**: Image information - **size_slug**: GPU size identifier - **networks**: Network information including IP addresses - **tags**: Applied tags ### Example Output ```json { "data": { "disk": 720, "id": 412345678, "image": { "id": 98765, "name": "GPU H100 Base - Ubuntu 22.04", "slug": "gpu-h100-base-ubuntu-22-04" }, "memory": 245760, "name": "my-gpu-droplet", "networks": { "v4": [ { "ip_address": "143.198.100.50", "type": "public" }, { "ip_address": "10.132.0.5", "type": "private" } ] }, "region": { "name": "Toronto 1", "slug": "tor1" }, "size_slug": "gpu-h100x1-80gb", "status": "active", "tags": [ "gpu", "ml-training" ], "vcpus": 20 }, "timestamp": "2026-03-12T21:13:32.946693411Z", "type": "digitalocean.gpuDroplet.fetched" } ``` ## Get Knowledge Base **Component key:** `digitalocean.getKnowledgeBase` The Get Knowledge Base component retrieves comprehensive information about an existing knowledge base on the DigitalOcean Gradient AI Platform. ### How it works Fetches the knowledge base details including its OpenSearch database, all attached data sources, and the latest indexing job status. ### Use Cases - **Pre-flight checks**: Inspect a knowledge base before attaching it to an agent or running evaluations - **Health monitoring**: Check indexing status and data source count on a schedule - **Teardown workflows**: Fetch the database ID before deleting the knowledge base - **Auditing**: Verify region, embedding model, and data source configuration ### Output Returns the full knowledge base object including: - **uuid**, **name**, **status**, **region**, **tags** — core properties - **embeddingModelUUID**, **embeddingModelName** — embedding model details - **projectId**, **projectName** — associated project - **database** — OpenSearch database object with id, name, and status - **dataSources** — array of all attached data sources with type and source details - **lastIndexingJob** — full indexing job details: status, phase, totalTokens, data source progress, timing, and report availability - **createdAt**, **updatedAt** — timestamps ### Example Output ```json { "data": { "createdAt": "2025-01-01T00:00:00Z", "dataSources": [ { "chunkingAlgorithm": "CHUNKING_ALGORITHM_SECTION_BASED", "createdAt": "2025-01-01T00:00:00Z", "spacesBucket": "tor1/product-data", "type": "spaces", "updatedAt": "2025-06-01T00:00:00Z", "uuid": "a1b2c3d4-0000-0000-0000-000000000001" }, { "chunkingAlgorithm": "CHUNKING_ALGORITHM_SEMANTIC", "crawlingOption": "SCOPED", "createdAt": "2025-02-01T00:00:00Z", "type": "web", "updatedAt": "2025-06-01T00:00:00Z", "uuid": "a1b2c3d4-0000-0000-0000-000000000002", "webURL": "https://docs.example.com" } ], "database": { "id": "abf1055a-745d-4c24-a1db-1959ea819264", "name": "product-catalog-os", "status": "online" }, "databaseStatus": "ONLINE", "embeddingModelName": "GTE Large EN v1.5", "embeddingModelUUID": "05700391-7aa8-11ef-bf8f-4e013e2ddde4", "lastIndexingJob": { "completedDataSources": 2, "createdAt": "2025-06-01T00:00:00Z", "finishedAt": "2025-06-01T00:05:32Z", "isReportAvailable": true, "phase": "BATCH_JOB_PHASE_COMPLETE", "startedAt": "2025-06-01T00:00:00Z", "status": "INDEX_JOB_STATUS_COMPLETED", "totalDataSources": 2, "totalTokens": "12345", "uuid": "b2c3d4e5-0000-0000-0000-000000000001" }, "name": "product-catalog-v2", "projectId": "37455431-84bd-4fa2-94cf-e8486f8f8c5e", "projectName": "AI Agents", "region": "tor1", "tags": [ "production", "docs" ], "updatedAt": "2025-06-01T00:00:00Z", "uuid": "20cd8434-6ea1-11f0-bf8f-4e013e2ddde4" }, "timestamp": "2025-06-01T00:05:32Z", "type": "digitalocean.knowledge_base.fetched" } ``` ## Get Object **Component key:** `digitalocean.getObject` The Get Object component retrieves an object and its metadata from a DigitalOcean Spaces bucket. ### Prerequisites Spaces Access Key ID and Secret Access Key must be configured in the DigitalOcean integration settings. The integration works without them for other components (Droplets, DNS, etc.), but they are required for any Spaces operation. ### Configuration - **Bucket**: The Spaces bucket to read from. The dropdown lists all buckets across all regions — the region is determined automatically. - **File Path**: The path to the object within the bucket (e.g. reports/daily.csv) - **Include Body**: Download the object content. Only supported for text-based content types (JSON, YAML, CSV, plain text, etc.) ### Output Channels - **Found**: The object exists — metadata, tags, and optional body are returned - **Not Found**: The object does not exist in the bucket (404) ### Output - **bucket**: The bucket name - **filePath**: The path to the object within the bucket - **endpoint**: The full Spaces URL of the object - **contentType**: MIME type of the object - **size**: Human-readable file size (e.g. 1.23 MiB) - **lastModified**: When the object was last modified (RFC1123 format) - **eTag**: MD5 hash of the object content — changes when the file changes - **metadata**: Custom metadata key-value pairs set on the object (x-amz-meta-* headers) - **tags**: Key-value tags applied to the object - **body**: Object content as a string (only present for text-based content types when Include Body is enabled) ### Use Cases - **Config reading**: Fetch a JSON or YAML config file and use its contents in downstream workflow steps - **File existence check**: Verify a file exists before triggering a process — route to notFound if it is missing - **Change detection**: Compare ETag or LastModified with a previously stored value to detect updates - **Backup verification**: Confirm a backup file was written today by checking LastModified - **Tag-based routing**: Read object tags to drive workflow logic (e.g. status=ready) ### Example Output ```json { "data": { "bucket": "my-company-assets", "contentType": "text/csv", "eTag": "a1b2c3d4ef567890a1b2c3d4ef567890", "endpoint": "https://my-company-assets.fra1.digitaloceanspaces.com/reports/daily.csv", "filePath": "reports/daily.csv", "lastModified": "Wed, 25 Mar 2026 08:45:00 GMT", "metadata": { "env": "production", "uploaded-by": "pipeline" }, "size": "41.31 KiB", "tags": { "env": "production", "status": "ready" } }, "timestamp": "2026-03-25T09:00:00Z", "type": "digitalocean.spaces.object.fetched" } ``` ## Index Knowledge Base **Component key:** `digitalocean.indexKnowledgeBase` The Index Knowledge Base component triggers a new indexing job on an existing knowledge base and polls until it completes. ### How it works Starts an indexing job that re-processes all data sources attached to the knowledge base. The component polls the job status every 30 seconds until the indexing job finishes successfully or fails. ### Use Cases - **Content refresh**: Re-index a knowledge base after updating files in a Spaces bucket or changing a website - **Scheduled re-indexing**: Combine with a Schedule trigger to re-index on a regular cadence (e.g. nightly) - **Pipeline orchestration**: Re-index after an upstream component adds or modifies data sources ### Output Returns the completed indexing job details: - **knowledgeBaseUUID**: UUID of the knowledge base - **knowledgeBaseName**: Name of the knowledge base - **jobUUID**: UUID of the indexing job - **status**: Final job status (e.g. INDEX_JOB_STATUS_COMPLETED) - **phase**: Final job phase (e.g. BATCH_JOB_PHASE_SUCCEEDED) - **totalTokens**: Total tokens consumed by the indexing job - **completedDataSources**: Number of data sources that finished indexing - **totalDataSources**: Total number of data sources - **startedAt**, **finishedAt**: Timing information - **isReportAvailable**: Whether a detailed indexing report is available ### Example Output ```json { "data": { "completedDataSources": 2, "finishedAt": "2025-06-01T00:05:32Z", "isReportAvailable": true, "jobUUID": "b2c3d4e5-0000-0000-0000-000000000001", "knowledgeBaseName": "product-catalog-v2", "knowledgeBaseUUID": "20cd8434-6ea1-11f0-bf8f-4e013e2ddde4", "phase": "BATCH_JOB_PHASE_SUCCEEDED", "startedAt": "2025-06-01T00:00:00Z", "status": "INDEX_JOB_STATUS_COMPLETED", "totalDataSources": 2, "totalTokens": "1500" }, "timestamp": "2025-06-01T00:05:32Z", "type": "digitalocean.knowledge_base.indexed" } ``` ## Manage Droplet Power **Component key:** `digitalocean.manageDropletPower` The Manage Droplet Power component performs power management operations on a droplet. ### Use Cases - **Automated restarts**: Reboot droplets on a schedule or in response to alerts - **Cost optimization**: Power off droplets during non-business hours - **Maintenance workflows**: Shutdown droplets before updates, power on after completion - **Recovery procedures**: Power cycle droplets experiencing issues ### Configuration - **Droplet**: The droplet to manage (required, supports expressions) - **Operation**: The power operation to perform (required): - **power_on**: Power on a powered-off droplet - **power_off**: Power off a running droplet (forced shutdown) - **shutdown**: Gracefully shutdown a running droplet - **reboot**: Gracefully reboot a running droplet - **power_cycle**: Power cycle a droplet (forced reboot) ### Output Returns the action result including: - **id**: Action ID - **status**: Final action status (completed or errored) - **type**: Type of action performed - **started_at**: When the action started - **completed_at**: When the action completed - **resource_id**: Droplet ID - **region**: Region slug ### Important Notes - **power_off** and **power_cycle** are forced operations and may cause data loss - **shutdown** and **reboot** are graceful and wait for the OS to complete the operation - The component waits for the action to complete before emitting - Actions may take several minutes depending on the droplet state ### Example Output ```json { "data": { "completed_at": "2026-03-12T22:27:14Z", "id": 3087531973, "region_slug": "fra1", "resource_id": 557861237, "resource_type": "droplet", "started_at": "2026-03-12T22:27:07Z", "status": "completed", "type": "power_off" }, "timestamp": "2026-03-12T22:27:20.613332846Z", "type": "digitalocean.droplet.power.power_off" } ``` ## Put Object **Component key:** `digitalocean.putObject` The Put Object component uploads a text-based object to a DigitalOcean Spaces bucket. ### Prerequisites Spaces Access Key ID and Secret Access Key must be configured in the DigitalOcean integration settings. ### Configuration - **Bucket**: The Spaces bucket to upload to. The dropdown lists all buckets — the region is determined automatically. - **File Path**: The full path including file name and extension (e.g. reports/2024/daily.csv). The content type is detected automatically from the extension. - **Body**: The text content to upload. Supports expressions to pass content from upstream components (e.g. `{{ $['HTTP Request'].body }}`). Only text-based formats are supported (JSON, CSV, YAML, plain text, XML, etc.) - **ACL**: Access control — `private` (default) restricts access to the owner, `public-read` makes the object publicly accessible. - **Metadata**: Optional key-value pairs stored as object metadata (x-amz-meta-* headers). Supports expressions. - **Tags**: Optional key-value tags applied to the object. Can be changed later without re-uploading. Supports expressions. ### Output - **bucket**: The bucket name - **filePath**: The path to the uploaded object - **endpoint**: The full Spaces URL of the object - **eTag**: MD5 hash of the uploaded content - **contentType**: Detected MIME type based on file extension - **size**: Human-readable size of the uploaded content - **metadata**: Metadata set on the object (only present if metadata was provided) - **tags**: Tags set on the object (only present if tags were provided) ### Use Cases - **Config publishing**: Upload a generated JSON or YAML config file to Spaces for downstream services to consume - **Report storage**: Save a CSV or text report generated by an upstream component - **Objectcopy**: Combine with Get Object to copy an object across buckets, preserving metadata and tags ### Example Output ```json { "data": { "bucket": "my-company-assets", "contentType": "text/csv", "eTag": "a1b2c3d4ef567890a1b2c3d4ef567890", "endpoint": "https://my-company-assets.fra1.digitaloceanspaces.com/reports/daily.csv", "filePath": "reports/daily.csv", "metadata": { "uploaded-by": "pipeline" }, "size": "128 B", "tags": { "env": "production" } }, "timestamp": "2026-03-25T09:00:00Z", "type": "digitalocean.spaces.object.uploaded" } ``` ## Run Evaluation **Component key:** `digitalocean.runEvaluation` The Run Evaluation component triggers a Gradient AI evaluation test case against an agent, waits for it to complete, and reports whether the agent passed or failed. ### How it works Runs a pre-configured evaluation test case against the selected agent. The test case already defines the prompts, metrics, and pass/fail thresholds. The component polls until the evaluation finishes, then fetches the results and routes to the appropriate output channel. ### Use Cases - **Blue/green deployments**: Evaluate a staging agent before promoting it to production - **Regression testing**: Automatically verify agent quality after knowledge base or configuration changes - **Continuous validation**: Schedule periodic evaluations to detect quality drift ### Configuration - **Test Case**: A pre-configured evaluation test case with prompts, metrics, and thresholds (required) - **Agent**: The agent to evaluate (required) - **Run Name**: A name for this evaluation run, visible in the DigitalOcean console (required, max 64 characters). Supports expressions for dynamic naming. ### Output Channels - **Passed**: The evaluation completed and the agent met all pass criteria defined in the test case - **Failed**: The evaluation completed but the agent did not meet the pass criteria, or the evaluation run itself errored ### Output Returns the evaluation results including: - **evaluationRunUUID**: UUID of the evaluation run - **testCaseUUID / testCaseName**: The test case that was run - **agentUUID / agentName**: The agent that was evaluated - **passed**: Whether the agent passed the evaluation - **status**: Final status of the evaluation run - **starMetric**: The primary metric result (name, numberValue, stringValue) - **runLevelMetrics**: All run-level metric results (name, numberValue, stringValue) - **prompts**: Per-prompt results including input, output, ground truth, and per-prompt metric scores - **startedAt / finishedAt**: Timing information - **errorDescription**: Present on the Failed channel if the run itself errored ### Notes - The evaluation typically takes 1–5 minutes depending on the number of prompts and complexity - The component polls every 30 seconds until completion - If the evaluation run itself fails (API error, timeout, etc.), the result is emitted to the Failed channel with the error description ### Example Output ```json { "data": { "agentName": "support-agent", "agentUUID": "7d5c762a-2e66-11f1-b074-4e013e2ddde4", "evaluationRunUUID": "ba42b577-9dab-40a9-a375-315a5be1922e", "finishedAt": "2025-01-01T00:03:44Z", "passed": true, "prompts": [ { "groundTruth": "A Droplet is a virtual machine that runs on DigitalOcean's cloud infrastructure.", "input": "What is a Droplet?", "metrics": [ { "metricName": "Correctness (general hallucinations)", "numberValue": 100, "stringValue": "" }, { "metricName": "Retrieved context relevance", "numberValue": 0, "stringValue": "" } ], "output": "A Droplet is a type of virtual private server (VPS) provided by a cloud platform." }, { "groundTruth": "Droplets have flexible pricing based on instance type, region, and options you select.", "input": "What is the pricing for Droplet?", "metrics": [ { "metricName": "Correctness (general hallucinations)", "numberValue": 66.67, "stringValue": "" }, { "metricName": "Retrieved context relevance", "numberValue": 0, "stringValue": "" } ], "output": "The pricing for Droplet starts at $5/month for a basic plan." } ], "runLevelMetrics": [ { "metricName": "Retrieved context relevance", "numberValue": 0, "stringValue": "" }, { "metricName": "Response-context completeness", "numberValue": 0, "stringValue": "" }, { "metricName": "Correctness (general hallucinations)", "numberValue": 93.33, "stringValue": "" } ], "starMetric": { "metricName": "Correctness (general hallucinations)", "numberValue": 93.33, "stringValue": "" }, "startedAt": "2025-01-01T00:00:00Z", "status": "successful", "testCaseName": "Product Knowledge Baseline", "testCaseUUID": "c6d75370-2f3e-11f1-b074-4e013e2ddde4" }, "timestamp": "2025-01-01T00:03:44Z", "type": "digitalocean.evaluation.passed" } ``` ## Update Alert Policy **Component key:** `digitalocean.updateAlertPolicy` The Update Alert Policy component modifies an existing monitoring alert policy with new settings. > **Note:** Monitoring is only available for droplets that had monitoring enabled during creation. Droplets created without monitoring will not report metrics or trigger alerts. ### Use Cases - **Threshold tuning**: Adjust alert thresholds in response to changing baselines or scaling events - **Enable/disable policies**: Toggle alert policies on or off as part of maintenance windows or incident management - **Notification changes**: Update notification channels (email or Slack) without recreating the policy - **Automated policy management**: Programmatically adjust alert policies as part of infrastructure workflows ### Configuration - **Alert Policy**: The alert policy to update (required, supports expressions) - **Description**: Human-readable name for the alert policy (required) - **Metric Type**: The droplet metric to monitor, such as CPU Usage or Memory Usage (required) - **Comparison**: Alert when the value is GreaterThan or LessThan the threshold (required) - **Threshold Value**: The numeric threshold that triggers the alert (required) - **Evaluation Window**: The rolling time window over which the metric is averaged (required) - **Droplets**: Specific droplets to scope the policy to (optional) - **Tags**: Monitor all droplets with matching tags (optional) - **Enabled**: Whether the alert policy is active (default: true) - **Email Notifications**: Email addresses to notify when the alert fires (optional) - **Slack Channel**: Slack channel to post alerts to, e.g. #alerts (optional) - **Slack Webhook URL**: Incoming webhook URL for the Slack workspace (required when Slack Channel is set) ### Output Returns the updated alert policy including: - **uuid**: Alert policy UUID - **description**: Human-readable description - **type**: Metric type being monitored - **compare**: Comparison operator (GreaterThan/LessThan) - **value**: Threshold value - **window**: Evaluation window - **enabled**: Whether the policy is active - **alerts**: Configured notification channels (email and/or Slack) ### Important Notes - The update operation replaces the entire alert policy — all fields must be provided, not just the ones being changed - At least one notification channel (email or Slack) is required - **Slack Channel** and **Slack Webhook URL** must be provided together - Scoping by **Droplets** and **Tags** are independent — you can use either, both, or neither (applies to all droplets) ### Example Output ```json { "data": { "alerts": { "email": [ "sammy@digitalocean.com" ] }, "compare": "GreaterThan", "description": "High CPU Usage", "enabled": true, "entities": [ "558899681" ], "tags": [], "type": "v1/insights/droplet/cpu", "uuid": "ffcaf816-f6a5-4b4a-b4c4-e84532755e82", "value": 80, "window": "5m" }, "timestamp": "2026-03-18T09:29:00.308296519Z", "type": "digitalocean.alertpolicy.updated" } ``` ## Update App **Component key:** `digitalocean.updateApp` The Update App component modifies an existing DigitalOcean App Platform application. ### Use Cases - **Update configuration**: Change app settings like environment variables, branch, build commands, and more - **Rename apps**: Update the app name - **Migrate regions**: Move the app to a different region - **Inject secrets**: Add or update environment variables such as database connection strings - **Switch branches**: Change the deployed branch without recreating the app - **Scale resources**: Adjust instance size and count for services, workers, and jobs - **Configure networking**: Update ingress paths, CORS settings, and VPC connections - **Manage databases**: Add or update database attachments (dev or managed) ### Configuration - **App**: The app to update (required) - **Name**: Update the app name (optional) - **Region**: Update the region the app is deployed in (optional) - **Branch**: The branch to deploy from (optional, applies to all components' source providers) - **Deploy on Push**: Toggle automatic deployment when code is pushed to the branch - **Environment Slug**: Update the runtime environment/buildpack - **Build Command**: Update the build command - **Run Command**: Update the run command (services, workers, jobs) - **Source Directory**: Update the source directory path - **HTTP Port**: Update the service listening port - **Instance Size**: Update the instance size slug - **Instance Count**: Update the number of instances - **Output Directory**: Update the static site output directory - **Index/Error/Catchall Document**: Update static site document settings - **Environment Variables**: Key-value pairs to add or update (merges with existing) #### Ingress Configuration - **Ingress Path**: Update the path prefix for routing traffic - **CORS Allow Origins**: Update allowed origins for Cross-Origin Resource Sharing - **CORS Allow Methods**: Update HTTP methods allowed for CORS requests #### Database Configuration - **Add Database**: Attach a new database to the app - **Database Component Name, Engine, Version**: Configure the database - **Use Managed Database**: Connect to an existing managed database cluster #### VPC Configuration - **VPC**: Update the VPC ID for the app ### Output Returns the updated app including: - **id**: The unique app ID - **name**: The app name - **region**: The region where the app is deployed - **live_url**: The live URL for the app - **default_ingress**: The default ingress URL - **active_deployment**: Information about the updated deployment ### Notes - Environment variables are merged with existing ones (not replaced) - Build/runtime settings are applied to all matching components - Updating an app triggers a new deployment - The component emits an output once the deployment reaches ACTIVE status - If the deployment fails, the component will report the failure - Dev databases are free and suitable for development; use managed databases for production ### Example Output ```json { "data": { "defaultIngress": "https://my-app-22-b6v8c.ondigitalocean.app", "id": "6d8abe1c-7cc5-4db3-b1aa-d9cdd1c127e7", "liveURL": "https://my-app-22-b6v8c.ondigitalocean.app", "name": "my-app-22", "region": { "continent": "Asia", "data_centers": [ "blr1" ], "flag": "india", "label": "Bangalore", "slug": "blr" } }, "timestamp": "2026-03-24T07:06:01.044139416Z", "type": "digitalocean.app.updated" } ``` ## Update GPU Droplet **Component key:** `digitalocean.updateGPUDroplet` The Update GPU Droplet component allows renaming and upsizing an existing GPU droplet. ### Use Cases - **Renaming**: Update the hostname of a GPU droplet - **Upsizing**: Scale up a GPU droplet to a larger GPU size for more compute power - **Combined updates**: Rename and upsize in a single operation ### Configuration - **Droplet**: The GPU droplet to update (required, supports expressions) - **New Name**: The new hostname for the GPU droplet (optional, supports expressions) - **New GPU Size**: The new GPU size to upsize the droplet to (optional, only upsizing is supported) ### Output Returns the updated GPU droplet object including: - **id**: Droplet ID - **name**: Updated droplet hostname - **status**: Current droplet status - **size_slug**: New GPU size identifier (if resized) - **region**: Region information - **networks**: Network information including IP addresses ### Important Notes - At least one of **New Name** or **New GPU Size** must be provided - Only **upsizing** is supported — you cannot downsize a GPU droplet - The GPU droplet must be powered off before resizing - If both rename and resize are specified, rename is performed first - The component waits for each operation to complete before proceeding ### Example Output ```json { "data": { "disk": 2046, "id": 412345678, "image": { "id": 98765, "name": "GPU H100 Base - Ubuntu 22.04", "slug": "gpu-h100-base-ubuntu-22-04" }, "memory": 655360, "name": "my-gpu-droplet-renamed", "networks": { "v4": [ { "ip_address": "143.198.100.50", "type": "public" }, { "ip_address": "10.132.0.5", "type": "private" } ] }, "region": { "name": "Toronto 1", "slug": "tor1" }, "size_slug": "gpu-h100x8-640gb", "status": "active", "tags": [ "gpu", "ml-training" ], "vcpus": 160 }, "timestamp": "2026-03-12T22:30:00.000000000Z", "type": "digitalocean.gpuDroplet.updated" } ``` ## Upsert DNS Record **Component key:** `digitalocean.upsertDNSRecord` The Upsert DNS Record component idempotently creates or updates a DNS record for a DigitalOcean-managed domain. It first looks up existing records with the same name and type. If a match is found it updates the record in-place; otherwise it creates a new one. ### Use Cases - **Idempotent provisioning**: Safely run DNS setup steps multiple times without creating duplicates - **IP updates**: Keep A/AAAA records in sync with changing IP addresses - **Dynamic configuration**: Update TXT records (e.g. SPF, DKIM) as part of automated workflows ### Configuration - **Domain**: The DigitalOcean-managed domain to manage the record in (required) - **Type**: The DNS record type (required): A, AAAA, CNAME, MX, NS, TXT, SRV, CAA - **Name**: The subdomain name for the record (required, use @ for root) - **Data**: The record value, e.g. an IP address or hostname (required, supports expressions) - **TTL**: Time-to-live in seconds (optional, defaults to 1800) - **Priority**: Record priority for MX/SRV records (optional) - **Port**: Port number for SRV records (optional) - **Weight**: Weight for SRV records (optional) ### Output Returns the created or updated DNS record including: - **id**: Record ID - **type**: Record type - **name**: Subdomain name - **data**: Record value - **ttl**: Time-to-live - **priority**: Priority (for MX/SRV) - **port**: Port (for SRV) - **weight**: Weight (for SRV) ### Example Output ```json { "data": { "data": "192.0.2.2", "id": 12345678, "name": "www", "port": null, "priority": null, "ttl": 1800, "type": "A", "weight": null }, "timestamp": "2026-03-13T10:10:00.000000000Z", "type": "digitalocean.dns.record.upserted" } ``` #### Discord Source URL: https://docs.superplane.com/components/discord Send messages to Discord channels and fetch mentions import { CardGrid, LinkCard } from "@astrojs/starlight/components"; ## Actions ## Instructions To set up Discord integration: 1. Go to the **Discord Developer Portal** (https://discord.com/developers/applications) 2. Click **New Application** and give it a name 3. Go to **OAuth2** → **URL Generator**: - Under **Scopes**, select **bot** - Under **Bot Permissions**, select **View Channels**, **Send Messages**, and **Read Message History** - Copy the generated URL and open it in a new tab to invite the bot to your server 4. Go to the **Bot** section: - Click **Add Bot** (if not already added) - Uncheck the **Public Bot** option - Under **Token**, click **Reset Token** then **Copy** to get your bot token 5. Paste the **Bot Token** in the **Bot Token** field below ## Get Last Mention **Component key:** `discord.getLastMention` The Get Last Mention component fetches recent messages from a Discord channel and returns the latest one that mentions your bot. ### Use Cases - **Command polling**: Retrieve the most recent mention command in a channel - **Manual workflows**: Pull latest bot mention on demand in a workflow step - **Mention auditing**: Inspect the latest mention payload before replying ### Configuration - **Channel**: Discord channel to search for mentions - **Since**: Optional date string lower-bound for mentions (only mentions at or after this time are considered). Supports expressions. Accepted formats include ISO 8601 (recommended) and Go's default timestamp format (e.g. 2026-03-16 04:17:08.750328135 +0000 UTC). ### Output The payload includes: - **channel_id**: Channel queried - **mention**: Full message payload for the latest bot mention (when found) Output channels: - **found**: Emitted when a matching mention is found - **notFound**: Emitted when no matching mention is found ### Notes - Requires the bot permission **Read Message History** in the selected channel - Only non-bot-authored messages are considered - Datetimes without timezone in **Since** are interpreted as UTC ### Example Output ```json { "data": { "channel_id": "1381731186335651880", "mention": { "author": { "bot": false, "id": "98432147091234567", "username": "pedro" }, "channel_id": "1381731186335651880", "content": "\u003c@1372980427293554709\u003e can you run /deploy?", "guild_id": "1381731029892325376", "id": "1381731283190517770", "mentions": [ { "bot": true, "id": "1372980427293554709", "username": "superplane-bot" } ], "timestamp": "2026-03-10T15:04:05.000Z" } }, "timestamp": "2026-03-10T15:04:05.000Z", "type": "discord.getLastMention.result" } ``` ## Send Text Message **Component key:** `discord.sendTextMessage` The Send Text Message component sends a message to a Discord channel. ### Use Cases - **Notifications**: Send notifications about workflow events or system status - **Alerts**: Alert teams about important events or errors - **Updates**: Provide status updates on long-running processes ### Configuration - **Channel**: Select the Discord channel to send the message to - **Content**: Plain text message content (max 2000 characters) - **Embed Title**: Optional title for a rich embed - **Embed Description**: Optional description for a rich embed - **Embed Color**: Hex color code for the embed (e.g., #5865F2) - **Embed URL**: Optional URL to link from the embed title ### Output Returns metadata about the sent message including message ID, channel ID, and author information. ### Notes - Either content or embed (title/description) must be provided - The Discord bot must be installed and have permission to post to the selected channel - Supports Discord's rich embed formatting for visually appealing messages ### Example Output ```json { "data": { "author": { "bot": true, "id": "1111111111111111111", "username": "Webhook" }, "channel_id": "9876543210987654321", "content": "Hello from SuperPlane", "id": "1234567890123456789", "timestamp": "2026-01-16T12:00:00.000Z" }, "timestamp": "2026-01-16T17:56:16.680755501Z", "type": "discord.message.sent" } ``` #### DockerHub Source URL: https://docs.superplane.com/components/dockerhub Manage and react to DockerHub repositories and tags import { CardGrid, LinkCard } from "@astrojs/starlight/components"; ## Triggers ## Actions ## Instructions To generate a DockerHub access token: - Go to **DockerHub** → **Account Settings** → **Personal Access Tokens** - Generate a new token - **Copy the token**, and enter your DockerHub username and the token below ## On Image Push **Trigger key:** `dockerhub.onImagePush` The On Image Push trigger starts a workflow execution when an image tag is pushed to DockerHub. ### Use Cases - **Build pipelines**: Trigger builds and deployments on container pushes - **Release workflows**: Promote artifacts when a new tag is published - **Security automation**: Kick off scans or alerts for newly pushed images ### Configuration - **Repository**: DockerHub repository name, in the format of `namespace/name` - **Tags**: Optional filters for image tags (for example: `latest` or `^v[0-9]+`) ### Webhook Setup This trigger generates a webhook URL in SuperPlane. Add that URL as a DockerHub webhook for the selected repository so DockerHub can deliver push events. ### Example Data ```json { "data": { "callback_url": "https://hub.docker.com/u/superplane/demo/hook/abcd/", "push_data": { "pushed_at": 1736400000, "pusher": "superplane-bot", "tag": "v1.2.3" }, "repository": { "description": "Demo image for SuperPlane workflows", "is_private": false, "name": "demo", "namespace": "superplane", "pull_count": 3456, "repo_name": "superplane/demo", "repo_url": "https://hub.docker.com/r/superplane/demo", "star_count": 12, "status": "Active" } }, "timestamp": "2026-02-03T12:00:00Z", "type": "dockerhub.image.push" } ``` ## Get Image Tag **Component key:** `dockerhub.getImageTag` The Get Image Tag component retrieves metadata for a DockerHub image tag. ### Use Cases - **Release automation**: Fetch tag metadata for deployments - **Audit trails**: Resolve tag details for traceability - **Insights**: Inspect image sizes, digests, and last pushed times ### Configuration - **Repository**: DockerHub repository name, in the format of `namespace/name` - **Tag**: Image tag to retrieve (for example: `latest` or `v1.2.3`) ### Example Output ```json { "data": { "full_size": 52837442, "id": 123456, "images": [ { "architecture": "amd64", "digest": "sha256:fe12ab34cd56ef78ab90cd12ef34ab56cd78ef90ab12cd34ef56ab78cd90ef12", "last_pulled": "2025-01-06T11:02:10.123456Z", "last_pushed": "2025-01-05T21:06:53.506400Z", "os": "linux", "size": 52837442, "status": "active" } ], "last_updated": "2025-01-05T21:06:53.506400Z", "last_updater": 1234, "last_updater_username": "superplane-bot", "name": "latest", "repository": 98765, "status": "active", "tag_last_pulled": "2025-01-06T11:02:10.123456Z", "tag_last_pushed": "2025-01-05T21:06:53.506400Z", "v2": "true" }, "timestamp": "2026-02-03T12:00:00Z", "type": "dockerhub.tag" } ``` #### Elastic Source URL: https://docs.superplane.com/components/elastic Index documents into Elasticsearch and receive Kibana webhooks import { CardGrid, LinkCard } from "@astrojs/starlight/components"; ## Triggers ## Actions ## Instructions To connect Elastic to SuperPlane: 1. Paste your **Elasticsearch URL** and **Kibana URL**. In Elastic Cloud, open https://cloud.elastic.co/home and copy both endpoints from the same deployment under the manage section. 2. In Settings, create an API key and paste it into SuperPlane. The key must be able to access Elasticsearch, Kibana cases, and Kibana connectors. ## When Alert Fires **Trigger key:** `elastic.onAlertFires` The When Alert Fires trigger starts a workflow execution when a Kibana alert rule fires via a webhook connector. ### Shared Connector SuperPlane creates **one Kibana Webhook connector per integration**, shared across all triggers that use the same Kibana instance. Each incoming request is routed to the correct trigger using the `eventType` field in the request body — this trigger only processes requests where `eventType` is `"alert_fired"`. Requests intended for other trigger types (e.g. `"document_indexed"`) are silently ignored. ### Setup 1. Select the Kibana alert rule in SuperPlane and save the trigger. 2. SuperPlane automatically creates or reuses the shared Kibana Webhook connector and attaches it to the selected rule if it is missing. This provisioning happens when the live version is published. Autosave on a draft version does not create the connector. #### Kibana action body SuperPlane configures the rule action body with these fields: ```json { "eventType": "alert_fired", "ruleId": "{{rule.id}}", "ruleName": "{{rule.name}}", "spaceId": "{{rule.spaceId}}", "tags": {{rule.tags}}, "severity": "{{context.severity}}", "status": "{{rule.status}}" } ``` The `eventType` field is required for routing. Kibana substitutes `{{rule.id}}` and `{{rule.name}}` at delivery time. Fields omitted from the body will not be filterable in SuperPlane. ### Filtering Select at least one **Rule**. Additional filter fields are optional. When multiple values are provided in a list, any value matching is sufficient (OR). All active filter types must match simultaneously (AND across types). **Rule ID** is the most reliable selector because rule names are user-editable. Use it when you need precise per-rule routing. ### Webhook Verification SuperPlane generates a random signing secret and configures the Kibana connector to include it on every request. Requests without the correct secret are rejected automatically. ### Event Data Each received alert emits the parsed JSON body sent by Kibana directly as the event data. Use the workflow event timestamp to know when SuperPlane received it. ### Example Data ```json { "data": { "context": { "message": "Error rate exceeded threshold: 15%", "threshold": 10, "value": 15 }, "eventType": "alert_fired", "ruleId": "abc-123", "ruleName": "High error rate detected", "severity": "critical", "spaceId": "default", "status": "active", "tags": [ "infrastructure", "prod" ] }, "timestamp": "2026-03-12T09:00:00Z", "type": "elastic.alert" } ``` ## When Case Status Changes **Trigger key:** `elastic.onCaseStatusChange` The When Case Status Changes trigger fires a workflow execution when a Kibana Security case changes status. ### Shared Connector SuperPlane creates **one Kibana Webhook connector per integration**, shared across Elastic triggers that use the same Kibana instance. Each incoming request is routed to the correct trigger instance using two fields in the request body: - `eventType`: must be `"case_status_changed"`. - `routeKey`: a unique ID assigned per trigger node so multiple case-status triggers can coexist safely. ### How it works 1. When the trigger is saved, SuperPlane creates or reuses the shared Kibana Webhook connector. 2. SuperPlane automatically provisions a Kibana **Elasticsearch query** rule against `.kibana_alerting_cases` using `cases.updated_at` as the time field. 3. Every minute, that Kibana rule checks for case updates in the current window and fires the shared connector when matches are found. 4. SuperPlane receives the webhook, verifies the secret, validates the routing fields, then queries Kibana for cases updated since the stored checkpoint. 5. SuperPlane compares each returned case's current status to the last status stored in trigger metadata and only emits when the value changed. 6. SuperPlane emits one `elastic.case.status.changed` event per matching case whose status actually changed. Provisioning happens when the live version is published. Autosave on a draft version does not create the connector or rule. ### Configuration - **Cases**: Select one or more specific cases to monitor. - **Statuses** *(optional)*: Only fire when a case has one of these statuses. Leave empty to fire for any case update. - **Severities** *(optional)*: Only fire for cases with one of these severities. Leave empty to accept all severities. - **Tags** *(optional)*: Only fire for cases that include at least one tag matching any of these predicates. Leave empty to accept all cases. ### Event Data The trigger emits the full case details including id, title, status, severity, version, tags, description, and timestamps. ### Example Data ```json { "data": { "createdAt": "2026-03-12T09:00:00.000Z", "description": "Elevated error rate detected in production.", "id": "3c0a2b10-4e5f-11ee-be56-0242ac120002", "severity": "high", "status": "in-progress", "tags": [ "production", "incident" ], "title": "Production incident", "updatedAt": "2026-03-12T10:00:00.000Z", "version": "WzE3LDFd" }, "timestamp": "2026-03-12T10:00:00Z", "type": "elastic.case.status.changed" } ``` ## On Document Indexed **Trigger key:** `elastic.onDocumentIndexed` The On Document Indexed trigger starts a workflow execution when a new document is indexed into an Elasticsearch index. ### Shared Connector SuperPlane creates **one Kibana Webhook connector per integration**, shared across all triggers that use the same Kibana instance. Each incoming request is routed to the correct trigger instance using two fields in the request body: - `eventType`: must be `"document_indexed"` — requests with any other value are silently ignored, allowing the shared connector to serve both this trigger and others (e.g. When Alert Fires). - `routeKey`: a unique ID assigned per trigger node — allows multiple On Document Indexed nodes on the same canvas to each react only to their own Kibana rule. ### How it works 1. When the trigger is saved, SuperPlane creates or reuses the shared Kibana Webhook connector and provisions a Kibana Elasticsearch query rule for the configured index. 2. Every minute, the rule checks for documents with an `@timestamp` value within the current window. When matches are found, Kibana fires the connector. 3. SuperPlane receives the webhook, queries Elasticsearch for all documents newer than its stored checkpoint, and emits one event per document. Provisioning happens when the live version is published. Autosave on a draft version does not create the connector or rule. ### Configuration - **Index**: The Elasticsearch index to monitor for new documents. > **Note**: This trigger requires an `@timestamp` field mapped as `date` on indexed documents. Documents without that field will be missed. To ensure all documents are captured, configure an ingest pipeline on the index to auto-populate the field if absent: > ```json > { "set": { "field": "@timestamp", "value": "{{{_ingest.timestamp}}}", "override": false } } > ``` ### Webhook Verification SuperPlane generates a random signing secret and configures the Kibana connector to include it on every request. Requests without the correct secret are rejected automatically. ### Event Data The webhook acts as a signal. When it fires, SuperPlane queries Elasticsearch for documents newer than the stored checkpoint and emits one event per document containing its ID, index, and full source. ### Example Data ```json { "data": { "id": "doc-1", "index": "workflow-audit", "source": { "@timestamp": "2026-03-12T09:00:00Z", "message": "deployment started", "service": "api" } }, "timestamp": "2026-03-12T09:00:00Z", "type": "elastic.document.indexed" } ``` ## Create Case **Component key:** `elastic.createCase` The Create Case component opens a new case in Kibana Security. ### Configuration - **Title**: The case title - **Severity**: Case severity (low, medium, high, or critical) - **Owner**: The Kibana application that owns the case - **Description**: A description of the case - **Tags**: Optional list of tags to attach to the case ### Outputs The component emits an event containing: - `id`: The case ID assigned by Kibana - `title`: The case title - `status`: The initial case status - `severity`: The case severity - `version`: The case version (can be provided to later updates for explicit optimistic locking) - `createdAt`: The timestamp when the case was created ### Example Output ```json { "data": { "createdAt": "2026-03-12T09:00:00.000Z", "id": "3c0a2b10-4e5f-11ee-be56-0242ac120002", "severity": "high", "status": "open", "title": "Production incident", "version": "WzE2LDFd" }, "timestamp": "2026-03-12T09:00:00Z", "type": "elastic.case.created" } ``` ## Get Case **Component key:** `elastic.getCase` The Get Case component retrieves an existing case from Kibana Security by its ID. ### Configuration - **Case**: The Kibana case to retrieve ### Outputs The component emits an event containing: - `id`: The case ID - `title`: The case title - `description`: The case description - `status`: The case status - `severity`: The case severity - `tags`: The case tags - `version`: The current case version returned by Kibana - `createdAt`: The timestamp when the case was created - `updatedAt`: The timestamp when the case was last updated ### Example Output ```json { "data": { "createdAt": "2026-03-12T09:00:00.000Z", "description": "Elevated error rate detected in production.", "id": "3c0a2b10-4e5f-11ee-be56-0242ac120002", "severity": "high", "status": "open", "tags": [ "production", "incident" ], "title": "Production incident", "updatedAt": "2026-03-12T10:00:00.000Z", "version": "WzE2LDFd" }, "timestamp": "2026-03-12T09:00:00Z", "type": "elastic.case.retrieved" } ``` ## Get Document **Component key:** `elastic.getDocument` The Get Document component retrieves a JSON document from an Elasticsearch index by its ID. ### Configuration - **Index**: The Elasticsearch index to read from - **Document**: The document to retrieve ### Outputs The component emits an event containing: - `id`: The document ID - `index`: The index the document was read from - `version`: The document version number - `source`: The document fields ### Example Output ```json { "data": { "id": "aB3kLmN4oPqR", "index": "workflow-audit", "source": { "env": "production", "message": "deployment started" }, "version": 3 }, "timestamp": "2026-03-12T09:00:00Z", "type": "elastic.document.retrieved" } ``` ## Index Document **Component key:** `elastic.indexDocument` The Index Document component writes a JSON document to an Elasticsearch index. ### Use Cases - **Audit logging**: Record workflow actions in Elasticsearch for centralized search and dashboards - **Incident records**: Index structured incident data for analysis and alerting - **Workflow output**: Store results from any workflow step for downstream querying ### Configuration - **Index**: The Elasticsearch index name to write to (e.g. `workflow-audit`) - **Document**: The JSON object to index. The editor starts with an `@timestamp` template so documents are compatible with On Document Indexed by default. - **Document ID** *(optional)*: A stable ID for idempotent writes. If omitted, Elasticsearch generates one automatically. Providing an ID means re-runs update the existing document rather than creating a duplicate. ### Outputs The component emits an event containing: - `id`: The document ID assigned by Elasticsearch - `index`: The index the document was written to - `result`: Operation result (`created` or `updated`) - `version`: The document version number ### Example Output ```json { "data": { "id": "aB3kLmN4oPqR", "index": "workflow-audit", "result": "created", "version": 1 }, "timestamp": "2026-03-12T09:00:00Z", "type": "elastic.document.indexed" } ``` ## Update Case **Component key:** `elastic.updateCase` The Update Case component applies a partial update to an existing Kibana Security case. ### Configuration - **Case**: The Kibana case to update - **Title**: New title for the case (optional) - **Description**: New description for the case (optional) - **Status**: New status for the case (optional) - **Severity**: New severity for the case (optional) - **Tags**: New tags for the case (optional) ### Outputs The component emits an event containing: - `id`: The case ID - `title`: The updated case title - `status`: The updated case status - `severity`: The updated case severity - `version`: The new case version - `updatedAt`: The timestamp when the case was last updated ### Example Output ```json { "data": { "id": "3c0a2b10-4e5f-11ee-be56-0242ac120002", "severity": "high", "status": "in-progress", "title": "Production incident", "updatedAt": "2026-03-12T10:00:00.000Z", "version": "WzE3LDFd" }, "timestamp": "2026-03-12T09:00:00Z", "type": "elastic.case.updated" } ``` ## Update Document **Component key:** `elastic.updateDocument` The Update Document component applies a partial update to an existing document in an Elasticsearch index. ### Configuration - **Index**: The Elasticsearch index containing the document - **Document**: The document to update - **Fields**: The fields to merge into the existing document (partial update). The editor starts with an `@timestamp` template for convenience. ### Outputs The component emits an event containing: - `id`: The document ID - `index`: The index the document belongs to - `result`: Operation result (`updated`) - `version`: The new document version number ### Example Output ```json { "data": { "id": "aB3kLmN4oPqR", "index": "workflow-audit", "result": "updated", "version": 4 }, "timestamp": "2026-03-12T09:00:00Z", "type": "elastic.document.updated" } ``` #### FireHydrant Source URL: https://docs.superplane.com/components/firehydrant Manage and react to incidents in FireHydrant import { CardGrid, LinkCard } from "@astrojs/starlight/components"; ## Triggers ## Actions ## Instructions To connect FireHydrant, create an API key: 1. Go to **Settings → API Keys → Create API Key** in your FireHydrant account. This requires Owner permissions. 2. The API key should have **Write Access** in order to create incidents and webhooks. 3. Copy the API key and paste it into the configuration for this integration. ## On Incident **Trigger key:** `firehydrant.onIncident` The On Incident trigger starts a workflow execution when a FireHydrant incident is created or reaches a specific milestone. ### Use Cases - **Incident response**: Automatically notify Slack, update a status page, or create a Jira ticket when an incident is opened - **Alert escalation**: Trigger escalation workflows when critical incidents are created - **Milestone tracking**: React to incidents reaching specific milestones such as mitigated or resolved - **Cross-tool sync**: Sync new FireHydrant incidents to other incident management tools ### Configuration - **Current Milestone**: Select which incident milestones to trigger on (started, acknowledged, mitigated, resolved, etc.). The workflow will trigger when an incident is created or updated to match any of the selected milestones. - **Severities** (optional): Filter by severity levels. Only incidents matching the selected severities will trigger the workflow. If empty, all severities are accepted. ### Event Data Each incident event includes: - **name**: Incident name/title - **number**: Incident number - **severity**: Severity level - **priority**: Priority level - **current_milestone**: Current milestone (e.g., started, acknowledged) - **summary**: Incident summary ### Webhook Setup This trigger automatically sets up a FireHydrant webhook endpoint when configured. The endpoint is managed by SuperPlane and will be cleaned up when the trigger is removed. ### Example Data ```json { "data": { "event": "incident.created", "incident": { "conference_bridges": [ { "id": "cb-9f1a2c3d", "name": "Zoom War Room", "provider": "zoom", "url": "https://zoom.us/j/9876543210" } ], "counts": { "starred_events": 3, "starred_messages": 12 }, "created_at": "2026-03-02 14:43:05 UTC", "current_milestone": "started", "custom_fields": [ { "display_name": "Detected by", "id": "b370d5b8-9ef1-49d5-be4a-96ee6e536c8b", "value": "Datadog Monitor: DB Health Check" } ], "customer_impact_summary": "All production API requests are failing due to database deletion. Users cannot log in or access core features.", "description": "Primary production database was accidentally deleted during maintenance.", "follow_ups": [ { "id": "fu-123", "status": "pending", "title": "Implement database deletion safeguards" } ], "id": "21fe20b5-8012-4a51-a34c-623b1389af66", "impacts": [ { "description": "Production users unable to access platform", "id": "impact-1", "type": "customer" } ], "incident_channels": [ { "id": "ic-789", "name": "#incident-001", "type": "slack", "visibility": "private" } ], "labels": [ "database", "production", "outage" ], "last_note": "Engineering team restoring latest backup from 14:30 UTC.", "milestones": [ { "created_at": "2026-03-02 14:43:05 UTC", "duration": "", "id": "d0eaad5c-6922-4f35-adfb-9cf481d39f46", "name": "Started", "occurred_at": "2026-03-02 14:43:05 UTC", "original_milestone_id": "99e55a31-894a-4e76-b680-89b3acab0d7b", "type": "started", "updated_at": "2026-03-02 14:43:06 UTC", "updated_by_id": "bd23faac-dcda-4fd7-a968-4e0b6a04bf35", "updated_by_type": "Bot" } ], "name": "Production Database Accidentally Deleted", "number": 42, "priority": "P1", "private_status_page_url": "https://app.firehydrant.io/incidents/internal/status_page/mock-url", "role_assignments": [ { "role": "Incident Commander", "user_id": "user-111", "user_name": "Alice Johnson" }, { "role": "Communications Lead", "user_id": "user-222", "user_name": "Bob Smith" } ], "severity": "SEV1", "started_at": "2026-03-02 14:43:05 UTC", "summary": "Production outage caused by accidental database deletion.", "tags": [ "critical", "customer-impacting" ], "tasks": [ { "description": "Restore database from latest backup", "id": "task-1", "status": "in_progress" }, { "description": "Validate data integrity after restore", "id": "task-2", "status": "pending" } ], "team_assignments": [ { "team_id": "team-ops", "team_name": "Operations" }, { "team_id": "team-eng", "team_name": "Engineering" } ], "updated_at": "2026-03-02 14:45:10 +0000" }, "operation": "CREATED", "resource_type": "incident" }, "timestamp": "2026-03-02T14:43:07.292043553Z", "type": "firehydrant.incident.created" } ``` ## Create Incident **Component key:** `firehydrant.createIncident` The Create Incident component creates a new incident in FireHydrant. ### Use Cases - **Alert escalation**: Create incidents from monitoring alerts or error tracking - **Cross-tool sync**: Open a FireHydrant incident from other SuperPlane triggers (e.g., PagerDuty, Rootly, GitHub) - **Manual incident creation**: Create incidents from workflow events - **Automated response**: Automatically declare incidents when thresholds are breached ### Configuration - **Name**: Incident name/title (required, supports expressions) - **Summary**: Short summary of the incident (optional, supports expressions) - **Description**: Detailed description of the incident (optional, supports expressions) - **Severity**: Severity level, e.g., SEV1, SEV2 (optional, populated from FireHydrant) - **Priority**: Priority level, e.g., P1, P2 (optional, populated from FireHydrant) ### Output Returns the created incident object including: - **id**: Incident ID - **name**: Incident name - **description**: Incident description - **summary**: Incident summary - **customer_impact_summary**: Summary of customer impact - **current_milestone**: Current milestone (e.g., started, acknowledged) - **number**: Incident number - **incident_url**: URL to the incident in FireHydrant - **severity**: Severity level - **priority**: Priority level - **tag_list**: List of tags associated with the incident - **impacts**: List of impacts associated with the incident - **milestones**: List of milestones associated with the incident ### Example Output ```json { "data": { "current_milestone": "started", "customer_impact_summary": "Some customers are experiencing slow performance and intermittent errors when accessing the application.", "description": "Users are experiencing slow database queries and connection timeouts.", "id": "04d9fd1a-ba9c-417d-b396-58a6e2c374de", "impacts": [], "incident_url": "https://app.firehydrant.com/incidents/04d9fd1a-ba9c-417d-b396-58a6e2c374de", "milestones": [ { "occurred_at": "2026-01-19T12:00:00Z", "type": "started" } ], "name": "Database connection issues", "number": 603, "priority": "P1", "severity": "SEV1", "summary": "Database connection pool exhausted causing cascading failures.", "tag_list": [] }, "timestamp": "2026-01-19T12:00:00Z", "type": "firehydrant.incident" } ``` #### GitHub Source URL: https://docs.superplane.com/components/github Manage and react to changes in your GitHub repositories import { CardGrid, LinkCard } from "@astrojs/starlight/components"; ## Triggers ## Actions ## On Branch Created **Trigger key:** `github.onBranchCreated` The On Branch Created trigger starts a workflow execution when a new branch is created in a GitHub repository. ### Use Cases - **Branch automation**: Set up environments or resources for new branches - **Branch validation**: Validate branch naming conventions - **Notification workflows**: Notify teams when important branches are created - **Branch processing**: Process or configure branches automatically ### Configuration - **Repository**: Select the GitHub repository to monitor - **Branches**: Configure which branches to listen for using predicates (e.g., equals "main", starts with "feature-") ### Event Data Each branch event includes: - **ref**: The branch reference (e.g., "refs/heads/feature/new-feature") - **ref_type**: Type of reference (branch) - **repository**: Repository information - **sender**: User who created the branch ### Webhook Setup This trigger automatically sets up a GitHub webhook when configured. The webhook is managed by SuperPlane and will be cleaned up when the trigger is removed. ### Example Data ```json { "data": { "description": "Example repository for webhook payloads", "master_branch": "main", "pusher_type": "user", "ref": "feature/new-endpoint", "ref_type": "branch", "repository": { "full_name": "acme/widgets", "html_url": "https://github.com/acme/widgets", "id": 123456 }, "sender": { "html_url": "https://github.com/octocat", "id": 101, "login": "octocat" } }, "timestamp": "2026-01-16T17:56:16.680755501Z", "type": "github.branchCreated" } ``` ## On Check Run **Trigger key:** `github.onCheckRun` The On Check Run trigger starts a workflow execution when a GitHub Checks API check run changes. GitHub check runs are created by GitHub Apps and power many pull request checks such as Cloudflare Pages, DCO, Sourcery, and GitHub Actions check runs. They are separate from legacy Commit Statuses API statuses. Use On Commit Status for legacy commit status events. ### Use Cases - **Pull request automation**: React when Checks API checks complete or fail - **Quality gates**: Continue workflows only after a specific check run reaches the expected state - **Notifications**: Notify teams when app-provided checks fail or require action - **Merge orchestration**: Combine this trigger with List Check Runs For Ref to decide whether all checks are green ### Configuration - **Repository**: Select the GitHub repository to monitor - **Statuses**: Select check run statuses to listen for (queued, in_progress, completed, requested, waiting, pending) - **Conclusions** *(optional)*: Filter completed check runs by conclusion - **Names** *(optional)*: Filter check run names using predicates, e.g. equals "DCO" or matches "Cloudflare.*" - **Branches** *(optional)*: Filter check suite head branches using predicates - **Pull requests only**: Emit only check runs that GitHub associates with at least one pull request ### Event Data Each event includes: - **action**: The check_run webhook action - **check_run**: Check run details, including name, status, conclusion, head SHA, app, pull requests, and URLs - **repository**: Repository information - **sender**: User or app actor associated with the webhook event ### Webhook Setup This trigger automatically sets up a GitHub webhook when configured. The webhook is managed by SuperPlane and will be cleaned up when the trigger is removed. ### Notes GitHub may return an empty pull_requests array for check runs created from forked repository pushes. When Pull requests only is enabled, those fork-originated check runs may be filtered out because GitHub does not include PR metadata in the webhook payload. ### Example Data ```json { "data": { "action": "completed", "check_run": { "app": { "name": "DCO" }, "check_suite": { "head_branch": "feature/snake-updates", "head_sha": "d6f3c8a2e8b7f0a9c0a1f67f0c5d7b2a1d9e3f44" }, "completed_at": "2026-06-01T12:02:00Z", "conclusion": "success", "details_url": "https://github.com/acme/snaketoy/runs/123456789", "head_sha": "d6f3c8a2e8b7f0a9c0a1f67f0c5d7b2a1d9e3f44", "html_url": "https://github.com/acme/snaketoy/runs/123456789", "id": 123456789, "name": "DCO", "pull_requests": [ { "base": { "ref": "main" }, "head": { "ref": "feature/snake-updates", "sha": "d6f3c8a2e8b7f0a9c0a1f67f0c5d7b2a1d9e3f44" }, "html_url": "https://github.com/acme/snaketoy/pull/42", "number": 42 } ], "started_at": "2026-06-01T12:00:00Z", "status": "completed" }, "repository": { "full_name": "acme/snaketoy", "html_url": "https://github.com/acme/snaketoy" }, "sender": { "html_url": "https://github.com/octocat", "login": "octocat" } }, "timestamp": "2026-06-01T12:02:01Z", "type": "github.checkRun" } ``` ## On Commit Status **Trigger key:** `github.onCommitStatus` The On Commit Status trigger starts a workflow execution when a GitHub commit status is created or updated. GitHub commit statuses are the legacy status objects created through the Commit Statuses API. They are separate from GitHub Checks API check runs, which power many PR checks from GitHub Apps such as Cloudflare Pages, DCO, and Sourcery. This trigger does not receive those check-run events. For GitHub Actions workflows, use the On Workflow Run trigger instead. ### Use Cases - **Merge automation**: Re-evaluate pull request merge criteria when required status checks change - **CI/CD orchestration**: React to status updates from external CI systems - **Quality gates**: Route workflows based on commit status context and state - **Notifications**: Notify teams when important status checks fail or recover ### Configuration - **Repository**: Select the GitHub repository to monitor - **States**: Select which commit status states to listen for (error, failure, pending, success) - **Contexts** *(optional)*: Configure which status contexts to listen for using predicates (e.g., equals "ci/build", matches "deploy/.*") - **Branches** *(optional)*: Configure which branch names to listen for using predicates. GitHub includes branches that contain the status SHA. ### Event Data Each status event includes: - **state**: The new commit status state (error, failure, pending, success) - **context**: The status context, such as "ci/build" - **sha**: Commit SHA for the status - **description**: Optional status description - **target_url**: Optional link added to the status - **branches**: Branches containing the status SHA - **commit**: Commit information - **repository**: Repository information - **sender**: User who created the status event. This is not necessarily the commit author ### Webhook Setup This trigger automatically sets up a GitHub webhook when configured. The webhook is managed by SuperPlane and will be cleaned up when the trigger is removed. ### Example Data ```json { "data": { "branches": [ { "commit": { "sha": "d6f3c8a2e8b7f0a9c0a1f67f0c5d7b2a1d9e3f44", "url": "https://api.github.com/repos/acme-labs/snaketoy/commits/d6f3c8a2e8b7f0a9c0a1f67f0c5d7b2a1d9e3f44" }, "name": "main", "protected": true } ], "commit": { "commit": { "message": "Add checkout validation" }, "html_url": "https://github.com/acme-labs/snaketoy/commit/d6f3c8a2e8b7f0a9c0a1f67f0c5d7b2a1d9e3f44", "sha": "d6f3c8a2e8b7f0a9c0a1f67f0c5d7b2a1d9e3f44" }, "context": "ci/build", "created_at": "2026-01-16T17:56:16Z", "description": "Build completed successfully", "id": 15384176893, "repository": { "full_name": "acme-labs/snaketoy", "html_url": "https://github.com/acme-labs/snaketoy", "id": 101, "name": "snaketoy" }, "sender": { "html_url": "https://github.com/octocat", "id": 583231, "login": "octocat" }, "sha": "d6f3c8a2e8b7f0a9c0a1f67f0c5d7b2a1d9e3f44", "state": "success", "target_url": "https://github.com/acme-labs/snaketoy/actions/runs/123456789", "updated_at": "2026-01-16T17:57:20Z" }, "timestamp": "2026-01-16T17:56:16.680755501Z", "type": "github.status" } ``` ## On Issue **Trigger key:** `github.onIssue` The On Issue trigger starts a workflow execution when issue events occur in a GitHub repository. ### Use Cases - **Issue automation**: Automate responses to new or updated issues - **Notification workflows**: Send notifications when issues are created or closed - **Task management**: Sync issues with external task management systems - **Label automation**: Automatically label or categorize issues ### Configuration - **Repository**: Select the GitHub repository to monitor - **Actions**: Select which issue actions to listen for (opened, closed, reopened, etc.) ### Event Data Each issue event includes: - **action**: The action that triggered the event (opened, closed, reopened, etc.) - **issue**: Complete issue information including title, body, state, labels, assignees - **repository**: Repository information - **sender**: User who triggered the event ### Webhook Setup This trigger automatically sets up a GitHub webhook when configured. The webhook is managed by SuperPlane and will be cleaned up when the trigger is removed. ### Example Data ```json { "data": { "action": "opened", "assignee": null, "issue": { "html_url": "https://github.com/acme/widgets/issues/42", "number": 42, "state": "open", "title": "Fix flaky build", "user": { "login": "octocat" } }, "repository": { "full_name": "acme/widgets", "html_url": "https://github.com/acme/widgets", "id": 123456 }, "sender": { "html_url": "https://github.com/octocat", "id": 101, "login": "octocat" } }, "timestamp": "2026-01-16T17:56:16.680755501Z", "type": "github.issue" } ``` ## On Issue Comment **Trigger key:** `github.onIssueComment` The On Issue Comment trigger starts a workflow execution when comments are added to issues. ### Use Cases - **Command processing**: Process slash commands in issue comments (e.g., /assign, /close) - **Bot interactions**: Respond to comments with automated actions - **Issue automation**: Automate issue management based on comment content - **Notification systems**: Notify teams when important comments are added ### Configuration - **Repository**: Select the GitHub repository to monitor - **Content Filter**: Optional regex pattern to filter comments (e.g., `/solve` to only trigger on comments containing "/solve") ### Event Data Each comment event includes: - **comment**: Comment information including body, author, created timestamp - **issue**: Issue information the comment was added to - **repository**: Repository information - **sender**: User who added the comment ### Webhook Setup This trigger automatically sets up a GitHub webhook when configured. The webhook is managed by SuperPlane and will be cleaned up when the trigger is removed. ### Example Data ```json { "data": { "action": "created", "comment": { "body": "I can reproduce this", "html_url": "https://github.com/acme/widgets/issues/42#issuecomment-5001", "id": 5001 }, "issue": { "html_url": "https://github.com/acme/widgets/issues/42", "number": 42, "title": "Fix flaky build" }, "repository": { "full_name": "acme/widgets", "html_url": "https://github.com/acme/widgets", "id": 123456 }, "sender": { "html_url": "https://github.com/octocat", "id": 101, "login": "octocat" } }, "timestamp": "2026-01-16T17:56:16.680755501Z", "type": "github.issueComment" } ``` ## On PR Comment **Trigger key:** `github.onPRComment` The On PR Comment trigger starts a workflow execution when comments are added on a pull request conversation. ### Use Cases - **Command processing**: Process slash commands in PR conversation comments (e.g., /deploy, /test) - **Bot interactions**: Respond to comments with automated actions - **Notification systems**: Notify teams when important PR conversation comments are added ### Configuration - **Repository**: Select the GitHub repository to monitor - **Content Filter**: Optional regex pattern to filter comments (e.g., `/solve` to only trigger on comments containing "/solve") ### Event Data Each comment event includes: - **comment**: Comment information including body, author, created timestamp - **issue**: Issue/PR information; for this trigger it is always a pull request issue - **repository**: Repository information - **sender**: User who added the comment SuperPlane passes through the full GitHub webhook payload under data for the issue_comment event type. Common expression paths: - PR number: `root().data.issue.number` - PR title: `root().data.issue.title` - PR URL: `root().data.issue.pull_request.html_url` - Comment body: `root().data.comment.body` ### Webhook Setup This trigger automatically sets up a GitHub webhook when configured. The webhook is managed by SuperPlane and will be cleaned up when the trigger is removed. ### Example Data ```json { "data": { "action": "created", "comment": { "author_association": "CONTRIBUTOR", "body": "Looks good to me — can we also update the README example to match the new title?", "created_at": "2026-02-25T18:14:22Z", "html_url": "https://github.com/acme-labs/snaketoy/pull/42#issuecomment-4928173041", "id": 4928173041, "issue_url": "https://api.github.com/repos/acme-labs/snaketoy/issues/42", "node_id": "IC_kwDOQ7c2jM7zXq2R", "performed_via_github_app": null, "pin": null, "reactions": { "+1": 2, "-1": 0, "confused": 0, "eyes": 1, "heart": 0, "hooray": 1, "laugh": 0, "rocket": 0, "total_count": 4, "url": "https://api.github.com/repos/acme-labs/snaketoy/issues/comments/4928173041/reactions" }, "updated_at": "2026-02-25T18:14:29Z", "url": "https://api.github.com/repos/acme-labs/snaketoy/issues/comments/4928173041", "user": { "avatar_url": "https://avatars.githubusercontent.com/u/124578901?v=4", "events_url": "https://api.github.com/users/jules-ramirez/events{/privacy}", "followers_url": "https://api.github.com/users/jules-ramirez/followers", "following_url": "https://api.github.com/users/jules-ramirez/following{/other_user}", "gists_url": "https://api.github.com/users/jules-ramirez/gists{/gist_id}", "gravatar_id": "", "html_url": "https://github.com/jules-ramirez", "id": 124578901, "login": "jules-ramirez", "node_id": "MDQ6VXNlcjEyNDU3ODkwMQ==", "organizations_url": "https://api.github.com/users/jules-ramirez/orgs", "received_events_url": "https://api.github.com/users/jules-ramirez/received_events", "repos_url": "https://api.github.com/users/jules-ramirez/repos", "site_admin": false, "starred_url": "https://api.github.com/users/jules-ramirez/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/jules-ramirez/subscriptions", "type": "User", "url": "https://api.github.com/users/jules-ramirez", "user_view_type": "public" } }, "issue": { "active_lock_reason": null, "assignee": null, "assignees": [], "author_association": "MEMBER", "body": "This PR renames the game title shown in the UI and updates the page header accordingly.", "closed_at": null, "comments": 3, "comments_url": "https://api.github.com/repos/acme-labs/snaketoy/issues/42/comments", "created_at": "2026-02-25T18:02:11Z", "draft": false, "events_url": "https://api.github.com/repos/acme-labs/snaketoy/issues/42/events", "html_url": "https://github.com/acme-labs/snaketoy/pull/42", "id": 5129048832, "labels": [ { "color": "a2eeef", "default": true, "description": "New feature or request", "id": 889120331, "name": "enhancement", "node_id": "LA_kwDOQ7c2jM8AAAABN9qLiw", "url": "https://api.github.com/repos/acme-labs/snaketoy/labels/enhancement" } ], "labels_url": "https://api.github.com/repos/acme-labs/snaketoy/issues/42/labels{/name}", "locked": false, "milestone": null, "node_id": "PR_kwDOQ7c2jM7hY2qB", "number": 42, "performed_via_github_app": null, "pull_request": { "diff_url": "https://github.com/acme-labs/snaketoy/pull/42.diff", "html_url": "https://github.com/acme-labs/snaketoy/pull/42", "merged_at": null, "patch_url": "https://github.com/acme-labs/snaketoy/pull/42.patch", "url": "https://api.github.com/repos/acme-labs/snaketoy/pulls/42" }, "reactions": { "+1": 5, "-1": 0, "confused": 0, "eyes": 2, "heart": 1, "hooray": 0, "laugh": 0, "rocket": 1, "total_count": 9, "url": "https://api.github.com/repos/acme-labs/snaketoy/issues/42/reactions" }, "repository_url": "https://api.github.com/repos/acme-labs/snaketoy", "state": "open", "state_reason": null, "timeline_url": "https://api.github.com/repos/acme-labs/snaketoy/issues/42/timeline", "title": "Rename title from 'Snake' to 'Snake Toy'", "updated_at": "2026-02-25T18:14:29Z", "url": "https://api.github.com/repos/acme-labs/snaketoy/issues/42", "user": { "avatar_url": "https://avatars.githubusercontent.com/u/90231477?v=4", "events_url": "https://api.github.com/users/renato-dev/events{/privacy}", "followers_url": "https://api.github.com/users/renato-dev/followers", "following_url": "https://api.github.com/users/renato-dev/following{/other_user}", "gists_url": "https://api.github.com/users/renato-dev/gists{/gist_id}", "gravatar_id": "", "html_url": "https://github.com/renato-dev", "id": 90231477, "login": "renato-dev", "node_id": "MDQ6VXNlcjkwMjMxNDc3", "organizations_url": "https://api.github.com/users/renato-dev/orgs", "received_events_url": "https://api.github.com/users/renato-dev/received_events", "repos_url": "https://api.github.com/users/renato-dev/repos", "site_admin": false, "starred_url": "https://api.github.com/users/renato-dev/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/renato-dev/subscriptions", "type": "User", "url": "https://api.github.com/users/renato-dev", "user_view_type": "public" } }, "repository": { "allow_forking": true, "archive_url": "https://api.github.com/repos/acme-labs/snaketoy/{archive_format}{/ref}", "archived": false, "assignees_url": "https://api.github.com/repos/acme-labs/snaketoy/assignees{/user}", "blobs_url": "https://api.github.com/repos/acme-labs/snaketoy/git/blobs{/sha}", "branches_url": "https://api.github.com/repos/acme-labs/snaketoy/branches{/branch}", "clone_url": "https://github.com/acme-labs/snaketoy.git", "collaborators_url": "https://api.github.com/repos/acme-labs/snaketoy/collaborators{/collaborator}", "comments_url": "https://api.github.com/repos/acme-labs/snaketoy/comments{/number}", "commits_url": "https://api.github.com/repos/acme-labs/snaketoy/commits{/sha}", "compare_url": "https://api.github.com/repos/acme-labs/snaketoy/compare/{base}...{head}", "contents_url": "https://api.github.com/repos/acme-labs/snaketoy/contents/{+path}", "contributors_url": "https://api.github.com/repos/acme-labs/snaketoy/contributors", "created_at": "2024-08-11T13:09:40Z", "default_branch": "main", "deployments_url": "https://api.github.com/repos/acme-labs/snaketoy/deployments", "description": "A tiny snake fangame written in JavaScript + HTML5 canvas", "disabled": false, "downloads_url": "https://api.github.com/repos/acme-labs/snaketoy/downloads", "events_url": "https://api.github.com/repos/acme-labs/snaketoy/events", "fork": false, "forks": 7, "forks_count": 7, "forks_url": "https://api.github.com/repos/acme-labs/snaketoy/forks", "full_name": "acme-labs/snaketoy", "git_commits_url": "https://api.github.com/repos/acme-labs/snaketoy/git/commits{/sha}", "git_refs_url": "https://api.github.com/repos/acme-labs/snaketoy/git/refs{/sha}", "git_tags_url": "https://api.github.com/repos/acme-labs/snaketoy/git/tags{/sha}", "git_url": "git://github.com/acme-labs/snaketoy.git", "has_discussions": true, "has_downloads": true, "has_issues": true, "has_pages": false, "has_projects": true, "has_pull_requests": true, "has_wiki": true, "homepage": "https://acme.example/snaketoy", "hooks_url": "https://api.github.com/repos/acme-labs/snaketoy/hooks", "html_url": "https://github.com/acme-labs/snaketoy", "id": 712304981, "is_template": false, "issue_comment_url": "https://api.github.com/repos/acme-labs/snaketoy/issues/comments{/number}", "issue_events_url": "https://api.github.com/repos/acme-labs/snaketoy/issues/events{/number}", "issues_url": "https://api.github.com/repos/acme-labs/snaketoy/issues{/number}", "keys_url": "https://api.github.com/repos/acme-labs/snaketoy/keys{/key_id}", "labels_url": "https://api.github.com/repos/acme-labs/snaketoy/labels{/name}", "language": "JavaScript", "languages_url": "https://api.github.com/repos/acme-labs/snaketoy/languages", "license": { "key": "mit", "name": "MIT License", "node_id": "MDc6TGljZW5zZTEz", "spdx_id": "MIT", "url": "https://api.github.com/licenses/mit" }, "merges_url": "https://api.github.com/repos/acme-labs/snaketoy/merges", "milestones_url": "https://api.github.com/repos/acme-labs/snaketoy/milestones{/number}", "mirror_url": null, "name": "snaketoy", "node_id": "MDEwOlJlcG9zaXRvcnk3MTIzMDQ5ODE=", "notifications_url": "https://api.github.com/repos/acme-labs/snaketoy/notifications{?since,all,participating}", "open_issues": 12, "open_issues_count": 12, "owner": { "avatar_url": "https://avatars.githubusercontent.com/u/55120911?v=4", "events_url": "https://api.github.com/users/acme-labs/events{/privacy}", "followers_url": "https://api.github.com/users/acme-labs/followers", "following_url": "https://api.github.com/users/acme-labs/following{/other_user}", "gists_url": "https://api.github.com/users/acme-labs/gists{/gist_id}", "gravatar_id": "", "html_url": "https://github.com/acme-labs", "id": 55120911, "login": "acme-labs", "node_id": "MDEyOk9yZ2FuaXphdGlvbjU1MTIwOTEx", "organizations_url": "https://api.github.com/users/acme-labs/orgs", "received_events_url": "https://api.github.com/users/acme-labs/received_events", "repos_url": "https://api.github.com/users/acme-labs/repos", "site_admin": false, "starred_url": "https://api.github.com/users/acme-labs/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/acme-labs/subscriptions", "type": "Organization", "url": "https://api.github.com/users/acme-labs", "user_view_type": "public" }, "private": false, "pull_request_creation_policy": "all", "pulls_url": "https://api.github.com/repos/acme-labs/snaketoy/pulls{/number}", "pushed_at": "2026-02-25T18:13:58Z", "releases_url": "https://api.github.com/repos/acme-labs/snaketoy/releases{/id}", "size": 1380, "ssh_url": "git@github.com:acme-labs/snaketoy.git", "stargazers_count": 24, "stargazers_url": "https://api.github.com/repos/acme-labs/snaketoy/stargazers", "statuses_url": "https://api.github.com/repos/acme-labs/snaketoy/statuses/{sha}", "subscribers_url": "https://api.github.com/repos/acme-labs/snaketoy/subscribers", "subscription_url": "https://api.github.com/repos/acme-labs/snaketoy/subscription", "svn_url": "https://github.com/acme-labs/snaketoy", "tags_url": "https://api.github.com/repos/acme-labs/snaketoy/tags", "teams_url": "https://api.github.com/repos/acme-labs/snaketoy/teams", "topics": [ "game", "canvas", "javascript" ], "trees_url": "https://api.github.com/repos/acme-labs/snaketoy/git/trees{/sha}", "updated_at": "2026-02-12T09:41:27Z", "url": "https://api.github.com/repos/acme-labs/snaketoy", "visibility": "public", "watchers": 24, "watchers_count": 24, "web_commit_signoff_required": false }, "sender": { "avatar_url": "https://avatars.githubusercontent.com/u/55120911?v=4", "events_url": "https://api.github.com/users/acme-ci/events{/privacy}", "followers_url": "https://api.github.com/users/acme-ci/followers", "following_url": "https://api.github.com/users/acme-ci/following{/other_user}", "gists_url": "https://api.github.com/users/acme-ci/gists{/gist_id}", "gravatar_id": "", "html_url": "https://github.com/acme-ci", "id": 77100412, "login": "acme-ci", "node_id": "MDQ6VXNlcjc3MTAwNDEy", "organizations_url": "https://api.github.com/users/acme-ci/orgs", "received_events_url": "https://api.github.com/users/acme-ci/received_events", "repos_url": "https://api.github.com/users/acme-ci/repos", "site_admin": false, "starred_url": "https://api.github.com/users/acme-ci/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/acme-ci/subscriptions", "type": "User", "url": "https://api.github.com/users/acme-ci", "user_view_type": "public" } }, "timestamp": "2026-02-25T18:14:31.384219122Z", "type": "github.prComment" } ``` ## On PR Review Comment **Trigger key:** `github.onPRReviewComment` The On PR Review Comment trigger starts a workflow execution when review comments are added to pull requests. ### Use Cases - **Code review automation**: React to line-level review comments - **Review workflows**: Trigger follow-up workflows when a review is submitted - **Notification systems**: Notify teams when new review comments are posted ### Configuration - **Repository**: Select the GitHub repository to monitor - **Content Filter**: Optional regex pattern to filter comment/review body (e.g., `/solve`) ### Event Data This trigger handles two GitHub webhook events: - **pull_request_review_comment**: line-level code review comments (`comment` and `pull_request`) - **pull_request_review**: submitted review comments (`review` and `pull_request`) SuperPlane passes through the full GitHub webhook payload under data. Common expression paths: - PR number: `root().data.pull_request.number` - Branch name: `root().data.pull_request.head.ref` - Head SHA: `root().data.pull_request.head.sha` - Review comment body: `root().data.comment.body` (pull_request_review_comment) - Review submission body: `root().data.review.body` (pull_request_review) ### Webhook Setup This trigger automatically sets up a GitHub webhook when configured. The webhook is managed by SuperPlane and will be cleaned up when the trigger is removed. ### Example Data ```json { "data": { "action": "created", "comment": { "_links": { "html": { "href": "https://github.com/acme-labs/snaketoy/pull/42#discussion_r3179045528" }, "pull_request": { "href": "https://api.github.com/repos/acme-labs/snaketoy/pulls/42" }, "self": { "href": "https://api.github.com/repos/acme-labs/snaketoy/pulls/comments/3179045528" } }, "author_association": "CONTRIBUTOR", "body": "Small nit: could we also update the page heading to match the new title?", "commit_id": "d6f3c8a2e8b7f0a9c0a1f67f0c5d7b2a1d9e3f44", "created_at": "2026-02-25T18:22:13Z", "diff_hunk": "@@ -3,7 +3,7 @@\n \u003chead\u003e\n \u003cmeta charset=\"UTF-8\"\u003e\n \u003cmeta name=\"viewport\" content=\"width=device-width, user-scalable=no, initial-scale=1\"\u003e\n- \u003ctitle\u003eSnake\u003c/title\u003e\n+ \u003ctitle\u003eSnake Toy\u003c/title\u003e", "html_url": "https://github.com/acme-labs/snaketoy/pull/42#discussion_r3179045528", "id": 3179045528, "line": 6, "node_id": "PRRC_kwDOQ7c2jM6_9s1Y", "original_commit_id": "d6f3c8a2e8b7f0a9c0a1f67f0c5d7b2a1d9e3f44", "original_line": 6, "original_position": 5, "original_start_line": null, "path": "index.html", "position": 5, "pull_request_review_id": 4632189077, "pull_request_url": "https://api.github.com/repos/acme-labs/snaketoy/pulls/42", "reactions": { "+1": 1, "-1": 0, "confused": 0, "eyes": 0, "heart": 0, "hooray": 0, "laugh": 0, "rocket": 0, "total_count": 1, "url": "https://api.github.com/repos/acme-labs/snaketoy/pulls/comments/3179045528/reactions" }, "side": "RIGHT", "start_line": null, "start_side": null, "subject_type": "line", "updated_at": "2026-02-25T18:22:21Z", "url": "https://api.github.com/repos/acme-labs/snaketoy/pulls/comments/3179045528", "user": { "avatar_url": "https://avatars.githubusercontent.com/u/124578901?v=4", "events_url": "https://api.github.com/users/jules-ramirez/events{/privacy}", "followers_url": "https://api.github.com/users/jules-ramirez/followers", "following_url": "https://api.github.com/users/jules-ramirez/following{/other_user}", "gists_url": "https://api.github.com/users/jules-ramirez/gists{/gist_id}", "gravatar_id": "", "html_url": "https://github.com/jules-ramirez", "id": 124578901, "login": "jules-ramirez", "node_id": "MDQ6VXNlcjEyNDU3ODkwMQ==", "organizations_url": "https://api.github.com/users/jules-ramirez/orgs", "received_events_url": "https://api.github.com/users/jules-ramirez/received_events", "repos_url": "https://api.github.com/users/jules-ramirez/repos", "site_admin": false, "starred_url": "https://api.github.com/users/jules-ramirez/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/jules-ramirez/subscriptions", "type": "User", "url": "https://api.github.com/users/jules-ramirez", "user_view_type": "public" } }, "pull_request": { "_links": { "comments": { "href": "https://api.github.com/repos/acme-labs/snaketoy/issues/42/comments" }, "commits": { "href": "https://api.github.com/repos/acme-labs/snaketoy/pulls/42/commits" }, "html": { "href": "https://github.com/acme-labs/snaketoy/pull/42" }, "issue": { "href": "https://api.github.com/repos/acme-labs/snaketoy/issues/42" }, "review_comment": { "href": "https://api.github.com/repos/acme-labs/snaketoy/pulls/comments{/number}" }, "review_comments": { "href": "https://api.github.com/repos/acme-labs/snaketoy/pulls/42/comments" }, "self": { "href": "https://api.github.com/repos/acme-labs/snaketoy/pulls/42" }, "statuses": { "href": "https://api.github.com/repos/acme-labs/snaketoy/statuses/d6f3c8a2e8b7f0a9c0a1f67f0c5d7b2a1d9e3f44" } }, "active_lock_reason": null, "assignee": null, "assignees": [], "author_association": "MEMBER", "auto_merge": null, "base": { "label": "acme-labs:main", "ref": "main", "repo": { "allow_auto_merge": false, "allow_forking": true, "allow_merge_commit": true, "allow_rebase_merge": true, "allow_squash_merge": true, "allow_update_branch": false, "archive_url": "https://api.github.com/repos/acme-labs/snaketoy/{archive_format}{/ref}", "archived": false, "assignees_url": "https://api.github.com/repos/acme-labs/snaketoy/assignees{/user}", "blobs_url": "https://api.github.com/repos/acme-labs/snaketoy/git/blobs{/sha}", "branches_url": "https://api.github.com/repos/acme-labs/snaketoy/branches{/branch}", "clone_url": "https://github.com/acme-labs/snaketoy.git", "collaborators_url": "https://api.github.com/repos/acme-labs/snaketoy/collaborators{/collaborator}", "comments_url": "https://api.github.com/repos/acme-labs/snaketoy/comments{/number}", "commits_url": "https://api.github.com/repos/acme-labs/snaketoy/commits{/sha}", "compare_url": "https://api.github.com/repos/acme-labs/snaketoy/compare/{base}...{head}", "contents_url": "https://api.github.com/repos/acme-labs/snaketoy/contents/{+path}", "contributors_url": "https://api.github.com/repos/acme-labs/snaketoy/contributors", "created_at": "2024-08-11T13:09:40Z", "default_branch": "main", "delete_branch_on_merge": false, "deployments_url": "https://api.github.com/repos/acme-labs/snaketoy/deployments", "description": "A tiny snake fangame written in JavaScript + HTML5 canvas", "disabled": false, "downloads_url": "https://api.github.com/repos/acme-labs/snaketoy/downloads", "events_url": "https://api.github.com/repos/acme-labs/snaketoy/events", "fork": false, "forks": 7, "forks_count": 7, "forks_url": "https://api.github.com/repos/acme-labs/snaketoy/forks", "full_name": "acme-labs/snaketoy", "git_commits_url": "https://api.github.com/repos/acme-labs/snaketoy/git/commits{/sha}", "git_refs_url": "https://api.github.com/repos/acme-labs/snaketoy/git/refs{/sha}", "git_tags_url": "https://api.github.com/repos/acme-labs/snaketoy/git/tags{/sha}", "git_url": "git://github.com/acme-labs/snaketoy.git", "has_discussions": true, "has_downloads": true, "has_issues": true, "has_pages": false, "has_projects": true, "has_pull_requests": true, "has_wiki": true, "homepage": "https://acme.example/snaketoy", "hooks_url": "https://api.github.com/repos/acme-labs/snaketoy/hooks", "html_url": "https://github.com/acme-labs/snaketoy", "id": 712304981, "is_template": false, "issue_comment_url": "https://api.github.com/repos/acme-labs/snaketoy/issues/comments{/number}", "issue_events_url": "https://api.github.com/repos/acme-labs/snaketoy/issues/events{/number}", "issues_url": "https://api.github.com/repos/acme-labs/snaketoy/issues{/number}", "keys_url": "https://api.github.com/repos/acme-labs/snaketoy/keys{/key_id}", "labels_url": "https://api.github.com/repos/acme-labs/snaketoy/labels{/name}", "language": "JavaScript", "languages_url": "https://api.github.com/repos/acme-labs/snaketoy/languages", "license": { "key": "mit", "name": "MIT License", "node_id": "MDc6TGljZW5zZTEz", "spdx_id": "MIT", "url": "https://api.github.com/licenses/mit" }, "merge_commit_message": "PR_TITLE", "merge_commit_title": "MERGE_MESSAGE", "merges_url": "https://api.github.com/repos/acme-labs/snaketoy/merges", "milestones_url": "https://api.github.com/repos/acme-labs/snaketoy/milestones{/number}", "mirror_url": null, "name": "snaketoy", "node_id": "MDEwOlJlcG9zaXRvcnk3MTIzMDQ5ODE=", "notifications_url": "https://api.github.com/repos/acme-labs/snaketoy/notifications{?since,all,participating}", "open_issues": 12, "open_issues_count": 12, "owner": { "avatar_url": "https://avatars.githubusercontent.com/u/55120911?v=4", "events_url": "https://api.github.com/users/acme-labs/events{/privacy}", "followers_url": "https://api.github.com/users/acme-labs/followers", "following_url": "https://api.github.com/users/acme-labs/following{/other_user}", "gists_url": "https://api.github.com/users/acme-labs/gists{/gist_id}", "gravatar_id": "", "html_url": "https://github.com/acme-labs", "id": 55120911, "login": "acme-labs", "node_id": "MDEyOk9yZ2FuaXphdGlvbjU1MTIwOTEx", "organizations_url": "https://api.github.com/users/acme-labs/orgs", "received_events_url": "https://api.github.com/users/acme-labs/received_events", "repos_url": "https://api.github.com/users/acme-labs/repos", "site_admin": false, "starred_url": "https://api.github.com/users/acme-labs/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/acme-labs/subscriptions", "type": "Organization", "url": "https://api.github.com/users/acme-labs", "user_view_type": "public" }, "private": false, "pull_request_creation_policy": "all", "pulls_url": "https://api.github.com/repos/acme-labs/snaketoy/pulls{/number}", "pushed_at": "2026-02-25T18:21:49Z", "releases_url": "https://api.github.com/repos/acme-labs/snaketoy/releases{/id}", "size": 1380, "squash_merge_commit_message": "COMMIT_MESSAGES", "squash_merge_commit_title": "COMMIT_OR_PR_TITLE", "ssh_url": "git@github.com:acme-labs/snaketoy.git", "stargazers_count": 24, "stargazers_url": "https://api.github.com/repos/acme-labs/snaketoy/stargazers", "statuses_url": "https://api.github.com/repos/acme-labs/snaketoy/statuses/{sha}", "subscribers_url": "https://api.github.com/repos/acme-labs/snaketoy/subscribers", "subscription_url": "https://api.github.com/repos/acme-labs/snaketoy/subscription", "svn_url": "https://github.com/acme-labs/snaketoy", "tags_url": "https://api.github.com/repos/acme-labs/snaketoy/tags", "teams_url": "https://api.github.com/repos/acme-labs/snaketoy/teams", "topics": [ "game", "javascript", "canvas" ], "trees_url": "https://api.github.com/repos/acme-labs/snaketoy/git/trees{/sha}", "updated_at": "2026-02-12T09:41:27Z", "url": "https://api.github.com/repos/acme-labs/snaketoy", "use_squash_pr_title_as_default": false, "visibility": "public", "watchers": 24, "watchers_count": 24, "web_commit_signoff_required": false }, "sha": "2d5a1dfbba9d0a8a7f7b14b08a1b6c7c1e2f3a4b", "user": { "avatar_url": "https://avatars.githubusercontent.com/u/90231477?v=4", "events_url": "https://api.github.com/users/renato-dev/events{/privacy}", "followers_url": "https://api.github.com/users/renato-dev/followers", "following_url": "https://api.github.com/users/renato-dev/following{/other_user}", "gists_url": "https://api.github.com/users/renato-dev/gists{/gist_id}", "gravatar_id": "", "html_url": "https://github.com/renato-dev", "id": 90231477, "login": "renato-dev", "node_id": "MDQ6VXNlcjkwMjMxNDc3", "organizations_url": "https://api.github.com/users/renato-dev/orgs", "received_events_url": "https://api.github.com/users/renato-dev/received_events", "repos_url": "https://api.github.com/users/renato-dev/repos", "site_admin": false, "starred_url": "https://api.github.com/users/renato-dev/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/renato-dev/subscriptions", "type": "User", "url": "https://api.github.com/users/renato-dev", "user_view_type": "public" } }, "body": "Renames the UI title and keeps the game logic unchanged.", "closed_at": null, "comments_url": "https://api.github.com/repos/acme-labs/snaketoy/issues/42/comments", "commits_url": "https://api.github.com/repos/acme-labs/snaketoy/pulls/42/commits", "created_at": "2026-02-25T18:02:11Z", "diff_url": "https://github.com/acme-labs/snaketoy/pull/42.diff", "draft": false, "head": { "label": "renato-dev:rename-title", "ref": "rename-title", "repo": { "default_branch": "main", "description": "A tiny snake fangame written in JavaScript + HTML5 canvas", "fork": false, "forks_count": 7, "full_name": "acme-labs/snaketoy", "html_url": "https://github.com/acme-labs/snaketoy", "id": 712304981, "language": "JavaScript", "name": "snaketoy", "node_id": "MDEwOlJlcG9zaXRvcnk3MTIzMDQ5ODE=", "open_issues_count": 12, "owner": { "avatar_url": "https://avatars.githubusercontent.com/u/55120911?v=4", "html_url": "https://github.com/acme-labs", "id": 55120911, "login": "acme-labs", "node_id": "MDEyOk9yZ2FuaXphdGlvbjU1MTIwOTEx", "site_admin": false, "type": "Organization" }, "private": false, "stargazers_count": 24, "url": "https://api.github.com/repos/acme-labs/snaketoy", "watchers_count": 24 }, "sha": "d6f3c8a2e8b7f0a9c0a1f67f0c5d7b2a1d9e3f44", "user": { "avatar_url": "https://avatars.githubusercontent.com/u/90231477?v=4", "events_url": "https://api.github.com/users/renato-dev/events{/privacy}", "followers_url": "https://api.github.com/users/renato-dev/followers", "following_url": "https://api.github.com/users/renato-dev/following{/other_user}", "gists_url": "https://api.github.com/users/renato-dev/gists{/gist_id}", "gravatar_id": "", "html_url": "https://github.com/renato-dev", "id": 90231477, "login": "renato-dev", "node_id": "MDQ6VXNlcjkwMjMxNDc3", "organizations_url": "https://api.github.com/users/renato-dev/orgs", "received_events_url": "https://api.github.com/users/renato-dev/received_events", "repos_url": "https://api.github.com/users/renato-dev/repos", "site_admin": false, "starred_url": "https://api.github.com/users/renato-dev/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/renato-dev/subscriptions", "type": "User", "url": "https://api.github.com/users/renato-dev", "user_view_type": "public" } }, "html_url": "https://github.com/acme-labs/snaketoy/pull/42", "id": 4982710331, "issue_url": "https://api.github.com/repos/acme-labs/snaketoy/issues/42", "labels": [], "locked": false, "merge_commit_sha": "8b1a4c7d9e0f2a3b4c5d6e7f8a9b0c1d2e3f4a5b", "merged_at": null, "milestone": null, "node_id": "PR_kwDOQ7c2jM7hY2qB", "number": 42, "patch_url": "https://github.com/acme-labs/snaketoy/pull/42.patch", "requested_reviewers": [], "requested_teams": [], "review_comment_url": "https://api.github.com/repos/acme-labs/snaketoy/pulls/comments{/number}", "review_comments_url": "https://api.github.com/repos/acme-labs/snaketoy/pulls/42/comments", "state": "open", "statuses_url": "https://api.github.com/repos/acme-labs/snaketoy/statuses/d6f3c8a2e8b7f0a9c0a1f67f0c5d7b2a1d9e3f44", "title": "Rename title from 'Snake' to 'Snake Toy'", "updated_at": "2026-02-25T18:22:21Z", "url": "https://api.github.com/repos/acme-labs/snaketoy/pulls/42", "user": { "avatar_url": "https://avatars.githubusercontent.com/u/90231477?v=4", "events_url": "https://api.github.com/users/renato-dev/events{/privacy}", "followers_url": "https://api.github.com/users/renato-dev/followers", "following_url": "https://api.github.com/users/renato-dev/following{/other_user}", "gists_url": "https://api.github.com/users/renato-dev/gists{/gist_id}", "gravatar_id": "", "html_url": "https://github.com/renato-dev", "id": 90231477, "login": "renato-dev", "node_id": "MDQ6VXNlcjkwMjMxNDc3", "organizations_url": "https://api.github.com/users/renato-dev/orgs", "received_events_url": "https://api.github.com/users/renato-dev/received_events", "repos_url": "https://api.github.com/users/renato-dev/repos", "site_admin": false, "starred_url": "https://api.github.com/users/renato-dev/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/renato-dev/subscriptions", "type": "User", "url": "https://api.github.com/users/renato-dev", "user_view_type": "public" } }, "repository": { "created_at": "2024-08-11T13:09:40Z", "default_branch": "main", "description": "A tiny snake fangame written in JavaScript + HTML5 canvas", "fork": false, "forks_count": 7, "full_name": "acme-labs/snaketoy", "html_url": "https://github.com/acme-labs/snaketoy", "id": 712304981, "language": "JavaScript", "name": "snaketoy", "node_id": "MDEwOlJlcG9zaXRvcnk3MTIzMDQ5ODE=", "open_issues_count": 12, "owner": { "avatar_url": "https://avatars.githubusercontent.com/u/55120911?v=4", "html_url": "https://github.com/acme-labs", "id": 55120911, "login": "acme-labs", "node_id": "MDEyOk9yZ2FuaXphdGlvbjU1MTIwOTEx", "site_admin": false, "type": "Organization" }, "private": false, "pushed_at": "2026-02-25T18:21:49Z", "stargazers_count": 24, "updated_at": "2026-02-12T09:41:27Z", "url": "https://api.github.com/repos/acme-labs/snaketoy", "visibility": "public", "watchers_count": 24 }, "sender": { "avatar_url": "https://avatars.githubusercontent.com/u/77100412?v=4", "events_url": "https://api.github.com/users/acme-ci/events{/privacy}", "followers_url": "https://api.github.com/users/acme-ci/followers", "following_url": "https://api.github.com/users/acme-ci/following{/other_user}", "gists_url": "https://api.github.com/users/acme-ci/gists{/gist_id}", "gravatar_id": "", "html_url": "https://github.com/acme-ci", "id": 77100412, "login": "acme-ci", "node_id": "MDQ6VXNlcjc3MTAwNDEy", "organizations_url": "https://api.github.com/users/acme-ci/orgs", "received_events_url": "https://api.github.com/users/acme-ci/received_events", "repos_url": "https://api.github.com/users/acme-ci/repos", "site_admin": false, "starred_url": "https://api.github.com/users/acme-ci/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/acme-ci/subscriptions", "type": "User", "url": "https://api.github.com/users/acme-ci", "user_view_type": "public" } }, "timestamp": "2026-02-25T18:22:23.912774300Z", "type": "github.prReviewComment" } ``` ## On Pull Request **Trigger key:** `github.onPullRequest` The On Pull Request trigger starts a workflow execution when pull request events occur in a GitHub repository. ### Use Cases - **PR automation**: Automate actions when PRs are opened, merged, or closed - **Code review workflows**: Trigger review processes or notifications - **CI/CD integration**: Run tests or builds on PR events - **Status updates**: Update systems when PR status changes ### Configuration - **Repository**: Select the GitHub repository to monitor - **Actions**: Select which PR actions to listen for (opened, edited, closed, synchronize, etc.) ### Event Data Each PR event includes: - **action**: The action that triggered the event (opened, edited, closed, synchronize, etc.) - **changes**: When action is edited, includes what changed (title, body, base branch) - **pull_request**: Complete PR information including title, body, state, labels - **repository**: Repository information - **sender**: User who triggered the event ### Webhook Setup This trigger automatically sets up a GitHub webhook when configured. The webhook is managed by SuperPlane and will be cleaned up when the trigger is removed. ### Example Data ```json { "data": { "action": "opened", "assignee": null, "number": 101, "pull_request": { "html_url": "https://github.com/acme/widgets/pull/101", "number": 101, "state": "open", "title": "Add new endpoint", "user": { "login": "octocat" } }, "repository": { "full_name": "acme/widgets", "html_url": "https://github.com/acme/widgets", "id": 123456 }, "sender": { "html_url": "https://github.com/octocat", "id": 101, "login": "octocat" } }, "timestamp": "2026-01-16T17:56:16.680755501Z", "type": "github.pullRequest" } ``` ## On Push **Trigger key:** `github.onPush` The On Push trigger starts a workflow execution when code is pushed to a GitHub repository. ### Use Cases - **CI/CD automation**: Trigger builds and deployments on code pushes - **Code quality checks**: Run linting and tests on every push - **Notification workflows**: Send notifications when code is pushed - **Documentation updates**: Automatically update documentation on push ### Configuration - **Repository**: Select the GitHub repository to monitor - **Refs**: Configure which branches/tags to monitor (e.g., `refs/heads/main`, `refs/tags/*`) - **Paths** *(optional)*: Glob patterns (GitHub Actions–style) for added, modified, and removed files. Use `!` prefix to exclude (for example `billing/**` with `!billing/**/*.md`). Patterns starting only with `!` assume an include of `**`. Lists stored as legacy ref-style predicates still honor `equals` values as globs; `matches` must be replaced with glob patterns. If the webhook has no per-commit file lists (empty `commits` or missing `added`/`modified`/`removed` arrays), a configured path filter cannot match and the trigger will not fire. Leave empty to fire on all pushes. ### Event Data Each push event includes: - **repository**: Repository information - **ref**: The branch or tag that was pushed to - **commits**: Array of commit information (each with `added`, `modified`, `removed` file arrays) - **pusher**: Information about who pushed - **before/after**: Commit SHAs before and after the push ### Webhook Setup This trigger automatically sets up a GitHub webhook when configured. The webhook is managed by SuperPlane and will be cleaned up when the trigger is removed. ### Example Data ```json { "data": { "after": "4f9c2e1a7b3d45c0d1e9f23456789abcdeffed01", "base_ref": null, "before": "1a2b3c4d5e6f708192a3b4c5d6e7f8090a1b2c3d", "commits": [ { "added": [], "author": { "date": "2026-03-10T14:22:11+01:00", "email": "alex.doe@example.com", "name": "Alex Doe", "username": "alexdoe" }, "committer": { "date": "2026-03-10T14:22:11+01:00", "email": "noreply@example.com", "name": "GitHub", "username": "web-flow" }, "distinct": true, "id": "4f9c2e1a7b3d45c0d1e9f23456789abcdeffed01", "message": "feat: add lightweight metrics endpoint (#42)\n\nAdds a basic /metrics handler with a minimal gauge.", "modified": [ "cmd/server/main.go", "pkg/metrics/handler.go", "docs/metrics.md" ], "removed": [], "timestamp": "2026-03-10T14:22:11+01:00", "tree_id": "7a8b9c0d1e2f3a4b5c6d7e8f90123456789abcde", "url": "https://github.com/example-org/example-repo/commit/4f9c2e1a7b3d45c0d1e9f23456789abcdeffed01" } ], "compare": "https://github.com/example-org/example-repo/compare/1a2b3c4d5e6f...4f9c2e1a7b3d", "created": false, "deleted": false, "forced": false, "head_commit": { "added": [], "author": { "date": "2026-03-10T14:22:11+01:00", "email": "alex.doe@example.com", "name": "Alex Doe", "username": "alexdoe" }, "committer": { "date": "2026-03-10T14:22:11+01:00", "email": "noreply@example.com", "name": "GitHub", "username": "web-flow" }, "distinct": true, "id": "4f9c2e1a7b3d45c0d1e9f23456789abcdeffed01", "message": "feat: add lightweight metrics endpoint (#42)\n\nAdds a basic /metrics handler with a minimal gauge.", "modified": [ "cmd/server/main.go", "pkg/metrics/handler.go", "docs/metrics.md" ], "removed": [], "timestamp": "2026-03-10T14:22:11+01:00", "tree_id": "7a8b9c0d1e2f3a4b5c6d7e8f90123456789abcde", "url": "https://github.com/example-org/example-repo/commit/4f9c2e1a7b3d45c0d1e9f23456789abcdeffed01" }, "organization": { "avatar_url": "https://avatars.githubusercontent.com/u/12345678?v=4", "description": "Example organization for demo data", "events_url": "https://api.github.com/orgs/example-org/events", "hooks_url": "https://api.github.com/orgs/example-org/hooks", "id": 12345678, "issues_url": "https://api.github.com/orgs/example-org/issues", "login": "example-org", "members_url": "https://api.github.com/orgs/example-org/members{/member}", "node_id": "O_kgDOBb1AaA", "public_members_url": "https://api.github.com/orgs/example-org/public_members{/member}", "repos_url": "https://api.github.com/orgs/example-org/repos", "url": "https://api.github.com/orgs/example-org" }, "pusher": { "email": "alex.doe@example.com", "name": "alexdoe" }, "ref": "refs/heads/main", "repository": { "allow_forking": true, "archive_url": "https://api.github.com/repos/example-org/example-repo/{archive_format}{/ref}", "archived": false, "assignees_url": "https://api.github.com/repos/example-org/example-repo/assignees{/user}", "blobs_url": "https://api.github.com/repos/example-org/example-repo/git/blobs{/sha}", "branches_url": "https://api.github.com/repos/example-org/example-repo/branches{/branch}", "clone_url": "https://github.com/example-org/example-repo.git", "collaborators_url": "https://api.github.com/repos/example-org/example-repo/collaborators{/collaborator}", "comments_url": "https://api.github.com/repos/example-org/example-repo/comments{/number}", "commits_url": "https://api.github.com/repos/example-org/example-repo/commits{/sha}", "compare_url": "https://api.github.com/repos/example-org/example-repo/compare/{base}...{head}", "contents_url": "https://api.github.com/repos/example-org/example-repo/contents/{+path}", "contributors_url": "https://api.github.com/repos/example-org/example-repo/contributors", "created_at": 1746900000, "custom_properties": {}, "default_branch": "main", "deployments_url": "https://api.github.com/repos/example-org/example-repo/deployments", "description": "Example repository for webhook payloads", "disabled": false, "downloads_url": "https://api.github.com/repos/example-org/example-repo/downloads", "events_url": "https://api.github.com/repos/example-org/example-repo/events", "fork": false, "forks": 2, "forks_count": 2, "forks_url": "https://api.github.com/repos/example-org/example-repo/forks", "full_name": "example-org/example-repo", "git_commits_url": "https://api.github.com/repos/example-org/example-repo/git/commits{/sha}", "git_refs_url": "https://api.github.com/repos/example-org/example-repo/git/refs{/sha}", "git_tags_url": "https://api.github.com/repos/example-org/example-repo/git/tags{/sha}", "git_url": "git://github.com/example-org/example-repo.git", "has_discussions": false, "has_downloads": true, "has_issues": true, "has_pages": false, "has_projects": true, "has_wiki": false, "homepage": null, "hooks_url": "https://api.github.com/repos/example-org/example-repo/hooks", "html_url": "https://github.com/example-org/example-repo", "id": 987654321, "is_template": false, "issue_comment_url": "https://api.github.com/repos/example-org/example-repo/issues/comments{/number}", "issue_events_url": "https://api.github.com/repos/example-org/example-repo/issues/events{/number}", "issues_url": "https://api.github.com/repos/example-org/example-repo/issues{/number}", "keys_url": "https://api.github.com/repos/example-org/example-repo/keys{/key_id}", "labels_url": "https://api.github.com/repos/example-org/example-repo/labels{/name}", "language": "TypeScript", "languages_url": "https://api.github.com/repos/example-org/example-repo/languages", "license": { "key": "apache-2.0", "name": "Apache License 2.0", "node_id": "MDc6TGljZW5zZTI=", "spdx_id": "Apache-2.0", "url": "https://api.github.com/licenses/apache-2.0" }, "master_branch": "main", "merges_url": "https://api.github.com/repos/example-org/example-repo/merges", "milestones_url": "https://api.github.com/repos/example-org/example-repo/milestones{/number}", "mirror_url": null, "name": "example-repo", "node_id": "R_kgDOAbCdEf", "notifications_url": "https://api.github.com/repos/example-org/example-repo/notifications{?since,all,participating}", "open_issues": 5, "open_issues_count": 5, "organization": "example-org", "owner": { "avatar_url": "https://avatars.githubusercontent.com/u/12345678?v=4", "email": null, "events_url": "https://api.github.com/users/example-org/events{/privacy}", "followers_url": "https://api.github.com/users/example-org/followers", "following_url": "https://api.github.com/users/example-org/following{/other_user}", "gists_url": "https://api.github.com/users/example-org/gists{/gist_id}", "gravatar_id": "", "html_url": "https://github.com/example-org", "id": 12345678, "login": "example-org", "name": "example-org", "node_id": "O_kgDOBb1AaA", "organizations_url": "https://api.github.com/users/example-org/orgs", "received_events_url": "https://api.github.com/users/example-org/received_events", "repos_url": "https://api.github.com/users/example-org/repos", "site_admin": false, "starred_url": "https://api.github.com/users/example-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/example-org/subscriptions", "type": "Organization", "url": "https://api.github.com/users/example-org", "user_view_type": "public" }, "private": false, "pulls_url": "https://api.github.com/repos/example-org/example-repo/pulls{/number}", "pushed_at": 1760000000, "releases_url": "https://api.github.com/repos/example-org/example-repo/releases{/id}", "size": 48200, "ssh_url": "git@github.com:example-org/example-repo.git", "stargazers": 3, "stargazers_count": 3, "stargazers_url": "https://api.github.com/repos/example-org/example-repo/stargazers", "statuses_url": "https://api.github.com/repos/example-org/example-repo/statuses/{sha}", "subscribers_url": "https://api.github.com/repos/example-org/example-repo/subscribers", "subscription_url": "https://api.github.com/repos/example-org/example-repo/subscription", "svn_url": "https://github.com/example-org/example-repo", "tags_url": "https://api.github.com/repos/example-org/example-repo/tags", "teams_url": "https://api.github.com/repos/example-org/example-repo/teams", "topics": [], "trees_url": "https://api.github.com/repos/example-org/example-repo/git/trees{/sha}", "updated_at": "2026-03-10T13:50:00Z", "url": "https://api.github.com/repos/example-org/example-repo", "visibility": "public", "watchers": 3, "watchers_count": 3, "web_commit_signoff_required": false }, "sender": { "avatar_url": "https://avatars.githubusercontent.com/u/87654321?v=4", "events_url": "https://api.github.com/users/octo-user/events{/privacy}", "followers_url": "https://api.github.com/users/octo-user/followers", "following_url": "https://api.github.com/users/octo-user/following{/other_user}", "gists_url": "https://api.github.com/users/octo-user/gists{/gist_id}", "gravatar_id": "", "html_url": "https://github.com/octo-user", "id": 87654321, "login": "octo-user", "node_id": "MDQ6VXNlcjg3NjU0MzIx", "organizations_url": "https://api.github.com/users/octo-user/orgs", "received_events_url": "https://api.github.com/users/octo-user/received_events", "repos_url": "https://api.github.com/users/octo-user/repos", "site_admin": false, "starred_url": "https://api.github.com/users/octo-user/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/octo-user/subscriptions", "type": "User", "url": "https://api.github.com/users/octo-user", "user_view_type": "public" } }, "timestamp": "2026-03-10T13:35:00.31254162Z", "type": "github.push" } ``` ## On Release **Trigger key:** `github.onRelease` The On Release trigger starts a workflow execution when release events occur in a GitHub repository. ### Use Cases - **Deployment automation**: Trigger deployments when releases are published - **Notification workflows**: Send notifications about new releases - **Release processing**: Process release artifacts or metadata - **Distribution workflows**: Distribute releases to multiple systems ### Configuration - **Repository**: Select the GitHub repository to monitor - **Actions**: Select which release actions to listen for (published, created, etc.) ### Event Data Each release event includes: - **action**: The action that triggered the event (published, created, etc.) - **release**: Complete release information including tag, name, body, assets - **repository**: Repository information - **sender**: User who triggered the event ### Webhook Setup This trigger automatically sets up a GitHub webhook when configured. The webhook is managed by SuperPlane and will be cleaned up when the trigger is removed. ### Example Data ```json { "data": { "action": "published", "release": { "html_url": "https://github.com/acme/widgets/releases/tag/v1.2.3", "id": 3001, "name": "Release 1.2.3", "tag_name": "v1.2.3" }, "repository": { "full_name": "acme/widgets", "html_url": "https://github.com/acme/widgets", "id": 123456 }, "sender": { "html_url": "https://github.com/octocat", "id": 101, "login": "octocat" } }, "timestamp": "2026-01-16T17:56:16.680755501Z", "type": "github.release" } ``` ## On Tag Created **Trigger key:** `github.onTagCreated` The On Tag Created trigger starts a workflow execution when a new tag is created in a GitHub repository. ### Use Cases - **Version tagging**: Trigger workflows when version tags are created - **Release automation**: Automatically create releases from tags - **Deployment triggers**: Deploy specific versions based on tags - **Tag processing**: Process or validate tags as they're created ### Configuration - **Repository**: Select the GitHub repository to monitor - **Tags**: Configure which tags to listen for using predicates (e.g., equals "v*", starts with "release-") ### Event Data Each tag event includes: - **ref**: The tag reference (e.g., "refs/tags/v1.0.0") - **ref_type**: Type of reference (tag) - **repository**: Repository information - **sender**: User who created the tag ### Webhook Setup This trigger automatically sets up a GitHub webhook when configured. The webhook is managed by SuperPlane and will be cleaned up when the trigger is removed. ### Example Data ```json { "data": { "description": "Example repository for webhook payloads", "master_branch": "main", "pusher_type": "user", "ref": "v1.2.3", "ref_type": "tag", "repository": { "full_name": "acme/widgets", "html_url": "https://github.com/acme/widgets", "id": 123456 }, "sender": { "html_url": "https://github.com/octocat", "id": 101, "login": "octocat" } }, "timestamp": "2026-01-16T17:56:16.680755501Z", "type": "github.tagCreated" } ``` ## On Workflow Run **Trigger key:** `github.onWorkflowRun` The On Workflow Run trigger starts a workflow execution when GitHub Actions workflow runs complete. ### Use Cases - **Workflow orchestration**: Chain workflows together based on completion - **Status monitoring**: Monitor CI/CD pipeline results - **Notification workflows**: Send notifications when workflows succeed or fail - **Post-processing**: Process artifacts or results after workflow completion ### Configuration - **Repository**: Select the GitHub repository to monitor - **Conclusions**: Select which workflow conclusions to listen for (success, failure, cancelled, etc.) - **Workflow Files**: Optional list of specific workflow files to monitor (leave empty for all workflows) ### Event Data Each workflow run event includes: - **action**: The action that triggered the event (completed, requested, etc.) - **workflow_run**: Complete workflow run information including status, conclusion, logs URL - **repository**: Repository information - **sender**: User who triggered the workflow ### Webhook Setup This trigger automatically sets up a GitHub webhook when configured. The webhook is managed by SuperPlane and will be cleaned up when the trigger is removed. ### Example Data ```json { "data": { "action": "completed", "organization": { "avatar_url": "https://avatars.githubusercontent.com/u/12345678?v=4", "description": "Example organization for demo data", "events_url": "https://api.github.com/orgs/example-org/events", "hooks_url": "https://api.github.com/orgs/example-org/hooks", "id": 12345678, "issues_url": "https://api.github.com/orgs/example-org/issues", "login": "example-org", "members_url": "https://api.github.com/orgs/example-org/members{/member}", "node_id": "O_kgDOBb1AaA", "public_members_url": "https://api.github.com/orgs/example-org/public_members{/member}", "repos_url": "https://api.github.com/orgs/example-org/repos", "url": "https://api.github.com/orgs/example-org" }, "repository": { "created_at": "2024-05-10T12:00:00Z", "default_branch": "main", "description": "Example repository for webhook payloads", "fork": false, "full_name": "example-org/example-repo", "html_url": "https://github.com/example-org/example-repo", "id": 987654321, "name": "example-repo", "node_id": "R_kgDOAbCdEf", "owner": { "avatar_url": "https://avatars.githubusercontent.com/u/12345678?v=4", "gravatar_id": "", "html_url": "https://github.com/example-org", "id": 12345678, "login": "example-org", "node_id": "O_kgDOBb1AaA", "site_admin": false, "type": "Organization", "url": "https://api.github.com/users/example-org" }, "private": false, "pushed_at": "2026-03-10T14:22:11Z", "updated_at": "2026-03-10T13:50:00Z", "url": "https://api.github.com/repos/example-org/example-repo" }, "sender": { "avatar_url": "https://avatars.githubusercontent.com/u/87654321?v=4", "gravatar_id": "", "html_url": "https://github.com/alexdoe", "id": 87654321, "login": "alexdoe", "node_id": "MDQ6VXNlcjg3NjU0MzIx", "site_admin": false, "type": "User", "url": "https://api.github.com/users/alexdoe" }, "workflow": { "badge_url": "https://github.com/example-org/example-repo/workflows/CI/badge.svg", "created_at": "2024-05-10T12:00:00Z", "html_url": "https://github.com/example-org/example-repo/actions/workflows/ci.yml", "id": 9876543, "name": "CI", "node_id": "W_kwDOBb1AaA0123456", "path": ".github/workflows/ci.yml", "state": "active", "updated_at": "2026-03-01T10:00:00Z", "url": "https://api.github.com/repos/example-org/example-repo/actions/workflows/9876543" }, "workflow_run": { "actor": { "avatar_url": "https://avatars.githubusercontent.com/u/87654321?v=4", "gravatar_id": "", "html_url": "https://github.com/alexdoe", "id": 87654321, "login": "alexdoe", "node_id": "MDQ6VXNlcjg3NjU0MzIx", "site_admin": false, "type": "User", "url": "https://api.github.com/users/alexdoe" }, "artifacts_url": "https://api.github.com/repos/example-org/example-repo/actions/runs/12345678901/artifacts", "cancel_url": "https://api.github.com/repos/example-org/example-repo/actions/runs/12345678901/cancel", "check_suite_id": 11223344556, "check_suite_node_id": "CS_kwDOBb1AaA0000000", "check_suite_url": "https://api.github.com/repos/example-org/example-repo/check-suites/11223344556", "conclusion": "success", "created_at": "2026-03-10T14:22:11Z", "event": "push", "head_branch": "main", "head_commit": { "author": { "email": "alex.doe@example.com", "name": "Alex Doe" }, "committer": { "email": "noreply@example.com", "name": "GitHub" }, "id": "4f9c2e1a7b3d45c0d1e9f23456789abcdeffed01", "message": "feat: add lightweight metrics endpoint (#42)\n\nAdds a basic /metrics handler with a minimal gauge.", "timestamp": "2026-03-10T14:22:11+01:00", "tree_id": "7a8b9c0d1e2f3a4b5c6d7e8f90123456789abcde" }, "head_repository": { "description": "Example repository for webhook payloads", "fork": false, "full_name": "example-org/example-repo", "html_url": "https://github.com/example-org/example-repo", "id": 987654321, "name": "example-repo", "node_id": "R_kgDOAbCdEf", "owner": { "avatar_url": "https://avatars.githubusercontent.com/u/12345678?v=4", "gravatar_id": "", "html_url": "https://github.com/example-org", "id": 12345678, "login": "example-org", "node_id": "O_kgDOBb1AaA", "site_admin": false, "type": "Organization", "url": "https://api.github.com/users/example-org" }, "private": false, "url": "https://api.github.com/repos/example-org/example-repo" }, "head_sha": "4f9c2e1a7b3d45c0d1e9f23456789abcdeffed01", "html_url": "https://github.com/example-org/example-repo/actions/runs/12345678901", "id": 12345678901, "jobs_url": "https://api.github.com/repos/example-org/example-repo/actions/runs/12345678901/jobs", "logs_url": "https://api.github.com/repos/example-org/example-repo/actions/runs/12345678901/logs", "name": "CI", "node_id": "WFR_kwLOBb1AaA123456789", "path": ".github/workflows/ci.yml", "pull_requests": [], "referenced_workflows": [], "repository": { "clone_url": "https://github.com/example-org/example-repo.git", "created_at": "2024-05-10T12:00:00Z", "default_branch": "main", "description": "Example repository for webhook payloads", "fork": false, "full_name": "example-org/example-repo", "git_url": "git://github.com/example-org/example-repo.git", "html_url": "https://github.com/example-org/example-repo", "id": 987654321, "name": "example-repo", "node_id": "R_kgDOAbCdEf", "owner": { "avatar_url": "https://avatars.githubusercontent.com/u/12345678?v=4", "gravatar_id": "", "html_url": "https://github.com/example-org", "id": 12345678, "login": "example-org", "node_id": "O_kgDOBb1AaA", "site_admin": false, "type": "Organization", "url": "https://api.github.com/users/example-org" }, "private": false, "pushed_at": "2026-03-10T14:22:11Z", "ssh_url": "git@github.com:example-org/example-repo.git", "updated_at": "2026-03-10T13:50:00Z", "url": "https://api.github.com/repos/example-org/example-repo" }, "rerun_url": "https://api.github.com/repos/example-org/example-repo/actions/runs/12345678901/rerun", "run_attempt": 1, "run_number": 42, "run_started_at": "2026-03-10T14:22:11Z", "status": "completed", "triggering_actor": { "avatar_url": "https://avatars.githubusercontent.com/u/87654321?v=4", "gravatar_id": "", "html_url": "https://github.com/alexdoe", "id": 87654321, "login": "alexdoe", "node_id": "MDQ6VXNlcjg3NjU0MzIx", "site_admin": false, "type": "User", "url": "https://api.github.com/users/alexdoe" }, "updated_at": "2026-03-10T14:25:30Z", "url": "https://api.github.com/repos/example-org/example-repo/actions/runs/12345678901", "workflow_id": 9876543, "workflow_url": "https://api.github.com/repos/example-org/example-repo/actions/workflows/9876543" } }, "timestamp": "2026-03-10T14:25:30.31254162Z", "type": "github.workflowRun" } ``` ## Add Issue Assignee **Component key:** `github.addIssueAssignee` The Add Issue Assignee component adds one or more assignees to an existing GitHub issue without affecting existing assignees. ### Use Cases - **Auto-assignment**: Automatically assign issues to team members based on workflow triggers - **Escalation**: Add additional assignees when issues require attention from specific people - **On-call routing**: Assign issues to the current on-call engineer ### Configuration - **Repository**: Select the GitHub repository containing the issue - **Issue Number**: The issue number to add assignees to (supports expressions) - **Assignees**: List of GitHub usernames to assign to the issue ### Output Returns the updated issue object with all current information. ### Example Output ```json { "data": { "assignees": [ { "id": 1, "login": "octocat" } ], "html_url": "https://github.com/acme/widgets/issues/42", "id": 101, "number": 42, "state": "open", "title": "Fix flaky build" }, "timestamp": "2026-01-16T17:56:16.680755501Z", "type": "github.issue" } ``` ## Add Issue Label **Component key:** `github.addIssueLabel` The Add Issue Label component adds one or more labels to an existing GitHub issue without affecting existing labels. ### Use Cases - **Triage automation**: Automatically label issues based on content or source - **Status tracking**: Add status labels as issues move through workflows - **Priority tagging**: Apply priority labels based on external signals ### Configuration - **Repository**: Select the GitHub repository containing the issue - **Issue Number**: The issue number to add labels to (supports expressions) - **Labels**: List of label names to add to the issue ### Output Returns the full list of labels currently on the issue after the addition. ### Example Output ```json { "data": [ { "color": "d73a4a", "default": true, "description": "Something isn't working", "id": 208045946, "name": "bug" }, { "color": "a2eeef", "default": true, "description": "New feature or request", "id": 208045947, "name": "enhancement" } ], "timestamp": "2026-01-16T17:56:16.680755501Z", "type": "github.labels" } ``` ## Add Pull Request Reviewers **Component key:** `github.addPullRequestReviewers` The Add Pull Request Reviewers component adds individual users and/or teams as reviewers on a GitHub pull request. ### Use Cases - **Automated reviewer assignment**: Request review from the relevant team when a pull request is opened - **Escalation workflows**: Add additional reviewers when a pull request needs attention - **On-call routing**: Request review from the current on-call engineer after checks pass ### Configuration - **Repository**: Select the GitHub repository containing the pull request - **Pull Request Number**: Pull request number to add reviewers to. Expressions are supported. - **Reviewers**: GitHub usernames to request as reviewers - **Team Reviewers**: Team slugs to request as team reviewers (optional) At least one reviewer or team reviewer is required. ### Output Returns the updated pull request object with the current requested reviewers. ### Example Output ```json { "data": { "base": { "label": "acme:main", "ref": "main" }, "created_at": "2026-04-22T10:00:00Z", "draft": false, "head": { "label": "acme:feature-branch", "ref": "feature-branch" }, "html_url": "https://github.com/acme/widgets/pull/42", "id": 1234567890, "number": 42, "requested_reviewers": [ { "html_url": "https://github.com/octocat", "id": 1, "login": "octocat" } ], "requested_teams": [ { "html_url": "https://github.com/orgs/acme/teams/justice-league", "id": 1, "slug": "justice-league" } ], "state": "open", "title": "Add new feature", "user": { "html_url": "https://github.com/octocat", "id": 1, "login": "octocat" } }, "timestamp": "2026-04-22T10:00:00.000000000Z", "type": "github.pullRequest" } ``` ## Add Reaction **Component key:** `github.addReaction` The Add Reaction component adds a reaction emoji to a GitHub comment. ### Use Cases - **Acknowledge commands**: Add eyes to PR comments to indicate automation saw them - **Workflow feedback**: React with +1 or rocket on success paths - **Fast triage signals**: Use reactions to show status without posting extra comments ### Configuration - **Repository**: Select the GitHub repository - **Target**: Choose PR conversation comment or PR review line comment - **Comment ID**: The GitHub comment ID to react to (supports expressions) - **Reaction**: One of GitHub's supported reaction values ### Output Returns the created GitHub reaction object, including id, content, user, and timestamp. ### Example Output ```json { "data": { "content": "eyes", "created_at": "2026-01-16T17:56:16Z", "id": 1, "user": { "login": "superplane-bot" } }, "timestamp": "2026-01-16T17:56:16.680755501Z", "type": "github.reaction" } ``` ## Create Deployment **Component key:** `github.createDeployment` The Create Deployment component registers a deployment with GitHub for a given ref and environment. This drives the **View deployment** button and environment box on pull requests—the same surface area used by Railway, Vercel, and Netlify. ### Use Cases - **Preview environments**: Create a deployment when a PR opens, then post statuses after provision/build - **Environment history**: Let GitHub track deployment activity per environment name - **Ephemeral previews**: Set **Transient environment** so GitHub treats the deployment as short-lived ### Configuration - **Repository**: GitHub repository for the deployment - **Ref**: Branch name, tag, or commit SHA to deploy - **Environment**: Environment name (for example preview-pr-42) - **Description**: Optional deployment description - **Task**: Optional deployment task (GitHub default is deploy if omitted) - **Transient environment**: Mark as ephemeral so GitHub can auto-clean inactive deployments - **Production environment**: Mark as production when applicable - **Auto merge** (default off): Whether GitHub may auto-merge the default branch into the ref if needed - **Required contexts**: Status check context names that must pass before the deployment is created (same names as commit status **context**). Leave empty to skip status gating (recommended for previews, avoids HTTP 409 when CI is pending). If you list one or more contexts, only those must be green. GitHub may respond with HTTP 202 while it prepares verification; this component retries automatically for a short period ### Output Emits github.deployment with the created deployment, including id for **Create Deployment Status**. ### Example Output ```json { "data": { "created_at": "2024-01-01T00:00:00Z", "creator": { "avatar_url": "https://avatars.githubusercontent.com/u/12345678?v=4", "events_url": "https://api.github.com/users/example-user/events{/privacy}", "followers_url": "https://api.github.com/users/example-user/followers", "following_url": "https://api.github.com/users/example-user/following{/other_user}", "gists_url": "https://api.github.com/users/example-user/gists{/gist_id}", "gravatar_id": "", "html_url": "https://github.com/example-user", "id": 12345678, "login": "example-user", "node_id": "MDQ6VXNlcjEyMzQ1Njc4", "organizations_url": "https://api.github.com/users/example-user/orgs", "received_events_url": "https://api.github.com/users/example-user/received_events", "repos_url": "https://api.github.com/users/example-user/repos", "site_admin": false, "starred_url": "https://api.github.com/users/example-user/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/example-user/subscriptions", "type": "User", "url": "https://api.github.com/users/example-user" }, "description": "Test deployment", "environment": "preview-pr-1", "id": 1234567890, "node_id": "DE_kwDOExampleNodeId12345", "payload": {}, "ref": "feat/example-branch", "repository_url": "https://api.github.com/repos/example-org/example-repo", "sha": "abc123def456abc123def456abc123def456abc1", "statuses_url": "https://api.github.com/repos/example-org/example-repo/deployments/1234567890/statuses", "task": "deploy", "updated_at": "2024-01-01T00:00:00Z", "url": "https://api.github.com/repos/example-org/example-repo/deployments/1234567890" }, "timestamp": "2024-01-01T00:00:00.000000000Z", "type": "github.deployment" } ``` ## Create Deployment Status **Component key:** `github.createDeploymentStatus` The Create Deployment Status component posts a new status for an existing deployment. Use it after provisioning succeeds or fails, or to mark a preview as **inactive** when tearing down. ### Use Cases - **Preview ready**: success with **Environment URL** for the **View deployment** link - **Failed build or deploy**: failure or error with **Log URL** - **Teardown**: inactive when the environment is removed ### Configuration - **Repository**: GitHub repository - **Deployment ID**: Numeric deployment id (often from a prior **Create Deployment** step) - **State**: pending, queued, in_progress, success, failure, error, or inactive - **Description**: Optional status description - **Environment URL**: Live preview URL for **View deployment** (GitHub requires http(s); host-only values get https:// prepended) - **Log URL**: Link to logs (same http(s) rules; GitHub validates this like target_url) - **Environment**: Optional environment label override on the status ### Output Emits github.deploymentStatus with the created status record. ### Example Output ```json { "data": { "created_at": "2024-01-01T00:00:00Z", "creator": { "avatar_url": "https://avatars.githubusercontent.com/u/12345678?v=4", "events_url": "https://api.github.com/users/example-user/events{/privacy}", "followers_url": "https://api.github.com/users/example-user/followers", "following_url": "https://api.github.com/users/example-user/following{/other_user}", "gists_url": "https://api.github.com/users/example-user/gists{/gist_id}", "gravatar_id": "", "html_url": "https://github.com/example-user", "id": 12345678, "login": "example-user", "node_id": "MDQ6VXNlcjEyMzQ1Njc4", "organizations_url": "https://api.github.com/users/example-user/orgs", "received_events_url": "https://api.github.com/users/example-user/received_events", "repos_url": "https://api.github.com/users/example-user/repos", "site_admin": false, "starred_url": "https://api.github.com/users/example-user/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/example-user/subscriptions", "type": "User", "url": "https://api.github.com/users/example-user" }, "deployment_url": "https://api.github.com/repos/example-org/example-repo/deployments/1234567890", "description": "Test deployment status check", "environment": "preview-pr-1", "environment_url": "https://example.com", "id": 9876543210, "log_url": "https://example.com", "node_id": "DES_kwDOExampleNodeId12345", "repository_url": "https://api.github.com/repos/example-org/example-repo", "state": "success", "target_url": "https://example.com", "updated_at": "2024-01-01T00:00:00Z", "url": "https://api.github.com/repos/example-org/example-repo/deployments/1234567890/statuses/9876543210" }, "timestamp": "2024-01-01T00:00:00.000000000Z", "type": "github.deploymentStatus" } ``` ## Create Issue **Component key:** `github.createIssue` The Create Issue component creates a new issue in a specified GitHub repository. ### Use Cases - **Automated bug reporting**: Create issues automatically when errors are detected - **Task creation**: Generate issues from external systems or workflows - **Notification tracking**: Convert notifications into trackable issues - **Workflow automation**: Create issues as part of automated processes ### Configuration - **Repository**: Select the GitHub repository where the issue will be created - **Title**: The issue title (supports expressions) - **Body**: The issue body/description (supports markdown and expressions) - **Assignees**: Optional list of GitHub usernames to assign the issue to - **Labels**: Optional list of labels to apply to the issue ### Output Returns the created issue object with details including: - Issue number - URL - State - Created timestamp - All issue metadata ### Example Output ```json { "data": { "html_url": "https://github.com/acme/widgets/issues/42", "id": 101, "number": 42, "state": "open", "title": "Fix flaky build", "user": { "login": "octocat" } }, "timestamp": "2026-01-16T17:56:16.680755501Z", "type": "github.issue" } ``` ## Create Issue Comment **Component key:** `github.createIssueComment` The Create Issue Comment component adds a comment to an existing GitHub issue or pull request. Issues and pull requests share the same comment API in GitHub. ### Use Cases - **Deployment updates**: Post deployment status or remediation updates to GitHub issues - **Runbook linking**: Add runbook links, error details, or status for responders - **Cross-platform sync**: Sync Slack or PagerDuty notes into GitHub as comments - **Automated comments**: Add automated comments based on workflow events ### Configuration - **Repository**: Select the GitHub repository containing the issue - **Issue Number**: The issue or PR number to comment on (supports expressions) - **Body**: The comment text (supports Markdown and expressions) ### Output Returns the created comment object including: - Comment ID and URL - Comment body - Author information - Created timestamp ### Example Output ```json { "data": { "body": "Deployment to production completed successfully.", "created_at": "2026-01-16T17:56:16Z", "html_url": "https://github.com/acme/widgets/issues/42#issuecomment-5001", "id": 5001, "updated_at": "2026-01-16T17:56:16Z", "user": { "login": "superplane-app[bot]" } }, "timestamp": "2026-01-16T17:56:16.680755501Z", "type": "github.issueComment" } ``` ## Create Pull Request **Component key:** `github.createPullRequest` The Create Pull Request component creates a new pull request in a specified GitHub repository. ### Use Cases - **Automated PR creation**: Open pull requests automatically as part of CI/CD pipelines - **Branch promotion**: Create PRs to promote changes between branches - **Workflow automation**: Generate PRs from external triggers or scheduled workflows ### Configuration - **Repository**: Select the GitHub repository where the pull request will be created - **Head**: The branch containing the changes (source branch) - **Base**: The branch you want the changes pulled into (target branch, defaults to "main") - **Title**: The pull request title (supports expressions) - **Body**: Optional pull request description (supports markdown and expressions) - **Draft**: Whether to create the pull request as a draft ### Output Returns the created pull request object with details including: - Pull request number - URL - State - Head and base branch information - Created timestamp ### Limitations - Only same-repository pull requests are supported. Cross-repository (fork) pull requests using GitHub's owner:branch head syntax are not currently supported - both the head and base branch must live in the selected repository. ### Example Output ```json { "data": { "base": { "label": "acme:main", "ref": "main" }, "created_at": "2026-04-22T10:00:00Z", "draft": false, "head": { "label": "acme:feature-branch", "ref": "feature-branch" }, "html_url": "https://github.com/acme/widgets/pull/42", "id": 1234567890, "number": 42, "state": "open", "title": "Add new feature", "user": { "html_url": "https://github.com/octocat", "id": 1, "login": "octocat" } }, "timestamp": "2026-04-22T10:00:00.000000000Z", "type": "github.pullRequest" } ``` ## Create Release **Component key:** `github.createRelease` The Create Release component creates a new release in a GitHub repository. ### Use Cases - **Automated releases**: Create releases automatically after successful builds - **Version management**: Tag and release new versions of software - **Deployment automation**: Create releases as part of deployment workflows - **Release notes**: Automatically generate and publish release notes ### Configuration - **Repository**: Select the GitHub repository - **Version Strategy**: How to determine the version (manual tag, auto-increment) - **Tag Name**: Git tag name for the release (supports expressions) - **Name**: Release title/name (optional, supports expressions) - **Body**: Release notes/description (optional, supports markdown and expressions) - **Draft**: Create as draft release (not published) - **Prerelease**: Mark as pre-release - **Generate Release Notes**: Automatically generate release notes from commits ### Output Returns the created release object with all release information including tag, assets, and metadata. ### Example Output ```json { "data": { "draft": false, "html_url": "https://github.com/acme/widgets/releases/tag/v1.2.3", "id": 3001, "name": "Release 1.2.3", "prerelease": false, "tag_name": "v1.2.3" }, "timestamp": "2026-01-16T17:56:16.680755501Z", "type": "github.release" } ``` ## Create Review **Component key:** `github.createReview` The Create Review component submits a pull request review (approve, request changes, or comment) on a GitHub pull request. ### Use Cases - **Automation**: Auto-approve when checks pass - **Quality gates**: Request changes when checks fail - **Bots**: Post review feedback ### Configuration - **Repository**: Select the GitHub repository - **Pull Number**: Pull request number - **Event**: APPROVE, REQUEST_CHANGES, or COMMENT - **Body**: Optional review body (required for REQUEST_CHANGES and COMMENT) ### Output Emits the submitted review object including: - id, state, submitted_at - body and user ### Example Output ```json { "data": { "body": "LGTM. Approving after successful CI.", "html_url": "https://github.com/acme/widgets/pull/42#pullrequestreview-9001", "id": 9001, "state": "APPROVED", "submitted_at": "2026-01-25T12:34:56Z", "user": { "html_url": "https://github.com/octocat", "id": 1, "login": "octocat" } }, "timestamp": "2026-01-25T12:34:56.000000000Z", "type": "github.pullRequestReview" } ``` ## Delete Release **Component key:** `github.deleteRelease` The Delete Release component removes a release from a GitHub repository. ### Use Cases - **Cleanup**: Remove old or incorrect releases - **Rollback**: Delete releases that were created in error - **Maintenance**: Clean up draft or test releases - **Automated cleanup**: Remove releases as part of maintenance workflows ### Configuration - **Repository**: Select the GitHub repository - **Release Strategy**: How to find the release (by tag name or latest) - **Tag Name**: Git tag name of the release to delete (if using tag strategy) - **Delete Tag**: Also delete the associated Git tag (optional) ### Output Returns confirmation of the deletion. ### Example Output ```json { "data": { "deleted_at": "2026-01-16T17:55:00Z", "draft": false, "html_url": "https://github.com/acme/widgets/releases/tag/v1.2.3", "id": 3001, "name": "Release 1.2.3", "prerelease": false, "tag_deleted": true, "tag_name": "v1.2.3" }, "timestamp": "2026-01-16T17:56:16.680755501Z", "type": "github.release" } ``` ## Get Combined Commit Status **Component key:** `github.getCombinedCommitStatus` The Get Combined Commit Status component reads GitHub's combined commit status for a commit, branch, or tag. This component uses the Commit Statuses API. It summarizes legacy commit statuses, such as statuses posted by external CI systems through GitHub's statuses endpoint. It does not include GitHub Checks API check runs. ### Use Cases - **Status gates**: Check whether all commit status contexts are green before continuing - **Pull request automation**: Pair with On Commit Status to re-evaluate a PR when one status changes - **Branch protection helpers**: Inspect the aggregate status for a branch head or merge commit - **Notifications**: Send concise status summaries when a commit is blocked by failed or pending statuses ### Configuration - **Repository**: Select the GitHub repository - **Ref**: Commit SHA, branch name, or tag name to inspect. Expressions are supported. ### Output Emits a combined commit status object on the default output channel. The payload includes the combined **state**, **sha**, **total_count**, and the latest status for each status context in **statuses**. ### Example Output ```json { "data": { "commit_url": "https://api.github.com/repos/acme-labs/snaketoy/commits/d6f3c8a2e8b7f0a9c0a1f67f0c5d7b2a1d9e3f44", "repository_url": "https://api.github.com/repos/acme-labs/snaketoy", "sha": "d6f3c8a2e8b7f0a9c0a1f67f0c5d7b2a1d9e3f44", "state": "failure", "statuses": [ { "context": "ci/build", "created_at": "2026-01-16T17:45:00Z", "description": "Build passed", "state": "success", "target_url": "https://ci.example.com/builds/123", "updated_at": "2026-01-16T17:45:10Z" }, { "context": "ci/lint", "created_at": "2026-01-16T17:45:20Z", "description": "Lint failed", "state": "failure", "target_url": "https://ci.example.com/builds/124", "updated_at": "2026-01-16T17:46:00Z" }, { "context": "deploy/preview", "created_at": "2026-01-16T17:46:10Z", "description": "Deployment pending", "state": "pending", "target_url": "https://deploy.example.com/previews/42", "updated_at": "2026-01-16T17:46:10Z" } ], "total_count": 3 }, "timestamp": "2026-01-16T17:56:16.680755501Z", "type": "github.combinedCommitStatus" } ``` ## Get Issue **Component key:** `github.getIssue` The Get Issue component retrieves a specific issue from a GitHub repository by its issue number. ### Use Cases - **Issue lookup**: Fetch issue details for processing or display - **Workflow automation**: Get issue information to make decisions in workflows - **Data enrichment**: Retrieve issue data to combine with other information - **Status checking**: Check issue status before performing actions ### Configuration - **Repository**: Select the GitHub repository containing the issue - **Issue Number**: The issue number to retrieve (supports expressions) ### Output Returns the complete issue object including: - Issue number, title, and body - State (open/closed) - Labels and assignees - Created and updated timestamps - Author information - Comments count and other metadata ### Example Output ```json { "data": { "comments": 3, "html_url": "https://github.com/acme/widgets/issues/42", "id": 101, "number": 42, "state": "open", "title": "Fix flaky build", "user": { "login": "octocat" } }, "timestamp": "2026-01-16T17:56:16.680755501Z", "type": "github.issue" } ``` ## Get Release **Component key:** `github.getRelease` The Get Release component retrieves release information from a GitHub repository. ### Use Cases - **Release Monitoring**: Get details about a specific release - **Deployment Pipelines**: Fetch release assets and metadata for deployment - **Version Tracking**: Monitor release status and changelog - **CI/CD Integration**: Retrieve release information for build processes ### Configuration - **Repository**: Select the GitHub repository - **Release Strategy**: How to find the release (by tag name, by ID, or latest) - **Tag Name**: Git tag name of the release (if using tag strategy) - **Release ID**: Numeric release ID (if using ID strategy) ### Output Returns release information including: - Release ID, name, and tag name - Release body/description - Draft and prerelease status - Created and published timestamps - Author information - Asset URLs ### Example Output ```json { "data": { "assets": [ { "browser_download_url": "https://github.com/acme/widgets/releases/download/v1.2.3/app-v1.2.3.zip", "content_type": "application/zip", "download_count": 42, "id": 1, "label": "Application Bundle", "name": "app-v1.2.3.zip", "size": 1024000 } ], "author": { "avatar_url": "https://github.com/images/error/octocat_happy.gif", "html_url": "https://github.com/octocat", "id": 1, "login": "octocat" }, "body": "## What's Changed\n\n- Feature A\n- Bug fix B", "created_at": "2026-01-15T10:00:00Z", "draft": false, "html_url": "https://github.com/acme/widgets/releases/tag/v1.2.3", "id": 3001, "name": "Release 1.2.3", "prerelease": false, "published_at": "2026-01-16T12:00:00Z", "tag_name": "v1.2.3" }, "timestamp": "2026-01-16T17:56:16.680755501Z", "type": "github.release" } ``` ## Get Repository Permission **Component key:** `github.getRepositoryPermission` The Get Repository Permission component retrieves a user's effective permission level for a GitHub repository. ### Use Cases - **Access checks**: Verify if a user has expected repository access - **Automation gates**: Branch workflow behavior by repository permissions - **Auditing**: Inspect repository roles in automated compliance checks - **Triage routing**: Route incidents based on whether a user can push/administer ### Example Output ```json { "data": { "permission": "admin", "role_name": "admin", "user": { "html_url": "https://github.com/octocat", "id": 1, "login": "octocat" } }, "timestamp": "2026-02-26T14:30:00Z", "type": "github.repositoryPermission" } ``` ## Get Workflow Usage **Component key:** `github.getWorkflowUsage` The Get Workflow Usage component retrieves billable GitHub Actions usage (minutes) for the installation's organization. ### Prerequisites This action calls GitHub's **billing usage** API, which requires the GitHub App to have **Organization permission: Organization administration (read)**. **Important**: Existing installations will need to approve the new permission when prompted by GitHub. Until the permission is granted, this action will return a 403 error. **Note**: This component uses GitHub's enhanced billing usage report API, which provides detailed usage information. ### Behavior - Returns billing data for the **current billing cycle** - Only private repositories on GitHub-hosted runners accrue billable minutes - Public repositories and self-hosted runners show zero billable usage - Can filter by specific repositories when selected - Uses enhanced billing platform API for accurate reporting ### Configuration - **Repositories** (optional, multiselect): Select one or more specific repositories to track. These will be included in the output for reference (max 5) and stored in node metadata with full repository details (ID, name, URL). When repositories are selected, only usage for those repositories is included in the totals. ### Output Returns usage data with: - `minutes_used`: Total billable minutes used in the current billing cycle - `minutes_used_breakdown`: Map of minutes by runner SKU (e.g., "Actions Linux": 120, "Actions Windows": 60, "Actions macOS": 30) - `included_minutes`: Always 0 (not provided by enhanced billing API) - `total_paid_minutes_used`: Estimated paid minutes based on cost data - `repositories`: List of selected repositories for tracking (max 5) **Note**: Breakdown is by runner SKU (OS and type), not by individual workflow. ### Node Metadata The component stores repository information in node metadata: - Repository ID, name, and URL for each selected repository (max 5) - This metadata is displayed in the workflow canvas for easy reference ### Use Cases - **Billing Monitoring**: Track GitHub Actions usage for billing purposes - **Quota Management**: Monitor usage to avoid exceeding billing quotas - **Cost Control**: Alert when usage approaches limits or budget thresholds - **Usage Reporting**: Generate monthly or periodic usage reports for compliance - **Resource Planning**: Analyze runner usage patterns by OS type ### References - [GitHub Billing Usage API](https://docs.github.com/rest/billing/usage) - [GitHub Enhanced Billing Platform](https://docs.github.com/billing/using-the-new-billing-platform) - [Permissions required for GitHub Apps - Organization Administration](https://docs.github.com/en/rest/overview/permissions-required-for-github-apps#organization-permissions-for-administration) - [Viewing your usage of metered products](https://docs.github.com/en/billing/managing-billing-for-github-actions/viewing-your-github-actions-usage) ### Example Output ```json { "data": { "included_minutes": 0, "minutes_used": 1840.5, "minutes_used_breakdown": { "Actions Linux": 1200, "Actions Windows": 400.5, "Actions macOS": 240 }, "repositories": [ "repo1", "repo2", "repo3" ], "total_paid_minutes_used": 150 }, "timestamp": "2026-02-17T20:00:00Z", "type": "github.workflowUsage" } ``` ## List Check Runs For Ref **Component key:** `github.listCheckRunsForRef` The List Check Runs For Ref component retrieves GitHub Checks API check runs for a commit SHA, branch, or tag. Use it after On Check Run or other GitHub triggers to inspect the full set of Checks API results for the same ref before deciding whether to continue. ### Use Cases - **PR quality gates**: Continue only when all check runs for a PR commit are complete and green - **Check aggregation**: Inspect the full Checks API state after one check run changes - **Notifications**: Build summaries for failed or pending check runs ### Configuration - **Repository**: Select the GitHub repository - **Ref**: Commit SHA, branch, or tag ref - **Check Name** *(optional)*: Return only check runs with this name - **Status** *(optional)*: Return only check runs with this status - **Filter**: Use latest to return the latest run per check suite, or all to include all matching runs ### Output Returns GitHub's check run list response, including total_count and check_runs. Each check run includes its name, status, conclusion, URLs, app metadata, associated pull requests, and timestamps. ### Example Output ```json { "data": { "check_runs": [ { "app": { "name": "DCO" }, "conclusion": "success", "details_url": "https://github.com/acme/snaketoy/runs/123456789", "head_sha": "d6f3c8a2e8b7f0a9c0a1f67f0c5d7b2a1d9e3f44", "html_url": "https://github.com/acme/snaketoy/runs/123456789", "id": 123456789, "name": "DCO", "pull_requests": [ { "html_url": "https://github.com/acme/snaketoy/pull/42", "number": 42 } ], "status": "completed" }, { "app": { "name": "Cloudflare Pages" }, "conclusion": "success", "details_url": "https://dash.cloudflare.com/example", "head_sha": "d6f3c8a2e8b7f0a9c0a1f67f0c5d7b2a1d9e3f44", "html_url": "https://github.com/acme/snaketoy/runs/987654321", "id": 987654321, "name": "Cloudflare Pages", "pull_requests": [ { "html_url": "https://github.com/acme/snaketoy/pull/42", "number": 42 } ], "status": "completed" } ], "total_count": 2 }, "timestamp": "2026-06-01T12:02:02Z", "type": "github.checkRuns" } ``` ## Merge Pull Request **Component key:** `github.mergePullRequest` The Merge Pull Request component merges an open pull request in a GitHub repository. ### Use Cases - **Automated PR merge gates**: Merge a pull request after status checks or check runs pass - **Release automation**: Merge approved promotion branches into a release branch - **Queue workflows**: Merge pull requests from a controlled SuperPlane workflow ### Configuration - **Repository**: Select the GitHub repository containing the pull request - **Pull Request Number**: Pull request number to merge. Expressions are supported. - **Merge Method**: Merge strategy to use. Defaults to "merge". - **Expected SHA**: Optional head SHA guard. GitHub rejects the merge if the pull request head has changed. - **Commit Title**: Optional title for the merge commit, squash commit, or rebase commit. - **Commit Message**: Optional commit message for the merge commit or squash commit. ### Output Returns GitHub's merge result, including whether the pull request was merged, the resulting commit SHA, and GitHub's message. ### Example Output ```json { "data": { "merged": true, "message": "Pull Request successfully merged", "sha": "0e98bc41ab56cee9ff17883607b56f96e7814c98" }, "timestamp": "2026-04-22T10:00:00.000000000Z", "type": "github.pullRequestMerge" } ``` ## Publish Commit Status **Component key:** `github.publishCommitStatus` The Publish Commit Status component creates a status check on a GitHub commit, commonly used for CI/CD integrations. ### Use Cases - **CI/CD integration**: Report build and test results to GitHub - **Status reporting**: Update commit status from external systems - **Deployment tracking**: Mark commits as deployed or failed - **Quality gates**: Report code quality check results ### Configuration - **Repository**: Select the GitHub repository - **Commit SHA**: The full 40-character commit SHA (supports expressions) - **State**: Status state - pending, success, failure, or error - **Context**: A label to identify this status check (e.g., "ci/build", "deploy/production") - **Description**: Short description of the status (max ~140 characters, optional) - **Target URL**: Link to build logs, test results, or deployment details (optional) ### Output Returns the created status object with all status information. ### Example Output ```json { "data": { "context": "ci/build", "created_at": "2026-01-16T17:45:00Z", "description": "All checks passed", "state": "success", "target_url": "https://ci.example.com/builds/123", "updated_at": "2026-01-16T17:45:10Z" }, "timestamp": "2026-01-16T17:56:16.680755501Z", "type": "github.commitStatus" } ``` ## Remove Issue Assignee **Component key:** `github.removeIssueAssignee` The Remove Issue Assignee component removes one or more assignees from an existing GitHub issue without affecting other assignees. ### Use Cases - **De-escalation**: Remove assignees when issues are resolved or transferred - **Rotation**: Remove previous on-call assignees when rotating responsibilities - **Cleanup**: Remove assignees who are no longer involved with an issue ### Configuration - **Repository**: Select the GitHub repository containing the issue - **Issue Number**: The issue number to remove assignees from (supports expressions) - **Assignees**: List of GitHub usernames to remove from the issue ### Output Returns the updated issue object with all current information. ### Example Output ```json { "data": { "assignees": [], "html_url": "https://github.com/acme/widgets/issues/42", "id": 101, "number": 42, "state": "open", "title": "Fix flaky build" }, "timestamp": "2026-01-16T17:56:16.680755501Z", "type": "github.issue" } ``` ## Remove Issue Label **Component key:** `github.removeIssueLabel` The Remove Issue Label component removes one or more labels from an existing GitHub issue without affecting other labels. ### Use Cases - **Triage cleanup**: Remove temporary triage labels after processing - **Status transitions**: Remove old status labels when issues move forward - **Automated cleanup**: Strip labels that no longer apply based on workflow events ### Configuration - **Repository**: Select the GitHub repository containing the issue - **Issue Number**: The issue number to remove labels from (supports expressions) - **Labels**: List of label names to remove from the issue ### Output Returns the remaining list of labels on the issue after the removal. ### Example Output ```json { "data": [ { "color": "a2eeef", "default": true, "description": "New feature or request", "id": 208045947, "name": "enhancement" } ], "timestamp": "2026-01-16T17:56:16.680755501Z", "type": "github.labels" } ``` ## Run Workflow **Component key:** `github.runWorkflow` The Run Workflow component triggers a GitHub Actions workflow and waits for it to complete. ### Use Cases - **CI/CD orchestration**: Trigger builds and deployments from SuperPlane workflows - **Automated testing**: Run test suites as part of workflow automation - **Multi-stage pipelines**: Coordinate complex deployment pipelines - **Workflow chaining**: Chain multiple GitHub Actions workflows together ### How It Works 1. Dispatches the specified GitHub Actions workflow with optional inputs 2. Waits for the workflow run to complete (monitored via webhook and polling) 3. Routes execution based on workflow conclusion: - **Passed channel**: Workflow completed successfully - **Failed channel**: Workflow failed or was cancelled ### Configuration - **Repository**: Select the GitHub repository containing the workflow - **Workflow File**: Path to the workflow file (e.g., `.github/workflows/ci.yml`) - **Branch or Tag**: Git reference to run the workflow on (default: main) - **Inputs**: Optional workflow inputs as key-value pairs (supports expressions) ### Output Channels - **Passed**: Emitted when workflow completes successfully - **Failed**: Emitted when workflow fails or is cancelled ### Notes - The component automatically sets up webhook monitoring for workflow completion - Falls back to polling if webhook doesn't arrive - Can be cancelled, which will cancel the running GitHub Actions workflow ### Example Output ```json { "data": { "workflow_run": { "conclusion": "success", "html_url": "https://github.com/acme/widgets/actions/runs/9001", "id": 9001, "status": "completed" } }, "timestamp": "2026-01-16T17:56:16.680755501Z", "type": "github.workflow.finished" } ``` ## Update Issue **Component key:** `github.updateIssue` The Update Issue component modifies an existing GitHub issue with new information. ### Use Cases - **Status updates**: Change issue state (open/closed) based on workflow results - **Label management**: Add or update labels on issues - **Assignee updates**: Assign issues to team members automatically - **Content updates**: Update issue title or body with new information ### Configuration - **Repository**: Select the GitHub repository containing the issue - **Issue Number**: The issue number to update (supports expressions) - **Title**: New title for the issue (optional, supports expressions) - **Body**: New body/description for the issue (optional, supports expressions) - **State**: Change issue state to "open" or "closed" (optional) - **Assignees**: List of GitHub usernames to assign the issue to (optional) - **Labels**: List of labels to apply to the issue (optional) ### Output Returns the updated issue object with all current information. ### Example Output ```json { "data": { "html_url": "https://github.com/acme/widgets/issues/42", "id": 101, "number": 42, "state": "closed", "title": "Fix flaky build", "updated_at": "2026-01-16T17:40:00Z" }, "timestamp": "2026-01-16T17:56:16.680755501Z", "type": "github.issue" } ``` ## Update Issue Comment **Component key:** `github.updateIssueComment` The **Update Issue Comment** component edits an existing comment on a GitHub issue or pull request. ### Use Cases - **Status updates**: Update a summary comment on a PR instead of posting new comments on every run - **Living reports**: Keep a single comment with the latest test results, coverage, or review status - **Avoid spam**: Update one comment instead of flooding a PR with repeated bot comments ### Configuration - **Repository**: Select the GitHub repository - **Comment ID**: The numeric ID of the comment to update (supports expressions) - **Body**: The new comment text (supports Markdown and expressions) ### Output Returns the updated comment object including comment ID, URL, body, and timestamps. ### Notes - The comment ID is returned in the output of `github.createIssueComment` as `id` - You can store the comment ID in canvas memory on first run, then use it for subsequent updates - The authenticated user must have permission to edit the comment (must be the comment author or have admin access) ### Example Output ```json { "data": { "author_association": "NONE", "body": "## Docs Review Summary\n\n**Verdict:** No update needed\n\nAll changes are internal refactors with no user-facing impact.", "created_at": "2026-01-16T17:56:16Z", "html_url": "https://github.com/acme/widgets/issues/42#issuecomment-1234567890", "id": 1234567890, "issue_url": "https://api.github.com/repos/acme/widgets/issues/42", "node_id": "IC_kwDOExample", "reactions": { "+1": 0, "-1": 0, "confused": 0, "eyes": 0, "heart": 0, "hooray": 0, "laugh": 0, "rocket": 0, "total_count": 0, "url": "https://api.github.com/repos/acme/widgets/issues/comments/1234567890/reactions" }, "updated_at": "2026-01-16T18:30:00Z", "url": "https://api.github.com/repos/acme/widgets/issues/comments/1234567890", "user": { "avatar_url": "https://avatars.githubusercontent.com/u/12345678?v=4", "html_url": "https://github.com/apps/superplane-app", "id": 12345678, "login": "superplane-app[bot]", "node_id": "BOT_kwExample", "site_admin": false, "type": "Bot", "url": "https://api.github.com/users/superplane-app[bot]" } }, "timestamp": "2026-01-16T18:30:00.680755501Z", "type": "github.issueComment" } ``` ## Update Release **Component key:** `github.updateRelease` The Update Release component modifies an existing GitHub release. ### Use Cases - **Release updates**: Update release notes or metadata after creation - **Draft to published**: Convert draft releases to published releases - **Metadata updates**: Update release name, description, or tags - **Prerelease management**: Change prerelease status ### Configuration - **Repository**: Select the GitHub repository - **Release Strategy**: How to find the release (by tag name or latest) - **Tag Name**: Git tag name of the release to update (if using tag strategy) - **Name**: New release title/name (optional, supports expressions) - **Body**: New release notes/description (optional, supports markdown and expressions) - **Draft**: Update draft status - **Prerelease**: Update prerelease status - **Generate Release Notes**: Regenerate release notes from commits ### Output Returns the updated release object with all current information. ### Example Output ```json { "data": { "draft": false, "html_url": "https://github.com/acme/widgets/releases/tag/v1.2.3", "id": 3001, "name": "Release 1.2.3", "prerelease": false, "tag_name": "v1.2.3", "updated_at": "2026-01-16T17:50:00Z" }, "timestamp": "2026-01-16T17:56:16.680755501Z", "type": "github.release" } ``` #### GitLab Source URL: https://docs.superplane.com/components/gitlab Manage and react to changes in your GitLab repositories import { CardGrid, LinkCard } from "@astrojs/starlight/components"; ## Triggers ## Actions ## Instructions When connecting using App OAuth: - Leave **Client ID** and **Secret** empty to start the setup wizard. When connecting using Personal Access Token: - Go to Preferences → Personal Access Token → Add New token - Use **Scopes**: api, read_user, read_api, write_repository, read_repository - Copy the token and paste it into the **Access Token** configuration field, then click **Save**. ## On Issue **Trigger key:** `gitlab.onIssue` The On Issue trigger starts a workflow execution when issue events occur in a GitLab project. ### Use Cases - **Notify Slack** when an issue is created or assigned for triage - **Create a Jira issue** when a GitLab issue is created for traceability - **Update external dashboards** or close linked tickets when an issue is closed ### Configuration - **Project** (required): GitLab project to monitor - **Actions** (required): Select which issue actions to listen for (opened, closed, reopened, etc.). Default: opened. - **Labels** (optional): Only trigger for issues with specific labels ### Outputs - **Default channel**: Emits issue payload including issue IID, title, state, labels, assignees, author, and action type ### Webhook Setup This trigger automatically sets up a GitLab webhook when configured. The webhook is managed by SuperPlane and will be cleaned up when the trigger is removed. ### Example Data ```json { "data": { "assignees": [ { "avatar_url": "https://www.gravatar.com/avatar/abc123", "id": 1, "name": "John Doe", "username": "johndoe" } ], "event_type": "issue", "labels": [ { "color": "#dc3545", "created_at": "2026-01-01T00:00:00Z", "description": "Bug reports", "group_id": null, "id": 206, "project_id": 15, "template": false, "title": "bug", "type": "ProjectLabel", "updated_at": "2026-01-01T00:00:00Z" } ], "object_attributes": { "action": "open", "created_at": "2026-02-05T14:00:00Z", "description": "This is an example issue description for testing the webhook", "id": 301, "iid": 1, "state": "opened", "title": "Example Issue", "updated_at": "2026-02-05T14:00:00Z", "url": "https://gitlab.com/group/my-project/-/issues/1" }, "object_kind": "issue", "project": { "avatar_url": null, "default_branch": "main", "description": "Example project", "git_http_url": "https://gitlab.com/group/my-project.git", "git_ssh_url": "git@gitlab.com:group/my-project.git", "id": 15, "name": "my-project", "namespace": "group", "path_with_namespace": "group/my-project", "visibility_level": 20, "web_url": "https://gitlab.com/group/my-project" }, "repository": { "description": "Example project", "homepage": "https://gitlab.com/group/my-project", "name": "my-project", "url": "git@gitlab.com:group/my-project.git" }, "user": { "avatar_url": "https://www.gravatar.com/avatar/abc123", "email": "johndoe@example.com", "id": 1, "name": "John Doe", "username": "johndoe" } }, "timestamp": "2026-02-05T14:00:00.000000000Z", "type": "gitlab.issue" } ``` ## On Merge Request **Trigger key:** `gitlab.onMergeRequest` The On Merge Request trigger starts a workflow execution when merge request events occur in a GitLab project. ### Configuration - **Project** (required): GitLab project to monitor - **Actions** (required): Select which merge request actions to listen for (open, close, merge, etc.). Default: open. ### Outputs - **Default channel**: Emits merge request payload data with action, project, and object attributes ### Example Data ```json { "data": { "assignees": [ { "avatar_url": "https://www.gravatar.com/avatar/ab12cd34?s=80\u0026d=identicon", "email": "jrivera@example.com", "id": 4, "name": "Jamie Rivera", "username": "jrivera" } ], "changes": { "title": { "current": "Add merge request trigger", "previous": "Add trigger" } }, "event_type": "merge_request", "labels": [ { "id": 101, "title": "backend" } ], "object_attributes": { "action": "open", "description": "Adds support for additional GitLab webhook trigger types.", "id": 93, "iid": 12, "state": "opened", "title": "Add merge request trigger" }, "object_kind": "merge_request", "project": { "avatar_url": null, "ci_config_path": null, "default_branch": "main", "description": "Project used to demonstrate merge request webhook payloads.", "git_http_url": "https://gitlab.example.com/group/example.git", "git_ssh_url": "ssh://git@gitlab.example.com:group/example.git", "id": 1, "name": "Example Project", "namespace": "group", "path_with_namespace": "group/example", "visibility_level": 20, "web_url": "https://gitlab.example.com/group/example" }, "repository": { "description": "Project used to demonstrate merge request webhook payloads.", "git_http_url": "https://gitlab.example.com/group/example.git", "git_ssh_url": "ssh://git@gitlab.example.com:group/example.git", "homepage": "https://gitlab.example.com/group/example", "name": "Example Project", "url": "ssh://git@gitlab.example.com/group/example.git", "visibility_level": 20 }, "reviewers": [ { "avatar_url": "https://www.gravatar.com/avatar/ef56gh78?s=80\u0026d=identicon", "email": "mlee@example.com", "id": 6, "name": "Morgan Lee", "state": "unreviewed", "username": "mlee" } ], "user": { "avatar_url": "https://www.gravatar.com/avatar/1a29da0ccd099482194440fac762f5ccb4ec53227761d1859979367644a889a5?s=80\u0026d=identicon", "email": "agarcia@example.com", "id": 1, "name": "Alex Garcia", "username": "agarcia" } }, "timestamp": "2026-02-12T20:40:00.000000000Z", "type": "gitlab.mergeRequest" } ``` ## On Milestone **Trigger key:** `gitlab.onMilestone` The On Milestone trigger starts a workflow execution when milestone events occur in a GitLab project. ### Configuration - **Project** (required): GitLab project to monitor - **Actions** (required): Select which milestone actions to listen for. Default: create. ### Outputs - **Default channel**: Emits milestone payload data with action, project, and object attributes ### Example Data ```json { "data": { "action": "create", "event_type": "milestone", "object_attributes": { "created_at": "2025-06-16 14:10:57 UTC", "description": "First stable release", "due_date": "2025-06-30", "group_id": null, "id": 61, "iid": 10, "project_id": 1, "start_date": "2025-06-16", "state": "active", "title": "v1.0", "updated_at": "2025-06-16 14:10:57 UTC" }, "object_kind": "milestone", "project": { "avatar_url": null, "ci_config_path": null, "default_branch": "master", "description": "Aut reprehenderit ut est.", "git_http_url": "http://example.com/gitlabhq/gitlab-test.git", "git_ssh_url": "git@example.com:gitlabhq/gitlab-test.git", "homepage": "http://example.com/gitlabhq/gitlab-test", "http_url": "http://example.com/gitlabhq/gitlab-test.git", "id": 1, "name": "Gitlab Test", "namespace": "GitlabHQ", "path_with_namespace": "gitlabhq/gitlab-test", "ssh_url": "git@example.com:gitlabhq/gitlab-test.git", "url": "http://example.com/gitlabhq/gitlab-test.git", "visibility_level": 20, "web_url": "http://example.com/gitlabhq/gitlab-test" } }, "timestamp": "2026-02-12T20:40:00.000000000Z", "type": "gitlab.milestone" } ``` ## On Pipeline **Trigger key:** `gitlab.onPipeline` The On Pipeline trigger starts a workflow execution when pipeline events occur in a GitLab project. ### Configuration - **Project** (required): GitLab project to monitor - **Statuses** (required): Select which pipeline statuses to listen for. Default: success, failed, canceled. ### Outputs - **Default channel**: Emits pipeline webhook payload data including status, ref, SHA, and project information ### Webhook Setup This trigger automatically sets up a GitLab webhook when configured. The webhook is managed by SuperPlane and will be cleaned up when the trigger is removed. ### Example Data ```json { "data": { "merge_request": { "iid": 12, "title": "Improve CI pipeline" }, "object_attributes": { "created_at": "2026-02-10 12:00:00 UTC", "duration": 190, "finished_at": "2026-02-10 12:03:10 UTC", "id": 12345, "iid": 321, "ref": "main", "sha": "f4f6c5a0d2e5ad34be4c17c3f166f4d2ff8b0a55", "source": "push", "status": "success", "updated_at": "2026-02-10 12:03:10 UTC", "url": "https://gitlab.com/group/example-project/-/pipelines/12345" }, "object_kind": "pipeline", "project": { "id": 987, "name": "example-project", "path_with_namespace": "group/example-project", "web_url": "https://gitlab.com/group/example-project" }, "user": { "id": 22, "name": "Jamie Rivera", "username": "jrivera" } }, "timestamp": "2026-02-13T18:00:00.000000000Z", "type": "gitlab.pipeline" } ``` ## On Release **Trigger key:** `gitlab.onRelease` The On Release trigger starts a workflow execution when release events occur in a GitLab project. ### Configuration - **Project** (required): GitLab project to monitor - **Actions** (required): Select which release actions to listen for. Default: create. ### Outputs - **Default channel**: Emits release payload data with action and release metadata ### Example Data ```json { "data": { "action": "create", "assets": { "count": 2, "links": [ { "id": 1, "link_type": "other", "name": "Changelog", "url": "https://example.net/changelog" } ], "sources": [ { "format": "zip", "url": "https://example.com/gitlab-org/release-webhook-example/-/archive/v1.1/release-webhook-example-v1.1.zip" }, { "format": "tar.gz", "url": "https://example.com/gitlab-org/release-webhook-example/-/archive/v1.1/release-webhook-example-v1.1.tar.gz" } ] }, "commit": { "author": { "email": "user@example.com", "name": "Example User" }, "id": "ee0a3fb31ac16e11b9dbb596ad16d4af654d08f8", "message": "Release v1.1", "timestamp": "2020-10-31T14:58:32+11:00", "title": "Release v1.1", "url": "https://example.com/gitlab-org/release-webhook-example/-/commit/ee0a3fb31ac16e11b9dbb596ad16d4af654d08f8" }, "created_at": "2020-11-02 12:55:12 UTC", "description": "v1.1 has been released", "id": 1, "name": "v1.1", "object_kind": "release", "project": { "avatar_url": null, "ci_config_path": null, "default_branch": "master", "description": "", "git_http_url": "https://example.com/gitlab-org/release-webhook-example.git", "git_ssh_url": "ssh://git@example.com/gitlab-org/release-webhook-example.git", "id": 1, "name": "release-webhook-example", "namespace": "Gitlab", "path_with_namespace": "gitlab-org/release-webhook-example", "visibility_level": 0, "web_url": "https://example.com/gitlab-org/release-webhook-example" }, "released_at": "2020-11-02 12:55:12 UTC", "tag": "v1.1", "url": "https://example.com/gitlab-org/release-webhook-example/-/releases/v1.1" }, "timestamp": "2026-02-12T20:40:00.000000000Z", "type": "gitlab.release" } ``` ## On Tag **Trigger key:** `gitlab.onTag` The On Tag trigger starts a workflow execution when tag push events occur in a GitLab project. ### Configuration - **Project** (required): GitLab project to monitor - **Tags** (required): Configure tag filters using predicates. You can match full refs (refs/tags/v1.0.0) or tag names (v1.0.0). ### Outputs - **Default channel**: Emits tag push payload data including ref, before/after SHA, and project information ### Example Data ```json { "data": { "after": "82b3d5ae55f7080f1e6022629cdb57bfae7cccc7", "before": "0000000000000000000000000000000000000000", "checkout_sha": "82b3d5ae55f7080f1e6022629cdb57bfae7cccc7", "commits": [], "event_name": "tag_push", "message": "Tag message", "object_kind": "tag_push", "project": { "avatar_url": null, "ci_config_path": null, "default_branch": "master", "description": "", "git_http_url": "http://example.com/jsmith/example.git", "git_ssh_url": "git@example.com:jsmith/example.git", "id": 1, "name": "Example", "namespace": "Jsmith", "path_with_namespace": "jsmith/example", "visibility_level": 0, "web_url": "http://example.com/jsmith/example" }, "push_options": {}, "ref": "refs/tags/v1.0.0", "ref_protected": true, "repository": { "description": "", "git_http_url": "http://example.com/jsmith/example.git", "git_ssh_url": "git@example.com:jsmith/example.git", "homepage": "http://example.com/jsmith/example", "name": "Example", "url": "ssh://git@example.com/jsmith/example.git", "visibility_level": 0 }, "total_commits_count": 0, "user_email": "john@example.com", "user_id": 1, "user_name": "John Smith", "user_username": "jsmith" }, "timestamp": "2026-02-12T20:40:00.000000000Z", "type": "gitlab.tag" } ``` ## On Vulnerability **Trigger key:** `gitlab.onVulnerability` The On Vulnerability trigger starts a workflow execution when vulnerability events occur in a GitLab project. ### Configuration - **Project** (required): GitLab project to monitor ### Outputs - **Default channel**: Emits vulnerability payload data including severity, state, location, and linked issues ### Example Data ```json { "data": { "object_attributes": { "auto_resolved": false, "confidence": "unknown", "confidence_overridden": false, "confirmed_at": "2025-01-08T00:46:14.413Z", "confirmed_by_id": 1, "created_at": "2025-01-08T00:46:14.413Z", "cvss": [ { "vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H", "vendor": "NVD" } ], "dismissed_at": null, "dismissed_by_id": null, "identifiers": [ { "external_id": "29dce398-220a-4315-8c84-16cd8b6d9b05", "external_type": "gemnasium", "name": "Gemnasium-29dce398-220a-4315-8c84-16cd8b6d9b05", "url": "https://gitlab.com/gitlab-org/security-products/gemnasium-db/-/blob/master/gem/rexml/CVE-2024-41123.yml" }, { "external_id": "CVE-2024-41123", "external_type": "cve", "name": "CVE-2024-41123", "url": "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-41123" } ], "issues": [ { "created_at": "2025-01-08T00:46:14.429Z", "title": "REXML ReDoS vulnerability", "updated_at": "2025-01-08T00:46:14.429Z", "url": "https://example.com/flightjs/Flight/-/issues/1" } ], "location": { "dependency": { "package": { "name": "rexml" }, "version": "3.3.1" }, "file": "Gemfile.lock" }, "project_id": 1, "report_type": "dependency_scanning", "resolved_at": null, "resolved_by_id": null, "resolved_on_default_branch": false, "severity": "high", "severity_overridden": false, "state": "confirmed", "title": "REXML DoS vulnerability", "updated_at": "2025-01-08T00:46:14.413Z", "url": "https://example.com/flightjs/Flight/-/security/vulnerabilities/1" }, "object_kind": "vulnerability" }, "timestamp": "2026-02-12T20:40:00.000000000Z", "type": "gitlab.vulnerability" } ``` ## Create Issue **Component key:** `gitlab.createIssue` The Create Issue component creates a new issue in a specified GitLab project. ### Use Cases - **Automated Bug Reporting**: Create issues when a monitoring system detects an error - **Task Management**: Automatically create tasks for new employee onboarding - **Feedback Loop**: Turn customer feedback into actionable issues ### Configuration - **Project** (required): The GitLab project where the issue will be created - **Title** (required): The title of the new issue - **Description** (optional): The description/body of the issue - **Assignees** (optional): Users to assign the issue to - **Labels** (optional): Labels to apply to the issue (e.g., bug, enhancement) - **Milestone** (optional): Milestone to associate with the issue - **Due Date** (optional): Date when the issue is due ### Output The component outputs the created issue object, including: - **id**: The internal ID of the issue - **iid**: The project-relative ID of the issue - **web_url**: The URL to view the issue in GitLab - **state**: The current state of the issue (opened/closed) ### Example Output ```json { "data": { "_links": { "award_emoji": "http://gitlab.example.com/api/v4/projects/1/issues/1/award_emoji", "notes": "http://gitlab.example.com/api/v4/projects/1/issues/1/notes", "project": "http://gitlab.example.com/api/v4/projects/1", "self": "http://gitlab.example.com/api/v4/projects/1/issues/1" }, "assignee": { "avatar_url": "https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80\u0026d=identicon", "id": 1, "name": "Administrator", "state": "active", "username": "root", "web_url": "http://gitlab.example.com/root" }, "assignees": [ { "avatar_url": "https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80\u0026d=identicon", "id": 1, "name": "Administrator", "state": "active", "username": "root", "web_url": "http://gitlab.example.com/root" } ], "author": { "avatar_url": "https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80\u0026d=identicon", "id": 1, "name": "Administrator", "state": "active", "username": "root", "web_url": "http://gitlab.example.com/root" }, "blocking_issues_count": 0, "closed_at": null, "closed_by": null, "confidential": false, "created_at": "2023-01-01T10:00:00.000Z", "description": "This is an example issue created via SuperPlane", "discussion_locked": null, "downvotes": 0, "due_date": null, "has_tasks": false, "id": 1, "iid": 1, "issue_type": "issue", "labels": [ "bug", "urgent" ], "merge_requests_count": 0, "milestone": null, "project_id": 3, "references": { "full": "gitlab-org/gitlab-test#1", "relative": "#1", "short": "#1" }, "state": "opened", "task_completion_status": { "completed_count": 0, "count": 0 }, "time_stats": { "human_time_estimate": null, "human_total_time_spent": null, "time_estimate": 0, "total_time_spent": 0 }, "title": "Example Issue", "type": "ISSUE", "updated_at": "2023-01-01T10:00:00.000Z", "upvotes": 0, "user_notes_count": 0, "web_url": "http://gitlab.example.com/gitlab-org/gitlab-test/issues/1", "weight": null }, "timestamp": "2023-01-01T10:00:00.000Z", "type": "gitlab.issue" } ``` ## Get Latest Pipeline **Component key:** `gitlab.getLatestPipeline` The Get Latest Pipeline component retrieves the newest pipeline for a GitLab project. ### Configuration - **Project** (required): The GitLab project to query - **Ref** (optional): Branch or tag to scope the latest pipeline search ### Example Output ```json { "data": { "before_sha": "f4f6c5a0d2e5ad34be4c17c3f166f4d2ff8b0a55", "committed_at": "2026-02-13T19:20:45.000Z", "coverage": "87.1", "created_at": "2026-02-13T19:21:00.000Z", "detailed_status": { "group": "success", "has_details": true, "icon": "status_success", "label": "passed", "text": "passed", "tooltip": "passed" }, "duration": 268, "finished_at": "2026-02-13T19:25:43.000Z", "id": 457882200, "iid": 9822, "project_id": 123456, "queued_duration": 12.6, "ref": "main", "sha": "afce89e8d28741d4f65ec71ad0a4174a801122cd", "source": "merge_request_event", "started_at": "2026-02-13T19:21:15.000Z", "status": "success", "tag": false, "updated_at": "2026-02-13T19:25:43.000Z", "user": { "avatar_url": "https://www.gravatar.com/avatar/ef56gh78", "id": 18, "name": "Alex Garcia", "username": "agarcia" }, "web_url": "https://gitlab.com/group/example-project/-/pipelines/457882200", "yaml_errors": null }, "timestamp": "2026-02-13T19:25:43.000Z", "type": "gitlab.pipeline" } ``` ## Get Pipeline **Component key:** `gitlab.getPipeline` The Get Pipeline component retrieves details for a specific GitLab pipeline. ### Configuration - **Project** (required): The GitLab project containing the pipeline - **Pipeline** (required): Select a pipeline from the selected project ### Output Returns pipeline data including status, ref, SHA, and pipeline URL. ### Example Output ```json { "data": { "before_sha": "0000000000000000000000000000000000000000", "committed_at": "2026-02-13T17:59:22.000Z", "coverage": null, "created_at": "2026-02-13T18:00:00.000Z", "detailed_status": { "group": "running", "has_details": true, "icon": "status_running", "label": "running", "text": "running", "tooltip": "running" }, "duration": 0, "finished_at": null, "id": 457882113, "iid": 9821, "project_id": 123456, "queued_duration": 8.2, "ref": "main", "sha": "f4f6c5a0d2e5ad34be4c17c3f166f4d2ff8b0a55", "source": "push", "started_at": "2026-02-13T18:00:12.000Z", "status": "running", "tag": false, "updated_at": "2026-02-13T18:00:10.000Z", "user": { "avatar_url": "https://www.gravatar.com/avatar/abc123", "id": 22, "name": "Jamie Rivera", "username": "jrivera" }, "web_url": "https://gitlab.com/group/example-project/-/pipelines/457882113", "yaml_errors": null }, "timestamp": "2026-02-13T18:00:10.000Z", "type": "gitlab.pipeline" } ``` ## Get Test Report Summary **Component key:** `gitlab.getTestReportSummary` The Get Test Report Summary component fetches the test report summary for a GitLab pipeline. ### Configuration - **Project** (required): The GitLab project containing the pipeline - **Pipeline** (required): Select a pipeline from the selected project ### Example Output ```json { "data": { "test_suites": [ { "build_ids": [ 8934210 ], "error_count": 0, "failed_count": 1, "name": "backend-rspec", "skipped_count": 0, "success_count": 247, "suite_error": null, "total_count": 248, "total_time": 81.27 }, { "build_ids": [ 8934211 ], "error_count": 0, "failed_count": 1, "name": "frontend-jest", "skipped_count": 1, "success_count": 162, "suite_error": null, "total_count": 164, "total_time": 71.19 } ], "total": { "count": 412, "error": 0, "failed": 2, "skipped": 1, "success": 409, "suite_error": null, "time": 152.46 } }, "timestamp": "2026-02-13T19:26:01.000Z", "type": "gitlab.testReportSummary" } ``` ## Run Pipeline **Component key:** `gitlab.runPipeline` The Run Pipeline component triggers a GitLab pipeline and waits for it to complete. ### Use Cases - **CI/CD orchestration**: Trigger GitLab pipelines from SuperPlane workflows - **Deployment automation**: Run deployment pipelines with inputs - **Pipeline chaining**: Coordinate follow-up actions after pipeline completion ### Example Output ```json { "data": { "pipeline": { "before_sha": "0000000000000000000000000000000000000000", "committed_at": "2026-02-13T17:59:22.000Z", "coverage": "86.5", "created_at": "2026-02-13T18:00:00.000Z", "detailed_status": { "group": "success", "has_details": true, "icon": "status_success", "label": "passed", "text": "passed", "tooltip": "passed" }, "duration": 240, "finished_at": "2026-02-13T18:04:12.000Z", "id": 457882113, "iid": 9821, "project_id": 123456, "queued_duration": 8.2, "ref": "main", "sha": "f4f6c5a0d2e5ad34be4c17c3f166f4d2ff8b0a55", "source": "web", "started_at": "2026-02-13T18:00:12.000Z", "status": "success", "tag": false, "updated_at": "2026-02-13T18:04:12.000Z", "url": "https://gitlab.com/group/example-project/-/pipelines/457882113", "user": { "avatar_url": "https://www.gravatar.com/avatar/abc123", "id": 22, "name": "Jamie Rivera", "username": "jrivera" }, "web_url": "https://gitlab.com/group/example-project/-/pipelines/457882113", "yaml_errors": null } }, "timestamp": "2026-02-13T18:04:12.000Z", "type": "gitlab.pipeline.finished" } ``` #### Google Cloud Source URL: https://docs.superplane.com/components/googlecloud Manage and use Google Cloud resources in your workflows import { CardGrid, LinkCard } from "@astrojs/starlight/components"; ## Triggers ## Actions ## Instructions ## Connection method ### Service Account Key 1. Go to [IAM & Admin → Service Accounts](https://console.cloud.google.com/iam-admin/serviceaccounts) in the Google Cloud Console. 2. Select a service account → **Keys** → **Add Key** → **JSON**. 3. Paste the downloaded JSON below. ### Workload Identity Federation (keyless) 1. Create a [Workload Identity Pool](https://cloud.google.com/iam/docs/workload-identity-federation) with an OIDC provider. 2. Set the **Issuer URL** to this SuperPlane instance's URL. 3. Set the **Audience** to the pool provider resource name. 4. Grant the federated identity permission to [impersonate a service account](https://cloud.google.com/iam/docs/workload-identity-federation-with-other-providers#mapping) with the roles your workflows need. 5. Enter the **pool provider resource name** and **Project ID** below. ## Required IAM roles - `roles/logging.configWriter` — create logging sinks for event triggers - `roles/pubsub.admin` — manage Pub/Sub topics, subscriptions, and IAM policies for event delivery - Additional roles depending on which components you use (e.g. `roles/compute.admin` for VM management, `roles/monitoring.viewer` to read VM metrics, `roles/cloudsql.admin` to manage Cloud SQL databases and instances) ## Artifact Registry • On Artifact Analysis **Trigger key:** `gcp.artifactregistry.onArtifactAnalysis` The On Artifact Analysis trigger starts a workflow execution when Google Container Analysis publishes a new occurrence (e.g. vulnerability finding, build provenance, or attestation) for an artifact. **Trigger behavior:** SuperPlane subscribes to the `container-analysis-occurrences-v1` Pub/Sub topic that Container Analysis automatically publishes to. ### Use Cases - **Security automation**: React to new vulnerability findings for your container images - **Compliance workflows**: Trigger policy enforcement when attestations are created - **Build provenance**: React to new build provenance records ### Setup **Required GCP setup:** Ensure the **Container Analysis API** (`containeranalysis.googleapis.com`) and **Pub/Sub API** are enabled in your project. The service account must have `roles/pubsub.admin` and `roles/containeranalysis.occurrences.viewer`. ### Configuration - **Occurrence Kinds**: Filter by occurrence type. Leave empty to receive only **DISCOVERY** occurrences (one event per completed scan — recommended). Set explicitly to receive other types such as VULNERABILITY (one event per CVE found). - **Location / Repository / Package**: Optional filters to scope events to a specific artifact. ### Event Data Each event contains the full Container Analysis Occurrence resource, including `kind`, `resourceUri`, `noteName`, and the occurrence-specific data (e.g. `vulnerability` for vulnerability findings). ### Example Data ```json { "data": { "kind": "VULNERABILITY", "name": "projects/my-project/occurrences/vuln-001", "noteName": "projects/goog-vulnz/notes/CVE-2023-1234", "resourceUri": "https://us-central1-docker.pkg.dev/my-project/my-repo/my-image@sha256:abc123", "vulnerability": { "cvssScore": 7.5, "packageIssue": [ { "affectedPackage": "libssl1.1", "affectedVersion": { "kind": "NORMAL", "name": "1.1.1n-0+deb11u3" }, "fixedVersion": { "kind": "NORMAL", "name": "1.1.1n-0+deb11u5" } } ], "severity": "HIGH" } }, "timestamp": "2025-01-01T00:00:00Z", "type": "gcp.artifactregistry.artifact.analysis" } ``` ## Artifact Registry • On Artifact Push **Trigger key:** `gcp.artifactregistry.onArtifactPush` The On Artifact Push trigger starts a workflow execution when a Docker image or other container artifact is pushed to Artifact Registry. **Trigger behavior:** SuperPlane subscribes to the `gcr` Pub/Sub topic that Artifact Registry automatically publishes to for container image push events. ### Use Cases - **Post-push automation**: Trigger vulnerability scans, deployments, or notifications when a new image is pushed - **Release workflows**: Promote artifacts through environments when a new tag is published - **Security automation**: Kick off container analysis on every new push ### Setup **Required GCP setup:** Ensure the **Artifact Registry API** and **Pub/Sub API** are enabled in your project. The service account must have `roles/pubsub.admin` so SuperPlane can create the push subscription. ### Configuration - **Location**: Optional filter by Artifact Registry location. Leave empty to receive events for all locations. - **Repository**: Optional filter by repository name. Leave empty to receive events for all repositories. ### Event Data Each event contains: - `action`: Always `INSERT` for pushes - `digest`: Full image digest URI (e.g. `us-central1-docker.pkg.dev/project/repo/image@sha256:abc`) - `tag`: Full image tag URI (e.g. `us-central1-docker.pkg.dev/project/repo/image:latest`) ### Example Data ```json { "data": { "action": "INSERT", "digest": "https://us-central1-docker.pkg.dev/my-project/my-repo/my-image@sha256:abc123def456", "tag": "https://us-central1-docker.pkg.dev/my-project/my-repo/my-image:latest" }, "timestamp": "2025-01-01T00:00:00Z", "type": "gcp.artifactregistry.artifact.push" } ``` ## Cloud Build • On Build Complete **Trigger key:** `gcp.cloudbuild.onBuildComplete` The On Build Complete trigger starts a workflow execution when a GCP Cloud Build build finishes. **Trigger behavior:** SuperPlane subscribes to the `cloud-builds` Pub/Sub topic that Cloud Build automatically publishes to. Build notifications are pushed to SuperPlane and matched to this trigger. ### Use Cases - **Post-build automation**: Deploy artifacts, send notifications, or update tickets after a build succeeds - **Failure handling**: Alert teams or create incidents when builds fail - **Build pipelines**: Chain multiple build steps across different projects ### Setup **Required GCP setup:** Ensure the **Cloud Build API** and **Pub/Sub API** are enabled in your project. The service account used by the integration must have `roles/pubsub.admin` so SuperPlane can automatically create the `cloud-builds` topic and its push subscription. ### Configuration - **Statuses**: Filter by terminal Cloud Build status. - **Build Source**: Optionally limit events to trigger-based builds or direct/API builds. Leave empty to listen to both. - **Cloud Build Trigger**: Filter to a specific Cloud Build trigger. This only applies to trigger-based builds and cannot be combined with **Build Source = Direct/API Builds**. ### Event Data Each event contains the full Cloud Build resource, including `id`, `status` (SUCCESS, FAILURE, INTERNAL_ERROR, TIMEOUT, CANCELLED, EXPIRED), `buildTriggerId`, `logUrl`, `createTime`, `finishTime`, and more. ### Example Data ```json { "data": { "buildTriggerId": "abcdefgh-1234-5678-abcd-123456789012", "createTime": "2025-01-01T00:00:00Z", "finishTime": "2025-01-01T00:05:00Z", "id": "12345678-abcd-1234-5678-abcdef012345", "logUrl": "https://console.cloud.google.com/cloud-build/builds/12345678-abcd-1234-5678-abcdef012345", "projectId": "my-project", "status": "SUCCESS" }, "timestamp": "2025-01-01T00:05:00Z", "type": "gcp.cloudbuild.build" } ``` ## Compute • On VM Instance **Trigger key:** `gcp.compute.onVMInstance` The On VM Instance trigger starts a workflow execution when a Compute Engine VM instance lifecycle event occurs. **Trigger behavior:** SuperPlane creates a Cloud Logging sink that captures Compute Engine audit log events and routes them to a shared Pub/Sub topic. Events are pushed to SuperPlane and matched to this trigger automatically. ### Use Cases - **Post-provisioning automation**: Run configuration, monitoring, or security setup after a VM is created - **Inventory and compliance**: Record new VMs or trigger audits - **Notifications**: Notify teams or systems when new VMs appear in a project or zone ### Setup **Required GCP setup:** Ensure the **Pub/Sub** API is enabled in your project and the integration's service account has `roles/logging.configWriter` and `roles/pubsub.admin` permissions. SuperPlane automatically creates a Cloud Logging sink to capture VM instance events. ### Event Data Each event includes the audit log entry with resourceName (e.g. projects/my-project/zones/us-central1-a/instances/my-vm), serviceName (compute.googleapis.com), methodName (v1.compute.instances.insert), and the full log entry data. ### Example Data ```json { "data": { "data": { "protoPayload": { "methodName": "v1.compute.instances.insert", "resourceName": "projects/my-project/zones/us-central1-a/instances/my-vm", "serviceName": "compute.googleapis.com" } }, "logName": "projects/my-project/logs/cloudaudit.googleapis.com%2Factivity", "methodName": "v1.compute.instances.insert", "resourceName": "projects/my-project/zones/us-central1-a/instances/my-vm", "serviceName": "compute.googleapis.com", "timestamp": "2025-02-14T12:00:00Z" }, "timestamp": "2025-02-14T12:00:00Z", "type": "gcp.compute.vmInstance" } ``` ## Monitoring • On Alert **Trigger key:** `gcp.monitoring.onAlert` The On Alert trigger starts a workflow execution when a Cloud Monitoring alerting policy fires (opens) or resolves (closes) an incident. ### Trigger behavior When this trigger is set up, SuperPlane automatically creates a **webhook notification channel** in Cloud Monitoring that points back at SuperPlane. Cloud Monitoring POSTs the incident to SuperPlane whenever a policy attached to that channel changes state. To route a policy's incidents here, attach this trigger's notification channel to the policy via the **Create Alerting Policy** or **Update Alerting Policy** component's *Notification Channels* field. The channel's resource name is shown on the node after setup. ### Configuration - **States**: Which incident states to emit on — `open` (fired) and/or `closed` (resolved). Defaults to `open`. ### Event Data Emits one `gcp.monitoring.alert` event per matching incident, including the incident id, state, policy and condition names, the affected resource and metric, the observed/threshold values, and the incident URL. ### Important Notes - Requires the `roles/monitoring.notificationChannelEditor` (or `roles/monitoring.editor`) IAM role so SuperPlane can create the webhook channel. - Removing the trigger deletes the webhook notification channel it created. ### Example Data ```json { "data": { "conditionName": "CPU utilization above threshold", "incidentId": "0.abcdef1234567890", "metricDisplayName": "CPU utilization", "metricType": "compute.googleapis.com/instance/cpu/utilization", "observedValue": "0.93", "policyName": "projects/my-project/alertPolicies/1234567890123456789", "resourceDisplayName": "my-vm", "resourceName": "my-vm", "scopingProjectId": "my-project", "startedAt": 1767225600, "state": "open", "summary": "CPU utilization for gce_instance my-vm is above the threshold of 0.8 with a value of 0.93.", "thresholdValue": "0.8", "url": "https://console.cloud.google.com/monitoring/alerting/incidents/0.abcdef1234567890?project=my-project" }, "timestamp": "2026-01-01T00:00:00Z", "type": "gcp.monitoring.alert" } ``` ## Pub/Sub • On Message **Trigger key:** `gcp.pubsub.onMessage` The On Message trigger starts a workflow execution when a message is published to a GCP Pub/Sub topic. **Trigger behavior:** SuperPlane creates a push subscription on the selected topic. Published messages are pushed to SuperPlane and delivered to this trigger. ### Use Cases - **Event-driven workflows**: React to messages published by your applications - **Queue processing**: Process tasks published to Pub/Sub topics - **System integration**: Connect Pub/Sub events to downstream workflow steps ### Setup **Required GCP setup:** Ensure the **Pub/Sub API** is enabled in your project. The service account used by the integration must have `roles/pubsub.admin` to create push subscriptions on your topics. ### Configuration - **Topic**: Select the Pub/Sub topic to listen to. - **Subscription (optional)**: Reuse an existing subscription name. Leave empty to let SuperPlane create one. ### Event Data Each event contains the decoded message payload plus Pub/Sub metadata: - `data`: The decoded message body - `messageId`: The Pub/Sub message ID - `publishTime`: When the message was published - `attributes`: Any message attributes ### Example Data ```json { "data": { "attributes": { "eventType": "order.created" }, "data": "{\"event\":\"order.created\",\"orderId\":\"ord_abc123\"}", "messageId": "1234567890", "publishTime": "2025-01-01T00:00:00Z" }, "timestamp": "2025-01-01T00:00:00Z", "type": "gcp.pubsub.message" } ``` ## Artifact Registry • Get Artifact **Component key:** `gcp.artifactregistry.getArtifact` Retrieves the details of a specific artifact version from Google Artifact Registry. ### Configuration Provide either a **Resource URL** or the four fields below: - **Resource URL**: Full resource URL of the image (e.g. `https://us-central1-docker.pkg.dev/project/repo/image@sha256:abc`). Use this to pass a digest directly from an upstream event such as On Artifact Push. - **Location**: The GCP region where the repository is located. - **Repository**: The Artifact Registry repository containing the artifact. - **Package**: The package (image, library, etc.) within the repository. - **Version**: The version or tag to retrieve. ### Output The full Version resource, including `name`, `createTime`, `updateTime`, `description`, `relatedTags`, and `metadata`. ### Supported Formats Artifact Registry supports all package formats when using **Select from Registry** mode. **Resource URL** mode is intended for container image URLs (for example from On Artifact Push events). ### Example Output ```json { "data": { "createTime": "2025-01-01T00:00:00Z", "description": "my-image:latest", "fingerprints": [ { "type": "DIRSUM_SHA256", "value": "Ac2PwnIxFXnnS6DfUou2JchB7F+krMAKv4f6sJr8VzM=" } ], "metadata": { "buildTime": "1980-01-01T00:00:01Z", "imageSizeBytes": "20971520", "mediaType": "application/vnd.docker.distribution.manifest.v2+json", "name": "projects/my-project/locations/us-central1/repositories/my-repo/dockerImages/my-image@sha256:abc123def456" }, "name": "projects/my-project/locations/us-central1/repositories/my-repo/packages/my-image/versions/sha256:abc123def456", "updateTime": "2025-01-01T00:05:00Z" }, "timestamp": "2025-01-01T00:05:00Z", "type": "gcp.artifactregistry.version" } ``` ## Artifact Registry • Get Artifact Analysis **Component key:** `gcp.artifactregistry.getArtifactAnalysis` Retrieves existing Container Analysis occurrences for an artifact from Google Container Analysis. ### Configuration Provide either a **Resource URL** or the four fields below: - **Resource URL**: Full resource URL of the image (e.g. `https://us-central1-docker.pkg.dev/project/repo/image@sha256:abc`). Use this to pass a digest directly from an upstream event such as On Artifact Push. - **Location**: The GCP region where the repository is located. - **Repository**: The Artifact Registry repository containing the artifact. - **Package**: The package (image) within the repository. - **Version**: The version (digest) to query. ### Output An analysis summary for the artifact, including: - `resourceUri`: The analyzed artifact URI - `scanStatus`: Discovery scan status (if available) - Severity counts: `critical`, `high`, `medium`, `low` - `vulnerabilities`: Total vulnerability occurrences - `fixAvailable`: Count of vulnerabilities with fixes ### Notes - The **Container Analysis API** (`containeranalysis.googleapis.com`) must be enabled. - The service account needs `roles/containeranalysis.occurrences.viewer`. - This summarizes existing occurrences for the selected artifact. ### Example Output ```json { "data": { "critical": 0, "fixAvailable": 1, "high": 1, "low": 0, "medium": 2, "resourceUri": "https://us-central1-docker.pkg.dev/my-project/my-repo/my-image@sha256:abc123", "scanStatus": "FINISHED_SUCCESS", "vulnerabilities": 3 }, "timestamp": "2025-01-01T00:05:00Z", "type": "gcp.containeranalysis.occurrences" } ``` ## Cloud Build • Create Build **Component key:** `gcp.cloudbuild.createBuild` Creates and starts a Google Cloud Build build, then waits for the build to reach a terminal status. ### Configuration - **Steps** (required): JSON array of build steps. Each step needs at minimum a `name` (builder image) and optional `args`. Example: `[{"name":"gcr.io/cloud-builders/docker","args":["build","-t","gcr.io/$PROJECT_ID/myapp","."]}]` - **Source**: Optional JSON object for the build source. This is the most flexible option and supports `gitSource`, `repoSource`, or `storageSource`. Example: `{"gitSource":{"url":"https://github.com/org/repo.git","revision":"main"}}` - **Connected Repository**: Optional Cloud Build 2nd-gen repository path. Select a location, connection, repository, and branch/tag/commit directly from GCP. SuperPlane sends `source.connectedRepository` and creates the build in the repository's region. - **Repository / Branch / Tag / Commit SHA**: Convenience shortcut for repository-backed builds. If the repository value looks like a Git URL (`https://...`, `ssh://...`, or `git@...`), SuperPlane creates `source.gitSource`. Otherwise it treats the value as a Cloud Source Repository name and creates `source.repoSource`. Choose exactly one revision field. - **Images**: Optional list of Docker image names to push after the build. - **Substitutions**: JSON object of substitution key-value pairs (e.g. `{"_ENV":"production"}`). - **Timeout**: Build timeout (e.g. `600s`). Defaults to Cloud Build default (10 minutes). - **Project ID Override**: Optionally run the build in a different project than the connected integration. ### Output The terminal Build resource, including `id`, `status`, `logUrl`, `createTime`, `finishTime`, and more. ### Output Channels - **Passed**: Emitted when Cloud Build finishes with `SUCCESS`. - **Failed**: Emitted when Cloud Build finishes with any other terminal status, including `FAILURE`, `INTERNAL_ERROR`, `TIMEOUT`, `CANCELLED`, or `EXPIRED`. ### Notes - SuperPlane listens for Cloud Build notifications through the connected GCP integration and falls back to polling if an event does not arrive. - SuperPlane automatically creates the shared `cloud-builds` Pub/Sub topic and push subscription when the GCP integration has `roles/pubsub.admin` and both the **Cloud Build** and **Pub/Sub** APIs are enabled. - Cancelling the running execution from the UI sends a Cloud Build cancel request for the active build. ### Example Output ```json { "data": { "createTime": "2025-01-01T00:00:00Z", "finishTime": "2025-01-01T00:05:00Z", "id": "12345678-abcd-1234-5678-abcdef012345", "logUrl": "https://console.cloud.google.com/cloud-build/builds/12345678-abcd-1234-5678-abcdef012345", "projectId": "my-project", "status": "SUCCESS" }, "timestamp": "2025-01-01T00:05:00Z", "type": "gcp.cloudbuild.build" } ``` ## Cloud Build • Get Build **Component key:** `gcp.cloudbuild.getBuild` Retrieves the details of a specific Google Cloud Build build. ### Configuration - **Build ID** (required): The ID or full resource name of the Cloud Build build to retrieve. - **Project ID Override**: Override the GCP project ID from the integration. ### Output The full Build resource, including `id`, `status` (SUCCESS, FAILURE, WORKING, QUEUED, etc.), `logUrl`, `steps`, `images`, `createTime`, `finishTime`, and more. ### Example Output ```json { "data": { "createTime": "2025-01-01T00:00:00Z", "finishTime": "2025-01-01T00:05:00Z", "id": "12345678-abcd-1234-5678-abcdef012345", "logUrl": "https://console.cloud.google.com/cloud-build/builds/12345678-abcd-1234-5678-abcdef012345", "projectId": "my-project", "status": "SUCCESS" }, "timestamp": "2025-01-01T00:05:00Z", "type": "gcp.cloudbuild.build" } ``` ## Cloud Build • Run Trigger **Component key:** `gcp.cloudbuild.runTrigger` Runs an existing Cloud Build trigger and waits for the resulting build to reach a terminal status. ### Configuration - **Trigger** (required): The Cloud Build trigger to run. Select from triggers in the connected project. - **Branch or tag**: Override the branch or tag to build from. Leave empty to use the trigger's configured default. A 40-character hex string is treated as a commit SHA. - **Project ID Override**: Optionally run the trigger in a different project than the connected integration. ### Output The terminal Build resource, including `id`, `status`, `logUrl`, `createTime`, `finishTime`, and more. ### Output Channels - **Passed**: Emitted when Cloud Build finishes with `SUCCESS`. - **Failed**: Emitted when Cloud Build finishes with any other terminal status, including `FAILURE`, `INTERNAL_ERROR`, `TIMEOUT`, `CANCELLED`, or `EXPIRED`. ### Notes - SuperPlane listens for Cloud Build notifications through the connected GCP integration and falls back to polling if an event does not arrive. - SuperPlane automatically creates the shared `cloud-builds` Pub/Sub topic and push subscription when the GCP integration has `roles/pubsub.admin` and both the **Cloud Build** and **Pub/Sub** APIs are enabled. - Cancelling the running execution from the UI sends a Cloud Build cancel request for the active build. ### Example Output ```json { "data": { "buildTriggerId": "abcdefgh-1234-5678-abcd-123456789012", "createTime": "2025-01-01T00:00:00Z", "finishTime": "2025-01-01T00:05:00Z", "id": "12345678-abcd-1234-5678-abcdef012345", "logUrl": "https://console.cloud.google.com/cloud-build/builds/12345678-abcd-1234-5678-abcdef012345", "projectId": "my-project", "status": "SUCCESS" }, "timestamp": "2025-01-01T00:05:00Z", "type": "gcp.cloudbuild.build" } ``` ## Cloud DNS • Create Record **Component key:** `gcp.clouddns.createRecord` The Create Record component creates a new DNS record set in a Google Cloud DNS managed zone. ### Configuration - **Managed Zone** (required): The Cloud DNS managed zone where the record will be created. - **Record Name** (required): The DNS name for the record (e.g. `api.example.com`). A trailing dot is added automatically. - **Record Type** (required): The DNS record type (A, AAAA, CNAME, TXT, MX, etc.). - **TTL** (required): Time to live in seconds. Defaults to 300. - **Record Values** (required): The values for the record (e.g. IP addresses for A records). ### Required IAM roles The service account must have `roles/dns.admin` or `roles/dns.editor` on the project. ### Output - `change.id`: The Cloud DNS change ID. - `change.status`: The change status (`done`). - `change.startTime`: When the change was submitted. - `record.name`: The DNS record name. - `record.type`: The DNS record type. ### Example Output ```json { "data": { "change": { "id": "1", "startTime": "2026-01-28T10:30:00.000Z", "status": "done" }, "record": { "name": "api.example.com.", "type": "A" } }, "timestamp": "2026-01-28T10:30:00.000Z", "type": "gcp.clouddns.change" } ``` ## Cloud DNS • Delete Record **Component key:** `gcp.clouddns.deleteRecord` The Delete Record component deletes a DNS record set from a Google Cloud DNS managed zone. ### Configuration - **Managed Zone** (required): The Cloud DNS managed zone containing the record. - **Record Name** (required): The DNS name of the record to delete (e.g. `api.example.com`). - **Record Type** (optional): The DNS record type to delete (A, AAAA, CNAME, TXT, MX, etc.). If not specified, all record sets with the given name are deleted. ### Required IAM roles The service account must have `roles/dns.admin` or `roles/dns.editor` on the project. ### Output - `change.id`: The Cloud DNS change ID. - `change.status`: The change status (`done`). - `change.startTime`: When the change was submitted. - `record.name`: The DNS record name. - `record.type`: The DNS record type (comma-separated when multiple types were deleted). ### Example Output ```json { "data": { "change": { "id": "2", "startTime": "2026-01-28T10:31:00.000Z", "status": "done" }, "record": { "name": "old.example.com.", "type": "A" } }, "timestamp": "2026-01-28T10:31:00.000Z", "type": "gcp.clouddns.change" } ``` ## Cloud DNS • Update Record **Component key:** `gcp.clouddns.updateRecord` The Update Record component updates an existing DNS record set in a Google Cloud DNS managed zone. ### Configuration - **Managed Zone** (required): The Cloud DNS managed zone containing the record. - **Record Name** (required): The DNS name of the record to update (e.g. `api.example.com`). - **Record Type** (required): The DNS record type (A, AAAA, CNAME, TXT, MX, etc.). - **TTL** (required): New time to live in seconds. - **Record Values** (required): The new values for the record. ### Required IAM roles The service account must have `roles/dns.admin` or `roles/dns.editor` on the project. ### Output - `change.id`: The Cloud DNS change ID. - `change.status`: The change status (`done`). - `change.startTime`: When the change was submitted. - `record.name`: The DNS record name. - `record.type`: The DNS record type. ### Example Output ```json { "data": { "change": { "id": "3", "startTime": "2026-01-28T10:32:00.000Z", "status": "done" }, "record": { "name": "api.example.com.", "type": "A" } }, "timestamp": "2026-01-28T10:32:00.000Z", "type": "gcp.clouddns.change" } ``` ## Cloud Functions • Invoke Function **Component key:** `gcp.cloudfunctions.invokeFunction` Invokes a Google Cloud Function and waits for the response. ### Configuration - **Location** (required): The GCP region where the function is deployed (e.g. `us-central1`). - **Function** (required): The Cloud Function to invoke. Select from the list of deployed functions. - **Payload**: Optional JSON object sent as the function's input data. - **Project ID Override**: Override the GCP project ID from the integration. Leave empty to use the integration's project. ### Required IAM roles The service account used by the integration must have `roles/cloudfunctions.developer` (or `roles/cloudfunctions.viewer` + `roles/cloudfunctions.invoker`) on the project. - `roles/cloudfunctions.viewer` — list locations and functions (required for dropdowns) - `roles/cloudfunctions.invoker` — invoke the function - `roles/cloudfunctions.developer` — covers both of the above ### Output The invocation result, including: - `functionName`: Full resource name of the invoked function. - `executionId`: Unique ID assigned to this invocation. - `result`: The function's response, parsed as JSON when possible. - `resultRaw`: The raw string response (only present when the response is not valid JSON). ### Example Output ```json { "data": { "executionId": "h7g2k9qw3x", "functionName": "projects/my-project/locations/us-central1/functions/my-function", "result": { "message": "Hello, World!", "status": "ok" } }, "timestamp": "2025-01-01T00:00:05Z", "type": "gcp.cloudfunctions.invoke" } ``` ## Cloud SQL • Create Database **Component key:** `gcp.cloudsql.createDatabase` The Create Database component adds a new logical database to an existing Cloud SQL instance. ### Use Cases - **Application bootstrap**: Create an application-specific database as part of environment setup - **Tenant provisioning**: Add a dedicated database for a new customer or workspace - **Migration workflows**: Prepare a destination database before importing data ### Configuration - **Instance**: The Cloud SQL instance that will contain the new database (required) - **Database Name**: The name of the database to create (required, supports expressions) ### Output Emits a `gcp.cloudsql.database` payload with the created database's `name`, `instance`, `project`, `charset`, `collation`, and `selfLink`. ### Important Notes - Requires the `roles/cloudsql.admin` (or `roles/cloudsql.editor`) IAM role on the integration's service account, and the **Cloud SQL Admin API** enabled - Cloud SQL database creation is asynchronous; this component waits for the operation to finish before emitting ### Example Output ```json { "data": { "charset": "UTF8", "collation": "en_US.UTF8", "instance": "my-instance", "name": "app_db", "project": "my-project", "selfLink": "https://sqladmin.googleapis.com/v1/projects/my-project/instances/my-instance/databases/app_db" }, "timestamp": "2025-01-01T00:00:00Z", "type": "gcp.cloudsql.database" } ``` ## Cloud SQL • Create Instance **Component key:** `gcp.cloudsql.createInstance` The Create Instance component provisions a new Cloud SQL instance. ### Use Cases - **Environment setup**: Stand up a database server as part of provisioning an environment - **Ephemeral environments**: Create a dedicated instance for a preview or test run - **Infrastructure automation**: Provision databases as part of a broader workflow ### Configuration - **Name**: The instance ID (required) - **Database Version**: The database engine and version (required) - **Region**: The region to create the instance in, chosen from the regions where Cloud SQL is available - **Tier**: The machine tier (size), chosen from the predefined tiers available in the selected region. Custom machine types (`db-custom-*`) are not listed. - **Disk Size (GB)**: The data disk size (minimum 10) - **Disk Type**: SSD (default) or HDD - **Edition**: Enterprise or Enterprise Plus - **Availability**: Zonal (single zone, default) or Regional (adds a standby in another zone for high availability) - **Root Password**: Initial password for the default admin user (optional, stored as a secret) - **Assign Public IP**: Whether to give the instance a public IPv4 address (default yes) - **SSL Mode**: How the instance enforces SSL/TLS on incoming connections (optional) - **Authorized Networks**: CIDR ranges allowed to connect over the public IP (optional) - **Automated Backups**: Enable daily automated backups (optional) - **Deletion Protection**: Prevent the instance from being deleted until protection is removed (optional) - **Labels**: Key-value labels applied to the instance (optional) ### Output Emits a `gcp.cloudsql.instance` payload with the ready instance's `name`, `state`, `databaseVersion`, `region`, `tier`, `connectionName`, `ipAddress`, and `selfLink`. ### Important Notes - **Instance creation is asynchronous and takes several minutes.** This component polls the instance until it reaches `RUNNABLE` (or times out) before emitting, so downstream steps run only once the instance is ready. - A public IP with no **Authorized Networks** is reachable only through the Cloud SQL Auth Proxy or private access; add CIDR ranges to allow direct external clients. - With **Deletion Protection** enabled, the Delete Instance component will fail until protection is removed. - Requires the `roles/cloudsql.admin` (or `roles/cloudsql.editor`) IAM role, and the **Cloud SQL Admin API** enabled. ### Example Output ```json { "data": { "connectionName": "my-project:us-central1:my-instance", "databaseVersion": "POSTGRES_16", "diskSizeGb": "10", "edition": "ENTERPRISE", "ipAddress": "34.41.10.20", "name": "my-instance", "region": "us-central1", "selfLink": "https://sqladmin.googleapis.com/v1/projects/my-project/instances/my-instance", "state": "RUNNABLE", "tier": "db-f1-micro" }, "timestamp": "2025-01-01T00:00:00Z", "type": "gcp.cloudsql.instance" } ``` ## Cloud SQL • Delete Database **Component key:** `gcp.cloudsql.deleteDatabase` The Delete Database component permanently deletes a logical database from a Cloud SQL instance. ### Use Cases - **Teardown**: Remove a database as part of decommissioning an environment - **Tenant offboarding**: Delete a customer's dedicated database - **Cleanup**: Drop temporary databases created during a workflow ### Configuration - **Instance**: The Cloud SQL instance that contains the database (required) - **Database**: The database to delete (required) ### Output Emits a `gcp.cloudsql.database` payload with the deleted database's `name` and `instance`, and `deleted: true`. ### Important Notes - **This permanently deletes the database and all its data — it is irreversible.** - Requires the `roles/cloudsql.admin` (or `roles/cloudsql.editor`) IAM role on the integration's service account, and the **Cloud SQL Admin API** enabled - Cloud SQL database deletion is asynchronous; this component waits for the operation to finish before emitting ### Example Output ```json { "data": { "deleted": true, "instance": "my-instance", "name": "app_db" }, "timestamp": "2025-01-01T00:00:00Z", "type": "gcp.cloudsql.database" } ``` ## Cloud SQL • Delete Instance **Component key:** `gcp.cloudsql.deleteInstance` The Delete Instance component permanently deletes a Cloud SQL instance. ### Use Cases - **Teardown**: Remove an instance when decommissioning an environment - **Ephemeral cleanup**: Delete a preview/test instance when it is no longer needed ### Configuration - **Instance**: The Cloud SQL instance to delete (required) ### Output Emits a `gcp.cloudsql.instance` payload with the instance `name` and `deleted: true`. ### Important Notes - **This permanently deletes the instance and all its databases and data — it is irreversible.** - Instance deletion is asynchronous and takes several minutes; this component polls until the instance is fully deleted (or times out) before emitting. - Requires the `roles/cloudsql.admin` (or `roles/cloudsql.editor`) IAM role, and the **Cloud SQL Admin API** enabled. ### Example Output ```json { "data": { "deleted": true, "name": "my-instance" }, "timestamp": "2025-01-01T00:00:00Z", "type": "gcp.cloudsql.instance" } ``` ## Cloud SQL • Get Database **Component key:** `gcp.cloudsql.getDatabase` The Get Database component retrieves a logical database from a Cloud SQL instance. ### Use Cases - **Existence checks**: Confirm a database is present before acting on it - **Enrichment**: Read a database's charset/collation to feed a downstream step - **Auditing**: Capture database details as part of a workflow ### Configuration - **Instance**: The Cloud SQL instance that contains the database (required) - **Database**: The database to fetch (required) ### Output Emits a `gcp.cloudsql.database` payload with the database's `name`, `instance`, `project`, `charset`, `collation`, and `selfLink`. ### Important Notes - Requires the `roles/cloudsql.viewer` (or `roles/cloudsql.admin`) IAM role on the integration's service account, and the **Cloud SQL Admin API** enabled ### Example Output ```json { "data": { "charset": "UTF8", "collation": "en_US.UTF8", "instance": "my-instance", "name": "app_db", "project": "my-project", "selfLink": "https://sqladmin.googleapis.com/v1/projects/my-project/instances/my-instance/databases/app_db" }, "timestamp": "2025-01-01T00:00:00Z", "type": "gcp.cloudsql.database" } ``` ## Cloud SQL • Get Instance **Component key:** `gcp.cloudsql.getInstance` The Get Instance component retrieves a Cloud SQL instance's configuration and current status. ### Use Cases - **Readiness polling**: After Create Instance, poll until the instance reaches `RUNNABLE` - **Enrichment**: Read the connection name or IP address to feed a downstream step - **Auditing**: Capture instance details as part of a workflow ### Configuration - **Instance**: The Cloud SQL instance to fetch (required) ### Output Emits a `gcp.cloudsql.instance` payload with the instance `name`, `state`, `databaseVersion`, `region`, `tier`, `connectionName`, `ipAddress`, and `selfLink`. ### Important Notes - Requires the `roles/cloudsql.viewer` (or `roles/cloudsql.admin`) IAM role, and the **Cloud SQL Admin API** enabled. ### Example Output ```json { "data": { "connectionName": "my-project:us-central1:my-instance", "databaseVersion": "POSTGRES_16", "diskSizeGb": "10", "edition": "ENTERPRISE", "ipAddress": "34.41.10.20", "name": "my-instance", "region": "us-central1", "selfLink": "https://sqladmin.googleapis.com/v1/projects/my-project/instances/my-instance", "state": "RUNNABLE", "tier": "db-f1-micro" }, "timestamp": "2025-01-01T00:00:00Z", "type": "gcp.cloudsql.instance" } ``` ## Compute • Create Load Balancer **Component key:** `gcp.compute.createLoadBalancer` The Create Load Balancer component builds a regional external passthrough Network Load Balancer (Layer 4). It gives you one public IP that spreads incoming TCP/UDP traffic across the VMs in an instance group, and routes around unhealthy VMs using a health check. Google Cloud has no single "load balancer" resource — a load balancer is a collection of resources. This component creates them for you, in order: 1. **Health check** — how the LB decides a VM is healthy 2. **Backend service** — references your instance group and the health check 3. **Forwarding rule** — the public IP + ports that send traffic to the backend service If any step fails, the resources already created are rolled back. ### Use Cases - **Distribute traffic**: Spread requests across several VMs running the same service - **Resilience**: Stop sending traffic to VMs that fail their health check - **Non-HTTP services**: Balance any TCP/UDP protocol (this is an L4 balancer; it does not terminate HTTPS or route by URL — use an Application Load Balancer for that) ### Configuration - **Name**: Base name for the load balancer; the pieces are named `-hc`, `-backend`, `-fr` (required) - **Region**: The region to create it in (required) - **Protocol**: `TCP` or `UDP` (default TCP) - **Ports**: One or more ports to forward, e.g. 80, 443 (required) - **Instance group**: The existing instance group whose VMs receive traffic (required) - **Health check protocol / port**: `TCP` (default), `HTTP`, or `HTTPS`; port defaults to the first forwarded port - **Reserved IP**: Optionally use a reserved static IP; leave blank for an ephemeral IP ### Output Returns the assembled load balancer: **name**, **region**, **ipAddress**, **protocol**, **ports**, and the underlying **forwardingRule**, **backendService**, **healthCheck**, plus **resources** (selfLinks of everything created). ### Important Notes - Targets an **existing** instance group; the group's VMs must be in the chosen region - Requires the `roles/compute.loadBalancerAdmin` IAM role - This is an L4 passthrough LB: it forwards ports and preserves the client IP; it does not terminate TLS ### Example Output ```json { "data": { "backendService": "web-lb-backend", "forwardingRule": "https://www.googleapis.com/compute/v1/projects/my-project/regions/us-central1/forwardingRules/web-lb-fr", "healthCheck": "web-lb-hc", "instanceGroup": "web-servers", "ipAddress": "34.1.2.3", "name": "web-lb", "ports": [ "80", "443" ], "protocol": "TCP", "region": "us-central1", "resources": [ "https://www.googleapis.com/compute/v1/projects/my-project/regions/us-central1/healthChecks/web-lb-hc", "https://www.googleapis.com/compute/v1/projects/my-project/regions/us-central1/backendServices/web-lb-backend", "https://www.googleapis.com/compute/v1/projects/my-project/regions/us-central1/forwardingRules/web-lb-fr" ] }, "timestamp": "2025-02-14T12:00:00Z", "type": "gcp.compute.loadBalancer.created" } ``` ## Compute • Create Static IP **Component key:** `gcp.compute.createStaticIP` The Create Static IP component reserves a regional external static (reserved) IP address in Compute Engine. A static IP keeps the same address across VM restarts and re-creations, unlike an ephemeral IP. Once reserved it can be attached to a VM instance with the **Manage Static IP** component. ### Use Cases - **Stable endpoints**: Give a service a fixed public address that survives VM replacement - **Blue/green deployments**: Reserve the address ahead of time, then attach it to whichever VM is live - **DNS**: Point an A record at a reserved address you control ### Configuration - **Name**: The name for the new address resource (required, lowercase RFC1035 — e.g. `web-prod-ip`) - **Region**: The region to reserve the address in (required). Regional external IPs can only be attached to VMs in the same region. - **Network Tier**: `PREMIUM` (default) or `STANDARD` - **Description**: Optional human-readable description ### Output Returns the reserved address: - **name**, **address** (the reserved IP), **region**, **status**, **addressType**, **networkTier**, **selfLink** ### Important Notes - Reserving and holding a static IP that is not attached to a running resource incurs charges - The component waits for the underlying regional operation to complete before reading the address back ### Example Output ```json { "data": { "address": "34.1.2.3", "addressType": "EXTERNAL", "name": "web-prod-ip", "networkTier": "PREMIUM", "region": "us-central1", "selfLink": "https://www.googleapis.com/compute/v1/projects/my-project/regions/us-central1/addresses/web-prod-ip", "status": "RESERVED" }, "timestamp": "2025-02-14T12:00:00Z", "type": "gcp.compute.staticIP.created" } ``` ## Compute • Delete Load Balancer **Component key:** `gcp.compute.deleteLoadBalancer` The Delete Load Balancer component tears down a regional external passthrough Network Load Balancer. You select its **forwarding rule** (the load balancer's entry point), and the component follows the references and deletes the pieces in reverse order: 1. **Forwarding rule** (the public IP + ports) 2. **Backend service** it pointed at 3. **Health check** the backend service used ### Use Cases - **Cleanup**: Remove a load balancer created by **Create Load Balancer** - **Teardown**: Decommission a service's front end as part of a workflow ### Configuration - **Load Balancer**: The regional external forwarding rule that anchors the load balancer (required) ### Output Returns what was removed: **forwardingRule**, **backendService**, **healthCheck**, **region**. ### Important Notes - The instance group the backend service referenced is **not** deleted — only the load balancer's own resources - The health check is removed on a best-effort basis; if it is shared by another load balancer the API keeps it and a note is returned - Requires the `roles/compute.loadBalancerAdmin` IAM role ### Example Output ```json { "data": { "backendService": "web-lb-backend", "forwardingRule": "web-lb-fr", "healthCheck": "web-lb-hc", "region": "us-central1" }, "timestamp": "2025-02-14T12:00:00Z", "type": "gcp.compute.loadBalancer.deleted" } ``` ## Compute • Delete Static IP **Component key:** `gcp.compute.deleteStaticIP` The Delete Static IP component releases (deletes) a regional external static IP reservation. ### Use Cases - **Cost optimization**: Release reserved IPs that are no longer needed (idle reserved IPs are billed) - **Cleanup**: Tear down addresses as part of environment teardown ### Configuration - **Static IP**: Pick from the reserved external IPs across all regions, or pass an expression chained from an upstream node (e.g. the `selfLink` emitted by `gcp.compute.createStaticIP`). The selection encodes both the region and the address name. ### Output Returns the released address: - **name**: The name of the address that was released - **region**: The region it was in ### Important Notes - A static IP that is still **attached** to a VM cannot be deleted — detach it first with **Manage Static IP** - If the address is not found at the resolved region/name, the action fails so that misconfigured or stale expressions do not silently mask incomplete cleanup ### Example Output ```json { "data": { "name": "web-prod-ip", "region": "us-central1" }, "timestamp": "2025-02-14T12:00:00Z", "type": "gcp.compute.staticIP.deleted" } ``` ## Compute • Manage Static IP **Component key:** `gcp.compute.manageStaticIP` The Manage Static IP component attaches a reserved external static IP to a VM instance, or detaches the instance's current external IP. Attaching works by managing the network interface's external access config: any existing external IP on the interface is removed first, then the static IP is assigned. Detaching removes the external access config entirely (the instance keeps its internal IP but loses external connectivity unless another address is attached). ### Use Cases - **Blue/green deployments**: Move a stable public IP from the old VM to the new one with zero DNS changes - **Failover**: Reassign a reserved IP from a failed VM to a healthy replacement - **Maintenance**: Temporarily detach a public IP while a VM is serviced ### Configuration - **Action**: `attach` or `detach` (required) - **VM Instance**: The target VM. The selection encodes both the zone and the instance name. - **Static IP** *(attach only)*: The reserved external IP to attach. Only IPs in the selected VM's region are listed, since a regional IP can attach only to a VM in the same region. - **Network Interface**: The interface to modify (default `nic0`) ### Output Returns the instance state after the operation: - **instanceId**, **name**, **zone**, **status**, **selfLink**, **machineType**, **internalIP**, **externalIP** - **action**: The action performed (attach or detach) ### Important Notes - A regional static IP can only be attached to a VM in the **same region** - Attaching is idempotent: if the static IP is already the instance's external IP, the component succeeds without changes - Detaching is idempotent: if the interface already has no external IP, the component succeeds without changes - The component waits for each underlying zone operation to complete before emitting ### Example Output ```json { "data": { "action": "attach", "externalIP": "34.1.2.3", "instanceId": "1234567890123456789", "internalIP": "10.0.0.2", "machineType": "e2-medium", "name": "my-vm", "selfLink": "https://www.googleapis.com/compute/v1/projects/my-project/zones/us-central1-a/instances/my-vm", "status": "RUNNING", "zone": "us-central1-a" }, "timestamp": "2025-02-14T12:00:00Z", "type": "gcp.compute.staticIP.attached" } ``` ## Compute • Create Image **Component key:** `gcp.createImage` The Create Image component creates a custom Compute Engine image. ### Use Cases - **Golden image pipelines**: Build immutable, reusable images from validated disks - **Backup workflows**: Capture disk state as a restorable image before changes - **Release automation**: Produce versioned images as part of CI/CD ### Configuration - **Image Name**: Name for the new image (lowercase, numbers, hyphens; 1–63 chars). - **Source**: Where the image is created from: - **Disk**: A persistent disk (pick the region, zone, then the disk). - **Snapshot**: A disk snapshot. - **Image**: Another custom image in the project. - **Image family**: Optional family to group related images (e.g. `my-app`). - **Description**: Optional human-readable description. - **Labels**: Optional key-value labels (billing, environment, team). - **Storage location**: Optional single region or multi-region to store the image (e.g. `us` or `europe-west1`). Defaults to the source's region. - **Force create**: When the source is a disk attached to a running instance, create the image anyway (may produce an inconsistent image). ### Output Emits the created image: name, selfLink, family, status, diskSizeGb, sourceDisk, labels, deprecationState, creationTimestamp. ### Important Notes - Creating an image from a disk attached to a running VM is not recommended unless **Force create** is enabled. - The component waits for the underlying global operation to complete before emitting. ### Example Output ```json { "data": { "creationTimestamp": "2026-06-02T12:00:00.000-07:00", "deprecationState": "ACTIVE", "diskSizeGb": 10, "family": "my-app", "imageId": "1234567890123456789", "labels": { "env": "production" }, "name": "my-app-2026-06-02", "selfLink": "https://www.googleapis.com/compute/v1/projects/my-project/global/images/my-app-2026-06-02", "sourceDisk": "my-disk", "status": "READY", "storageLocations": [ "us" ] }, "timestamp": "2026-06-02T12:00:00Z", "type": "gcp.compute.image.created" } ``` ## Compute • Create Virtual Machine **Component key:** `gcp.createVM` Creates a new Google Compute Engine VM. ### Steps 1. **Machine Configuration** – Region, zone, machine type, provisioning model (Spot/Standard), instance name. 2. **OS & Storage** – Boot disk source (public/custom image, snapshot, existing disk), disk type, size, snapshot schedule. 3. **Security** – Shielded VM (secure boot, vTPM, integrity monitoring), Confidential VM (AMD SEV/SEV-SNP, Intel TDX). 4. **Identity & API access** – VM service account, OAuth scopes, OS Login, block project-wide SSH keys. 5. **Networking** – VPC, subnet, NIC type, internal/external IP (including static), network tags, firewall rules. 6. **Management** – Metadata, startup script, automatic restart, on host maintenance, maintenance policy. 7. **Advanced** – GPU accelerators, placement policy (min node CPUs), sole-tenant/host affinity, resource policies. ### Output Emits a payload with instance details: instanceId, selfLink, internalIP, externalIP, status, zone, name, machineType. ### Example Output ```json { "data": { "externalIP": "34.1.2.3", "instanceId": "1234567890123456789", "internalIP": "10.0.0.2", "machineType": "e2-medium", "name": "my-vm", "selfLink": "https://www.googleapis.com/compute/v1/projects/my-project/zones/us-central1-a/instances/my-vm", "status": "RUNNING", "zone": "us-central1-a" }, "timestamp": "2025-02-14T12:00:00Z", "type": "gcp.createVM.completed" } ``` ## Compute • Delete Image **Component key:** `gcp.deleteImage` The Delete Image component permanently deletes a Compute Engine custom image. ### Use Cases - **Cleanup**: Remove temporary or test images after use - **Cost optimization**: Delete unused images to reduce storage costs - **Lifecycle automation**: Remove obsolete images as part of release pipelines ### Configuration - **Image**: The custom image to delete. Pick from the list of images in your project, or pass an expression chained from an upstream node (e.g. the `selfLink` emitted by `gcp.createImage`). ### Output Returns the name of the deleted image. ### Important Notes - This operation is **permanent** and cannot be undone. - If the image is not found, the action fails so that misconfigured or stale expressions do not silently mask incomplete cleanup. - Deleting an image does not affect VM instances or disks already created from it. ### Example Output ```json { "data": { "imageName": "my-app-2026-06-02" }, "timestamp": "2026-06-02T12:00:00Z", "type": "gcp.compute.image.deleted" } ``` ## Compute • Delete VM Instance **Component key:** `gcp.deleteVMInstance` The Delete VM Instance component permanently deletes a Compute Engine VM instance. ### Use Cases - **Cleanup**: Remove temporary or test VMs after use - **Cost optimization**: Automatically tear down unused infrastructure - **Automated workflows**: Delete VMs as part of deployment rollback or cleanup processes - **Environment management**: Remove ephemeral environments after testing ### Configuration - **VM Instance**: Pick from the list of VMs in your project, or pass an expression chained from an upstream node (e.g. the `selfLink` emitted by `gcp.createVM`). The selection encodes both the zone and the instance name. ### Output Returns information about the deleted instance: - **instanceName**: The name of the instance that was deleted - **zone**: The zone the instance was in ### Important Notes - This operation is **permanent** and cannot be undone - All data on the instance will be lost unless boot/data disks have auto-delete disabled - The instance will be stopped if running before deletion - If the instance is not found at the resolved zone/name, the action fails so that misconfigured or stale expressions do not silently mask incomplete cleanup ### Example Output ```json { "data": { "instanceName": "my-vm", "zone": "us-central1-a" }, "timestamp": "2025-02-14T12:00:00Z", "type": "gcp.compute.vmInstance.deleted" } ``` ## Compute • Get VM Instance **Component key:** `gcp.getVMInstance` The Get VM Instance component reads the current state of a Compute Engine VM instance and emits its details on the default output channel. ### Use Cases - **Status checks**: Verify a VM is in the expected state (e.g. `RUNNING`) before proceeding with downstream work. - **Detail lookup**: Fetch IPs, machine type, or selfLink for use in later workflow steps. - **Health gates**: Pair with a condition to branch a workflow based on instance status. ### Configuration - **VM Instance**: Pick from the list of VMs in your project, or pass an expression chained from an upstream node (e.g. `selfLink` from `gcp.createVM`). The selection encodes both the zone and the instance name. ### Output The emitted payload contains the full instance summary: - **instanceId**, **selfLink**, **status**, **zone**, **name**, **machineType** - **internalIP**, **externalIP** (when present) ### Important Notes - If the instance is not found at the resolved zone/name, the action fails so that misconfigured or stale expressions do not silently mask a missing resource. - The integration's bound project is authoritative; a chained `selfLink` pointing at a different project is rejected rather than silently rewritten. ### Example Output ```json { "data": { "externalIP": "34.1.2.3", "instanceId": "1234567890123456789", "internalIP": "10.0.0.2", "machineType": "e2-medium", "name": "my-vm", "selfLink": "https://www.googleapis.com/compute/v1/projects/my-project/zones/us-central1-a/instances/my-vm", "status": "RUNNING", "zone": "us-central1-a" }, "timestamp": "2025-02-14T12:00:00Z", "type": "gcp.compute.vmInstance.fetched" } ``` ## Compute • Get VM Metrics **Component key:** `gcp.getVMInstanceMetrics` The Get VM Metrics component retrieves CPU utilization and network throughput metrics for a Compute Engine VM instance from Cloud Monitoring over a specified lookback window. ### Use Cases - **Performance monitoring**: Sample current resource utilization before scaling decisions - **Incident investigation**: Pull recent metrics when responding to an alert - **Capacity planning**: Gather trend data to inform right-sizing of infrastructure - **Automated scaling**: Use metric outputs to conditionally trigger resize or power operations ### Configuration - **VM Instance**: Pick from the list of VMs in your project, or pass an expression chained from an upstream node. The selection encodes both the zone and the instance name. - **Lookback Period**: How far back to retrieve metrics — 1h, 6h, 24h, 7d, or 14d (required). ### Output Returns an averaged metrics payload over the lookback window: - **instanceId**: The numeric ID of the queried instance - **name**, **zone**: Instance identity - **start**, **end**: ISO 8601 timestamps of the metrics window - **lookbackPeriod**: The selected lookback period - **avgCpuUsagePercent**: Average CPU utilization percentage over the window - **avgNetworkInboundBytesPerSec**: Average received network throughput in bytes/sec - **avgNetworkOutboundBytesPerSec**: Average sent network throughput in bytes/sec All metric values are rounded to two decimal places. ### Important Notes - Requires the `roles/monitoring.viewer` IAM role on the integration's service account. - Metrics are read from Cloud Monitoring (`compute.googleapis.com` metrics), which are available for all Compute Engine instances by default. - Data point resolution varies by window: shorter windows return finer-grained data. ### Example Output ```json { "data": { "avgCpuUsagePercent": 23.47, "avgNetworkInboundBytesPerSec": 10485.76, "avgNetworkOutboundBytesPerSec": 8192.33, "end": "2025-02-14T12:00:00Z", "instanceId": "1234567890123456789", "lookbackPeriod": "1h", "name": "my-vm", "start": "2025-02-14T11:00:00Z", "zone": "us-central1-a" }, "timestamp": "2025-02-14T12:00:00Z", "type": "gcp.compute.vmInstance.metrics" } ``` ## Compute • Manage VM Power **Component key:** `gcp.manageVMInstancePower` The Manage VM Power component performs power management operations on a Compute Engine VM instance. ### Use Cases - **Automated restarts**: Reset instances on a schedule or in response to alerts - **Cost optimization**: Stop instances during non-business hours - **Maintenance workflows**: Stop instances before updates, start them after completion - **Recovery procedures**: Reset instances experiencing issues ### Configuration - **VM Instance**: Pick from the list of VMs in your project, or pass an expression chained from an upstream node (e.g. the `selfLink` emitted by `gcp.createVM`). The selection encodes both the zone and the instance name. - **Operation**: The power operation to perform (required): - **start**: Start a stopped (TERMINATED) instance - **stop**: Stop a running instance - **reset**: Hard reset a running instance (does not perform a clean shutdown) - **suspend**: Suspend a running instance, preserving memory state - **resume**: Resume a suspended instance ### Output Returns the instance state after the operation completes: - **instanceId**, **name**, **zone**, **status**, **selfLink**, **machineType**, **internalIP**, **externalIP** - **operation**: The power operation that was performed ### Important Notes - **reset** is a forced operation and does not perform a clean OS shutdown - The component waits for the underlying zone operation to complete before emitting - Operations may take several minutes depending on the instance state ### Example Output ```json { "data": { "externalIP": "34.1.2.3", "instanceId": "1234567890123456789", "internalIP": "10.0.0.2", "machineType": "e2-medium", "name": "my-vm", "operation": "power_off", "selfLink": "https://www.googleapis.com/compute/v1/projects/my-project/zones/us-central1-a/instances/my-vm", "status": "TERMINATED", "zone": "us-central1-a" }, "timestamp": "2025-02-14T12:00:00Z", "type": "gcp.compute.vmInstance.power.power_off" } ``` ## Monitoring • Create Alerting Policy **Component key:** `gcp.monitoring.createAlertingPolicy` The Create Alerting Policy component creates a Cloud Monitoring alerting policy with one or more threshold conditions on Compute Engine instance metrics. ### Use Cases - **Capacity management**: Alert when CPU stays above a safe level - **Composite alerts**: Combine multiple conditions (e.g. high CPU AND high network) with a combiner - **Severity routing**: Tag policies Critical/Error/Warning and rate-limit or auto-close incidents ### Configuration - **Display Name**: Human-readable name for the policy (required) - **Condition type**: **Metric threshold** (default) or **PromQL query** (Google Managed Prometheus) - **Conditions** (threshold type): One or more threshold conditions. Each has: - **Metric**, **Comparison** (above `>` or below `<`), **Threshold**, **Duration** - Optional **Aligner**, **Rolling window**, **Group reducer** + **Group by fields** (aggregation) - Optional **Trigger** by count or percent of time series - **PromQL query** (PromQL type): a PromQL expression that fires while it returns results, plus an optional **For** duration and **Evaluation interval** — the Prometheus-style alerting rule - **Combiner**: How multiple conditions combine — OR / AND / AND-with-matching-resource (default OR) - **Severity**: Critical / Error / Warning (optional) - **Notification Channels**: Existing channels to alert (optional) - **User Labels**: Key/value labels on the policy (optional) - **Enabled**: Whether the policy is active (default: true) - **Auto-close** / **Notification rate limit**: Alert strategy (optional) - **Documentation** / **Documentation subject**: Markdown shown in notifications (optional) ### Output Returns the created policy: **name**, **id**, **displayName**, **enabled**, **combiner**, **severity**, **conditionsCount**, and the first condition's **comparison**, **thresholdValue**, **duration**, **filter**. ### Important Notes - Requires the `roles/monitoring.editor` IAM role on the integration's service account - Conditions monitor the metric across **all** Compute Engine instances in the project - Up to 6 conditions per policy ### Example Output ```json { "data": { "combiner": "OR", "comparison": "COMPARISON_GT", "conditionsCount": 1, "displayName": "High CPU on production instances", "duration": "300s", "enabled": true, "filter": "metric.type=\"compute.googleapis.com/instance/cpu/utilization\" AND resource.type=\"gce_instance\"", "id": "1234567890123456789", "name": "projects/my-project/alertPolicies/1234567890123456789", "notificationChannels": [ "projects/my-project/notificationChannels/9876543210" ], "thresholdValue": 0.8 }, "timestamp": "2025-02-14T12:00:00Z", "type": "gcp.monitoring.alertingPolicy.created" } ``` ## Monitoring • Create Snooze **Component key:** `gcp.monitoring.createSnooze` The Create Snooze component creates a Cloud Monitoring **snooze** that prevents the selected alerting policies from sending notifications for a window of time, starting now. It is the GCP equivalent of an Alertmanager silence. ### Use Cases - **Maintenance windows**: Mute alerts on policies while you deploy or patch - **Noise control**: Temporarily quiet a flapping policy while you fix the root cause - **Planned work**: Suppress notifications for a known, expected disruption ### Configuration - **Display Name**: Human-readable name for the snooze (required) - **Alerting Policies**: One or more policies to snooze (required, up to 16) - **Duration**: How long to snooze, starting now (required) ### Output Returns the created snooze: **name**, **id**, **displayName**, **policies**, **policiesCount**, **startTime**, **endTime**. ### Important Notes - The snooze starts immediately and ends after the chosen duration - A snooze suppresses notifications but does not stop incidents from opening - Requires the `roles/monitoring.editor` (or `roles/monitoring.snoozeEditor`) IAM role ### Example Output ```json { "data": { "displayName": "Deploy maintenance window", "endTime": "2025-02-14T13:00:00Z", "id": "1234567890123456789", "name": "projects/my-project/snoozes/1234567890123456789", "policies": [ "projects/my-project/alertPolicies/1111111111111111111" ], "policiesCount": 1, "startTime": "2025-02-14T12:00:00Z" }, "timestamp": "2025-02-14T12:00:00Z", "type": "gcp.monitoring.snooze.created" } ``` ## Monitoring • Delete Alerting Policy **Component key:** `gcp.monitoring.deleteAlertingPolicy` The Delete Alerting Policy component permanently deletes a Cloud Monitoring alerting policy. ### Use Cases - **Cleanup**: Remove policies for decommissioned services - **Environment teardown**: Delete alerting as part of tearing down ephemeral environments ### Configuration - **Alerting Policy**: Pick from the policies in your project, or pass an expression chained from an upstream node (e.g. the `name` emitted by `gcp.monitoring.createAlertingPolicy`). ### Output Returns the deleted policy reference: - **name**: The resource name that was deleted - **id**: The policy ID ### Important Notes - This operation is **permanent** and cannot be undone - Requires the `roles/monitoring.editor` IAM role on the integration's service account - If the policy is not found, the action fails so stale expressions don't silently mask incomplete cleanup ### Example Output ```json { "data": { "id": "1234567890123456789", "name": "projects/my-project/alertPolicies/1234567890123456789" }, "timestamp": "2025-02-14T12:00:00Z", "type": "gcp.monitoring.alertingPolicy.deleted" } ``` ## Monitoring • Expire Snooze **Component key:** `gcp.monitoring.expireSnooze` The Expire Snooze component ends an active snooze immediately, so the policies it covers resume sending notifications. It is the GCP equivalent of expiring an Alertmanager silence. It moves the snooze's end time to now. Cloud Monitoring requires a snooze window to be at least a minute long, so a snooze that started less than a minute ago is instead cancelled outright (collapsed to a zero-length window) — either way alerting resumes right away. ### Use Cases - **Early exit**: Maintenance finished ahead of schedule — re-enable alerting now - **Cleanup**: End a snooze created upstream once a workflow completes ### Configuration - **Snooze**: Pick from the snoozes in your project, or pass an expression chained from an upstream node (e.g. the `name` emitted by `gcp.monitoring.createSnooze`). ### Output Returns the updated snooze: **name**, **id**, **displayName**, **policies**, **startTime**, **endTime** (now). ### Important Notes - Cloud Monitoring has no delete-snooze operation; ending a snooze means setting its end time to the current time - Requires the `roles/monitoring.editor` (or `roles/monitoring.snoozeEditor`) IAM role ### Example Output ```json { "data": { "displayName": "Deploy maintenance window", "endTime": "2025-02-14T12:30:00Z", "id": "1234567890123456789", "name": "projects/my-project/snoozes/1234567890123456789", "policies": [ "projects/my-project/alertPolicies/1111111111111111111" ], "policiesCount": 1, "startTime": "2025-02-14T12:00:00Z" }, "timestamp": "2025-02-14T12:30:00Z", "type": "gcp.monitoring.snooze.expired" } ``` ## Monitoring • Get Alerting Policy **Component key:** `gcp.monitoring.getAlertingPolicy` The Get Alerting Policy component reads the configuration and state of a Cloud Monitoring alerting policy. ### Use Cases - **Auditing**: Inspect a policy's threshold, comparison, and enabled state - **Conditional workflows**: Branch on whether a policy is enabled or how it's configured - **Chaining**: Read a policy created upstream before updating or deleting it ### Configuration - **Alerting Policy**: Pick from the policies in your project, or pass an expression chained from an upstream node (e.g. the `name` emitted by `gcp.monitoring.createAlertingPolicy`). ### Output Returns the policy: - **name**, **id**, **displayName**, **enabled**, **combiner**, **conditionsCount** - **comparison**, **thresholdValue**, **duration**, **filter**: the first condition's threshold - **notificationChannels**: attached channels (when any) ### Important Notes - Requires the `roles/monitoring.viewer` IAM role on the integration's service account - If the policy is not found, the action fails so stale expressions don't silently mask a problem ### Example Output ```json { "data": { "combiner": "OR", "comparison": "COMPARISON_GT", "conditionsCount": 1, "displayName": "High CPU on production instances", "duration": "300s", "enabled": true, "filter": "metric.type=\"compute.googleapis.com/instance/cpu/utilization\" AND resource.type=\"gce_instance\"", "id": "1234567890123456789", "name": "projects/my-project/alertPolicies/1234567890123456789", "notificationChannels": [ "projects/my-project/notificationChannels/9876543210" ], "thresholdValue": 0.8 }, "timestamp": "2025-02-14T12:00:00Z", "type": "gcp.monitoring.alertingPolicy.fetched" } ``` ## Monitoring • Get Snooze **Component key:** `gcp.monitoring.getSnooze` The Get Snooze component reads a Cloud Monitoring snooze. ### Use Cases - **Auditing**: Inspect which policies are snoozed and until when - **Chaining**: Read a snooze created upstream before expiring it ### Configuration - **Snooze**: Pick from the snoozes in your project, or pass an expression chained from an upstream node (e.g. the `name` emitted by `gcp.monitoring.createSnooze`). ### Output Returns the snooze: **name**, **id**, **displayName**, **policies**, **policiesCount**, **startTime**, **endTime**. ### Important Notes - Requires the `roles/monitoring.viewer` IAM role on the integration's service account ### Example Output ```json { "data": { "displayName": "Deploy maintenance window", "endTime": "2025-02-14T13:00:00Z", "id": "1234567890123456789", "name": "projects/my-project/snoozes/1234567890123456789", "policies": [ "projects/my-project/alertPolicies/1111111111111111111" ], "policiesCount": 1, "startTime": "2025-02-14T12:00:00Z" }, "timestamp": "2025-02-14T12:30:00Z", "type": "gcp.monitoring.snooze.fetched" } ``` ## Monitoring • Update Alerting Policy **Component key:** `gcp.monitoring.updateAlertingPolicy` The Update Alerting Policy component modifies an existing Cloud Monitoring alerting policy in place. Only the fields you set are changed (sent as an update mask). ### Use Cases - **Threshold tuning**: Adjust a condition's threshold as baselines change - **Enable/disable**: Toggle a policy during maintenance windows - **Re-route**: Change notification channels, severity, or alert strategy ### Configuration - **Alerting Policy**: The policy to update (required, supports expressions) - **Condition type**: Toggle to **replace** the policy's conditions with a metric threshold or a PromQL query (leave off to keep current conditions) - **Conditions** (threshold type): Provide to replace with threshold conditions (each: metric, comparison, threshold, duration, optional aggregation/trigger) - **PromQL query** (PromQL type): Provide to replace with a single PromQL condition (with optional For duration and evaluation interval) - **Combiner**: OR / AND / AND-with-matching-resource - **Severity**: Critical / Error / Warning - **Enabled**: Enable, disable, or leave unchanged - **Notification Channels**: Replace channels (provide empty to clear) - **User Labels**: Replace user labels - **Auto-close / Notification rate limit**: Replace the alert strategy - **Documentation / subject**: Replace the documentation ### Output Returns the updated policy: **name**, **id**, **displayName**, **enabled**, **combiner**, **severity**, **conditionsCount**, and the first condition summary. ### Important Notes - At least one field must be provided - Providing **Conditions** replaces all existing conditions - **Auto-close**, **rate limit**, **documentation content**, and **documentation subject** are each updated independently — changing one leaves the others untouched - Requires the `roles/monitoring.editor` IAM role ### Example Output ```json { "data": { "combiner": "OR", "comparison": "COMPARISON_GT", "conditionsCount": 1, "displayName": "High CPU on production instances", "duration": "300s", "enabled": false, "filter": "metric.type=\"compute.googleapis.com/instance/cpu/utilization\" AND resource.type=\"gce_instance\"", "id": "1234567890123456789", "name": "projects/my-project/alertPolicies/1234567890123456789", "thresholdValue": 0.9 }, "timestamp": "2025-02-14T12:00:00Z", "type": "gcp.monitoring.alertingPolicy.updated" } ``` ## Managed Prometheus • Query **Component key:** `gcp.prometheus.query` The Query component runs an instant PromQL query against Google Cloud Managed Service for Prometheus (GMP). GMP stores Prometheus metrics in Cloud Monitoring (Monarch) and exposes a Prometheus-compatible HTTP frontend. This component calls `GET /v1/projects//location/global/prometheus/api/v1/query` and returns the result at a single point in time. ### Use Cases - **Threshold checks**: Evaluate an expression (e.g. `up` or `rate(...)`) and branch on the value - **Spot readings**: Read the current value of a metric to enrich a workflow - **Chaining**: Feed a metric value into a downstream notification or decision node ### Configuration - **Query**: Required PromQL expression to evaluate (supports expressions). Example: `up` The expression is evaluated at execution time ("now"). ### Output Emits one `gcp.prometheus.query` payload: - **resultType**: `vector`, `scalar`, etc. - **result**: the Prometheus result (series with their labels and value) - **seriesCount**: number of series returned ### Important Notes - Requires the `roles/monitoring.viewer` IAM role on the integration's service account - An invalid PromQL expression fails the action with the Prometheus error message ### Example Output ```json { "data": { "result": [ { "metric": { "__name__": "up", "instance": "10.0.0.5:9090", "job": "prometheus" }, "value": [ 1767225600, "1" ] } ], "resultType": "vector", "seriesCount": 1 }, "timestamp": "2026-01-01T00:00:00Z", "type": "gcp.prometheus.query" } ``` ## Managed Prometheus • Query Range **Component key:** `gcp.prometheus.queryRange` The Query Range component runs a PromQL range query against Google Cloud Managed Service for Prometheus (GMP) over an explicit time range. GMP stores Prometheus metrics in Cloud Monitoring (Monarch) and exposes a Prometheus-compatible HTTP frontend. This component calls `GET /v1/projects//location/global/prometheus/api/v1/query_range` and returns a matrix of samples between `start` and `end` at the given `step` resolution. ### Use Cases - **Trend analysis**: Pull a metric over a window to summarise or chart it downstream - **Incident investigation**: Fetch samples for a specific time range when responding to an alert - **Anomaly checks**: Evaluate an expression across time before acting ### Configuration - **Query**: Required PromQL expression to evaluate (supports expressions). Example: `rate(prometheus_http_requests_total[5m])` - **Start**: Required start timestamp in RFC3339 or Unix format (supports expressions). Example: `2026-01-01T00:00:00Z` - **End**: Required end timestamp in RFC3339 or Unix format (supports expressions). Example: `2026-01-02T00:00:00Z` - **Step**: Required query resolution step (e.g. `15s`, `1m`) ### Output Emits one `gcp.prometheus.queryRange` payload: - **resultType**: typically `matrix` - **result**: the Prometheus result (series with their labels and `values` over time) - **seriesCount**: number of series returned - **start**, **end**, **step**: the query window ### Important Notes - Requires the `roles/monitoring.viewer` IAM role on the integration's service account - An invalid PromQL expression fails the action with the Prometheus error message ### Example Output ```json { "data": { "end": "2026-01-01T01:00:00Z", "result": [ { "metric": { "__name__": "up", "instance": "10.0.0.5:9090", "job": "prometheus" }, "values": [ [ 1767225600, "1" ], [ 1767225660, "1" ], [ 1767225720, "0" ] ] } ], "resultType": "matrix", "seriesCount": 1, "start": "2026-01-01T00:00:00Z", "step": "60s" }, "timestamp": "2026-01-01T01:00:00Z", "type": "gcp.prometheus.queryRange" } ``` ## Pub/Sub • Create Subscription **Component key:** `gcp.pubsub.createSubscription` The Create Subscription component creates a new GCP Pub/Sub subscription on a topic. ### Use Cases - **Provisioning workflows**: Wire up subscriptions as part of service deployment - **Pull queue setup**: Create pull subscriptions for batch processing workflows - **Push integration**: Create push subscriptions that deliver messages to an HTTP endpoint ### Example Output ```json { "data": { "name": "projects/my-project/subscriptions/my-subscription", "subscription": "my-subscription", "topic": "my-topic", "type": "pull" }, "timestamp": "2025-01-01T00:00:00Z", "type": "gcp.pubsub.subscription" } ``` ## Pub/Sub • Create Topic **Component key:** `gcp.pubsub.createTopic` The Create Topic component creates a new GCP Pub/Sub topic. ### Use Cases - **Provisioning workflows**: Create topics as part of environment setup - **Dynamic routing**: Create topics on demand for new services or tenants - **Automation bootstrap**: Prepare messaging infrastructure before publishing ### Example Output ```json { "data": { "name": "projects/my-project/topics/my-topic", "topic": "my-topic" }, "timestamp": "2025-01-01T00:00:00Z", "type": "gcp.pubsub.topic" } ``` ## Pub/Sub • Delete Subscription **Component key:** `gcp.pubsub.deleteSubscription` The Delete Subscription component deletes a GCP Pub/Sub subscription. ### Use Cases - **Cleanup workflows**: Remove subscriptions as part of service teardown - **Lifecycle management**: Decommission subscriptions that are no longer needed - **Rollback automation**: Remove subscriptions created in failed provisioning runs ### Example Output ```json { "data": { "deleted": true, "subscription": "my-subscription" }, "timestamp": "2025-01-01T00:00:00Z", "type": "gcp.pubsub.subscription.deleted" } ``` ## Pub/Sub • Delete Topic **Component key:** `gcp.pubsub.deleteTopic` The Delete Topic component deletes a GCP Pub/Sub topic. ### Use Cases - **Cleanup workflows**: Remove temporary topics after execution - **Lifecycle management**: Decommission unused messaging resources - **Rollback automation**: Remove topics created in failed provisioning runs ### Example Output ```json { "data": { "deleted": true, "topic": "my-topic" }, "timestamp": "2025-01-01T00:00:00Z", "type": "gcp.pubsub.topic.deleted" } ``` ## Pub/Sub • Publish Message **Component key:** `gcp.pubsub.publishMessage` The Publish Message component sends a message to a GCP Pub/Sub topic. ### Use Cases - **Event fan-out**: Broadcast workflow results to multiple subscribers - **Notifications**: Publish operational updates to downstream systems - **Automation**: Trigger Pub/Sub-based pipelines from workflows ### Example Output ```json { "data": { "messageId": "1234567890", "topic": "my-topic" }, "timestamp": "2025-01-01T00:00:00Z", "type": "gcp.pubsub.message.published" } ``` ## Compute • Update Image **Component key:** `gcp.updateImage` The Update Image component updates an existing Compute Engine custom image. It can change the image's deprecation status (including marking it deprecated or obsolete) and update its labels. ### Use Cases - **Release lifecycle**: Mark older images deprecated or obsolete as newer ones ship - **Pointing consumers forward**: Set a replacement image so users are guided to the current version - **Inventory hygiene**: Keep image labels accurate for billing, environment, and ownership ### Configuration - **Image**: The custom image to update. - **Deprecation state**: Optionally change the image lifecycle state: - **No change**: Leave the current deprecation state untouched. - **Active**: Clear any deprecation (make the image fully usable again). - **Deprecated**: Mark the image deprecated (still usable; warns on use). - **Obsolete**: Mark the image obsolete (cannot be used to create new resources). - **Deleted**: Mark the image as logically deleted. - **Replacement image**: Optional image to recommend in place of this one (name or URL). Applies when setting a deprecation state. - **Labels**: Optional key-value labels to add or update on the image. Labels you provide are merged with the image's existing labels; existing labels you don't list are left unchanged. ### Output Emits the updated image: name, selfLink, family, status, diskSizeGb, labels, deprecationState, replacement, creationTimestamp. ### Important Notes - Setting the deprecation state to **Active** clears an existing deprecation. - Updating labels merges with the image's existing labels; labels you don't list are preserved. - The component waits for each underlying global operation to complete before emitting. ### Example Output ```json { "data": { "creationTimestamp": "2026-06-02T12:00:00.000-07:00", "deprecationState": "DEPRECATED", "diskSizeGb": 10, "family": "my-app", "imageId": "1234567890123456789", "labels": { "env": "production", "team": "platform" }, "name": "my-app-2026-06-02", "replacement": "https://www.googleapis.com/compute/v1/projects/my-project/global/images/my-app-v2", "selfLink": "https://www.googleapis.com/compute/v1/projects/my-project/global/images/my-app-2026-06-02", "status": "READY" }, "timestamp": "2026-06-02T12:00:00Z", "type": "gcp.compute.image.updated" } ``` ## Compute • Update VM Machine Type **Component key:** `gcp.updateVMInstanceType` The Update VM Machine Type component changes the machine type (size) of an existing Compute Engine VM instance. ### Use Cases - **Vertical scaling**: Resize an instance up or down in response to load - **Cost optimization**: Move to a smaller machine type during off-peak hours - **Right-sizing**: Adjust machine type based on observed utilization ### Configuration - **VM Instance**: Pick from the list of VMs in your project, or pass an expression chained from an upstream node (e.g. the `selfLink` emitted by `gcp.createVM`). The selection encodes both the zone and the instance name. - **Machine Type**: The new machine type name, e.g. `e2-medium` or `n2-standard-4` (required, supports expressions). - **Restart after update**: Whether to start the instance again after the machine type is changed. Enabled by default. Compute Engine requires the instance to be stopped to change its machine type, so a running instance is always stopped first. ### Output Returns the instance state after the update completes: - **instanceId**, **name**, **zone**, **status**, **selfLink**, **machineType**, **internalIP**, **externalIP** ### Important Notes - Changing the machine type requires the instance to be **stopped (TERMINATED)**. A running instance is stopped automatically before the change. - If **Restart after update** is enabled, the instance is started again once the new machine type is applied. - The new machine type must be available in the instance's zone. - The component waits for each underlying zone operation to complete before proceeding. ### Example Output ```json { "data": { "externalIP": "34.1.2.3", "instanceId": "1234567890123456789", "internalIP": "10.0.0.2", "machineType": "n2-standard-4", "name": "my-vm", "selfLink": "https://www.googleapis.com/compute/v1/projects/my-project/zones/us-central1-a/instances/my-vm", "status": "RUNNING", "zone": "us-central1-a" }, "timestamp": "2025-02-14T12:00:00Z", "type": "gcp.compute.vmInstance.machineTypeUpdated" } ``` #### Grafana Source URL: https://docs.superplane.com/components/grafana Connect Grafana alerts, alert rules, dashboards, annotations, silences, and data queries to SuperPlane workflows import { CardGrid, LinkCard } from "@astrojs/starlight/components"; ## Triggers ## Actions ## Instructions **Setup steps:** 1. In Grafana, go to **Administration → Users and access → Service Accounts**, select **Add service account**. > **Service Account Role:** > While naming the service account, go to **Roles → Basic roles** and select **Admin**. Navigate to the created service account and select **Add service account token**. Name it and set an expiration period then click **Generate token**. This is your **Service Account Token**. 2. Use your Grafana root URL as **Base URL** (for example `https://grafana.example.com`). 3. Fill in **Base URL** and **Service Account Token** below, then save. ## On Alert Firing **Trigger key:** `grafana.onAlertFiring` The On Alert Firing trigger starts a workflow when Grafana Unified Alerting sends a firing alert webhook. ### Setup 1. SuperPlane automatically creates or updates a Grafana Webhook contact point and notification policy route for this trigger when provisioning succeeds. 2. SuperPlane manages webhook bearer authentication automatically. 3. Provisioning requires a Grafana integration with **Base URL** and **Service Account Token** and sufficient permissions for alerting and provisioning APIs. ### Configuration - **Alert Names**: Optional exact alert name filters ### Event Data The trigger emits the full Grafana webhook payload, including: - status (firing/resolved) - alerts array with labels and annotations - groupLabels, commonLabels, commonAnnotations - externalURL and other alerting metadata ### Example Data ```json { "data": { "alerts": [ { "annotations": { "summary": "Error rate above threshold" }, "labels": { "alertname": "HighErrorRate", "service": "api" }, "status": "firing" } ], "commonLabels": { "alertname": "HighErrorRate" }, "externalURL": "http://grafana.local", "ruleUid": "alert_rule_uid", "status": "firing", "title": "High error rate" }, "timestamp": "2026-02-12T16:18:03.362582388Z", "type": "grafana.alert.firing" } ``` ## Add Incident Activity **Component key:** `grafana.addIncidentActivity` The Add Incident Activity component posts a user note to a Grafana IRM incident timeline. ### Configuration - **Incident**: The incident to update (required) - **Body**: Note body (required) ### Output Returns the created activity item. ### Example Output ```json { "data": { "activityItemID": "activity-123", "activityKind": "userNote", "body": "Root cause identified and mitigation is in progress.", "createdTime": "2026-04-20T10:05:00Z", "incidentID": "incident-123" }, "timestamp": "2026-04-20T10:05:00Z", "type": "grafana.incident.activityAdded" } ``` ## Create Alert Rule **Component key:** `grafana.createAlertRule` The Create Alert Rule component creates a Grafana-managed alert rule using the Alerting Provisioning HTTP API. ### Use Cases - **Monitoring onboarding**: create baseline alerts when a new service or environment is provisioned - **Incident automation**: create temporary alert rules during an incident or validation workflow - **Policy rollout**: standardize alert coverage across teams using a shared rule definition ### Configuration - **Title**: Human-readable alert name shown in Grafana - **Folder**: Existing Grafana folder that should contain the rule - **Rule Group**: Grafana rule group to create the rule in - **Data Source**: Existing Grafana data source the query should use - **Query**: Expression Grafana evaluates when checking the alert - **Lookback Window**: How far back to query when evaluating the rule - **Reducer / Condition / Threshold(s)**: How the series is reduced, how it is compared to thresholds, and optional upper bound for range conditions - **For**: How long the condition must hold before firing - **No Data / Execution Error State**: Grafana behavior when the query returns no data or errors - **Contact Point**: Optional Grafana contact point for notifications when the rule fires - **Labels / Annotations**: Optional routing and context metadata attached to the rule - **Paused**: Whether the rule starts paused ### Output Returns the created Grafana alert rule object, including identifiers and evaluation metadata. ### Example Output ```json { "data": { "annotations": { "summary": "High error rate detected" }, "condition": "C", "data": [ { "datasourceUid": "prometheus-main", "model": { "editorMode": "code", "expr": "sum(rate(http_requests_total{status=~\"5..\"}[5m]))", "intervalMs": 1000, "maxDataPoints": 43200, "query": "sum(rate(http_requests_total{status=~\"5..\"}[5m]))", "refId": "A" }, "queryType": "", "refId": "A", "relativeTimeRange": { "from": 300, "to": 0 } }, { "datasourceUid": "__expr__", "model": { "expression": "A", "id": "reduce", "reducer": "last", "refId": "B", "settings": { "mode": "dropNN" }, "type": "reduce" }, "queryType": "", "refId": "B", "relativeTimeRange": { "from": 0, "to": 0 } }, { "datasourceUid": "__expr__", "model": { "conditions": [ { "evaluator": { "params": [ 1 ], "type": "gt" }, "operator": { "type": "and" }, "query": { "params": [ "C" ] }, "reducer": { "type": "last" }, "type": "query" } ], "expression": "B", "id": "threshold", "refId": "C", "type": "threshold" }, "queryType": "", "refId": "C", "relativeTimeRange": { "from": 0, "to": 0 } } ], "execErrState": "Alerting", "folderUID": "infra", "for": "5m", "id": 42, "isPaused": false, "labels": { "service": "api", "severity": "critical" }, "noDataState": "NoData", "orgID": 1, "ruleGroup": "service-health", "title": "High error rate", "uid": "cergr5pm79hj4d", "updated": "2026-03-31T10:20:30Z" }, "timestamp": "2026-03-31T10:20:30Z", "type": "grafana.alertRule" } ``` ## Create Annotation **Component key:** `grafana.createAnnotation` The Create Annotation component writes an annotation into Grafana, marking operational events on dashboard timelines. ### Use Cases - **Deploy tracking**: Annotate graphs at the exact moment a deployment is triggered or completes - **Incident markers**: Place a marker when an incident is opened or resolved for post-incident correlation - **Maintenance windows**: Mark the start and end of a maintenance window as a region annotation - **Change correlation**: Record configuration changes, feature flag toggles, or rollbacks directly on the timeline ### Configuration - **Dashboard**: Optional — choose a dashboard from your Grafana instance to scope the annotation - **Panel**: Required — choose the panel within the selected dashboard to attach the annotation to - **Text**: The annotation message (required) - **Tags**: Optional list of tags to label the annotation (e.g. deploy, rollback, incident) - **Time**: Optional start time value. Examples: `{{ now() }}` or `{{ now() - duration("5m") }}` - **Time End**: Optional end time value for a region annotation. Examples: `{{ now() }}` or `{{ now() + duration("24h") }}` ### Output Returns the ID of the newly created annotation. ### Example Output ```json { "data": { "id": 42, "url": "https://grafana.example.com/d/production-overview/production-overview?from=1739376783362\u0026to=1739377383362" }, "timestamp": "2026-02-12T16:18:03.362582388Z", "type": "grafana.annotation.created" } ``` ## Create HTTP Synthetic Check **Component key:** `grafana.createHttpSyntheticCheck` The Create HTTP Synthetic Check component creates an HTTP synthetic check in Grafana Synthetic Monitoring. ### Use Cases - **Availability monitoring**: create checks for API and website uptime - **Deployment verification**: validate a service immediately after deployment - **Operational automation**: provision consistent HTTP checks from workflows ### Configuration Fields are grouped like other synthetic check components: - **Job** and **Labels**: Check display name and optional key/value labels - **Request**: URL, HTTP method, headers, body, redirects, basic auth, and bearer token - **Schedule**: Whether the check is enabled, frequency (seconds), timeout (ms), and probe locations - **Response validation**: SSL expectations, accepted status codes, and body/header regex rules (optional) - **Per-Check Alerts**: Optional Grafana synthetic monitoring alerts configured after check creation ### Output Returns the created Grafana synthetic check, including its ID and HTTP configuration. ### Example Output ```json { "data": { "alerts": [ { "name": "HTTPRequestDurationTooHighAvg", "period": "5m", "threshold": 500 } ], "check": { "alertSensitivity": "none", "alerts": [ { "name": "HTTPRequestDurationTooHighAvg", "period": "5m", "threshold": 500 } ], "basicMetricsOnly": true, "created": 1776248430, "enabled": true, "frequency": 60000, "id": 101, "job": "API health check", "labels": [ { "name": "service", "value": "api" } ], "modified": 1776248430, "probes": [ 1, 2 ], "settings": { "http": { "failIfHeaderMatchesRegexp": [ { "allowMissing": true, "header": "X-Canary", "regexp": "failed" } ], "failIfNotSSL": true, "failIfSSL": false, "headers": [ "Accept:application/json" ], "ipVersion": "V4", "method": "GET", "noFollowRedirects": false, "validStatusCodes": [ 200 ] } }, "target": "https://api.example.com/health", "timeout": 3000 }, "checkUrl": "https://grafana.example.com/a/grafana-synthetic-monitoring-app/checks/101" }, "timestamp": "2026-04-15T10:20:30Z", "type": "grafana.syntheticCheck.created" } ``` ## Create Silence **Component key:** `grafana.createSilence` The Create Silence component creates a new Alertmanager silence in Grafana, suppressing alert notifications that match the configured matchers during the specified time window. ### Use Cases - **Deploy window**: Suppress noisy alerts during a planned maintenance or deployment window - **Incident management**: Prevent alert storms from flooding on-call channels while an incident is being worked on - **Testing**: Silence alerts during load tests or chaos experiments ### Configuration - **Matchers**: One or more label matchers that identify which alerts to silence (required). Each matcher uses an operator: equal (=), not equal (!=), regex match (=~), or regex does not match (!~), matching Grafana Alertmanager semantics. - **Starts At**: The start of the silence window (required) - **Ends At**: The end of the silence window (required) - **Comment**: A description of why the silence is being created (required) - The createdBy field sent to Grafana is set automatically to SuperPlane-<org_name> and is not configurable ### Output Returns the ID of the newly created silence. ### Example Output ```json { "data": { "endsAt": "2026-04-01T10:24:30Z", "silenceId": "a3e5c2d1-8b4f-4e1a-9c7d-2f0e6b3a1d5c", "startsAt": "2026-03-31T10:24:30Z" }, "timestamp": "2026-03-31T10:24:30Z", "type": "grafana.silence.created" } ``` ## Declare Drill **Component key:** `grafana.declareDrill` The Declare Drill component creates a new drill incident in Grafana IRM. ### Use Cases - **Operational exercises**: Run incident response drills without affecting production metrics - **Process validation**: Test runbooks, roles, and integrations in a safe environment ### Configuration - **Title**: Drill title (required) - **Severity**: Pending, Critical, Major, or Minor (required) - **Description**: Optional initial status update added to the drill - **Labels**: Optional drill labels - **Status**: Start the drill as active or resolved - **Start Time**: Optional time when the drill began ### Output Returns the created Grafana IRM incident. ### Example Output ```json { "data": { "createdTime": "2026-04-20T10:00:00Z", "incidentID": "incident-123", "incidentUrl": "https://grafana.example.com/a/grafana-irm-app/incidents/incident-123", "isDrill": true, "labels": [ { "label": "api" }, { "label": "drill" } ], "modifiedTime": "2026-04-20T10:05:00Z", "severity": "minor", "status": "active", "summary": "Simulated database failover exercise for the API tier.", "title": "Quarterly response drill" }, "timestamp": "2026-04-20T10:05:00Z", "type": "grafana.incident.declared" } ``` ## Declare Incident **Component key:** `grafana.declareIncident` The Declare Incident component creates a new incident in Grafana IRM. ### Use Cases - **Automated incident declaration**: Open an incident when a deployment, alert, or workflow detects a production issue ### Configuration - **Title**: Incident title (required) - **Severity**: Pending, Critical, Major, or Minor (required) - **Description**: Optional initial status update added to the incident - **Labels**: Optional incident labels - **Status**: Start the incident as active or resolved - **Start Time**: Optional time when the incident began ### Output Returns the created Grafana IRM incident. ### Example Output ```json { "data": { "createdTime": "2026-04-20T10:00:00Z", "incidentID": "incident-123", "incidentUrl": "https://grafana.example.com/a/grafana-irm-app/incidents/incident-123", "isDrill": false, "labels": [ { "label": "api" }, { "label": "production" } ], "modifiedTime": "2026-04-20T10:05:00Z", "severity": "minor", "status": "active", "summary": "Database connection pool exhaustion identified as root cause.", "title": "High latency in web requests" }, "timestamp": "2026-04-20T10:05:00Z", "type": "grafana.incident.declared" } ``` ## Delete Alert Rule **Component key:** `grafana.deleteAlertRule` The Delete Alert Rule component deletes a Grafana-managed alert rule using the Alerting Provisioning HTTP API. ### Use Cases - **Alert cleanup**: remove temporary or obsolete rules after a rollout or incident - **Service retirement**: delete rules that are no longer needed when an environment is decommissioned - **Controlled cleanup**: pair deletions with approvals, notifications, or audit workflows ### Configuration - **Alert Rule**: The Grafana alert rule to delete ### Output Returns a confirmation object with the deleted alert rule UID, title, and deletion status. ### Example Output ```json { "data": { "deleted": true, "title": "High error rate", "uid": "cergr5pm79hj4d" }, "timestamp": "2026-03-31T10:24:30Z", "type": "grafana.alertRuleDeleted" } ``` ## Delete Annotation **Component key:** `grafana.deleteAnnotation` The Delete Annotation component removes an annotation from Grafana by ID. ### Use Cases - **Cleanup incorrect markers**: Remove an annotation that was created with wrong text or tags - **Automated lifecycle**: Delete temporary markers (e.g. maintenance window start) once the event is complete - **Idempotent workflows**: Allow re-runs to clean up previously created annotations before re-creating them ### Configuration - **Annotation**: The annotation to delete, chosen from your Grafana instance (required) ### Output Returns the annotation ID and a confirmation that the annotation was deleted. ### Example Output ```json { "data": { "deleted": true, "id": 42 }, "timestamp": "2026-02-12T16:18:03.362582388Z", "type": "grafana.annotation.deleted" } ``` ## Delete HTTP Synthetic Check **Component key:** `grafana.deleteHttpSyntheticCheck` The Delete HTTP Synthetic Check component deletes an existing Grafana synthetic check. ### Configuration - **Synthetic Check**: The synthetic check to delete ### Output Returns a compact confirmation payload for the deleted check. ### Example Output ```json { "data": { "deleted": true, "job": "API health check", "syntheticCheck": "101", "target": "https://api.example.com/health" }, "timestamp": "2026-04-15T10:35:30Z", "type": "grafana.syntheticCheck.deleted" } ``` ## Delete Silence **Component key:** `grafana.deleteSilence` The Delete Silence component expires an existing silence in Grafana Alertmanager. ### Use Cases - **End a maintenance window early**: Remove a silence once deployment or maintenance completes ahead of schedule - **Automated cleanup**: Expire silences created by automation after the condition they covered has resolved ### Configuration - **Silence**: The silence to expire (required) ### Output Returns the silence ID and a confirmation that the silence was deleted. ### Example Output ```json { "data": { "deleted": true, "silenceId": "a3e5c2d1-8b4f-4e1a-9c7d-2f0e6b3a1d5c" }, "timestamp": "2026-03-31T10:24:30Z", "type": "grafana.silence.deleted" } ``` ## Get Alert Rule **Component key:** `grafana.getAlertRule` The Get Alert Rule component fetches a Grafana-managed alert rule using the Alerting Provisioning HTTP API. ### Use Cases - **Configuration review**: inspect the current source of truth before changing a rule - **Workflow enrichment**: include alert rule details in notifications, tickets, or approvals - **Drift checks**: compare the current Grafana rule against an expected configuration ### Configuration - **Alert Rule**: The Grafana alert rule to retrieve ### Output Returns the full Grafana alert rule object, including title, folder, group, condition, queries, labels, and annotations. ### Example Output ```json { "data": { "annotations": { "summary": "High error rate detected" }, "condition": "C", "data": [ { "datasourceUid": "prometheus-main", "model": { "editorMode": "code", "expr": "sum(rate(http_requests_total{status=~\"5..\"}[5m]))", "intervalMs": 1000, "maxDataPoints": 43200, "query": "sum(rate(http_requests_total{status=~\"5..\"}[5m]))", "refId": "A" }, "queryType": "", "refId": "A", "relativeTimeRange": { "from": 300, "to": 0 } }, { "datasourceUid": "__expr__", "model": { "expression": "A", "id": "reduce", "reducer": "last", "refId": "B", "settings": { "mode": "dropNN" }, "type": "reduce" }, "queryType": "", "refId": "B", "relativeTimeRange": { "from": 0, "to": 0 } }, { "datasourceUid": "__expr__", "model": { "conditions": [ { "evaluator": { "params": [ 1 ], "type": "gt" }, "operator": { "type": "and" }, "query": { "params": [ "C" ] }, "reducer": { "type": "last" }, "type": "query" } ], "expression": "B", "id": "threshold", "refId": "C", "type": "threshold" }, "queryType": "", "refId": "C", "relativeTimeRange": { "from": 0, "to": 0 } } ], "execErrState": "Alerting", "folderUID": "infra", "for": "5m", "id": 42, "isPaused": false, "labels": { "service": "api", "severity": "critical" }, "noDataState": "NoData", "orgID": 1, "ruleGroup": "service-health", "title": "High error rate", "uid": "cergr5pm79hj4d", "updated": "2026-03-31T10:20:30Z" }, "timestamp": "2026-03-31T10:20:30Z", "type": "grafana.alertRule" } ``` ## Get Dashboard **Component key:** `grafana.getDashboard` The Get Dashboard component fetches a Grafana dashboard using the Grafana Dashboards HTTP API. ### Use Cases - **Dashboard inspection**: retrieve current dashboard configuration for review or downstream use - **Workflow enrichment**: include dashboard details in notifications, tickets, or approvals - **Panel discovery**: list panels available in a dashboard for subsequent rendering or linking ### Configuration - **Dashboard**: The Grafana dashboard UID to retrieve ### Output Returns the Grafana dashboard object, including title, slug, URL, folder, tags, and panel summaries. ### Example Output ```json { "data": { "folder": "fdg4m1rt63hj8q", "folderTitle": "Platform", "panels": [ { "id": 1, "title": "Request Rate", "type": "timeseries" }, { "id": 2, "title": "Error Rate", "type": "timeseries" }, { "id": 3, "title": "P99 Latency", "type": "gauge" } ], "slug": "production-overview", "tags": [ "production", "platform" ], "title": "Production Overview", "uid": "cIBgcSjkk", "url": "https://grafana.example.com/d/cIBgcSjkk/production-overview" }, "timestamp": "2026-03-31T10:24:30Z", "type": "grafana.dashboard" } ``` ## Get HTTP Synthetic Check **Component key:** `grafana.getHttpSyntheticCheck` The Get HTTP Synthetic Check component fetches a Grafana synthetic check and enriches it with best-effort operational metrics. ### Use Cases - **Operational inspection**: fetch the current HTTP check configuration - **Workflow enrichment**: branch using recent synthetic check health data - **Troubleshooting**: pull current latency and run totals into incident workflows ### Configuration - **Synthetic Check**: The synthetic check to retrieve ### Output Channels - **Up**: All probe locations are passing - **Partial**: Some probe locations are passing and some are failing - **Down**: All probe locations are failing ### Output Returns a combined payload containing: - **configuration**: the Grafana synthetic check definition - **alerts**: the configured per-check synthetic alerts when available - **metrics**: best-effort operational metrics derived from Grafana synthetic monitoring metrics; when present, **lastOutcome** is one of **Up**, **Partial**, or **Down**, matching the output channels ### Example Output ```json { "data": { "alerts": [ { "name": "ProbeFailedExecutionsTooHigh", "period": "5m", "threshold": 1 } ], "checkUrl": "https://grafana.example.com/a/grafana-synthetic-monitoring-app/checks/101", "configuration": { "alertSensitivity": "none", "alerts": [ { "name": "ProbeFailedExecutionsTooHigh", "period": "5m", "threshold": 1 } ], "basicMetricsOnly": true, "created": 1776248430, "enabled": true, "frequency": 60000, "id": 101, "job": "API health check", "labels": [ { "name": "service", "value": "api" } ], "modified": 1776248730, "probes": [ 1, 2 ], "settings": { "http": { "failIfNotSSL": true, "failIfSSL": false, "headers": [ "Accept:application/json" ], "ipVersion": "V4", "method": "GET", "noFollowRedirects": false, "validStatusCodes": [ 200 ] } }, "target": "https://api.example.com/health", "timeout": 3000 }, "metrics": { "averageLatencySeconds24h": 0.142, "failureRuns24h": 2, "frequencyMilliseconds": 60000, "lastExecutionAt": "2026-04-15T10:25:00Z", "lastOutcome": "Up", "reachabilityPercent24h": 99.86, "sslEarliestExpiryAt": "2026-05-15T10:25:00Z", "sslEarliestExpiryDays": 30, "successRuns24h": 1438, "totalRuns24h": 1440, "uptimePercent24h": 99.9 } }, "timestamp": "2026-04-15T10:25:30Z", "type": "grafana.syntheticCheck" } ``` ## Get Incident **Component key:** `grafana.getIncident` The Get Incident component retrieves a single incident from Grafana IRM. ### Configuration - **Incident**: The incident to retrieve (required) ### Output Returns the full Grafana IRM incident object. ### Example Output ```json { "data": { "createdTime": "2026-04-20T10:00:00Z", "incidentID": "incident-123", "incidentUrl": "https://grafana.example.com/a/grafana-irm-app/incidents/incident-123", "isDrill": false, "labels": [ { "label": "api" }, { "label": "production" } ], "modifiedTime": "2026-04-20T10:05:00Z", "severity": "minor", "status": "active", "summary": "Database connection pool exhaustion identified as root cause.", "title": "High latency in web requests" }, "timestamp": "2026-04-20T10:05:00Z", "type": "grafana.incident" } ``` ## Get Silence **Component key:** `grafana.getSilence` The Get Silence component fetches the details of a single silence from Grafana Alertmanager using its ID. ### Use Cases - **Inspect a silence**: Retrieve full details of a silence including state, comment, matchers, and times - **Verify a silence**: Confirm a silence is still active before taking action in a workflow ### Configuration - **Silence**: The silence to retrieve (required) ### Output Returns the silence object including ID, state, comment, matchers, start/end times, and the author. ### Example Output ```json { "data": { "comment": "Deploy window for v2.1.0", "createdBy": "devops-bot", "endsAt": "2026-03-31T11:00:00.000Z", "id": "a3e5c2d1-8b4f-4e1a-9c7d-2f0e6b3a1d5c", "matchers": [ { "isEqual": true, "isRegex": false, "name": "env", "value": "production" } ], "startsAt": "2026-03-31T10:00:00.000Z", "status": { "state": "active" }, "updatedAt": "2026-03-31T10:00:00.000Z" }, "timestamp": "2026-03-31T10:24:30Z", "type": "grafana.silence" } ``` ## List Alert Rules **Component key:** `grafana.listAlertRules` The List Alert Rules component lists Grafana-managed alert rules using the Alerting Provisioning HTTP API. ### Use Cases - **Alert audits**: review which Grafana alert rules currently exist - **Workflow enrichment**: send alert inventories to Slack, Jira, or documentation steps - **Follow-up automation**: feed alert rule summaries into downstream review or cleanup workflows ### Configuration All fields are optional: - **Folder**: When set, only alert rules in this Grafana folder are listed - **Rule Group**: When set, only rules in this Grafana rule group are listed When both are omitted, the component lists alert rules across the instance (subject to Grafana permissions). ### Output Returns an object containing the list of Grafana alert rule summaries, including each rule UID and title. ### Example Output ```json { "data": { "alertRules": [ { "title": "High error rate", "uid": "cergr5pm79hj4d" }, { "title": "High latency", "uid": "aer9k2pm71sh2b" }, { "title": "Service unavailable", "uid": "bfg4m1rt63hj8q" } ] }, "timestamp": "2026-03-31T10:24:30Z", "type": "grafana.alertRules" } ``` ## List Annotations **Component key:** `grafana.listAnnotations` The List Annotations component retrieves annotations from Grafana, optionally filtered by tag, dashboard, or time range. ### Use Cases - **Audit operational events**: Review recent deploy, incident, or change markers on a timeline - **Correlate incidents**: Retrieve annotations from around an incident time window for post-incident analysis - **Workflow branching**: Check for existing markers before creating duplicate annotations ### Configuration - **Dashboard**: Optional — filter to annotations on a specific dashboard from your Grafana instance - **Panel**: Optional — filter to annotations on a specific panel within the selected dashboard - **Text**: Optional — filter annotations whose text contains this value - **Tags**: Filter to annotations matching all of the specified tags (optional) - **From / To**: Time range filter values (optional). Examples: `{{ now() - duration("1h") }}` and `{{ now() }}` - **Limit**: Maximum number of annotations to return (optional) ### Output Returns a list of annotation objects including ID, text, tags, time, and dashboard/panel references. ### Example Output ```json { "data": { "annotations": [ { "dashboardUID": "abc123", "id": 42, "panelId": 3, "tags": [ "deploy", "production" ], "text": "Deploy v1.2.3 to production", "time": 1739376000000, "timeEnd": 1739376000000, "type": "annotation" }, { "dashboardUID": "abc123", "id": 41, "panelId": 3, "tags": [ "rollback", "production" ], "text": "Rollback to v1.2.2", "time": 1739289600000, "timeEnd": 1739289600000, "type": "annotation" } ], "from": "2026-02-12T15:18:03.362582388Z", "to": "2026-02-12T16:18:03.362582388Z" }, "timestamp": "2026-02-12T16:18:03.362582388Z", "type": "grafana.annotations" } ``` ## List Silences **Component key:** `grafana.listSilences` The List Silences component retrieves silences from Grafana Alertmanager. ### Use Cases - **Audit**: Review all currently active or pending silences in your Grafana instance - **Detect if already muted**: Check whether a specific alert or label set is already silenced before creating a duplicate - **Workflow logic**: Branch on silence state — e.g. skip escalation if an alert is already silenced ### Configuration - **Filter**: Optional label matcher string to filter silences (e.g. `alertname=~"High.*"`) ### Output Returns a list of silence objects, each including ID, state, comment, matchers, start/end times, and the author. ### Example Output ```json { "data": { "silences": [ { "comment": "Deploy window for v2.1.0", "createdBy": "devops-bot", "endsAt": "2026-03-31T11:00:00.000Z", "id": "a3e5c2d1-8b4f-4e1a-9c7d-2f0e6b3a1d5c", "matchers": [ { "isEqual": true, "isRegex": false, "name": "env", "value": "production" } ], "startsAt": "2026-03-31T10:00:00.000Z", "status": { "state": "active" }, "updatedAt": "2026-03-31T10:00:00.000Z" } ] }, "timestamp": "2026-03-31T10:24:30Z", "type": "grafana.silences" } ``` ## Query Data Source **Component key:** `grafana.queryDataSource` The Query Data Source component executes a query against a Grafana data source using the Grafana Query API. ### Use Cases - **Metrics investigation**: Run PromQL or other datasource queries from workflows - **Alert validation**: Validate alert conditions before escalation - **Incident context**: Pull current metrics into incident workflows ### Configuration - **Data Source**: The Grafana data source to query - **Query**: The datasource query (PromQL, InfluxQL, etc.) - **Time From / Time To**: Optional expressions for the query range (for example `now() - duration("5m")` and `now()`) - If omitted, SuperPlane defaults the query to the last 5 minutes - **Format**: Optional query format (depends on the datasource) ### Output Returns the Grafana query API response JSON. ### Example Output ```json { "data": { "results": { "A": { "frames": [ { "data": { "values": [ [ "2026-02-07T08:00:00Z", "2026-02-07T08:01:00Z" ], [ 1, 1 ] ] }, "schema": { "fields": [ { "name": "time", "type": "time" }, { "name": "value", "type": "number" } ] } } ] } } }, "timestamp": "2026-02-12T16:18:03.362582388Z", "type": "grafana.query.result" } ``` ## Query Logs **Component key:** `grafana.queryLogs` The Query Logs component executes a LogQL query against a Loki-backed Grafana data source. ### Use Cases - **Incident investigation**: Search logs for errors or anomalies during an incident response workflow - **Deploy validation**: Confirm absence of error patterns following a deployment - **Log enrichment**: Pull relevant log lines into a workflow for summarization or downstream notification ### Configuration - **Data Source**: The Loki data source to query (required) - **Query**: A LogQL query expression (required), e.g. `{app="myservice"} |= "error"` - **Time From / Time To**: Optional log query range. Supports expr-golang values like `{{ now() + duration("1m") }}`, absolute values like `2026-04-08T15:30Z`, and relative Grafana values like `now-15m` or `now+2h`. Datetime values without an explicit offset are interpreted as UTC. - **Limit**: Maximum number of log lines to return (optional) ### Output Returns the Grafana query API response containing matching log frames. ### Example Output ```json { "data": { "results": { "A": { "frames": [ { "data": { "values": [ [ "2026-02-12T16:17:00Z", "2026-02-12T16:17:30Z" ], [ "error: connection refused to db", "error: timeout waiting for response" ], [ { "app": "myservice", "level": "error" }, { "app": "myservice", "level": "error" } ] ] }, "schema": { "fields": [ { "name": "Time", "type": "time" }, { "name": "Line", "type": "string" }, { "name": "labels", "type": "other" } ] } } ] } } }, "timestamp": "2026-02-12T16:18:03.362582388Z", "type": "grafana.logs.result" } ``` ## Query Traces **Component key:** `grafana.queryTraces` The Query Traces component executes a TraceQL query against a Tempo-backed Grafana data source. ### Use Cases - **Incident triage**: Find traces for a failing service during an incident to identify slow or erroring spans - **Deploy validation**: Confirm trace patterns look healthy after a deployment - **Latency investigation**: Search for high-latency traces matching a specific service or operation ### Configuration - **Data Source**: The Tempo data source to query (required) - **Query**: A TraceQL query expression (required), e.g. `{ .http.status_code = 500 }` - **Time From / Time To**: Optional trace search range. Supports expr-golang values like `{{ now() + duration("1m") }}`, absolute values like `2026-04-08T15:30Z`, and relative Grafana values like `now-15m` or `now+2h`. Datetime values without an explicit offset are interpreted as UTC. ### Output Returns the Grafana query API response containing matching trace frames. ### Example Output ```json { "data": { "results": { "A": { "frames": [ { "data": { "values": [ [ "abc123def456" ], [ "0000000000000001" ], [ "HTTP GET /api/orders" ], [ 1523000 ], [ "order-service" ] ] }, "schema": { "fields": [ { "name": "traceID", "type": "string" }, { "name": "spanID", "type": "string" }, { "name": "operationName", "type": "string" }, { "name": "duration", "type": "number" }, { "name": "serviceName", "type": "string" } ] } } ] } } }, "timestamp": "2026-02-12T16:18:03.362582388Z", "type": "grafana.traces.result" } ``` ## Render Panel **Component key:** `grafana.renderPanel` The Render Panel component constructs a Grafana image render URL for a dashboard panel using the Grafana Image Renderer. ### Use Cases - **Incident snapshots**: attach or link a rendered panel image in tickets or notifications - **Scheduled reports**: generate a reusable render URL for panel snapshots - **Workflow enrichment**: pass a compact panel image URL through workflow steps ### Configuration - **Dashboard**: The Grafana dashboard containing the panel to render - **Panel**: The panel to render - **Width**: Image width in pixels (default 1000) - **Height**: Image height in pixels (default 500) - **From**: Optional start of the time range. Examples: `{{ now() - duration("1h") }}` or `now-1h` - **To**: Optional end of the time range. Examples: `{{ now() }}` or `now` ### Output Returns the Grafana render URL along with the dashboard UID and panel. ### Example Output ```json { "data": { "dashboard": "cIBgcSjkk", "panel": 2, "url": "https://grafana.example.com/render/d-solo/cIBgcSjkk/production-overview?panelId=2\u0026width=1000\u0026height=500\u0026tz=UTC" }, "timestamp": "2026-03-31T10:24:30Z", "type": "grafana.panel.image" } ``` ## Resolve Incident **Component key:** `grafana.resolveIncident` The Resolve Incident component marks an existing Grafana IRM incident as resolved. ### Configuration - **Incident**: The incident to resolve (required) - **Summary**: Optional resolution note added to the incident activity before resolving ### Output Returns the resolved Grafana IRM incident. ### Example Output ```json { "data": { "closedTime": "2026-04-20T10:10:00Z", "createdTime": "2026-04-20T10:00:00Z", "incidentID": "incident-123", "incidentUrl": "https://grafana.example.com/a/grafana-irm-app/incidents/incident-123", "isDrill": false, "labels": [ { "label": "api" }, { "label": "production" } ], "modifiedTime": "2026-04-20T10:10:00Z", "severity": "minor", "status": "resolved", "summary": "Database connection pool exhaustion identified as root cause.", "title": "High latency in web requests" }, "timestamp": "2026-04-20T10:10:00Z", "type": "grafana.incident.resolved" } ``` ## Update Alert Rule **Component key:** `grafana.updateAlertRule` The Update Alert Rule component updates a Grafana-managed alert rule using the Alerting Provisioning HTTP API. ### Use Cases - **Threshold tuning**: refine alert conditions after incidents or noisy periods - **Ownership changes**: update labels and annotations used for routing and context - **Rollout safety**: adjust alert rules during migrations or environment transitions ### Configuration - **Alert Rule**: The Grafana alert rule to update - **All other fields are optional**: only the values you provide will be changed - **Folder / Rule Group**: Optional location changes for the rule in Grafana - **Data Source / Query**: Optional query details Grafana evaluates - **Lookback / Reducer / Condition / Threshold(s)**: Optional changes to evaluation and thresholds - **Contact Point**: Set to a contact point to attach notifications; clear the value to remove notification settings from the rule - **Labels / Annotations**: Optional metadata to update alongside the rule ### Output Returns the updated Grafana alert rule object after the provisioning API applies the change. ### Example Output ```json { "data": { "annotations": { "summary": "High error rate detected" }, "condition": "C", "data": [ { "datasourceUid": "prometheus-main", "model": { "editorMode": "code", "expr": "sum(rate(http_requests_total{status=~\"5..\"}[5m]))", "intervalMs": 1000, "maxDataPoints": 43200, "query": "sum(rate(http_requests_total{status=~\"5..\"}[5m]))", "refId": "A" }, "queryType": "", "refId": "A", "relativeTimeRange": { "from": 300, "to": 0 } }, { "datasourceUid": "__expr__", "model": { "expression": "A", "id": "reduce", "reducer": "last", "refId": "B", "settings": { "mode": "dropNN" }, "type": "reduce" }, "queryType": "", "refId": "B", "relativeTimeRange": { "from": 0, "to": 0 } }, { "datasourceUid": "__expr__", "model": { "conditions": [ { "evaluator": { "params": [ 1 ], "type": "gt" }, "operator": { "type": "and" }, "query": { "params": [ "C" ] }, "reducer": { "type": "last" }, "type": "query" } ], "expression": "B", "id": "threshold", "refId": "C", "type": "threshold" }, "queryType": "", "refId": "C", "relativeTimeRange": { "from": 0, "to": 0 } } ], "execErrState": "Alerting", "folderUID": "infra", "for": "5m", "id": 42, "isPaused": false, "labels": { "service": "api", "severity": "critical" }, "noDataState": "NoData", "orgID": 1, "ruleGroup": "service-health", "title": "High error rate", "uid": "cergr5pm79hj4d", "updated": "2026-03-31T10:20:30Z" }, "timestamp": "2026-03-31T10:20:30Z", "type": "grafana.alertRule" } ``` ## Update HTTP Synthetic Check **Component key:** `grafana.updateHttpSyntheticCheck` The Update HTTP Synthetic Check component updates an existing Grafana Synthetic Monitoring HTTP check. ### Configuration - **Synthetic Check**: The synthetic check to update (required) - **Job**, **Labels**, **Request**, **Schedule**, **Response validation**, and **Per-Check Alerts** are **togglable**. Enable a section only when you want to change it; disabled sections keep the values currently stored in Grafana. ### Output Returns the updated Grafana synthetic check. ### Example Output ```json { "data": { "alerts": [ { "name": "ProbeFailedExecutionsTooHigh", "period": "5m", "threshold": 2 } ], "check": { "alertSensitivity": "none", "alerts": [ { "name": "ProbeFailedExecutionsTooHigh", "period": "5m", "threshold": 2 } ], "basicMetricsOnly": true, "created": 1776248430, "enabled": true, "frequency": 30000, "id": 101, "job": "API health check", "labels": [ { "name": "service", "value": "api" }, { "name": "environment", "value": "prod" } ], "modified": 1776249030, "probes": [ 1, 2, 3 ], "settings": { "http": { "failIfNotSSL": true, "failIfSSL": false, "headers": [ "Accept:application/json" ], "ipVersion": "V4", "method": "GET", "noFollowRedirects": false, "validStatusCodes": [ 200 ] } }, "target": "https://api.example.com/health", "timeout": 5000 }, "checkUrl": "https://grafana.example.com/a/grafana-synthetic-monitoring-app/checks/101" }, "timestamp": "2026-04-15T10:30:30Z", "type": "grafana.syntheticCheck.updated" } ``` ## Update Incident **Component key:** `grafana.updateIncident` The Update Incident component updates supported fields on an existing Grafana IRM incident. ### Configuration - **Incident**: The incident to update (required) - **Title**: Optional new incident title - **Severity**: Optional new severity: Pending, Critical, Major, or Minor - **Labels**: Optional labels to add to the incident - **Is Drill**: Optional drill flag ### Output Returns the updated Grafana IRM incident. ### Example Output ```json { "data": { "createdTime": "2026-04-20T10:00:00Z", "incidentID": "incident-123", "incidentUrl": "https://grafana.example.com/a/grafana-irm-app/incidents/incident-123", "isDrill": false, "labels": [ { "label": "api" }, { "label": "production" }, { "label": "customer-impacting" } ], "modifiedTime": "2026-04-20T10:07:00Z", "severity": "major", "status": "active", "summary": "Database connection pool exhaustion identified as root cause.", "title": "High latency in web requests" }, "timestamp": "2026-04-20T10:07:00Z", "type": "grafana.incident.updated" } ``` #### Harness Source URL: https://docs.superplane.com/components/harness Run and monitor Harness pipelines from SuperPlane workflows import { CardGrid, LinkCard } from "@astrojs/starlight/components"; ## Triggers ## Actions ## Instructions 1. **Create API key:** In Harness, create a service-account API key with permission to run and read pipeline executions. 2. **Connect once, then configure nodes:** Scope fields (**Org**, **Project**, **Pipeline**) are selected in each Harness node. 3. **Account ID is automatic:** SuperPlane resolves account scope from your API key. 4. **Trigger notifications are automatic:** For **On Pipeline Completed** with a selected **Pipeline**, SuperPlane provisions a pipeline notification rule for you. 5. **Auth method:** SuperPlane calls Harness APIs with `x-api-key: ` against `https://app.harness.io/gateway` unless overridden by Base URL. ## On Pipeline Completed **Trigger key:** `harness.onPipelineCompleted` The On Pipeline Completed trigger starts a workflow when a Harness pipeline execution finishes. ### Use Cases - **Failure notifications**: Send Slack alerts when critical pipelines fail - **Release automation**: Trigger post-deploy checks when a deployment pipeline succeeds - **Incident workflows**: Create tickets for aborted/expired pipeline runs ### Configuration - **Org**: Harness organization identifier - **Project**: Harness project identifier - **Pipeline Identifier**: Optional pipeline identifier filter. Leave empty to accept all pipeline completions. - **Statuses**: Completion statuses that should trigger the workflow. ### Webhook Setup SuperPlane automatically provisions Harness pipeline `notificationRules` when **Pipeline** is selected. If no pipeline is selected, or webhook delivery is unavailable in your Harness account, SuperPlane falls back to polling recent executions. ### Example Data ```json { "data": { "eventType": "PIPELINE_END", "executionId": "3y9YlBC9SrOn6W7bPT5nCw", "pipelineIdentifier": "deploy_prod", "raw": { "data": { "pipelineIdentifier": "deploy_prod", "planExecutionId": "3y9YlBC9SrOn6W7bPT5nCw", "status": "FAILED" }, "eventType": "PIPELINE_END" }, "status": "failed" }, "timestamp": "2026-02-12T18:45:55Z", "type": "harness.pipeline.completed" } ``` ## Run Pipeline **Component key:** `harness.runPipeline` The Run Pipeline component starts a Harness pipeline execution and waits for it to finish. ### Use Cases - **CI/CD orchestration**: Trigger deploy pipelines from workflow events - **Approval-based releases**: Run release pipelines after manual approvals - **Scheduled automation**: Kick off recurring maintenance or validation pipelines ### How It Works 1. Starts a Harness pipeline execution 2. Stores the execution ID in node execution state 3. Watches execution completion via webhook (with polling fallback) 4. Routes output to: - **Success** when execution succeeds - **Failed** when execution fails, aborts, or expires ### Configuration - **Org**: Harness organization identifier - **Project**: Harness project identifier - **Pipeline**: Harness pipeline identifier - **Ref**: Optional git ref (`refs/heads/main` or `refs/tags/v1.2.3`) - **Input Set References**: Optional input set identifiers - **Runtime Input YAML**: Optional YAML override for runtime inputs ### Example Output ```json { "data": { "endedAt": "2026-02-12T18:45:55Z", "executionId": "3y9YlBC9SrOn6W7bPT5nCw", "pipelineIdentifier": "deploy_prod", "planExecutionUrl": "https://app.harness.io/ng/account/acc123/module/cd/orgs/default/projects/platform/pipelines/deploy_prod/executions/3y9YlBC9SrOn6W7bPT5nCw/pipeline", "startedAt": "2026-02-12T18:42:10Z", "status": "succeeded" }, "timestamp": "2026-02-12T18:45:55Z", "type": "harness.pipeline.finished" } ``` #### Hetzner Cloud Source URL: https://docs.superplane.com/components/hetznercloud Create and delete Hetzner Cloud servers/load balancers and create/delete server snapshots import { CardGrid, LinkCard } from "@astrojs/starlight/components"; ## Actions ## Instructions **API Token:** Create a token in [Hetzner Cloud Console](https://console.hetzner.cloud/) → Project → Security → API Tokens. Use **Read & Write** scope. ## Create Load Balancer **Component key:** `hetzner.createLoadBalancer` The Create Load Balancer component creates a load balancer in Hetzner Cloud. ### How It Works 1. Creates a load balancer with the specified name, type, location, and algorithm via the Hetzner API 2. Emits the created load balancer details on the default output channel ### Configuration - **Name**: The name for the new load balancer (supports expressions) - **Type**: The load balancer type (e.g. lb11, lb21, lb31) - **Location**: The location where the load balancer will be created - **Algorithm**: The load balancing algorithm — Round Robin (default) or Least Connections ### Example Output ```json { "data": { "id": "12345", "name": "my-load-balancer", "status": "running" }, "timestamp": "2024-01-15T10:30:00Z", "type": "hetzner.load_balancer.created" } ``` ## Create Server **Component key:** `hetzner.createServer` The Create Server component creates a new server in Hetzner Cloud and waits for the create action to complete. ### How It Works 1. Creates a server with the given name, server type, image (system image or snapshot), and optional location/SSH keys/user data 2. Polls the Hetzner API until the create action finishes 3. Emits the server details on the default output when ready. If creation fails, the execution errors. ### Configuration - **Name**: Server name (supports expressions) - **Server type**: e.g. cx11, cpx11, cax11 - **Image**: System image or snapshot image ID - **Location** (optional): e.g. fsn1, nbg1, hel1 - **SSH keys** (optional): List of SSH key names or IDs - **Firewall** (optional): Attach an existing firewall to the server - **User data** (optional): Cloud-init user data ### Example Output ```json { "data": { "created": "2024-01-15T10:30:00+00:00", "id": 42, "name": "my-server", "publicIp": "1.2.3.4", "status": "running" }, "timestamp": "2024-01-15T10:30:00Z", "type": "hetzner.server.created" } ``` ## Create Snapshot **Component key:** `hetzner.createSnapshot` The Create Snapshot component creates a snapshot image from an existing Hetzner Cloud server and waits for completion. ### How It Works 1. Calls the Hetzner API to create a snapshot from the selected server 2. Polls the action until snapshot creation finishes 3. Emits snapshot details (including image ID) on success. If creation fails, the execution errors. ### Configuration - **Server**: Existing server to snapshot - **Snapshot name** (optional): Snapshot description/name in Hetzner Cloud ### Example Output ```json { "data": { "actionId": "12345", "imageId": 67890, "imageType": "snapshot", "serverId": "42", "snapshotName": "workflow-snapshot" }, "timestamp": "2024-01-15T10:30:00Z", "type": "hetzner.snapshot.created" } ``` ## Delete Load Balancer **Component key:** `hetzner.deleteLoadBalancer` The Delete Load Balancer component deletes a load balancer in Hetzner Cloud. ### How It Works 1. Deletes the selected load balancer via the Hetzner API 2. Emits on the default output when the load balancer is deleted. If deletion fails, the execution errors. ### Example Output ```json { "data": { "loadBalancerId": "12345" }, "timestamp": "2024-01-15T10:30:00Z", "type": "hetzner.load_balancer.deleted" } ``` ## Delete Server **Component key:** `hetzner.deleteServer` The Delete Server component deletes a server in Hetzner Cloud and waits for the delete action to complete. ### How It Works 1. Deletes the selected server via the Hetzner API 2. Polls the API until the delete action finishes 3. Emits on the default output when the server is deleted. If deletion fails, the execution errors. ### Example Output ```json { "data": { "actionId": 123, "serverId": 42 }, "timestamp": "2024-01-15T10:30:00Z", "type": "hetzner.server.deleted" } ``` ## Delete Snapshot **Component key:** `hetzner.deleteSnapshot` The Delete Snapshot component deletes a snapshot image in Hetzner Cloud. ### How It Works 1. Deletes the selected snapshot via the Hetzner API 2. Emits on the default output when the snapshot is deleted. If deletion fails, the execution errors. ### Example Output ```json { "data": { "imageId": "67890" }, "timestamp": "2024-01-15T10:30:00Z", "type": "hetzner.snapshot.deleted" } ``` #### Honeycomb Source URL: https://docs.superplane.com/components/honeycomb Monitor observability alerts and send events to Honeycomb datasets import { CardGrid, LinkCard } from "@astrojs/starlight/components"; ## Triggers ## Actions ## Instructions Connect Honeycomb to SuperPlane using a Management Key. **Required configuration:** - **Site**: US (api.honeycomb.io) or EU (api.eu1.honeycomb.io) based on your account region. - **Management Key**: Found in Honeycomb under Team Settings > API Keys. Must be in format <keyID>:<secret>. - **Team Slug**: Your team identifier, visible in the Honeycomb URL: honeycomb.io/<team-slug>. - **Environment Slug**: The environment containing your datasets (e.g. "production"). Found under Team Settings > Environments. SuperPlane will automatically validate your credentials and manage all necessary Honeycomb resources — webhook recipients for triggers and ingest keys for actions — so no manual setup is required. ## On Alert Fired **Trigger key:** `honeycomb.onAlertFired` Starts a workflow execution when a Honeycomb Trigger fires. **Configuration:** - **Dataset Slug**: The slug of the dataset that contains your Honeycomb trigger. Found in the dataset URL: honeycomb.io/<team>/datasets/<dataset-slug>. - **Trigger**: The exact name of the Honeycomb trigger to listen to (case-insensitive). Found in your dataset under Triggers. **How it works:** SuperPlane automatically creates a webhook recipient in Honeycomb and attaches it to the selected trigger. No manual webhook setup is required. When the trigger fires, SuperPlane receives the webhook and starts a workflow execution with the full alert payload. ### Example Data ```json { "data": { "alert_type": "on_true", "description": "production environment:\nCurrent value greater than threshold value (5)", "id": "kQjkatCVK6M", "is_test": false, "name": "High Error Rate", "operator": "greater than", "result_groups": [ { "Group": {}, "Result": 8.5 } ], "result_groups_triggered": [], "result_url": "https://ui.honeycomb.io/myteam/environments/production/datasets/api-production/result/p3o2dvAhYxx/a/z5rYVCoNUZz?utm_content=view_graph\u0026utm_medium=Trigger\u0026utm_source=webhook", "status": "TRIGGERED", "summary": "Triggered: High Error Rate", "threshold": 5, "trigger_description": "API error rate has exceeded the acceptable threshold", "trigger_url": "https://ui.honeycomb.io/myteam/environments/production/datasets/api-production/triggers/kQjkatCVK6M?utm_content=edit_trigger\u0026utm_medium=Trigger\u0026utm_source=webhook", "version": "v0.1.0" }, "timestamp": "2024-01-15T10:30:00Z", "type": "honeycomb.alert.fired" } ``` ## Create Event **Component key:** `honeycomb.createEvent` Sends a JSON event to a Honeycomb dataset. Each key in the JSON object becomes a Honeycomb field. Notes: • Dataset must exist • Fields must be valid JSON object • Timestamp is auto-added if missing ### Example Output ```json { "data": { "dataset": "example", "fields": { "deployed_by": "github-actions", "duration_seconds": 42, "environment": "production", "event_type": "deployment", "service": "billing-api", "success": true, "version": "2.4.1" }, "status": "sent" }, "timestamp": "2026-02-27T11:34:29.510313029Z", "type": "honeycomb.event.created" } ``` #### Incident Source URL: https://docs.superplane.com/components/incident Manage and react to incidents in incident.io import { CardGrid, LinkCard } from "@astrojs/starlight/components"; ## Triggers ## Actions ## Instructions ## API integration 1. In [incident.io Settings > API keys](https://app.incident.io/settings/api-keys), click **Create API key** and give it a name. 2. Under **Add permissions**, select exactly these (use "Find a permission" if needed): - **View data, like public incidents and organisation settings** (needed to read severities) - **Create incidents** (needed for the Create Incident action) - **View all incident data, including private incidents** (only if you use private incidents) 3. Create the key and **paste the API key** in the Configuration section below. ## On Incident **Trigger key:** `incident.onIncident` The On Incident trigger starts a workflow execution when incident.io sends webhooks for incident created or updated events. ### Use Cases - **Incident automation**: Notify Slack, update a status page, or create a Jira ticket when an incident is opened or updated - **Notification workflows**: Send notifications when incidents are created or their status changes - **Integration workflows**: Sync incidents with external systems ### Configuration - **Events**: Select which events to listen for (Incident created, Incident updated) - **Webhook signing secret**: Use the **Set signing secret** action below (after creating the webhook in incident.io) to store the signing secret. It is stored securely and never in the workflow configuration. ### Webhook Setup incident.io does not provide an API to register webhook endpoints. After adding this trigger: 1. Save the canvas to generate the webhook URL, then copy it from this panel. 2. In incident.io go to **Settings > Webhooks** and create a new endpoint with that URL. 3. Subscribe to **Public incident created (v2)** and **Public incident updated (v2)**. 4. Copy the **Signing secret** from the endpoint, then use **Set signing secret** below to store it securely. ### Example Data ```json { "data": { "event_type": "public_incident.incident_created_v2", "incident": { "created_at": "2021-08-17T13:28:57.801578Z", "id": "01FDAG4SAP5TYPT98WGR2N7W91", "incident_status": { "id": "01FCNDV6P870EA6S7TK1DSYD5H", "name": "Triage" }, "name": "Our database is sad", "permalink": "https://app.incident.io/incidents/123", "reference": "INC-123", "severity": { "id": "01FCNDV6P870EA6S7TK1DSYDG0", "name": "Minor" }, "summary": "Our database is really really sad, and we don't know why yet.", "updated_at": "2021-08-17T13:28:57.801578Z", "visibility": "public" } }, "timestamp": "2026-01-19T12:00:00Z", "type": "incident.incident.created" } ``` ## Create Incident **Component key:** `incident.createIncident` The Create Incident component creates a new incident in incident.io. ### Use Cases - **Alert escalation**: Create incidents from monitoring alerts - **Error tracking**: Automatically create incidents when errors are detected - **Manual incident creation**: Create incidents from workflow events - **Integration workflows**: Create incidents from external system events ### Configuration - **Name**: The incident name or title (required, supports expressions) - **Summary**: Additional details about the incident (optional, supports expressions) - **Severity**: Select a severity from your incident.io organization (required) - **Visibility**: Public (anyone can access) or Private (only invited users) ### Output Returns the created incident object including: - **id**: Incident ID - **name**: Incident name - **reference**: Human-readable reference (e.g. INC-123) - **permalink**: Link to the incident in incident.io - **severity**: Severity details if set - **visibility**: public or private - **created_at**, **updated_at**: Timestamps ### Example Output ```json { "data": { "created_at": "2021-08-17T13:28:57.801578Z", "id": "01FDAG4SAP5TYPT98WGR2N7W91", "name": "Database connectivity issues", "permalink": "https://app.incident.io/incidents/123", "reference": "INC-123", "severity": { "id": "01FCNDV6P870EA6S7TK1DSYDG0", "name": "Minor" }, "summary": "Users are experiencing slow queries and connection timeouts.", "updated_at": "2021-08-17T13:28:57.801578Z", "visibility": "public" }, "timestamp": "2026-01-19T12:00:00Z", "type": "incident.incident" } ``` #### JFrog Artifactory Source URL: https://docs.superplane.com/components/jfrogartifactory Manage artifacts in JFrog Artifactory repositories import { CardGrid, LinkCard } from "@astrojs/starlight/components"; ## Triggers ## Actions ## Instructions To set up the JFrog Artifactory integration: 1. Log in to your JFrog Platform 2. Go to **User Menu** (top right) -> **Edit Profile** -> **Authentication Settings** 3. Click **Generate an Identity Token** 4. Copy the token and paste it in the **Access Token** field below 5. Enter your JFrog Platform URL without the /artifactory suffix (e.g. https://mycompany.jfrog.io) ## On Artifact Uploaded **Trigger key:** `jfrogArtifactory.onArtifactUploaded` The On Artifact Uploaded trigger starts a workflow execution when an artifact is deployed to JFrog Artifactory. ### Configuration - **Repository** (optional): Filter events to a specific repository. Leave empty to trigger for all repositories. ### Outputs - **Default channel**: Emits artifact deploy data including repo, path, name, size, and sha256. ### Example Data ```json { "data": { "name": "artifact-1.0.jar", "path": "com/example/artifact-1.0.jar", "repo": "libs-release-local", "sha256": "abc123def456ghi789jkl012mno345pqr678stu901vwx234yz567", "size": 12345 }, "timestamp": "2026-01-23T12:00:00Z", "type": "jfrogArtifactory.artifactUploaded" } ``` ## Delete Artifact **Component key:** `jfrogArtifactory.deleteArtifact` The Delete Artifact component removes an artifact from a JFrog Artifactory repository. ### Use Cases - **Cleanup pipelines**: Remove outdated or temporary artifacts after a release - **Storage management**: Delete artifacts that are no longer needed - **Automated housekeeping**: Trigger deletions based on workflow conditions ### Configuration - **Repository**: Select the Artifactory repository containing the artifact - **Path**: The path to the artifact within the repository (supports expressions) ### Output Returns the repository and path of the deleted artifact. ### Example Output ```json { "data": { "path": "/com/example/artifact/1.0/artifact-1.0.jar", "repo": "libs-release-local" }, "timestamp": "2026-01-23T12:00:00Z", "type": "jfrogArtifactory.artifact.deleted" } ``` ## Get Artifact Info **Component key:** `jfrogArtifactory.getArtifactInfo` The Get Artifact Info component retrieves metadata about an artifact stored in JFrog Artifactory. ### Use Cases - **Artifact verification**: Check artifact existence and checksums before deployment - **Pipeline metadata**: Retrieve artifact details for downstream workflow steps - **Audit and tracking**: Get creation time, size, and author information ### Configuration - **Repository**: Select the Artifactory repository containing the artifact - **Path**: The path to the artifact within the repository (supports expressions) ### Output Returns artifact metadata including repository, path, size, checksums, download URI, and timestamps. ### Example Output ```json { "data": { "checksums": { "md5": "d41d8cd98f00b204e9800998ecf8427e", "sha1": "da39a3ee5e6b4b0d3255bfef95601890afd80709", "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" }, "created": "2026-01-15T10:30:00.000Z", "createdBy": "admin", "downloadUri": "https://mycompany.jfrog.io/artifactory/libs-release-local/com/example/artifact/1.0/artifact-1.0.jar", "lastModified": "2026-01-15T10:30:00.000Z", "mimeType": "application/java-archive", "modifiedBy": "admin", "path": "/com/example/artifact/1.0/artifact-1.0.jar", "repo": "libs-release-local", "size": "12345", "uri": "https://mycompany.jfrog.io/artifactory/api/storage/libs-release-local/com/example/artifact/1.0/artifact-1.0.jar" }, "timestamp": "2026-01-23T12:00:00Z", "type": "jfrogArtifactory.artifact.info" } ``` #### Jira Source URL: https://docs.superplane.com/components/jira Manage issues in Jira import { CardGrid, LinkCard } from "@astrojs/starlight/components"; ## Actions ## Instructions To connect Jira to SuperPlane: 1. Open [Atlassian API tokens](https://id.atlassian.com/manage-profile/security/api-tokens). 2. Click **Create API token**, give it a recognizable label, and copy the generated token. 3. Paste your **Jira Site URL** into SuperPlane. For Jira Cloud, this usually looks like `https://your-domain.atlassian.net`. 4. Paste the Atlassian account **Email** that owns the API token. 5. Paste the generated **API Token**. ## Approve Workflow **Component key:** `jira.approveWorkflow` The Approve Workflow component approves or declines a Jira Service Management request approval. ### Use Cases - **Automated approval routing**: submit a JSM approval decision after external checks pass - **Escalation handling**: decline requests when a SuperPlane workflow detects a failed precondition - **Audit context**: add a customer request comment before submitting the approval decision ### Configuration - **Issue Key**: JSM request issue key, for example `ITSM-123`. - **Decision**: Approve or decline. - **Approval Selector**: Choose the latest pending approval or pick a specific one from the list. - **Approval**: The pending approval to decide. Required when picking a specific approval. - **Comment**: Optional public customer request comment posted before the approval decision. ### Output Returns the updated approval payload from Jira Service Management. ### Notes - Requires the API token's user to be in the approver list. - This component only works on Jira Service Management customer requests, not standard Jira issues. ### Example Output ```json { "data": { "approvers": [ { "approver": { "accountId": "5b10a2844c20165700ede21g", "displayName": "Alice Example", "emailAddress": "alice@example.com" }, "approverDecision": "approved" } ], "completedDate": { "iso8601": "2026-01-19T13:15:00+0000", "jira": "2026-01-19T13:15:00.000+0000" }, "finalDecision": "approved", "id": "1", "name": "Manager approval" }, "timestamp": "2026-01-19T13:15:00Z", "type": "jira.approval" } ``` ## Create Alert **Component key:** `jira.createAlert` The Create Alert component opens a new alert on Jira Service Management. ### Use Cases - **Monitoring integrations**: Raise an alert from metrics or logs - **Automation**: Drive on-call notifications from workflows ### Configuration - **Message** (required): Alert message text. - **Description**, **Note**, **Alias**, **Entity**, **Source** (optional): Standard Ops alert fields. - **Priority** (optional): Typically P1–P5; choose "Don't set" to omit. - **Tags** / **Actions** (optional): Lists of strings. - **Responders** / **Visible to** (optional): Rows with **id** and **type** (team, user, escalation, or schedule). - **Extra properties** (optional): JSON object merged into the API **extraProperties** field. ### Output After the Ops API accepts create, SuperPlane waits for asynchronous processing via the alerts **request status** API, then **GET**s the resulting alert. The payload matches **Get Alert** (full Ops alert JSON: **id**, **message**, **status**, etc.). If Jira delays processing beyond the polling window the step fails — use **Get Alert** with the Ops request id noted in logs if Atlassian exposes it. ### Notes - Requires Jira Service Management Ops permissions and API scopes for alerts on your Atlassian site; the integration stores your site **cloud id** during sync. ### Example Output ```json { "data": { "acknowledged": false, "actions": [], "alias": "alias", "count": 2, "createdAt": "2026-01-19T12:00:00Z", "description": "description", "entity": "an entity", "extraProperties": {}, "id": "439aa701-7cd6-4549-8992-d06650561222-1779166598474", "integrationName": "", "integrationType": "", "lastOccuredAt": "2026-01-19T12:00:00Z", "message": "message", "owner": "", "priority": "P2", "responders": [], "seen": false, "services": [], "snoozed": false, "source": "source", "status": "open", "tags": [ "test-tag" ], "tinyId": "4", "updatedAt": "2026-01-19T12:00:00Z" }, "timestamp": "2026-01-19T12:00:00Z", "type": "jira.alert.created" } ``` ## Create Heartbeat **Component key:** `jira.createHeartbeat` The Create Heartbeat component registers a new heartbeat in Jira Service Management Operations. ### Use Cases - **Cron monitoring**: Register an expected ping interval for scheduled jobs or agents - **Infrastructure checks**: Create heartbeats when provisioning monitored systems - **Automation setup**: Pair with Ping Heartbeat in workflows that report liveness ### Configuration - **Team**: JSM Operations team that owns the heartbeat - **Name** (required): Unique heartbeat name within the team - **Interval** (required): How often a ping is expected (minimum 1) - **Interval unit**: minutes, hours, or days - **Enabled**: Whether monitoring is active (defaults to enabled) - **Description**, **alert message**, **alert tags**, **alert priority**: Optional expiration alert settings ### Output Returns the created heartbeat object from the JSM Operations API, including **name**, **interval**, **intervalUnit**, **enabled**, and **status**. ### Notes - Requires Jira Service Management Operations (Premium) with heartbeats enabled on your site. - Re-sync the Jira integration so SuperPlane has your Atlassian cloud id. ### Example Output ```json { "data": { "alertMessage": "The alert has been raised", "alertPriority": "P3", "alertTags": [ "tag1" ], "description": "my new heartbeat", "enabled": true, "interval": 1, "intervalUnit": "minutes", "name": "DNS checker", "ownerTeamId": "b071f2e7-2159-4110-aa25-7718b2713ed5", "status": "Pending" }, "timestamp": "2026-01-19T12:00:00Z", "type": "jira.heartbeat.created" } ``` ## Create Incident **Component key:** `jira.createIncident` The Create Incident component opens a new incident in Jira Service Management. ### Use Cases - **Alert-driven incidents**: Create an incident from a monitoring or ticketing workflow - **Cross-tool orchestration**: Open a JSM incident when another system reports an outage - **Responder assignment**: Pass responders and other fields supported by your service desk ### Configuration - **Service desk**: Choose a Jira Service Management service desk (from your site via the JSM API) - **Request type**: Choose a request type on that service desk (lists after a service desk is selected) - **Summary** (required): Short title for the incident; sent as the Jira **summary** field (Jira requires this). You can set this directly, or supply summary only via **Additional fields**. - **Description** (optional): Plain text stored as Jira description (Atlassian Document Format). - **Due date** (optional): Jira **duedate** (use your site date format, typically YYYY-MM-DD). - **Priority** (optional): Jira priority **name** (for example Medium). - **Impact** (optional): Impact level from your Jira request type (options load after service desk and request type are selected). - **Urgency** (optional): Urgency level from your Jira request type (options load after service desk and request type are selected). - **Original estimate** (optional): Jira **timetracking.originalEstimate** (for example 2h, 1d). - **Custom fields** (optional): List of Jira field ids with JSON values—for affected services, pending reason, or any customfield_*; the value must be valid JSON (object or string) as Jira expects for that field type. - **Additional fields** (optional): JSON object merged into the API **fields** map (same pattern as other integrations such as Honeycomb **Fields JSON**). - **Update** (optional): JSON object for the Incidents API **update** property. - **Alert IDs** (optional): List of alert id strings to associate with the incident. ### Output Returns **id** (numeric issue id), **key** (e.g. ITSM-30), and **self** (issue REST URL) from the create response. ### Notes - Requires a Jira Cloud site with Jira Service Management and a synced SuperPlane Jira integration (cloud id is resolved automatically). - **Request types** must belong to Jira's **Incident management** work category; other request types (for example service requests) are hidden from the picker when Jira returns a practice field on request types. If your site uses an unrecognized practice value, contact support with a sample from GET /rest/servicedeskapi/servicedesk/{serviceDeskId}/requesttype/{requestTypeId} with expand=practice. - Field ids such as responders are site-specific; use **Custom fields** or **Additional fields** with values that match your JSM configuration. ### Example Output ```json { "data": { "id": "10050", "key": "ITSM-30", "self": "https://your-domain.atlassian.net/rest/api/3/issue/10050" }, "timestamp": "2026-01-19T12:00:00Z", "type": "jira.incident.created" } ``` ## Create Issue **Component key:** `jira.createIssue` The Create Issue component creates a new issue in Jira. ### Use Cases - **Task creation**: Automatically create tasks from workflow events - **Bug tracking**: Create bugs from error detection systems - **Feature requests**: Generate feature request issues from external inputs ### Configuration - **Project**: The Jira project to create the issue in - **Issue Type**: The type of issue (scoped to the chosen project) - **Summary**: The issue summary/title - **Description**: Optional description text - **Assignee**: Optional Jira user to assign the issue to - **Status**: Optional initial status. Jira always creates issues in the workflow's initial state, so when this is set the component executes a transition immediately after create. The status must be reachable via a transition from the initial state. ### Output Returns the created issue including: - **id**: The issue ID - **key**: The issue key (e.g. PROJ-123) - **self**: API URL for the issue - **fields**: Full issue fields after any status transition ### Example Output ```json { "data": { "fields": { "assignee": { "accountId": "5b10a2844c20165700ede21g", "displayName": "Alice Example", "emailAddress": "alice@example.com" }, "created": "2026-01-19T12:00:00.000+0000", "issuetype": { "name": "Bug" }, "labels": [ "backend", "p1" ], "priority": { "name": "High" }, "project": { "id": "10000", "key": "PROJ", "name": "Proj" }, "reporter": { "accountId": "5b10ac8d82e05b22cc7d4ef5", "displayName": "Bob Example" }, "status": { "name": "To Do", "statusCategory": { "key": "new", "name": "To Do" } }, "summary": "Investigate timeout on checkout flow", "updated": "2026-01-19T12:00:00.000+0000" }, "id": "10001", "key": "PROJ-123", "self": "https://your-domain.atlassian.net/rest/api/3/issue/10001" }, "timestamp": "2026-01-19T12:00:00Z", "type": "jira.issue" } ``` ## Delete Alert **Component key:** `jira.deleteAlert` The Delete Alert component removes an alert from Jira Service Management. Deletion is processed asynchronously like other mutating Ops operations. ### Configuration - **Alert**: Pick the Ops alert to delete from the integration resource list. ### Output Includes the API acknowledgement (**requestId**, etc.) and **deleted**: true for workflow convenience. ### Example Output ```json { "data": { "alertId": "439aa701-7cd6-4549-8992-d06650561222-1779166598474", "deleted": true, "requestId": "82e59857-e111-44a3-9f72-013783b94f52", "result": "Request will be processed" }, "timestamp": "2026-01-19T12:00:00Z", "type": "jira.alert.deleted" } ``` ## Delete Heartbeat **Component key:** `jira.deleteHeartbeat` The Delete Heartbeat component removes a heartbeat from Jira Service Management Operations. ### Use Cases - **Decommissioning**: Remove heartbeats when systems are retired - **Test cleanup**: Delete heartbeats created during automation tests - **Lifecycle management**: Tear down monitoring when workflows are disabled ### Configuration - **Team**: Team that owns the heartbeat - **Heartbeat**: Name of the heartbeat to delete ### Output Confirms deletion with **deleted** set to true and the **name** of the removed heartbeat. ### Notes - Requires Jira Service Management Operations with heartbeats enabled. - Deletion is permanent; recreate the heartbeat if needed. ### Example Output ```json { "data": { "deleted": true, "name": "DNS checker" }, "timestamp": "2026-01-19T12:00:00Z", "type": "jira.heartbeat.deleted" } ``` ## Delete Incident **Component key:** `jira.deleteIncident` The Delete Incident component removes an incident from Jira Service Management. ### Use Cases - **Automated cleanup**: Remove incidents created during tests or erroneous automation - **Lifecycle workflows**: Delete when a duplicate or mistaken incident is closed upstream ### Configuration - **Project** (optional): Narrows the issue picker to one Jira project (up to 500 most recently updated issues in that project). - **Issue**: The incident issue to delete (issue key from Jira search). ### Output Confirms deletion with **deleted** set to true. ### Example Output ```json { "data": { "deleted": true }, "timestamp": "2026-01-19T12:00:00Z", "type": "jira.incident.deleted" } ``` ## Delete Issue **Component key:** `jira.deleteIssue` The Delete Issue component permanently removes an issue from Jira. ### Use Cases - **Cleanup**: remove placeholder or duplicate issues created by automated flows - **CRUD completion**: pair with create/update flows for full lifecycle management ### Configuration - **Project**: The Jira project the issue belongs to - **Issue Key**: The issue key (e.g. `PROJ-123`) - **Delete Subtasks**: Also delete the issue's subtasks (Jira returns an error if subtasks exist and this is false) ### Output Returns the deleted issue's `id` and `key`, plus `deleted: true`. ### Example Output ```json { "data": { "deleted": true, "id": "10001", "key": "PROJ-123" }, "timestamp": "2026-01-19T13:00:00Z", "type": "jira.issueDeleted" } ``` ## Get Alert **Component key:** `jira.getAlert` The Get Alert component returns full alert details from Jira Service Management. ### Configuration - **Alert**: Pick a recent Ops alert from the integration resource list (same as Update / Delete Alert). ### Output Payload type **jira.alert.fetched** with the alert object (message, status, priority, responders, tags, etc.). ### Example Output ```json { "data": { "acknowledged": false, "actions": [], "alias": "alias", "count": 3, "createdAt": "2026-01-19T12:00:00Z", "description": "description", "entity": "entity", "extraProperties": {}, "id": "20bfb3c4-ded8-4123-b9d2-c7840a0d4589-1779115726660", "integrationName": "", "integrationType": "", "lastOccuredAt": "2026-01-19T12:00:00Z", "message": "message", "owner": "", "priority": "P2", "responders": [], "seen": false, "services": [], "snoozed": false, "source": "source", "status": "open", "tags": [], "tinyId": "3", "updatedAt": "2026-01-19T12:00:00Z" }, "timestamp": "2026-01-19T12:00:00Z", "type": "jira.alert.fetched" } ``` ## Get Incident **Component key:** `jira.getIncident` The Get Incident component returns incident details from Jira Service Management. ### Use Cases - **Enrichment**: Load incident DTO after an issue webhook or workflow step - **Status checks**: Read priority, status, responders, and affected services from JSM ### Configuration - **Project** (optional): When set, the issue picker lists issues in that project (by project key), paged from Jira search (up to 500, most recently updated first). Leave empty to list issues updated in roughly the last 90 days across projects you can access (same cap and ordering). - **Issue**: Choose an issue by key (from Jira search). The stored value is the issue key; numeric ids still work when they are saved as the issue reference. ### Output Payload type jira.incident.fetched with the incident object returned by Atlassian (summary, reporter, priority, status, responders, etc.). ### Example Output ```json { "data": { "priority": { "id": "1", "name": "High" }, "summary": "Example incident" }, "timestamp": "2026-01-19T12:00:00Z", "type": "jira.incident.fetched" } ``` ## Get Issue **Component key:** `jira.getIssue` The Get Issue component retrieves a Jira issue and its fields for downstream routing and inspection. ### Use Cases - **Routing decisions**: inspect status, assignee, labels, or priority before branching - **Escalation context**: include issue details in notifications or downstream tickets - **Cross-tool sync**: enrich workflows that mirror Jira state into other systems ### Configuration - **Project**: The Jira project the issue belongs to - **Issue Key**: The issue key (e.g. `PROJ-123`) - **Expand**: Optional comma-separated Jira expand values, such as `renderedFields,names` ### Output Returns the Jira issue object including `id`, `key`, `self` and the full `fields` map. ### Example Output ```json { "data": { "fields": { "assignee": { "accountId": "5b10a2844c20165700ede21g", "displayName": "Alice Example", "emailAddress": "alice@example.com" }, "created": "2026-01-19T12:00:00.000+0000", "issuetype": { "name": "Bug" }, "labels": [ "backend", "p1" ], "priority": { "name": "High" }, "project": { "id": "10000", "key": "PROJ", "name": "Proj" }, "reporter": { "accountId": "5b10ac8d82e05b22cc7d4ef5", "displayName": "Bob Example" }, "status": { "name": "In Progress", "statusCategory": { "key": "indeterminate", "name": "In Progress" } }, "summary": "Investigate timeout on checkout flow", "updated": "2026-01-19T12:30:00.000+0000" }, "id": "10001", "key": "PROJ-123", "self": "https://your-domain.atlassian.net/rest/api/3/issue/10001" }, "timestamp": "2026-01-19T12:00:00Z", "type": "jira.issue" } ``` ## Get Workflow **Component key:** `jira.getWorkflow` The Get Workflow component returns the Jira workflow that governs a given issue. ### Use Cases - **State-machine introspection**: see every status in the workflow plus where the issue is right now - **Routing decisions**: branch on which transitions are currently reachable before running `transitionIssue` - **Operator dashboards**: render the workflow as a graph next to the issue ### Configuration - **Project**: The Jira project the issue belongs to. - **Issue Key**: Jira issue key, for example `PROJ-123`. ### Output Returns: - `workflowName` and `workflowSchemeName` — the workflow scheme assigned to the project and the workflow it routes the issue's type to. - `currentStatus` / `currentStatusId` — where the issue is now. - `statuses` — every status the workflow defines (with `isCurrent` set on the current one). - `availableTransitions` — transitions reachable from the issue's current state, each with the transition id, name, and target status. ### Notes - Resolving the bound workflow goes `issue → project + issue type → workflow scheme → workflow`. Team-managed (next-gen) projects don't expose a workflow scheme; in that case `workflowName` and `statuses` are empty but `currentStatus` and `availableTransitions` are still populated. - The `availableTransitions` list reflects workflow rules, conditions, and the calling user's permissions — it is exactly what Jira would offer in the issue view. ### Example Output ```json { "data": { "availableTransitions": [ { "id": "21", "name": "Stop progress", "toStatus": "To Do", "toStatusId": "10001" }, { "id": "31", "name": "Resolve", "toStatus": "Done", "toStatusId": "10003" } ], "currentStatus": "In Progress", "currentStatusId": "10002", "issueKey": "PROJ-123", "issueType": "Task", "projectKey": "PROJ", "statuses": [ { "category": "TODO", "id": "10001", "name": "To Do" }, { "category": "IN_PROGRESS", "id": "10002", "isCurrent": true, "name": "In Progress" }, { "category": "DONE", "id": "10003", "name": "Done" } ], "workflowName": "Software Simplified Workflow", "workflowSchemeId": "101010", "workflowSchemeName": "Default workflow scheme" }, "timestamp": "2026-01-19T12:00:00Z", "type": "jira.workflow" } ``` ## Ping Heartbeat **Component key:** `jira.pingHeartbeat` The Ping Heartbeat component reports that a monitored system is alive. ### Use Cases - **Scheduled jobs**: Ping at the end of a cron workflow so JSM detects missed runs - **Deploy pipelines**: Confirm a service is up after deployment - **Agent check-ins**: Let automation prove an external process completed ### Configuration - **Team**: Team that owns the heartbeat - **Heartbeat**: Heartbeat name to ping (from the team's heartbeat list) ### Output Returns the API **message** (for example "PONG - Heartbeat received"). ### Notes - Requires Jira Service Management Operations with heartbeats enabled. - The heartbeat must already exist (use Create Heartbeat or configure it in JSM). ### Example Output ```json { "data": { "message": "PONG - Heartbeat received" }, "timestamp": "2026-01-19T12:00:00Z", "type": "jira.heartbeat.pinged" } ``` ## Transition Issue **Component key:** `jira.transitionIssue` The Transition Issue component moves a Jira issue through its workflow. ### Use Cases - **Automated triage**: move issues into the next workflow status after a SuperPlane event - **Cross-tool state sync**: mirror status changes from incident or deployment systems - **Resolution automation**: close issues with a transition-scoped resolution and comment ### Configuration - **Project**: Optional Jira project used to narrow the status picker. - **Issue Key**: Jira issue key, for example `PROJ-123`. - **Target Status**: Status to move the issue to. It must be reachable from the issue's current status. - **Comment**: Optional transition comment. - **Resolution**: Optional Jira resolution name to set during the transition. ### Output Returns the refreshed Jira issue after the transition. ### Notes - Jira does not allow direct status writes. This component finds an available transition whose target status matches the requested status. - Workflow conditions and validators still apply. ### Example Output ```json { "data": { "fields": { "project": { "id": "10000", "key": "PROJ", "name": "Proj" }, "resolution": { "name": "Done" }, "status": { "name": "Done", "statusCategory": { "key": "done", "name": "Done" } }, "summary": "Investigate timeout on checkout flow", "updated": "2026-01-19T13:00:00.000+0000" }, "id": "10001", "key": "PROJ-123", "self": "https://your-domain.atlassian.net/rest/api/3/issue/10001" }, "timestamp": "2026-01-19T13:00:00Z", "type": "jira.issue" } ``` ## Update Alert **Component key:** `jira.updateAlert` The Update Alert component runs updates on alerts on Jira Service Management. Toggle each optional subsection you need; untouched sections are not sent to Jira. ### Optional updates - **Description** → updates alert description - **Message** → updates alert message - **Priority** → updates alert priority (omit with "Don't set") - **Assignment** → assigns the alert to a Jira user (Atlassian account ID from the assignee picker) - **New note** → adds a new note - **Update existing note** → updates existing note with nested **note id** + **note** text - **Acknowledge alert** → acknowledges alert - **Close alert** → closes alert After updates, SuperPlane polls the **last asynchronous** Ops response (when applicable) and emits a fresh **GET alert** payload like **Get Alert**. ### Example Output ```json { "data": { "acknowledged": true, "actions": [], "alias": "alias", "count": 3, "createdAt": "2026-01-19T12:00:00Z", "description": "description", "entity": "entity", "extraProperties": {}, "id": "20bfb3c4-ded8-4123-b9d2-c7840a0d4589-1779115726660", "integrationName": "", "integrationType": "", "lastOccuredAt": "2026-01-19T12:00:00Z", "message": "message", "owner": "", "priority": "P5", "responders": [], "seen": false, "services": [], "snoozed": false, "source": "source", "status": "open", "tags": [], "tinyId": "3", "updatedAt": "2026-01-19T12:00:00Z" }, "timestamp": "2026-01-19T12:00:00Z", "type": "jira.alert.updated" } ``` ## Update Heartbeat **Component key:** `jira.updateHeartbeat` The Update Heartbeat component changes settings on an existing JSM Operations heartbeat. ### Use Cases - **Tune intervals**: Adjust expected ping frequency after operational changes - **Enable/disable monitoring**: Turn heartbeats on or off from automation - **Alert tuning**: Update expiration alert message, tags, or priority ### Configuration - **Team** and **Heartbeat** (required): Identify the heartbeat to update - **Optional fields** use toggles: only enabled fields are sent to the Jira API - Heartbeat **name** cannot be changed (create a new heartbeat instead) ### Output Returns the updated heartbeat object from the JSM Operations API. ### Notes - Enable at least one optional field toggle before saving or running the node. - Requires Jira Service Management Operations with heartbeats enabled. ### Example Output ```json { "data": { "alertMessage": "The alert has been raised", "alertPriority": "P3", "alertTags": [ "tag1" ], "description": "my new heartbeat", "enabled": true, "interval": 5, "intervalUnit": "minutes", "name": "DNS checker", "ownerTeamId": "b071f2e7-2159-4110-aa25-7718b2713ed5", "status": "Responsive" }, "timestamp": "2026-01-19T12:00:00Z", "type": "jira.heartbeat.updated" } ``` ## Update Issue **Component key:** `jira.updateIssue` The Update Issue component updates fields on an existing Jira issue. ### Use Cases - **Automated triage**: change status, priority, or assignee when a workflow processes the issue - **Cross-tool sync**: mirror state from another system into Jira - **Bulk relabeling**: apply labels based on workflow inputs ### Configuration - **Project**: The Jira project the issue belongs to - **Issue Key**: The issue key (e.g. `PROJ-123`) - **Summary**, **Description**, **Issue Type**, **Assignee**, **Priority**, **Labels**: Optional fields to update. At least one must be supplied. - **Notify Users**: Whether to send notification emails (defaults to Jira's behaviour) ### Output Returns the updated Jira issue as fetched after the update. ### Example Output ```json { "data": { "fields": { "assignee": { "accountId": "5b10a2844c20165700ede21g", "displayName": "Alice Example" }, "issuetype": { "name": "Bug" }, "labels": [ "backend", "p1", "in-review" ], "priority": { "name": "Medium" }, "project": { "id": "10000", "key": "PROJ", "name": "Proj" }, "status": { "name": "In Review" }, "summary": "Investigate timeout on checkout flow (updated)", "updated": "2026-01-19T12:45:00.000+0000" }, "id": "10001", "key": "PROJ-123", "self": "https://your-domain.atlassian.net/rest/api/3/issue/10001" }, "timestamp": "2026-01-19T12:45:00Z", "type": "jira.issue" } ``` #### LaunchDarkly Source URL: https://docs.superplane.com/components/launchdarkly Manage feature flags and react to flag changes in LaunchDarkly import { CardGrid, LinkCard } from "@astrojs/starlight/components"; ## Triggers ## Actions ## Instructions ## API integration 1. In the [LaunchDarkly Account settings > Authorization](https://app.launchdarkly.com/settings/authorization), click **Create token**. 2. Give the token a name and select a role with at least **Reader** permissions for feature flags. - For the **Delete Feature Flag** action, the role must also include **Writer** permissions. 3. Create the token and **paste the API access token** in the Configuration section below. ## On Feature Flag Change **Trigger key:** `launchdarkly.onFeatureFlagChange` The On Feature Flag Change trigger starts a workflow execution when LaunchDarkly sends webhooks for feature flags in a project. ### Use Cases - **Deployment automation**: Trigger deployments or rollbacks when a feature flag changes - **Audit workflows**: Track and log changes to flags for compliance - **Notification workflows**: Send notifications when a flag is created, updated, or deleted - **Integration workflows**: Sync flag changes with external systems ### Configuration - **Project**: The LaunchDarkly project to monitor - **Environments**: Optionally filter by environment(s). Leave empty to receive events for all environments. - **Feature Flags**: Optionally filter by specific flags or patterns. Leave empty to receive events for all flags. - **Actions**: Optionally filter by specific actions (e.g. only when a flag is turned on or off). Leave empty to receive all actions. ### Webhook Setup The webhook is automatically created in LaunchDarkly when you save the canvas. No manual setup is required. SuperPlane uses the LaunchDarkly API (via your configured API access token) to create a signed webhook scoped to the selected project, and securely stores the auto-generated signing secret. When LaunchDarkly sends events, SuperPlane verifies the signature and filters to the configured environments, flags, and actions automatically. ### Example Data ```json { "data": { "accesses": [ { "action": "updateOn", "resource": "proj/default:env/test:flag/another-toggle-feature" } ], "date": 1771939563356, "description": "", "kind": "flag", "member": { "email": "user@example.com", "firstName": "John", "lastName": "Doe" }, "name": "Another Toggle Feature", "parent": { "name": "Test", "resource": "proj/default:env/test" }, "target": { "name": "Another Toggle Feature", "resources": [ "proj/default:env/test:flag/another-toggle-feature" ] }, "title": "John Doe turned off the flag Another Toggle Feature in Test", "titleVerb": "turned off the flag" }, "timestamp": "2026-02-24T12:00:00Z", "type": "launchdarkly.flag.updateOn" } ``` ## Delete Feature Flag **Component key:** `launchdarkly.deleteFeatureFlag` The Delete Feature Flag component permanently deletes a feature flag from a LaunchDarkly project. ### Use Cases - **Flag cleanup**: Remove stale or temporary flags after rollout is complete - **Automated lifecycle**: Delete flags as part of a release workflow - **Maintenance workflows**: Clean up archived flags that are no longer needed ### Configuration - **Project Key**: The key of the LaunchDarkly project containing the flag - **Flag Key**: The key of the feature flag to delete (supports expressions) ### Output Returns a confirmation payload with the deleted flag's project and flag keys. **Warning**: This action is irreversible. Once deleted, the flag and all its targeting rules are permanently removed. ### Example Output ```json { "data": { "deleted": true, "flagKey": "toggle-feature", "projectKey": "default" }, "timestamp": "2026-01-19T12:00:00Z", "type": "launchdarkly.flag.deleted" } ``` ## Get Feature Flag **Component key:** `launchdarkly.getFeatureFlag` The Get Feature Flag component retrieves a specific feature flag from a LaunchDarkly project. ### Use Cases - **Flag lookup**: Fetch flag details for processing or display - **Workflow automation**: Get flag information to make decisions in workflows - **Status checking**: Check flag status before performing actions - **Audit and monitoring**: Retrieve flag data for compliance workflows ### Configuration - **Project Key**: The key of the LaunchDarkly project containing the flag - **Flag Key**: The key of the feature flag to retrieve (supports expressions) ### Output Returns the complete feature flag object including: - Flag key, name, and description - Kind (boolean, multivariate) - Creation date - Archived and temporary status - Variations, environments, and targeting rules ### Example Output ```json { "data": { "archived": false, "creationDate": 1704067200000, "description": "Controls access to the new feature", "key": "toggle-feature", "kind": "boolean", "name": "Toggle Feature", "temporary": false, "variations": [ { "name": "Enabled", "value": true }, { "name": "Disabled", "value": false } ] }, "timestamp": "2026-01-19T12:00:00Z", "type": "launchdarkly.flag" } ``` #### Logfire Source URL: https://docs.superplane.com/components/logfire Set up Logfire for AI Observability import { CardGrid, LinkCard } from "@astrojs/starlight/components"; ## Triggers ## Actions ## Instructions ## Create a Logfire API key for SuperPlane 1. Open **Settings** in Logfire. 2. Under **ORG: <your-username>**, select **API Keys**. 3. Click **New API Key**. 4. Enter a key name. 5. Enable these **five** scopes: - **Organization scopes**: `organization:write_channel` (required for auto-creating webhook channels) - **Project scopes**: `project:read `, `project:read_token `, `project:read_alert `, and `project:write_alert` 6. Select **All Project** or a specific project from the dropdown. 7. Click **Create API Key**. 8. Copy the API key and paste it. ## On Alert Received **Trigger key:** `logfire.onAlertReceived` The On Alert Received trigger starts a workflow execution when Logfire sends an alert payload to your SuperPlane webhook URL. ### Configuration Select the Logfire Project and Alert you want to trigger the workflow. ### Webhook setup After you save this trigger, SuperPlane provides a webhook URL. Add that URL as a Logfire notification webhook target so alert events are sent to this workflow. ### Example Data ```json { "data": { "alertId": "alt_123", "alertName": "Latency spike", "eventType": "firing", "message": "p95 latency exceeded threshold", "severity": "warning", "url": "https://logfire-us.pydantic.dev/my-org/my-project/alerts/alt_123" }, "timestamp": "2026-03-23T12:00:00.000000000Z", "type": "logfire.alert.received" } ``` ## Query Logfire **Component key:** `logfire.queryLogfire` The Query Logfire component executes a read-only SQL query against Logfire and returns query results for use in downstream steps. ### Use Cases - **Investigate traces and spans**: Query recent records for errors, latency spikes, or specific services - **Build reporting workflows**: Export Logfire data into Slack, email, dashboards, or data stores - **Conditional automation**: Query for specific conditions, then branch workflow logic based on returned rows - **Scheduled analytics**: Run recurring SQL queries to monitor usage and operational metrics ### Configuration - **Project**: Required Logfire project to query (scopes the generated read token) - **SQL**: Required SQL query (supports expressions). Example: `SELECT start_timestamp, message FROM records LIMIT 10` - **Time Window**: Optional preset time window (e.g., Last 5 minutes, Last 1 hour). Select "Custom" to specify exact timestamps - **Limit**: Optional maximum rows to return. If omitted, Logfire defaults to `500`; maximum is `10000` - **Row Oriented**: Optional JSON format toggle. `false` returns column-oriented JSON; `true` returns row-oriented JSON ### Output Emits one `logfire.query` event containing the Logfire query response (for example `columns` and/or `rows`, depending on format options). Use this output to transform, filter, or route query results to other components. ### Example Output ```json { "data": { "columns": [ { "name": "start_timestamp", "type": "timestamp" }, { "name": "message", "type": "text" } ], "rows": [ [ "2026-01-01T00:00:00Z", "Example Logfire record" ] ] }, "timestamp": "2026-03-23T12:00:00.000000000Z", "type": "logfire.query" } ``` #### Microsoft Azure Source URL: https://docs.superplane.com/components/microsoftazure Manage and automate Microsoft Azure resources and services import { CardGrid, LinkCard } from "@astrojs/starlight/components"; ## Triggers ## Actions ## Instructions ## Azure Workload Identity Federation Setup To connect SuperPlane to Microsoft Azure using Workload Identity Federation: ### 1. Create or Select an App Registration 1. Go to **Azure Portal** → **Azure Active Directory** → **App registrations** 2. Create a new registration or select an existing app 3. Note the **Application (client) ID** and **Directory (tenant) ID** ### 2. Complete the Connection Enter the following information below and create the integration: - **Tenant ID**: Your Azure AD tenant ID - **Client ID**: Your app registration's client ID - **Subscription ID**: Your Azure subscription ID After creation, you will be guided through configuring the Federated Identity Credential and granting the required permissions. SuperPlane will use Workload Identity Federation to authenticate without storing any credentials. ## On Blob Created **Trigger key:** `azure.onBlobCreated` The On Blob Created trigger starts a workflow execution when a blob is created or replaced in an Azure Storage Account. ### Use Cases - **Data pipelines**: Trigger processing when new files arrive in a storage container - **Image processing**: React to new images or media uploaded to blob storage - **Audit and compliance**: Record blob creation events for traceability - **ETL workflows**: Kick off data transformation when input files are uploaded ### How It Works This trigger listens to Azure Event Grid events from a Storage Account. When a blob is created or replaced, the `Microsoft.Storage.BlobCreated` event is delivered and the trigger fires with the full event payload. ### Configuration - **Resource Group** (required): The resource group containing the Storage Account. - **Storage Account** (required): The Storage Account to watch. - **Container Filter** (optional): A regex pattern to filter by container name. - **Blob Filter** (optional): A regex pattern to filter by blob path. ### Event Data Each blob created event includes: - **subject**: The full blob path in the format /blobServices/default/containers/{container}/blobs/{blob} - **data.api**: The operation that triggered the event (e.g., PutBlob, CopyBlob) - **data.contentType**: The content type of the blob - **data.contentLength**: The size of the blob in bytes - **data.blobType**: The blob type (BlockBlob, PageBlob, AppendBlob) - **data.url**: The URL of the blob ### Example Data ```json { "data": { "data": { "api": "PutBlob", "blobType": "BlockBlob", "clientRequestId": "6d6cef9a-a602-4a23-bc26-91bb68a2bf74", "contentLength": 524288, "contentType": "text/csv", "eTag": "0x8D4BCC2E4835CD0", "requestId": "d1e6b5a4-0001-0035-4a7b-2e5c4f000000", "sequencer": "00000000000004420000000000028963", "url": "https://mystorageaccount.blob.core.windows.net/mycontainer/path/to/myfile.csv" }, "dataVersion": "", "eventTime": "2026-03-16T10:00:00Z", "eventType": "Microsoft.Storage.BlobCreated", "id": "831e1650-001e-001b-66ab-eeb76e069631", "metadataVersion": "1", "subject": "/blobServices/default/containers/mycontainer/blobs/path/to/myfile.csv", "topic": "/subscriptions/12345678-1234-1234-1234-123456789abc/resourceGroups/my-rg/providers/Microsoft.Storage/storageAccounts/mystorageaccount" }, "timestamp": "2026-03-16T10:00:00Z", "type": "azure.blob.created" } ``` ## On Blob Deleted **Trigger key:** `azure.onBlobDeleted` The On Blob Deleted trigger starts a workflow execution when a blob is deleted from an Azure Storage Account. ### Use Cases - **Cleanup workflows**: Remove associated resources or records when a blob is deleted - **Audit and compliance**: Record blob deletions for traceability - **Notification workflows**: Alert teams when important files are removed from storage ### How It Works This trigger listens to Azure Event Grid events from a Storage Account. When a blob is deleted, the `Microsoft.Storage.BlobDeleted` event is delivered and the trigger fires with the full event payload. ### Configuration - **Resource Group** (required): The resource group containing the Storage Account. - **Storage Account** (required): The Storage Account to watch. - **Container Filter** (optional): A regex pattern to filter by container name. - **Blob Filter** (optional): A regex pattern to filter by blob path. ### Event Data Each blob deleted event includes: - **subject**: The full blob path in the format /blobServices/default/containers/{container}/blobs/{blob} - **data.api**: The operation that triggered the event (e.g., DeleteBlob) - **data.blobType**: The blob type (BlockBlob, PageBlob, AppendBlob) - **data.url**: The URL of the deleted blob ### Example Data ```json { "data": { "data": { "api": "DeleteBlob", "blobType": "BlockBlob", "clientRequestId": "6d6cef9a-a602-4a23-bc26-91bb68a2bf74", "contentLength": 0, "contentType": "text/csv", "eTag": "0x8D4BCC2E4835CD0", "requestId": "d1e6b5a4-0001-0035-4a7b-2e5c4f000000", "sequencer": "00000000000004420000000000028964", "url": "https://mystorageaccount.blob.core.windows.net/mycontainer/path/to/myfile.csv" }, "dataVersion": "", "eventTime": "2026-03-16T11:00:00Z", "eventType": "Microsoft.Storage.BlobDeleted", "id": "afc359b4-001e-001b-66ab-eeb76e069631", "metadataVersion": "1", "subject": "/blobServices/default/containers/mycontainer/blobs/path/to/myfile.csv", "topic": "/subscriptions/12345678-1234-1234-1234-123456789abc/resourceGroups/my-rg/providers/Microsoft.Storage/storageAccounts/mystorageaccount" }, "timestamp": "2026-03-16T11:00:00Z", "type": "azure.blob.deleted" } ``` ## On Image Deleted **Trigger key:** `azure.onContainerImageDeleted` The On Image Deleted trigger starts a workflow execution when a container image is deleted from an Azure Container Registry. ### Use Cases - **Cleanup workflows**: Remove associated resources when an image is deleted - **Audit trails**: Record image deletions for compliance purposes - **Notification workflows**: Alert teams when images are removed from the registry ### How It Works This trigger listens to Azure Event Grid events from an ACR registry. When an image or manifest is deleted, the `Microsoft.ContainerRegistry.ImageDeleted` event is delivered and the trigger fires with the full event payload. Note: Image deletions reference manifests by digest. Tags may be empty if the manifest itself was deleted. ### Configuration - **Resource Group** (required): The resource group containing the ACR registry. - **Registry** (required): The ACR registry to watch. - **Repository Filter** (optional): A regex pattern to filter by repository name. ### Event Data Each delete event includes: - **target.repository**: The repository name - **target.digest**: The manifest digest that was deleted - **target.tag**: The tag (may be empty for manifest deletes) - **actor.name**: The user or service principal that deleted the image ### Example Data ```json { "data": { "data": { "action": "delete", "actor": { "name": "myuser" }, "id": "afc359b4-001e-001b-66ab-eeb76e069631", "request": { "addr": "203.0.113.0:49926", "host": "myregistry.azurecr.io", "id": "6d6cef9a-a602-4a23-bc26-91bb68a2bf74", "method": "DELETE", "useragent": "docker/20.10.7" }, "source": { "addr": "myregistry.azurecr.io", "instanceID": "a29a591f-f89c-4f8d-b061-3c5d73d4756c" }, "target": { "digest": "sha256:abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890", "mediaType": "application/vnd.docker.distribution.manifest.v2+json", "repository": "myrepository", "tag": "", "url": "https://myregistry.azurecr.io/v2/myrepository/manifests/sha256:abcdef1234567890" }, "timestamp": "2026-03-16T11:00:00Z" }, "dataVersion": "1.0", "eventTime": "2026-03-16T11:00:00Z", "eventType": "Microsoft.ContainerRegistry.ImageDeleted", "id": "afc359b4-001e-001b-66ab-eeb76e069631", "metadataVersion": "1", "subject": "myregistry.azurecr.io/myrepository@sha256:abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890", "topic": "/subscriptions/12345678-1234-1234-1234-123456789abc/resourceGroups/my-rg/providers/Microsoft.ContainerRegistry/registries/myregistry" }, "timestamp": "2026-03-16T11:00:00Z", "type": "azure.image.deleted" } ``` ## On Image Pushed **Trigger key:** `azure.onContainerImagePushed` The On Image Pushed trigger starts a workflow execution when a container image is pushed to an Azure Container Registry. ### Use Cases - **CI/CD pipelines**: Trigger deployments when a new image version is pushed - **Image scanning**: Kick off security scans when new images arrive - **Notification workflows**: Notify teams when images are updated - **Tag tracking**: React to specific image tags being published ### How It Works This trigger listens to Azure Event Grid events from an ACR registry. When an image push succeeds, the `Microsoft.ContainerRegistry.ImagePushed` event is delivered and the trigger fires with the full event payload. ### Configuration - **Resource Group** (required): The resource group containing the ACR registry. - **Registry** (required): The ACR registry to watch. - **Repository Filter** (optional): A regex pattern to filter by repository name. - **Tag Filter** (optional): A regex pattern to filter by image tag. ### Event Data Each push event includes: - **target.repository**: The repository name - **target.tag**: The image tag - **target.digest**: The image manifest digest - **actor.name**: The user or service principal that pushed the image - **request.host**: The registry hostname ### Example Data ```json { "data": { "data": { "action": "push", "actor": { "name": "myuser" }, "id": "831e1650-001e-001b-66ab-eeb76e069631", "request": { "addr": "203.0.113.0:49926", "host": "myregistry.azurecr.io", "id": "6d6cef9a-a602-4a23-bc26-91bb68a2bf74", "method": "PUT", "useragent": "docker/20.10.7" }, "source": { "addr": "myregistry.azurecr.io", "instanceID": "a29a591f-f89c-4f8d-b061-3c5d73d4756c" }, "target": { "digest": "sha256:abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890", "length": 1234567, "mediaType": "application/vnd.docker.distribution.manifest.v2+json", "repository": "myrepository", "size": 1234567, "tag": "v1.2.3", "url": "https://myregistry.azurecr.io/v2/myrepository/manifests/sha256:abcdef1234567890" }, "timestamp": "2026-03-16T10:00:00Z" }, "dataVersion": "1.0", "eventTime": "2026-03-16T10:00:00Z", "eventType": "Microsoft.ContainerRegistry.ImagePushed", "id": "831e1650-001e-001b-66ab-eeb76e069631", "metadataVersion": "1", "subject": "myregistry.azurecr.io/myrepository:v1.2.3", "topic": "/subscriptions/12345678-1234-1234-1234-123456789abc/resourceGroups/my-rg/providers/Microsoft.ContainerRegistry/registries/myregistry" }, "timestamp": "2026-03-16T10:00:00Z", "type": "azure.image.pushed" } ``` ## On VM Deallocated **Trigger key:** `azure.onVirtualMachineDeallocated` The On VM Deallocated trigger starts a workflow execution when an Azure Virtual Machine is deallocated. ### Use Cases - **Cost tracking**: Log when VMs are deallocated and compute charges stop - **Resource cleanup**: Clean up associated resources (DNS, monitoring) when VMs are deallocated - **Scheduling verification**: Confirm VMs are being deallocated according to cost-saving schedules - **Capacity planning**: Track deallocation patterns for capacity planning - **Notification workflows**: Alert teams when VMs go offline ### How It Works This trigger listens to Azure Event Grid events for Virtual Machine deallocate actions. When a VM deallocate action succeeds (`status: Succeeded`), the trigger fires and provides the full Azure Event Grid event payload. Azure fires `Microsoft.Resources.ResourceActionSuccess` with operation name `Microsoft.Compute/virtualMachines/deallocate/action` when a VM is deallocated. Deallocation stops the VM and releases compute resources — the VM no longer incurs compute charges (only storage charges remain). **Important**: This trigger fires on deallocate, not on power-off (stop without deallocation). Use the "On VM Stopped" trigger for power-off events. ### Configuration - **Resource Group** (optional): Filter events to only trigger for VMs in a specific resource group. Leave empty to trigger for all resource groups in the subscription. - **VM Name Filter** (optional): A regex pattern to filter VMs by name. Only VMs whose name matches the pattern will trigger the workflow. Leave empty to trigger for all VM names. ### Event Data Each VM deallocate event includes the full Azure Event Grid event: - **id**: Unique event ID - **topic**: The Azure subscription topic - **subject**: The full ARM resource ID of the VM (with /deallocate appended) - **eventType**: The event type (`Microsoft.Resources.ResourceActionSuccess`) - **eventTime**: The timestamp when the event occurred - **data**: The event data including operationName, status, resourceProvider, resourceUri, subscriptionId, tenantId ### Azure Event Grid Setup Event Grid subscriptions are created automatically when the trigger is set up. SuperPlane will: 1. Create an Event Grid subscription at the Azure subscription scope 2. Configure it to forward `Microsoft.Resources.ResourceActionSuccess` events to the trigger webhook 3. Apply subject filters based on the configured resource group and resource type 4. Handle the Event Grid validation handshake automatically No manual setup is required. ### Notes - The trigger fires when a VM is deallocated (stopped and compute resources released) - After deallocation, only storage charges remain — compute charges stop - It does not fire on power-off (stop without deallocation) — use "On VM Stopped" for that - Failed deallocate operations do not trigger the workflow - The trigger processes events from Azure Event Grid in real-time - Multiple triggers can share the same Event Grid subscription if configured correctly ### Example Data ```json { "data": { "data": { "operationName": "Microsoft.Compute/virtualMachines/deallocate/action", "resourceProvider": "Microsoft.Compute", "resourceUri": "/subscriptions/12345678-1234-1234-1234-123456789abc/resourceGroups/my-rg/providers/Microsoft.Compute/virtualMachines/my-vm-01", "status": "Succeeded", "subscriptionId": "12345678-1234-1234-1234-123456789abc", "tenantId": "12345678-1234-1234-1234-123456789abc" }, "dataVersion": "2", "eventTime": "2026-02-11T10:30:00Z", "eventType": "Microsoft.Resources.ResourceActionSuccess", "id": "c3d4e5f6-a7b8-9012-cdef-123456789012", "metadataVersion": "1", "subject": "/subscriptions/12345678-1234-1234-1234-123456789abc/resourceGroups/my-rg/providers/Microsoft.Compute/virtualMachines/my-vm-01/deallocate", "topic": "/subscriptions/12345678-1234-1234-1234-123456789abc" }, "timestamp": "2026-02-11T10:30:00Z", "type": "azure.vm.deallocated" } ``` ## On VM Deleted **Trigger key:** `azure.onVirtualMachineDeleted` The On VM Deleted trigger starts a workflow execution when an Azure Virtual Machine is deleted. ### Use Cases - **Cleanup workflows**: Remove DNS records, monitoring agents, or other dependent resources when a VM is deleted - **Inventory tracking**: Update external inventory systems when VMs are removed - **Notification workflows**: Send notifications to teams when VMs are deleted - **Cost tracking**: Log VM deletion events for cost analysis and reporting - **Compliance auditing**: Track and audit VM deletions for security and compliance ### How It Works This trigger listens to Azure Event Grid events for Virtual Machine resource delete operations. When a VM delete operation succeeds (`status: Succeeded`), the trigger fires and provides the full Azure Event Grid event payload. Azure fires `Microsoft.Resources.ResourceDeleteSuccess` when a VM is successfully deleted. This is a distinct event from write operations — it only fires when the VM is actually removed, not during creation or updates. ### Configuration - **Resource Group** (optional): Filter events to only trigger for VMs in a specific resource group. Leave empty to trigger for all resource groups in the subscription. - **VM Name Filter** (optional): A regex pattern to filter VMs by name. Only VMs whose name matches the pattern will trigger the workflow. Leave empty to trigger for all VM names. ### Event Data Each VM delete event includes the full Azure Event Grid event: - **id**: Unique event ID - **topic**: The Azure subscription topic - **subject**: The full ARM resource ID of the VM - **eventType**: The event type (`Microsoft.Resources.ResourceDeleteSuccess`) - **eventTime**: The timestamp when the event occurred - **data**: The event data including operationName, status, resourceProvider, resourceUri, subscriptionId, tenantId ### Azure Event Grid Setup Event Grid subscriptions are created automatically when the trigger is set up. SuperPlane will: 1. Create an Event Grid subscription at the Azure subscription scope 2. Configure it to forward `Microsoft.Resources.ResourceDeleteSuccess` events to the trigger webhook 3. Apply subject filters based on the configured resource group and resource type 4. Handle the Event Grid validation handshake automatically No manual setup is required. ### Notes - The trigger fires only when a VM is successfully deleted - Failed delete operations do not trigger the workflow - The trigger processes events from Azure Event Grid in real-time - Multiple triggers can share the same Event Grid subscription if configured correctly ### Example Data ```json { "data": { "data": { "operationName": "Microsoft.Compute/virtualMachines/delete", "resourceProvider": "Microsoft.Compute", "resourceUri": "/subscriptions/12345678-1234-1234-1234-123456789abc/resourceGroups/my-rg/providers/Microsoft.Compute/virtualMachines/my-vm-01", "status": "Succeeded", "subscriptionId": "12345678-1234-1234-1234-123456789abc", "tenantId": "12345678-1234-1234-1234-123456789abc" }, "dataVersion": "2", "eventTime": "2026-02-11T10:30:00Z", "eventType": "Microsoft.Resources.ResourceDeleteSuccess", "id": "96257b6d-17d3-49e2-8369-fb185b29e1b5", "metadataVersion": "1", "subject": "/subscriptions/12345678-1234-1234-1234-123456789abc/resourceGroups/my-rg/providers/Microsoft.Compute/virtualMachines/my-vm-01", "topic": "/subscriptions/12345678-1234-1234-1234-123456789abc" }, "timestamp": "2026-02-11T10:30:00Z", "type": "azure.vm.deleted" } ``` ## On VM Restarted **Trigger key:** `azure.onVirtualMachineRestarted` The On VM Restarted trigger starts a workflow execution when an Azure Virtual Machine is restarted. ### Use Cases - **Post-restart validation**: Run health checks or smoke tests after a VM restarts - **Configuration reapplication**: Reapply configuration that may not persist across restarts - **Monitoring alerts**: Notify teams when VMs are restarted unexpectedly - **Audit logging**: Track VM restart events for compliance and troubleshooting ### How It Works This trigger listens to Azure Event Grid events for Virtual Machine restart actions. When a VM restart action succeeds (`status: Succeeded`), the trigger fires and provides the full Azure Event Grid event payload. Azure fires `Microsoft.Resources.ResourceActionSuccess` with operation name `Microsoft.Compute/virtualMachines/restart/action` when a VM is restarted. This reboots the VM in place without deallocating — the VM keeps its compute allocation and IP addresses. **Important**: This trigger fires only on explicit restart actions. It does not fire on start (after stop/deallocate) or power-off. Use the "On VM Started" or "On VM Stopped" triggers for those events. ### Configuration - **Resource Group** (optional): Filter events to only trigger for VMs in a specific resource group. Leave empty to trigger for all resource groups in the subscription. - **VM Name Filter** (optional): A regex pattern to filter VMs by name. Only VMs whose name matches the pattern will trigger the workflow. Leave empty to trigger for all VM names. ### Event Data Each VM restart event includes the full Azure Event Grid event: - **id**: Unique event ID - **topic**: The Azure subscription topic - **subject**: The full ARM resource ID of the VM (with /restart appended) - **eventType**: The event type (`Microsoft.Resources.ResourceActionSuccess`) - **eventTime**: The timestamp when the event occurred - **data**: The event data including operationName, status, resourceProvider, resourceUri, subscriptionId, tenantId ### Azure Event Grid Setup Event Grid subscriptions are created automatically when the trigger is set up. SuperPlane will: 1. Create an Event Grid subscription at the Azure subscription scope 2. Configure it to forward `Microsoft.Resources.ResourceActionSuccess` events to the trigger webhook 3. Apply subject filters based on the configured resource group and resource type 4. Handle the Event Grid validation handshake automatically No manual setup is required. ### Notes - The trigger fires when a VM is explicitly restarted (rebooted in place) - The VM keeps its compute allocation and IP addresses during a restart - It does not fire on start (after stop/deallocate) — use "On VM Started" for that - It does not fire on power-off or deallocate — use "On VM Stopped" or "On VM Deallocated" - Failed restart operations do not trigger the workflow - The trigger processes events from Azure Event Grid in real-time - Multiple triggers can share the same Event Grid subscription if configured correctly ### Example Data ```json { "data": { "data": { "operationName": "Microsoft.Compute/virtualMachines/restart/action", "resourceProvider": "Microsoft.Compute", "resourceUri": "/subscriptions/12345678-1234-1234-1234-123456789abc/resourceGroups/my-rg/providers/Microsoft.Compute/virtualMachines/my-vm-01", "status": "Succeeded", "subscriptionId": "12345678-1234-1234-1234-123456789abc", "tenantId": "12345678-1234-1234-1234-123456789abc" }, "dataVersion": "2", "eventTime": "2026-02-11T10:30:00Z", "eventType": "Microsoft.Resources.ResourceActionSuccess", "id": "d4e5f6a7-b8c9-0123-defa-234567890123", "metadataVersion": "1", "subject": "/subscriptions/12345678-1234-1234-1234-123456789abc/resourceGroups/my-rg/providers/Microsoft.Compute/virtualMachines/my-vm-01/restart", "topic": "/subscriptions/12345678-1234-1234-1234-123456789abc" }, "timestamp": "2026-02-11T10:30:00Z", "type": "azure.vm.restarted" } ``` ## On VM Started **Trigger key:** `azure.onVirtualMachineStarted` The On VM Started trigger starts a workflow execution when an Azure Virtual Machine is started. ### Use Cases - **Post-boot configuration**: Apply configuration, install agents, or run setup scripts when a VM starts - **Health checks**: Run health checks or readiness probes after a VM boots - **Notification workflows**: Notify teams when VMs come online - **Monitoring setup**: Register VMs with monitoring systems when they start - **Auto-scaling workflows**: Trigger downstream actions when new capacity comes online ### How It Works This trigger listens to Azure Event Grid events for Virtual Machine start actions. When a VM start action succeeds (`status: Succeeded`), the trigger fires and provides the full Azure Event Grid event payload. Azure fires `Microsoft.Resources.ResourceActionSuccess` with operation name `Microsoft.Compute/virtualMachines/start/action` when a VM is explicitly started. This event fires specifically when a stopped/deallocated VM is started via the Azure portal, CLI, or API. It does not fire on initial VM creation, restarts, or other VM actions. ### Configuration - **Resource Group** (optional): Filter events to only trigger for VMs in a specific resource group. Leave empty to trigger for all resource groups in the subscription. - **VM Name Filter** (optional): A regex pattern to filter VMs by name. Only VMs whose name matches the pattern will trigger the workflow. Leave empty to trigger for all VM names. ### Event Data Each VM start event includes the full Azure Event Grid event: - **id**: Unique event ID - **topic**: The Azure subscription topic - **subject**: The full ARM resource ID of the VM (with /start appended) - **eventType**: The event type (`Microsoft.Resources.ResourceActionSuccess`) - **eventTime**: The timestamp when the event occurred - **data**: The event data including operationName, status, resourceProvider, resourceUri, subscriptionId, tenantId ### Azure Event Grid Setup Event Grid subscriptions are created automatically when the trigger is set up. SuperPlane will: 1. Create an Event Grid subscription at the Azure subscription scope 2. Configure it to forward `Microsoft.Resources.ResourceActionSuccess` events to the trigger webhook 3. Apply subject filters based on the configured resource group and resource type 4. Handle the Event Grid validation handshake automatically No manual setup is required. ### Notes - The trigger fires when a stopped/deallocated VM is explicitly started - It does not fire on initial VM creation (use On VM Deleted's write counterpart for that) - It does not fire on VM restart — restart uses a separate `restart/action` operation - Failed start operations do not trigger the workflow - The trigger processes events from Azure Event Grid in real-time - Multiple triggers can share the same Event Grid subscription if configured correctly ### Example Data ```json { "data": { "data": { "operationName": "Microsoft.Compute/virtualMachines/start/action", "resourceProvider": "Microsoft.Compute", "resourceUri": "/subscriptions/12345678-1234-1234-1234-123456789abc/resourceGroups/my-rg/providers/Microsoft.Compute/virtualMachines/my-vm-01", "status": "Succeeded", "subscriptionId": "12345678-1234-1234-1234-123456789abc", "tenantId": "12345678-1234-1234-1234-123456789abc" }, "dataVersion": "2", "eventTime": "2026-02-11T10:30:00Z", "eventType": "Microsoft.Resources.ResourceActionSuccess", "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "metadataVersion": "1", "subject": "/subscriptions/12345678-1234-1234-1234-123456789abc/resourceGroups/my-rg/providers/Microsoft.Compute/virtualMachines/my-vm-01/start", "topic": "/subscriptions/12345678-1234-1234-1234-123456789abc" }, "timestamp": "2026-02-11T10:30:00Z", "type": "azure.vm.started" } ``` ## On VM Stopped **Trigger key:** `azure.onVirtualMachineStopped` The On VM Stopped trigger starts a workflow execution when an Azure Virtual Machine is powered off. ### Use Cases - **Cost alerts**: Notify teams when VMs are stopped but still allocated (still incurring compute charges) - **Shutdown workflows**: Run cleanup scripts or save state when a VM is powered off - **Compliance monitoring**: Track VM power-off events for audit trails - **Scheduling validation**: Verify that VMs are being stopped according to schedule ### How It Works This trigger listens to Azure Event Grid events for Virtual Machine power-off actions. When a VM power-off action succeeds (`status: Succeeded`), the trigger fires and provides the full Azure Event Grid event payload. Azure fires `Microsoft.Resources.ResourceActionSuccess` with operation name `Microsoft.Compute/virtualMachines/powerOff/action` when a VM is powered off. This stops the VM OS but keeps the compute allocation — the VM still incurs compute charges. To fully release compute resources, use deallocate instead. **Important**: This trigger fires on power-off (stop without deallocation), not on deallocate. Use the "On VM Deallocated" trigger for deallocate events. ### Configuration - **Resource Group** (optional): Filter events to only trigger for VMs in a specific resource group. Leave empty to trigger for all resource groups in the subscription. - **VM Name Filter** (optional): A regex pattern to filter VMs by name. Only VMs whose name matches the pattern will trigger the workflow. Leave empty to trigger for all VM names. ### Event Data Each VM stop event includes the full Azure Event Grid event: - **id**: Unique event ID - **topic**: The Azure subscription topic - **subject**: The full ARM resource ID of the VM (with /powerOff appended) - **eventType**: The event type (`Microsoft.Resources.ResourceActionSuccess`) - **eventTime**: The timestamp when the event occurred - **data**: The event data including operationName, status, resourceProvider, resourceUri, subscriptionId, tenantId ### Azure Event Grid Setup Event Grid subscriptions are created automatically when the trigger is set up. SuperPlane will: 1. Create an Event Grid subscription at the Azure subscription scope 2. Configure it to forward `Microsoft.Resources.ResourceActionSuccess` events to the trigger webhook 3. Apply subject filters based on the configured resource group and resource type 4. Handle the Event Grid validation handshake automatically No manual setup is required. ### Notes - The trigger fires when a VM is powered off (stopped without deallocation) - The VM still incurs compute charges after a power-off — use deallocate to release resources - It does not fire on deallocate — use the "On VM Deallocated" trigger for that - Failed power-off operations do not trigger the workflow - The trigger processes events from Azure Event Grid in real-time - Multiple triggers can share the same Event Grid subscription if configured correctly ### Example Data ```json { "data": { "data": { "operationName": "Microsoft.Compute/virtualMachines/powerOff/action", "resourceProvider": "Microsoft.Compute", "resourceUri": "/subscriptions/12345678-1234-1234-1234-123456789abc/resourceGroups/my-rg/providers/Microsoft.Compute/virtualMachines/my-vm-01", "status": "Succeeded", "subscriptionId": "12345678-1234-1234-1234-123456789abc", "tenantId": "12345678-1234-1234-1234-123456789abc" }, "dataVersion": "2", "eventTime": "2026-02-11T10:30:00Z", "eventType": "Microsoft.Resources.ResourceActionSuccess", "id": "b2c3d4e5-f6a7-8901-bcde-f12345678901", "metadataVersion": "1", "subject": "/subscriptions/12345678-1234-1234-1234-123456789abc/resourceGroups/my-rg/providers/Microsoft.Compute/virtualMachines/my-vm-01/powerOff", "topic": "/subscriptions/12345678-1234-1234-1234-123456789abc" }, "timestamp": "2026-02-11T10:30:00Z", "type": "azure.vm.stopped" } ``` ## Create Virtual Machine **Component key:** `azure.createVirtualMachine` The Create Virtual Machine component creates a new Azure VM with full configuration options. ### Use Cases - **Infrastructure provisioning**: Automatically create VMs as part of deployment workflows - **Development environments**: Spin up temporary VMs for testing and development - **Auto-scaling**: Create VMs in response to load or events - **Disaster recovery**: Quickly provision replacement VMs ### How It Works 1. Validates the VM configuration parameters 2. Initiates VM creation via the Azure Compute API 3. Waits for the VM to be fully provisioned (using Azure's Long-Running Operation pattern) 4. Returns the VM details including ID, name, and provisioning state ### Configuration - **Resource Group**: The Azure resource group where the VM will be created - **Name**: The name for the new virtual machine - **Location**: The Azure region (e.g., "eastus", "westeurope") - **Size**: The VM size (e.g., "Standard_B1s", "Standard_D2s_v3") - **Admin Username**: Administrator username for the VM - **Admin Password**: Administrator password for the VM (must meet Azure complexity requirements) - **Virtual Network / Subnet**: The network for the VM - **Network Interface ID**: Optional existing NIC (overrides VNet/Subnet) - **OS Image**: Select from common presets (Ubuntu, Debian, Windows Server) ### Output Returns the created VM information including: - **id**: The Azure resource ID of the VM - **name**: The name of the VM - **provisioningState**: The provisioning state (typically "Succeeded") - **location**: The Azure region where the VM was created - **size**: The VM size ### Notes - The VM creation is a Long-Running Operation (LRO) that typically takes 2-5 minutes - The component waits for the VM to be fully provisioned before completing - The admin password must meet Azure's complexity requirements (12+ characters, mixed case, numbers, symbols) - If Network Interface ID is empty, a NIC is created automatically from the selected VNet/Subnet ### Example Output ```json { "data": { "id": "/subscriptions/12345678-1234-1234-1234-123456789abc/resourceGroups/my-rg/providers/Microsoft.Compute/virtualMachines/my-vm", "location": "eastus", "name": "my-vm", "provisioningState": "Succeeded", "size": "Standard_B1s" }, "timestamp": "2026-03-16T10:00:00Z", "type": "azure.vm" } ``` ## Deallocate Virtual Machine **Component key:** `azure.deallocateVirtualMachine` The Deallocate Virtual Machine component deallocates an existing Azure VM, stopping it and releasing its compute resources. ### Use Cases - **Cost optimization**: Deallocate VMs to stop compute charges during off-hours - **Scheduled shutdown**: Deallocate VMs on a schedule to reduce costs - **Pre-resize operations**: Deallocate a VM before changing its size - **Environment teardown**: Deallocate VMs without deleting them ### How It Works 1. Validates the VM parameters 2. Initiates VM deallocation via the Azure Compute API 3. Waits for the VM to be fully deallocated (using Azure's Long-Running Operation pattern) 4. Returns the VM details including ID and name ### Configuration - **Resource Group**: The Azure resource group containing the VM - **VM Name**: The name of the virtual machine to deallocate ### Output Returns the deallocated VM information including: - **id**: The Azure resource ID of the VM - **name**: The name of the VM - **resourceGroup**: The resource group containing the VM ### Notes - Deallocation stops the VM and releases compute resources — **compute charges stop** - Only storage charges remain for the VM's disks - Dynamic public IP addresses are released on deallocation - The operation is a Long-Running Operation (LRO) that typically takes 1-3 minutes - The component waits for the VM to be fully deallocated before completing - To power off without releasing compute resources, use the "Stop Virtual Machine" action ### Example Output ```json { "data": { "id": "/subscriptions/12345678-1234-1234-1234-123456789abc/resourceGroups/my-rg/providers/Microsoft.Compute/virtualMachines/my-vm", "name": "my-vm", "resourceGroup": "my-rg" }, "timestamp": "2026-03-16T10:00:00Z", "type": "azure.vm" } ``` ## Delete Virtual Machine **Component key:** `azure.deleteVirtualMachine` The Delete Virtual Machine component deletes an existing Azure VM. ### Use Cases - **Infrastructure teardown**: Remove VMs as part of decommissioning workflows - **Cost optimization**: Delete unused or idle VMs to reduce costs - **Environment cleanup**: Remove temporary VMs after testing or development - **Auto-scaling**: Delete VMs in response to reduced load ### How It Works 1. Validates the VM deletion parameters 2. Initiates VM deletion via the Azure Compute API 3. Waits for the VM to be fully deleted (using Azure's Long-Running Operation pattern) 4. Returns the deleted VM details including ID and name ### Configuration - **Resource Group**: The Azure resource group containing the VM - **VM Name**: The name of the virtual machine to delete - **Delete Associated Resources**: When enabled, also deletes the VM's OS disk, data disks, network interfaces, and public IPs ### Output Returns the deleted VM information including: - **id**: The Azure resource ID of the deleted VM - **name**: The name of the deleted VM - **resourceGroup**: The resource group that contained the VM ### Notes - The VM deletion is a Long-Running Operation (LRO) that typically takes 1-3 minutes - The component waits for the VM to be fully deleted before completing - When "Delete Associated Resources" is enabled, Azure cascade-deletes OS disk, data disks, NICs, and public IPs along with the VM - Shared resources like virtual networks, subnets, and network security groups are never deleted - This operation is irreversible ### Example Output ```json { "data": { "id": "/subscriptions/12345678-1234-1234-1234-123456789abc/resourceGroups/my-rg/providers/Microsoft.Compute/virtualMachines/my-vm", "name": "my-vm", "resourceGroup": "my-rg" }, "timestamp": "2026-03-16T10:00:00Z", "type": "azure.vm" } ``` ## Restart Virtual Machine **Component key:** `azure.restartVirtualMachine` The Restart Virtual Machine component restarts an existing Azure VM in place. ### Use Cases - **Apply updates**: Restart VMs after applying OS or software updates - **Troubleshooting**: Restart VMs to recover from transient issues - **Configuration changes**: Restart VMs after configuration changes that require a reboot - **Automated maintenance**: Restart VMs as part of maintenance workflows ### How It Works 1. Validates the VM parameters 2. Initiates VM restart via the Azure Compute API 3. Waits for the VM to be fully restarted (using Azure's Long-Running Operation pattern) 4. Returns the VM details including ID and name ### Configuration - **Resource Group**: The Azure resource group containing the VM - **VM Name**: The name of the virtual machine to restart ### Output Returns the restarted VM information including: - **id**: The Azure resource ID of the VM - **name**: The name of the VM - **resourceGroup**: The resource group containing the VM ### Notes - The VM is rebooted in place — it keeps its compute allocation and IP addresses - The operation is a Long-Running Operation (LRO) that typically takes 1-3 minutes - The component waits for the VM to be fully restarted before completing - This performs a graceful restart of the VM ### Example Output ```json { "data": { "id": "/subscriptions/12345678-1234-1234-1234-123456789abc/resourceGroups/my-rg/providers/Microsoft.Compute/virtualMachines/my-vm", "name": "my-vm", "resourceGroup": "my-rg" }, "timestamp": "2026-03-16T10:00:00Z", "type": "azure.vm" } ``` ## Start Virtual Machine **Component key:** `azure.startVirtualMachine` The Start Virtual Machine component starts a stopped or deallocated Azure VM. ### Use Cases - **Resume workloads**: Start VMs that were previously stopped or deallocated - **Scheduled startup**: Start VMs as part of scheduled workflows - **Auto-scaling**: Start pre-provisioned VMs to handle increased demand - **Disaster recovery**: Start standby VMs as part of failover workflows ### How It Works 1. Validates the VM parameters 2. Initiates VM start via the Azure Compute API 3. Waits for the VM to be fully started (using Azure's Long-Running Operation pattern) 4. Returns the VM details including ID and name ### Configuration - **Resource Group**: The Azure resource group containing the VM - **VM Name**: The name of the virtual machine to start ### Output Returns the started VM information including: - **id**: The Azure resource ID of the VM - **name**: The name of the VM - **resourceGroup**: The resource group containing the VM ### Notes - The VM must be in a stopped or deallocated state to be started - The operation is a Long-Running Operation (LRO) that typically takes 1-3 minutes - The component waits for the VM to be fully started before completing - Once started, the VM will begin incurring compute charges ### Example Output ```json { "data": { "id": "/subscriptions/12345678-1234-1234-1234-123456789abc/resourceGroups/my-rg/providers/Microsoft.Compute/virtualMachines/my-vm", "name": "my-vm", "resourceGroup": "my-rg" }, "timestamp": "2026-03-16T10:00:00Z", "type": "azure.vm" } ``` ## Stop Virtual Machine **Component key:** `azure.stopVirtualMachine` The Stop Virtual Machine component powers off an existing Azure VM without deallocating it. ### Use Cases - **Temporary shutdown**: Stop a VM temporarily while keeping its compute allocation - **Maintenance windows**: Power off VMs during maintenance periods - **Pre-deallocate workflows**: Stop VMs before performing other operations ### How It Works 1. Validates the VM parameters 2. Initiates VM power-off via the Azure Compute API 3. Waits for the VM to be fully powered off (using Azure's Long-Running Operation pattern) 4. Returns the VM details including ID and name ### Configuration - **Resource Group**: The Azure resource group containing the VM - **VM Name**: The name of the virtual machine to stop ### Output Returns the stopped VM information including: - **id**: The Azure resource ID of the VM - **name**: The name of the VM - **resourceGroup**: The resource group containing the VM ### Notes - The VM is powered off but compute resources remain allocated — **you still incur compute charges** - To fully release compute resources and stop charges, use the "Deallocate Virtual Machine" action - The operation is a Long-Running Operation (LRO) that typically takes 1-2 minutes - The component waits for the VM to be fully powered off before completing ### Example Output ```json { "data": { "id": "/subscriptions/12345678-1234-1234-1234-123456789abc/resourceGroups/my-rg/providers/Microsoft.Compute/virtualMachines/my-vm", "name": "my-vm", "resourceGroup": "my-rg" }, "timestamp": "2026-03-16T10:00:00Z", "type": "azure.vm" } ``` #### Microsoft Teams Source URL: https://docs.superplane.com/components/microsoftteams Send and receive messages in Microsoft Teams channels import { CardGrid, LinkCard } from "@astrojs/starlight/components"; ## Triggers ## Actions ## Instructions ## Setup 1. **Create an Azure App Registration**: - Go to **Azure Portal** → **App registrations** → **New registration** - Name: "SuperPlane Bot" (or your preference) - Supported account types: **Accounts in any organizational directory** (multi-tenant) or single-tenant - Note the **Application (client) ID** — this is the **App ID** below - Go to **Certificates & secrets** → **New client secret** → copy the **Value** — this is the **App Password** below 2. **Add Graph API permissions** (required for channel listing): - Go to your **App Registration** → **API permissions** → **Add a permission** - Select **Microsoft Graph** → **Application permissions** - Add: **Team.ReadBasic.All** and **Channel.ReadBasic.All** - Click **Grant admin consent** 3. **Enter credentials** in the fields below and save ## On Mention **Trigger key:** `teams.onMention` The On Mention trigger starts a workflow execution when the Teams bot is @mentioned in a channel message. ### Use Cases - **Bot commands**: Process commands from Teams messages - **Bot interactions**: Create interactive Teams bots - **Team workflows**: Trigger workflows from Teams conversations - **Notification processing**: Process and respond to mentions ### Configuration - **Channel**: Optional channel filter — if specified, only mentions in this channel will trigger (leave empty to listen to all channels) - **Content Filter**: Optional regex pattern to filter messages by content (e.g., `/deploy` to only trigger on mentions containing "/deploy") ### Event Data Each mention event includes: - **text**: The message text containing the mention - **from**: User who mentioned the bot (ID and name) - **conversation**: Channel and team information - **timestamp**: When the mention occurred - **serviceUrl**: Bot Framework service URL for sending replies ### Setup This trigger automatically sets up a subscription for bot mention events when configured. The subscription is managed by SuperPlane and will be cleaned up when the trigger is removed. ### Note This trigger works with the default Bot Framework behavior — the bot receives messages where it is @mentioned without any additional permissions. ### Example Data ```json { "data": { "channelId": "msteams", "conversation": { "conversationType": "channel", "id": "19:abc123def456@thread.tacv2", "isGroup": true, "name": "General", "tenantId": "00000000-0000-0000-0000-000000000000" }, "entities": [ { "mentioned": { "id": "28:bot-id-here", "name": "SuperPlane Bot" }, "text": "\u003cat\u003eSuperPlane Bot\u003c/at\u003e", "type": "mention" } ], "from": { "aadObjectId": "00000000-0000-0000-0000-000000000001", "id": "29:1abc2def3ghi4jkl5mno6pqr7stu8vwx", "name": "John Doe" }, "id": "1700000000000", "recipient": { "id": "28:bot-id-here", "name": "SuperPlane Bot" }, "serviceUrl": "https://smba.trafficmanager.net/teams/", "text": "\u003cat\u003eSuperPlane Bot\u003c/at\u003e deploy the latest build to staging", "timestamp": "2026-01-16T12:00:00.000Z", "type": "message" }, "timestamp": "2026-01-16T12:00:00Z", "type": "teams.bot.mention" } ``` ## On Message **Trigger key:** `teams.onMessage` The On Message trigger starts a workflow execution when any message is posted in a Teams channel. ### Use Cases - **Message monitoring**: React to any message in a channel - **Keyword detection**: Process messages looking for specific content - **Activity tracking**: Track channel activity for analytics - **Auto-responses**: Automatically respond to specific message patterns ### Configuration - **Channel**: Optional channel filter — if specified, only messages in this channel will trigger (leave empty to listen to all channels) - **Content Filter**: Optional regex pattern to filter messages by content (e.g., `/ci` to only trigger on messages containing "/ci") ### Event Data Each message event includes: - **text**: The message text - **from**: User who sent the message (ID and name) - **conversation**: Channel and team information - **timestamp**: When the message was sent - **serviceUrl**: Bot Framework service URL for sending replies ### Setup This trigger automatically sets up a subscription for channel message events when configured. ### Important This trigger requires **Resource-Specific Consent (RSC)** permissions in the Teams app manifest. Specifically, the app must include the `ChannelMessage.Read.Group` permission. Without this permission, the bot will only receive messages where it is @mentioned. The generated Teams app manifest includes this permission by default. If you created the manifest manually, ensure this RSC permission is included. ### Example Data ```json { "data": { "channelId": "msteams", "conversation": { "conversationType": "channel", "id": "19:abc123def456@thread.tacv2", "isGroup": true, "name": "General", "tenantId": "00000000-0000-0000-0000-000000000000" }, "entities": [], "from": { "aadObjectId": "00000000-0000-0000-0000-000000000002", "id": "29:1abc2def3ghi4jkl5mno6pqr7stu8vwx", "name": "Jane Smith" }, "id": "1700000000001", "recipient": { "id": "28:bot-id-here", "name": "SuperPlane Bot" }, "serviceUrl": "https://smba.trafficmanager.net/teams/", "text": "The deployment to staging is complete. All tests passed.", "timestamp": "2026-01-16T12:05:00.000Z", "type": "message" }, "timestamp": "2026-01-16T12:05:00Z", "type": "teams.channel.message" } ``` ## Send Text Message **Component key:** `teams.sendTextMessage` The Send Text Message component sends a text message to a Microsoft Teams channel. ### Use Cases - **Notifications**: Send notifications about workflow events or system status - **Alerts**: Alert teams about important events or errors - **Updates**: Provide status updates on long-running processes - **Team communication**: Automate team communications from workflows ### Configuration - **Channel**: Select the Teams channel to send the message to - **Text**: The message text to send (supports expressions) ### Output Returns metadata about the sent message including the message ID and timestamp. ### Notes - The Teams bot must be installed in the team containing the target channel - Messages are sent as the configured bot user - The bot requires the appropriate permissions to post to the selected channel ### Example Output ```json { "data": { "conversationId": "19:abc123def456@thread.tacv2", "id": "1700000000002", "text": "Hello from SuperPlane", "timestamp": "2026-01-16T12:10:00.000Z" }, "timestamp": "2026-01-16T17:56:16.680755501Z", "type": "teams.message.sent" } ``` #### New Relic Source URL: https://docs.superplane.com/components/newrelic React to alerts and query telemetry data from New Relic import { CardGrid, LinkCard } from "@astrojs/starlight/components"; ## Triggers ## Actions ## Instructions ### Getting your credentials 1. **Account ID**: Click your name in the bottom-left corner of New Relic. Your Account ID is displayed under the account name. 2. **User API Key**: Go to the **API Keys** page. Click **Create a key**. Select key type **User**. Give it a name (e.g. "SuperPlane") and click **Create a key**. This key is used for NerdGraph/NRQL queries — no additional permissions are needed. 3. **License Key**: On the same **API Keys** page, find the key with type **Ingest - License** and copy it. This key is used for sending metrics. If no license key exists, click **Create a key** and select **Ingest - License**. 4. **Region**: Choose **US** if your New Relic URL is `one.newrelic.com`, or **EU** if it is `one.eu.newrelic.com`. ### Webhook Setup SuperPlane automatically creates a Webhook Notification Channel in your New Relic account when you add the **On Issue** trigger to your canvas. Just attach it to your alert workflow in New Relic to start receiving alerts. ## On Issue **Trigger key:** `newrelic.onIssue` The On Issue trigger starts a workflow execution when a New Relic alert issue is received via webhook. ### What this trigger does - Receives New Relic webhook payloads for alert issues - Filters by issue state (CREATED, ACTIVATED, ACKNOWLEDGED, CLOSED) - Optionally filters by priority (CRITICAL, HIGH, MEDIUM, LOW) - Emits matching issues as `newrelic.issue` events ### Configuration - **Statuses**: Required list of issue states to listen for - **Priorities**: Optional priority filter ### Webhook Setup SuperPlane automatically creates a Webhook Notification Channel in your New Relic account. Just attach it to your alert workflow to start receiving alerts. ### Example Data ```json { "data": { "accountId": 1234567, "conditionName": "CPU usage \u003e 90%", "createdAt": 1704067200000, "issueId": "MXxBSXxJU1NVRXwxMjM0NTY3ODk", "issueUrl": "https://one.newrelic.com/alerts-ai/issues/MXxBSXxJU1NVRXwxMjM0NTY3ODk", "policyName": "Production Infrastructure", "priority": "CRITICAL", "sources": [ "newrelic" ], "state": "ACTIVATED", "title": "High CPU usage on production server", "updatedAt": 1704067260000 }, "timestamp": "2026-01-19T12:00:00Z", "type": "newrelic.issue" } ``` ## Report Metric **Component key:** `newrelic.reportMetric` The Report Metric component sends custom metric data to New Relic's Metric API. ### Use Cases - **Deployment metrics**: Track deployment frequency and duration - **Business metrics**: Report custom KPIs like revenue, signups, or conversion rates - **Pipeline metrics**: Measure workflow execution times and success rates ### Configuration - `metricName`: The name of the metric (e.g., custom.deployment.count) - `metricType`: The type of metric (gauge, count, or summary) - `value`: The numeric value for the metric - `attributes`: Optional key-value labels for the metric - `timestamp`: Optional Unix epoch milliseconds (defaults to now) ### Outputs The component emits a metric confirmation containing: - `metricName`: The name of the reported metric - `metricType`: The type of the metric - `value`: The reported value - `timestamp`: The timestamp used ### Example Output ```json { "data": { "metricName": "custom.deployment.count", "metricType": "count", "timestamp": 1704067200000, "value": 1 }, "timestamp": "2026-01-19T12:00:00Z", "type": "newrelic.metric" } ``` ## Run NRQL Query **Component key:** `newrelic.runNRQLQuery` The Run NRQL Query component executes a NRQL query against New Relic data via the NerdGraph API. ### Use Cases - **Health checks**: Query application error rates or response times before deployments - **Capacity planning**: Check resource utilization metrics - **Incident investigation**: Query telemetry data during incident workflows ### Configuration - `query`: The NRQL query string to execute - `timeout`: Optional query timeout in seconds (default: 30) ### Outputs The component emits query results containing: - `query`: The executed NRQL query - `results`: Array of result rows returned by the query ### Example Output ```json { "data": { "query": "SELECT count(*) FROM Transaction SINCE 1 hour ago", "results": [ { "count": 42567 } ] }, "timestamp": "2026-01-19T12:00:00Z", "type": "newrelic.nrqlResult" } ``` #### Octopus Deploy Source URL: https://docs.superplane.com/components/octopusdeploy Deploy releases and react to deployment events in Octopus Deploy import { CardGrid, LinkCard } from "@astrojs/starlight/components"; ## Triggers ## Actions ## Instructions 1. **Server URL:** Your Octopus Deploy instance URL (e.g. `https://my-company.octopus.app`). 2. **API Key:** Create one in **Octopus Web Portal → Profile → My API Keys → New API Key**. - Enter a purpose (e.g., "SuperPlane Integration") and click **Generate New**. - **Copy the key immediately**—it cannot be viewed again. 3. **Space:** Select the Octopus Deploy space to use. Leave empty to use the default space. 4. **Auth:** SuperPlane sends requests using the `X-Octopus-ApiKey` header. 5. **Webhooks:** SuperPlane creates Octopus subscriptions automatically to receive deployment events. No manual setup is required. ## On Deployment Event **Trigger key:** `octopus.onDeploymentEvent` The On Deployment Event trigger emits events when a deployment's status changes in Octopus Deploy. ### Use Cases - **Deploy notifications**: Notify Slack or PagerDuty when deployments succeed or fail - **Post-deploy automation**: Trigger smoke tests after a successful deployment - **Incident creation**: Create a ticket automatically when a deployment fails - **Deployment tracking**: Log deployment events for audit or reporting ### Configuration - **Event Categories**: Deployment event types to listen for. Defaults to `DeploymentSucceeded` and `DeploymentFailed`. - **Project** (optional): Filter events to a specific Octopus Deploy project. - **Environment** (optional): Filter events to a specific deployment environment. ### Event Categories | Category | Description | |---------------------|-------------------------------------| | DeploymentQueued | A deployment has been queued | | DeploymentStarted | A deployment has started executing | | DeploymentSucceeded | A deployment completed successfully | | DeploymentFailed | A deployment has failed | ### Webhook Verification Octopus Deploy subscriptions are configured with a custom header secret. SuperPlane verifies incoming webhooks by comparing the `X-SuperPlane-Webhook-Secret` header value against the stored secret. ### Event Data Each emitted event includes the following fields: | Field | Description | |-----------------|------------------------------------------------------------| | `eventType` | The deployment event category (e.g. `DeploymentSucceeded`) | | `category` | Same as `eventType` | | `timestamp` | When the subscription payload was sent | | `occurredAt` | When the event occurred in Octopus | | `message` | Human-readable event description | | `projectId` | Octopus project ID (e.g. `Projects-123`) | | `environmentId` | Octopus environment ID (e.g. `Environments-1`) | | `releaseId` | Octopus release ID (e.g. `Releases-789`) | | `deploymentId` | Octopus deployment ID (e.g. `Deployments-1011`) | | `serverUri` | Your Octopus Deploy server URL | ### Example Data ```json { "data": { "category": "DeploymentSucceeded", "deploymentId": "Deployments-1011", "environmentId": "Environments-456", "eventType": "DeploymentSucceeded", "message": "Deploy to Production succeeded", "occurredAt": "2026-02-05T16:00:00.000+00:00", "projectId": "Projects-123", "releaseId": "Releases-789", "serverUri": "https://my-company.octopus.app", "timestamp": "2026-02-05T16:00:00.000+00:00" }, "timestamp": "2026-02-05T16:00:01.000+00:00", "type": "octopus.deployment.succeeded" } ``` ## Deploy Release **Component key:** `octopus.deployRelease` The Deploy Release component deploys a chosen release to a chosen environment in Octopus Deploy and waits for completion. ### Use Cases - **Deploy on merge**: Trigger a deployment after code is merged - **Scheduled deployments**: Deploy to staging or production on a schedule - **Approval-based deploys**: Deploy after manual approval in a workflow - **Chained deployments**: Deploy to next environment after success in the previous one ### How It Works 1. Creates a deployment for the selected release and environment via the Octopus Deploy API 2. Waits for the deployment task to complete (via webhook and polling fallback) 3. Routes execution based on deployment outcome: - **Success channel**: Task completed successfully - **Failed channel**: Task failed, timed out, or was cancelled ### Configuration - **Project**: The Octopus Deploy project - **Release**: The release to deploy (filtered by the selected project) - **Environment**: The target deployment environment ### Output Channels - **Success**: Emitted when the deployment completes successfully - **Failed**: Emitted when the deployment fails, times out, or is cancelled ### Notes - Deployment status is tracked via the Octopus Deploy task associated with the deployment - Polls the task status every 5 minutes as a fallback if the webhook does not arrive - Requires an API key configured on the Octopus Deploy integration ### Example Output ```json { "data": { "completedTime": "2026-02-05T16:05:00.000+00:00", "created": "2026-02-05T16:00:00.000+00:00", "deploymentId": "Deployments-1011", "duration": "5 minutes", "environmentId": "Environments-456", "projectId": "Projects-123", "releaseId": "Releases-789", "taskState": "Success" }, "timestamp": "2026-02-05T16:05:00.000+00:00", "type": "octopus.deployment.finished" } ``` #### OpenAI Source URL: https://docs.superplane.com/components/openai Generate text responses with OpenAI models import { CardGrid, LinkCard } from "@astrojs/starlight/components"; ## Actions ## Text Prompt **Component key:** `openai.textPrompt` The Text Prompt component generates text responses using OpenAI's language models. ### Use Cases - **Content generation**: Generate text content, summaries, or descriptions - **Natural language processing**: Process and transform text using AI - **Automated responses**: Generate responses to user queries or events - **Data transformation**: Convert structured data into natural language ### Configuration - **Model**: Select the OpenAI model to use (e.g., gpt-4, gpt-3.5-turbo) - **Prompt**: The text prompt to send to the model (supports expressions) ### Output Returns the generated response including: - **text**: The generated text response - **model**: The model used for generation - **usage**: Token usage information (prompt tokens, completion tokens, total tokens) - **id**: Response ID for tracking ### Notes - Requires a valid OpenAI API key configured in the application settings - Response quality and speed depend on the selected model - Token usage is tracked and may incur costs based on your OpenAI plan - Supports OpenAI-compatible providers by setting a custom Base URL in the integration settings (e.g., Azure OpenAI, Ollama, vLLM) ### Example Output ```json { "data": { "id": "cmpl-1234567890", "model": "gpt-5.2", "text": "Hello, world!", "usage": { "input_tokens": 10, "output_tokens": 10, "total_tokens": 20 } }, "timestamp": "2026-01-19T12:00:00Z", "type": "openai.response" } ``` #### Oracle Cloud Infrastructure Source URL: https://docs.superplane.com/components/oraclecloudinfrastructure Manage Oracle Cloud Infrastructure resources in workflows import { CardGrid, LinkCard } from "@astrojs/starlight/components"; ## Triggers ## Actions ## Instructions ## Connect Oracle Cloud Infrastructure SuperPlane authenticates to OCI using API Key authentication tied to a dedicated service user with least-privilege permissions. ### Part 1 — Create a Dedicated Group and Service User 1. Open the [OCI Console](https://cloud.oracle.com/) and sign in. 2. Go to **Menu** → **Identity & Security → Domains → Default → User Management → Groups**. 3. Click **Create Group**. 4. Set the name to `SuperPlaneIntegration` and add a description, then click **Create**. 5. In the same **User Management** tab, go to **Users → Create User**. 6. Fill in the details: - **Lastname:** `superplane-integration` - **Email:** use any valid email (not used for authentication) 7. In the **Groups** section, assign the user to the `SuperPlaneIntegration` group 8. Click **Create**. ### Part 2 — Create an IAM Policy 1. Go to **Identity & Security → Policies**. 2. Make sure you are in the **root compartment** (check the Compartment selector on the left). 3. Click **Create Policy**, name it `SuperPlanePolicies`, add a description and enable the **manual editor**. 4. Paste in the following statements, replacing `` with your target compartment name, and then Click **Create**.: ``` Allow group SuperPlaneIntegration to manage instances in tenancy Allow group SuperPlaneIntegration to manage volumes in tenancy Allow group SuperPlaneIntegration to manage volume-attachments in tenancy Allow group SuperPlaneIntegration to manage virtual-network-family in tenancy Allow group SuperPlaneIntegration to manage buckets in tenancy Allow group SuperPlaneIntegration to manage objects in tenancy Allow group SuperPlaneIntegration to manage objectstorage-namespaces in tenancy Allow group SuperPlaneIntegration to manage fn-app in tenancy Allow group SuperPlaneIntegration to manage fn-function in tenancy Allow group SuperPlaneIntegration to manage fn-invocation in tenancy Allow group SuperPlaneIntegration to manage ons-topics in tenancy Allow group SuperPlaneIntegration to manage ons-subscriptions in tenancy Allow group SuperPlaneIntegration to inspect compartments in tenancy Allow group SuperPlaneIntegration to inspect all-resources in tenancy Allow group SuperPlaneIntegration to manage cloudevents-rules in tenancy Allow group SuperPlaneIntegration to manage autonomous-database-family in tenancy Allow service cloudEvents to use ons-topics in tenancy ``` ### Part 3 — Generate API Keys for the Service User and Connect to SuperPlane 1. Go to **Menu** → **Identity & Security → Domains → Default → User Management → Users**. 2. Choose the service user you created, then go to **API Keys → Add API Key**. 3. Select **Generate API key pair**, download the private key file and then click **Add**. 4. Copy the **Configuration File Preview** values that appear to the UI: - **User OCID** (begins with `ocid1.user.`) - **Fingerprint** (e.g. `12:34:56:…`) - **Tenancy OCID** (begins with `ocid1.tenancy.`) 5. Select the **Region** that matches your OCI tenancy's home region. 6. Open the downloaded private key file and paste its full contents into the **Private Key** field. 7. Click **Connect** to validate the credentials and save the integration. ## On Compute Instance Created **Trigger key:** `oci.onComputeInstanceCreated` The On Compute Instance Created trigger starts a workflow execution whenever an OCI Compute instance launch completes. ### How It Works When the OCI integration is set up, SuperPlane automatically creates a shared **OCI Notifications (ONS) topic** and a tenancy-level **OCI Events rule** that forwards `com.oraclecloud.computeapi.launchinstance.end` events to that topic. When this trigger is added to a workflow, SuperPlane subscribes your workflow webhook to that topic and filters deliveries to the configured compartment — no manual OCI configuration is required. ### Configuration - **Compartment**: The compartment to monitor for new Compute instances. ### Event Data Each event payload includes: - `eventType` — `com.oraclecloud.computeapi.launchinstance.end` - `data.resourceId` — the instance OCID - `data.resourceName` — the instance display name - `data.compartmentId` — the compartment OCID - `data.availabilityDomain` — the availability domain - `eventTime` — ISO-8601 timestamp of the event ### Example Data ```json { "data": { "cloudEventsVersion": "0.1", "contentType": "application/json", "data": { "additionalDetails": { "imageId": "ocid1.image.oc1.eu-frankfurt-1.aaaaaaaExample1234567890abcdefghijklmnopqrstuvwxyz1234567890ab", "shape": "VM.Standard.E2.1.Micro", "type": "CustomerVmi" }, "availabilityDomain": "EXAMPLE:EU-FRANKFURT-1-AD-1", "compartmentId": "ocid1.tenancy.oc1..aaaaaaaExample1234567890abcdefghijklmnopqrstuvwxyz1234567890", "compartmentName": "root", "definedTags": {}, "freeformTags": {}, "resourceId": "ocid1.instance.oc1.eu-frankfurt-1.aaaaaaaExample1234567890abcdefghijklmnopqrstuvwxyz1234567890cd", "resourceName": "my-instance" }, "eventID": "00000000-0000-0000-0000-000000000000", "eventTime": "2026-01-01T00:00:00Z", "eventType": "com.oraclecloud.computeapi.launchinstance.end", "eventTypeVersion": "2.0", "extensions": { "compartmentId": "ocid1.tenancy.oc1..aaaaaaaExample1234567890abcdefghijklmnopqrstuvwxyz1234567890" }, "source": "ComputeApi" }, "timestamp": "2026-01-01T00:00:05Z", "type": "oci.onComputeInstanceCreated" } ``` ## On Instance State Change **Trigger key:** `oci.onInstanceStateChange` The On Instance State Change trigger starts a workflow execution whenever an Oracle Cloud Infrastructure Compute instance completes a power or termination operation. ### How It Works When the OCI integration is set up, SuperPlane creates a shared **OCI Notifications (ONS) topic** and a tenancy-level **OCI Events rule** that forwards Compute instance power and termination events to that topic. When this trigger is added to a workflow, SuperPlane subscribes your workflow webhook to that topic and filters deliveries to the configured compartment and selected state changes — no separate Events rule is created per trigger. ### Configuration - **Compartment**: The compartment to monitor for Compute instance state changes. - **State Changes**: Optional list of state changes to emit. Leave empty to emit all supported state changes. ### Event Data Each event payload includes: - `eventType` — the OCI Compute API event type, such as `com.oraclecloud.computeapi.instanceaction.end` - `data.resourceId` — the instance OCID - `data.resourceName` — the instance display name - `data.compartmentId` — the compartment OCID - `data.availabilityDomain` — the availability domain - `data.additionalDetails.instanceActionType` — the completed power action, such as `start`, `stop`, or `softstop` - `eventTime` — ISO-8601 timestamp of the event ### Example Data ```json { "data": { "cloudEventsVersion": "0.1", "contentType": "application/json", "data": { "additionalDetails": { "imageId": "ocid1.image.oc1.eu-frankfurt-1.aaaaaaaa4ktlslmw2fqu5trx2xk3rnnqozgstuqutjm3ffusi6juo3ef4zaq", "instanceActionType": "stop", "shape": "VM.Standard.E2.1.Micro", "type": "CustomerVmi" }, "availabilityDomain": "pYRG:EU-FRANKFURT-1-AD-3", "compartmentId": "ocid1.tenancy.oc1..aaaaaaaaorle4tqd7rmhv2w7h37k32u6bskjrsnbnfem6i7qjupvexidmwpq", "compartmentName": "root", "definedTags": {}, "freeformTags": {}, "resourceId": "ocid1.instance.oc1.eu-frankfurt-1.antheljthvjhcwice6b33efkswzlk56zv4n5rcnb7xf4gsdlvuqlihvszjlq", "resourceName": "test-instance-12" }, "eventID": "8fc0df4c-ea5d-4438-a817-db7fa6440b8a", "eventTime": "2026-04-22T20:34:54Z", "eventType": "com.oraclecloud.computeapi.instanceaction.end", "eventTypeVersion": "2.0", "extensions": { "compartmentId": "ocid1.tenancy.oc1..aaaaaaaaorle4tqd7rmhv2w7h37k32u6bskjrsnbnfem6i7qjupvexidmwpq" }, "source": "ComputeApi" }, "timestamp": "2026-04-22T20:35:05.079372195Z", "type": "oci.onInstanceStateChange" } ``` ## Create Application **Component key:** `oci.createApplication` The Create Application component creates a new Oracle Cloud Infrastructure Functions application. ### Use Cases - **Serverless environment provisioning**: Create application containers as part of a deployment workflow - **Environment lifecycle management**: Automatically create application environments for each release ### Configuration - **Compartment**: The compartment where the application will be created - **Display Name**: A human-readable name for the application - **Subnet OCIDs**: One or more subnet OCIDs (comma-separated) for the application's VCN configuration ### Output Emits the created application details including: - `applicationId` — application OCID - `displayName` — application name - `lifecycleState` — current state (`ACTIVE`) - `compartmentId` — the compartment OCID - `timeCreated` — ISO-8601 creation timestamp ### Example Output ```json { "data": { "applicationId": "ocid1.fnapp.oc1.eu-frankfurt-1.aaaaExample1234567890abcdefghijklmnopqrstuvwxyz", "compartmentId": "ocid1.tenancy.oc1..aaaaaaaExample1234567890abcdefghijklmnopqrstuvwxyz1234567890", "displayName": "my-functions-app", "lifecycleState": "ACTIVE", "timeCreated": "2026-04-22T20:31:25.145Z" }, "timestamp": "2026-04-22T20:31:58.249783188Z", "type": "oci.applicationCreated" } ``` ## Create Compute Instance **Component key:** `oci.createComputeInstance` The Create Compute Instance component provisions a new Oracle Cloud Infrastructure Compute instance and waits until it reaches **RUNNING** state before emitting. ### Use Cases - **Environment provisioning**: Spin up instances as part of deployment or testing workflows - **On-demand compute**: Launch instances when triggered by events in other systems - **Auto-scaling workflows**: Create additional capacity in response to metrics or alerts ### Configuration - **Compartment OCID**: The compartment where the instance will be created - **Availability Domain**: The OCI availability domain (e.g. `Uocm:PHX-AD-1`) - **Display Name**: Human-readable name for the instance - **Shape**: Compute shape (e.g. `VM.Standard.E4.Flex`, `VM.Standard2.1`) - **Image OCID**: OCID of the platform or custom image to boot from - **Subnet OCID**: OCID of the subnet where the primary VNIC will be placed - **SSH Public Key**: Optional SSH public key added to `~/.ssh/authorized_keys` on the instance - **OCPUs / Memory**: For flex shapes, the number of OCPUs and memory in GB ### Output Emits the created instance details on the default output channel, including: - `instanceId` — instance OCID - `displayName` — instance display name - `lifecycleState` — should be `RUNNING` - `publicIp` — public IP address (if assigned) - `privateIp` — primary private IP address - `shape` — the instance shape - `availabilityDomain` — the availability domain - `compartmentId` — the compartment OCID - `region` — the region - `timeCreated` — ISO-8601 creation timestamp ### Example Output ```json { "data": { "availabilityDomain": "XXXX:eu-frankfurt-1-AD-1", "compartmentId": "ocid1.tenancy.oc1..aaaaaaaExample1234567890abcdefghijklmnopqrstuvwxyz1234567890", "displayName": "test-instance-12", "instanceId": "ocid1.instance.oc1.eu-frankfurt-1.aaaaExample1234567890abcdefghijklmnopqrstuvwxyz", "lifecycleState": "RUNNING", "privateIp": "10.0.0.17", "publicIp": "192.0.2.1", "region": "eu-frankfurt-1", "shape": "VM.Standard.E2.1.Micro", "timeCreated": "2026-04-22T20:31:25.145Z" }, "timestamp": "2026-04-22T20:31:58.249783188Z", "type": "oci.computeInstanceCreated" } ``` ## Create Function **Component key:** `oci.createFunction` The Create Function component deploys a new serverless function within an existing OCI Functions application. ### Use Cases - **Continuous deployment**: Automatically deploy new function versions as part of a CI/CD pipeline - **Serverless provisioning**: Create functions on-demand as part of environment setup workflows ### Configuration - **Compartment**: The compartment containing the application - **Application**: The application to deploy the function into - **Display Name**: A human-readable name for the function - **Image**: The container image URI (e.g. `phx.ocir.io/namespace/repo/image:tag`) - **Memory (MB)**: Memory allocated to the function (minimum 128 MB) - **Timeout (seconds)**: Optional maximum execution time in seconds ### Output Emits the created function details including: - `functionId` — function OCID - `displayName` — function name - `applicationId` — parent application OCID - `image` — the container image - `invokeEndpoint` — the HTTPS endpoint used to invoke the function - `memoryInMBs` — memory allocated in megabytes - `lifecycleState` — current state - `timeCreated` — ISO-8601 creation timestamp ### Example Output ```json { "data": { "applicationId": "ocid1.fnapp.oc1.eu-frankfurt-1.aaaaExample1234567890abcdefghijklmnopqrstuvwxyz", "displayName": "my-function", "functionId": "ocid1.fnfunc.oc1.eu-frankfurt-1.aaaaExample1234567890abcdefghijklmnopqrstuvwxyz", "image": "phx.ocir.io/mynamespace/myrepo/myfunction:0.0.1", "invokeEndpoint": "https://aabbccddeeff.call.eu-frankfurt-1.oci.oraclecloud.com", "lifecycleState": "ACTIVE", "memoryInMBs": 256, "timeCreated": "2026-04-22T20:33:10.512Z" }, "timestamp": "2026-04-22T20:33:11.102345678Z", "type": "oci.functionCreated" } ``` ## Create Image **Component key:** `oci.createImage` The Create Image component creates an OCI Compute boot disk image. ### Use Cases - **Golden image pipelines**: Bake reusable server images from configured instances - **Environment promotion**: Import exported images from Object Storage into a target compartment - **Backup workflows**: Capture a known-good instance image before a risky change ### Configuration - **Source Type**: Create from an instance, import from an Object Storage URL, or import from a bucket object - **Compartment**: Compartment where the image is created - **Display Name**: Friendly name for the image - **Instance OCID**: Source instance when creating from an instance - **Source Image Type**: Image format for imported images, such as QCOW2, VMDK, or OCI - **Namespace, Bucket, Object**: Object Storage location when importing from a bucket object - **Tags**: Optional freeform tags to apply to the image ### Completion behavior The component waits for the image to reach `AVAILABLE` before emitting. ### Example Output ```json { "data": { "image": { "baseImageId": "ocid1.image.oc1.eu-frankfurt-1.aaaaaaaBaseImageExample", "compartmentId": "ocid1.compartment.oc1..aaaaaaaExample1234567890abcdefghijklmnopqrstuvwxyz", "createImageAllowed": true, "displayName": "app-golden-image-2026-04-28", "id": "ocid1.image.oc1.eu-frankfurt-1.aaaaaaaImageExample1234567890abcdefghijklmnopqrstuvwxyz", "launchMode": "PARAVIRTUALIZED", "lifecycleState": "AVAILABLE", "operatingSystem": "Oracle Linux", "operatingSystemVersion": "8", "sizeInMBs": 51200, "timeCreated": "2026-04-28T09:12:42.000Z" } }, "timestamp": "2026-04-28T09:15:12.000Z", "type": "oci.image" } ``` ## Delete Application **Component key:** `oci.deleteApplication` The Delete Application component removes an Oracle Cloud Infrastructure Functions application. > **Important:** OCI will reject the deletion with a 409 Conflict if the application still contains functions. > You must delete all functions inside the application (using the **Delete Function** component) before using this component. ### Configuration - **Compartment**: The compartment containing the application - **Application**: The application to delete. The application must have no remaining functions. ### Output Emits the deleted application ID on the default output channel: - `applicationId` — OCID of the deleted application - `deleted` — boolean confirming deletion - `displayName` — name of the deleted application ### Example Output ```json { "data": { "applicationId": "ocid1.fnapp.oc1.eu-frankfurt-1.aaaaExample1234567890abcdefghijklmnopqrstuvwxyz", "deleted": true, "displayName": "my-functions-app" }, "timestamp": "2026-04-22T20:35:00.000000000Z", "type": "oci.applicationDeleted" } ``` ## Delete Function **Component key:** `oci.deleteFunction` The Delete Function component removes a function from an Oracle Cloud Infrastructure Functions application. ### Configuration - **Compartment**: The compartment containing the application - **Application**: The application that owns the function - **Function**: The function to delete ### Output Emits the deleted function ID on the default output channel: - `functionId` — OCID of the deleted function - `deleted` — boolean confirming deletion ### Example Output ```json { "data": { "deleted": true, "functionId": "ocid1.fnfunc.oc1.eu-frankfurt-1.aaaaExample1234567890abcdefghijklmnopqrstuvwxyz" }, "timestamp": "2026-04-22T20:36:00.000000000Z", "type": "oci.functionDeleted" } ``` ## Delete Image **Component key:** `oci.deleteImage` The Delete Image component deletes an OCI Compute custom image. Oracle-provided platform images cannot be deleted. ### Use Cases - **Cleanup workflows**: Remove obsolete custom images - **Quota management**: Delete old images before creating new ones - **Security response**: Retire vulnerable images from automated provisioning ### Example Output ```json { "data": { "deletedAt": "2026-04-28T09:20:00Z", "imageId": "ocid1.image.oc1.eu-frankfurt-1.aaaaaaaImageExample1234567890abcdefghijklmnopqrstuvwxyz", "state": "DELETED" }, "timestamp": "2026-04-28T09:20:00Z", "type": "oci.imageDeleted" } ``` ## Delete Instance **Component key:** `oci.deleteInstance` The Delete Instance component terminates an Oracle Cloud Infrastructure Compute instance and waits until OCI reports it as terminated. ### Use Cases - **Cleanup workflows**: Tear down temporary instances after a test or deployment finishes - **Cost controls**: Delete unused Compute instances from automation - **Incident remediation**: Terminate compromised or unhealthy instances after replacement capacity exists ### Configuration - **Instance**: The OCI Compute instance to terminate. - **Preserve Boot Volume**: When enabled, OCI preserves the boot volume after instance termination. ### Output Emits a minimal deletion payload on the default output channel: - `instanceId` — instance OCID - `lifecycleState` — `TERMINATED` ### Example Output ```json { "data": { "instanceId": "ocid1.instance.oc1.eu-frankfurt-1.aaaaExample1234567890", "lifecycleState": "TERMINATED" }, "timestamp": "2026-04-22T20:40:00.000Z", "type": "oci.deleteInstance" } ``` ## Get Image **Component key:** `oci.getImage` The Get Image component retrieves metadata for an OCI Compute custom image. Oracle-provided platform images are not returned by this component. ### Use Cases - **Deployment checks**: Verify that an image is available before launching instances - **Traceability**: Resolve image details by OCID - **Audit workflows**: Capture operating system, launch mode, and lifecycle state metadata ### Example Output ```json { "data": { "image": { "baseImageId": "ocid1.image.oc1.eu-frankfurt-1.aaaaaaaBaseImageExample", "compartmentId": "ocid1.compartment.oc1..aaaaaaaExample1234567890abcdefghijklmnopqrstuvwxyz", "createImageAllowed": true, "displayName": "app-golden-image-2026-04-28", "id": "ocid1.image.oc1.eu-frankfurt-1.aaaaaaaImageExample1234567890abcdefghijklmnopqrstuvwxyz", "launchMode": "PARAVIRTUALIZED", "lifecycleState": "AVAILABLE", "operatingSystem": "Oracle Linux", "operatingSystemVersion": "8", "sizeInMBs": 51200, "timeCreated": "2026-04-28T09:12:42.000Z" } }, "timestamp": "2026-04-28T09:16:00.000Z", "type": "oci.image" } ``` ## Get Instance **Component key:** `oci.getInstance` The Get Instance component fetches the latest details for an Oracle Cloud Infrastructure Compute instance. ### Use Cases - **Inventory checks**: Read instance state, shape, region, and network addresses during a workflow - **Deployment gates**: Verify a target instance exists and is in the expected lifecycle state - **Audit workflows**: Capture instance metadata before another operation runs ### Configuration - **Instance**: The OCI Compute instance to fetch. ### Output Emits the instance details on the default output channel, including: - `instanceId` — instance OCID - `displayName` — instance display name - `lifecycleState` — current lifecycle state - `publicIp` — public IP address, if assigned - `privateIp` — primary private IP address, if available - `shape` — the instance shape - `availabilityDomain` — the availability domain - `compartmentId` — the compartment OCID - `region` — the region - `timeCreated` — ISO-8601 creation timestamp ### Example Output ```json { "data": { "availabilityDomain": "XXXX:eu-frankfurt-1-AD-1", "compartmentId": "ocid1.tenancy.oc1..aaaaaaaExample1234567890", "displayName": "test-instance-12", "instanceId": "ocid1.instance.oc1.eu-frankfurt-1.aaaaExample1234567890", "lifecycleState": "RUNNING", "privateIp": "10.0.0.17", "publicIp": "192.0.2.1", "region": "eu-frankfurt-1", "shape": "VM.Standard.E2.1.Micro", "timeCreated": "2026-04-22T20:31:25.145Z" }, "timestamp": "2026-04-22T20:32:00.000Z", "type": "oci.getInstance" } ``` ## Invoke Function **Component key:** `oci.invokeFunction` The Invoke Function component executes an Oracle Cloud Infrastructure serverless function and emits its response. ### Use Cases - **Data transformation**: Invoke a function to process or transform data mid-workflow - **Custom logic**: Run arbitrary serverless code as a workflow step - **Integration hooks**: Call a function to trigger external systems ### Configuration - **Compartment**: The compartment containing the application - **Application**: The application that owns the function - **Function**: The function to invoke - **Payload**: Optional JSON or plain-text body sent to the function ### Output Emits the function response on the default output channel: - `functionId` — OCID of the invoked function - `statusCode` — HTTP status code returned by the function runtime - `response` — raw response body as a string ### Example Output ```json { "data": { "functionId": "ocid1.fnfunc.oc1.eu-frankfurt-1.aaaaExample1234567890abcdefghijklmnopqrstuvwxyz", "response": "{\"result\": \"ok\", \"processed\": 42}", "statusCode": 200 }, "timestamp": "2026-04-22T20:34:05.987654321Z", "type": "oci.functionInvoked" } ``` ## Manage Instance Power **Component key:** `oci.manageInstancePower` The Manage Instance Power component performs a power lifecycle action on an Oracle Cloud Infrastructure Compute instance and waits for the target state. ### Use Cases - **Scheduled shutdowns**: Stop instances outside business hours to reduce cost - **Recovery workflows**: Reset or soft-reset an instance after an incident - **Startup automation**: Start instances before a deployment, test, or maintenance workflow runs ### Configuration - **Instance**: The OCI Compute instance. - **Action**: One of `START`, `STOP`, `SOFTSTOP`, `RESET`, or `SOFTRESET`. ### Output Emits the instance details on the default output channel once the instance reaches the expected lifecycle state: - `instanceId` — instance OCID - `displayName` — instance display name - `lifecycleState` — `RUNNING` for start/reset actions, or `STOPPED` for stop actions - `shape` — the instance shape - `availabilityDomain` — the availability domain - `compartmentId` — the compartment OCID - `region` — the region - `timeCreated` — ISO-8601 creation timestamp ### Example Output ```json { "data": { "availabilityDomain": "XXXX:eu-frankfurt-1-AD-1", "compartmentId": "ocid1.tenancy.oc1..aaaaaaaExample1234567890", "displayName": "test-instance-12", "instanceId": "ocid1.instance.oc1.eu-frankfurt-1.aaaaExample1234567890", "lifecycleState": "STOPPED", "region": "eu-frankfurt-1", "shape": "VM.Standard.E2.1.Micro", "timeCreated": "2026-04-22T20:31:25.145Z" }, "timestamp": "2026-04-22T20:35:00.000Z", "type": "oci.manageInstancePower" } ``` ## Update Image **Component key:** `oci.updateImage` The Update Image component updates the display name of an OCI Compute custom image. Oracle-provided platform images cannot be updated. ### Use Cases - **Release promotion**: Rename an image after validation - **Operational cleanup**: Standardize image names - **Inventory hygiene**: Keep image metadata readable in automated workflows ### Example Output ```json { "data": { "image": { "baseImageId": "ocid1.image.oc1.eu-frankfurt-1.aaaaaaaBaseImageExample", "compartmentId": "ocid1.compartment.oc1..aaaaaaaExample1234567890abcdefghijklmnopqrstuvwxyz", "createImageAllowed": true, "displayName": "app-golden-image-production", "id": "ocid1.image.oc1.eu-frankfurt-1.aaaaaaaImageExample1234567890abcdefghijklmnopqrstuvwxyz", "launchMode": "PARAVIRTUALIZED", "lifecycleState": "AVAILABLE", "operatingSystem": "Oracle Linux", "operatingSystemVersion": "8", "sizeInMBs": 51200, "timeCreated": "2026-04-28T09:12:42.000Z" } }, "timestamp": "2026-04-28T09:18:00.000Z", "type": "oci.image" } ``` ## Update Instance **Component key:** `oci.updateInstance` The Update Instance component updates mutable attributes on an Oracle Cloud Infrastructure Compute instance. ### Use Cases - **Rename instances**: Update the display name for operational clarity - **Resize flex shapes**: Adjust OCPUs or memory for supported flexible shapes - **Post-provisioning changes**: Apply instance settings after a workflow decides the desired capacity ### Configuration - **Instance**: The OCI Compute instance to update. - **Display Name**: Optional new display name. - **OCPUs**: Optional OCPU count for flexible shapes. - **Memory (GB)**: Optional memory size for flexible shapes. ### Output Emits the updated instance details on the default output channel, including: - `instanceId` — instance OCID - `displayName` — instance display name - `lifecycleState` — current lifecycle state - `publicIp` — public IP address, if assigned - `privateIp` — primary private IP address, if available - `shape` — the instance shape - `availabilityDomain` — the availability domain - `compartmentId` — the compartment OCID - `region` — the region - `timeCreated` — ISO-8601 creation timestamp ### Example Output ```json { "data": { "availabilityDomain": "XXXX:eu-frankfurt-1-AD-1", "compartmentId": "ocid1.tenancy.oc1..aaaaaaaExample1234567890", "displayName": "test-instance-renamed", "instanceId": "ocid1.instance.oc1.eu-frankfurt-1.aaaaExample1234567890", "lifecycleState": "RUNNING", "privateIp": "10.0.0.17", "publicIp": "192.0.2.1", "region": "eu-frankfurt-1", "shape": "VM.Standard.E2.1.Micro", "timeCreated": "2026-04-22T20:31:25.145Z" }, "timestamp": "2026-04-22T20:33:00.000Z", "type": "oci.updateInstance" } ``` #### PagerDuty Source URL: https://docs.superplane.com/components/pagerduty Manage and react to incidents in PagerDuty import { CardGrid, LinkCard } from "@astrojs/starlight/components"; ## Triggers ## Actions ## On Incident **Trigger key:** `pagerduty.onIncident` The On Incident trigger starts a workflow execution when PagerDuty incident events occur. ### Use Cases - **Incident automation**: Automate responses to incident events - **Notification workflows**: Send notifications when incidents are triggered or resolved - **Integration workflows**: Sync incidents with external systems - **Escalation handling**: Handle incident escalations automatically ### Configuration - **Service**: Select the PagerDuty service to monitor - **Events**: Select which incident events to listen for (triggered, acknowledged, resolved) - **Urgencies**: Filter by urgency level (low, high) - leave empty to listen to all urgencies ### Event Data Each incident event includes: - **event**: Event type (incident.triggered, incident.acknowledged, incident.resolved) - **incident**: Complete incident information including title, description, urgency, status - **service**: Service information - **assignments**: Current incident assignments ### Webhook Setup This trigger automatically sets up a PagerDuty webhook subscription when configured. The subscription is managed by SuperPlane and will be cleaned up when the trigger is removed. ### Example Data ```json { "data": { "agent": { "html_url": "https://acme.pagerduty.com/users/PLH1HKV", "id": "PLH1HKV", "self": "https://api.pagerduty.com/users/PLH1HKV", "summary": "Tenex Engineer", "type": "user_reference" }, "incident": { "assignees": [ { "html_url": "https://acme.pagerduty.com/users/PTUXL6G", "id": "PTUXL6G", "self": "https://api.pagerduty.com/users/PTUXL6G", "summary": "User 123", "type": "user_reference" } ], "conference_bridge": { "conference_number": "+1 1234123412,,987654321#", "conference_url": "https://example.com" }, "created_at": "2020-04-09T15:16:27Z", "escalation_policy": { "html_url": "https://acme.pagerduty.com/escalation_policies/PUS0KTE", "id": "PUS0KTE", "self": "https://api.pagerduty.com/escalation_policies/PUS0KTE", "summary": "Default", "type": "escalation_policy_reference" }, "html_url": "https://acme.pagerduty.com/incidents/PGR0VU2", "id": "PGR0VU2", "incident_key": "d3640fbd41094207a1c11e58e46b1662", "number": 2, "priority": { "html_url": "https://acme.pagerduty.com/account/incident_priorities", "id": "PSO75BM", "self": "https://api.pagerduty.com/priorities/PSO75BM", "summary": "P1", "type": "priority_reference" }, "reopened_at": "2020-10-02T18:45:22Z", "resolve_reason": null, "self": "https://api.pagerduty.com/incidents/PGR0VU2", "service": { "html_url": "https://acme.pagerduty.com/services/PF9KMXH", "id": "PF9KMXH", "self": "https://api.pagerduty.com/services/PF9KMXH", "summary": "API Service", "type": "service_reference" }, "status": "triggered", "teams": [ { "html_url": "https://acme.pagerduty.com/teams/PFCVPS0", "id": "PFCVPS0", "self": "https://api.pagerduty.com/teams/PFCVPS0", "summary": "Engineering", "type": "team_reference" } ], "title": "A little bump in the road", "type": "incident", "urgency": "high" } }, "timestamp": "2026-01-19T12:00:00Z", "type": "pagerduty.onIncident" } ``` ## On Incident Annotated **Trigger key:** `pagerduty.onIncidentAnnotated` The On Incident Annotated trigger starts a workflow execution when a note is added to a PagerDuty incident. ### Use Cases - **Note tracking**: Track when notes are added to incidents - **Collaboration workflows**: Trigger actions based on incident annotations - **Audit logging**: Log all notes added to incidents - **Integration sync**: Sync notes with external ticketing systems ### Configuration - **Service**: Select the PagerDuty service to monitor for incident annotations ### Event Data Each annotation event includes: - **agent**: Information about who added the note - **incident**: Complete incident information ### Webhook Setup This trigger automatically sets up a PagerDuty webhook subscription when configured. The subscription is managed by SuperPlane and will be cleaned up when the trigger is removed. ### Example Data ```json { "data": { "agent": { "html_url": "https://acme.pagerduty.com/users/PLH1HKV", "id": "PLH1HKV", "self": "https://api.pagerduty.com/users/PLH1HKV", "summary": "Tenex Engineer", "type": "user_reference" }, "annotation": { "content": "Investigating the root cause. Initial analysis suggests a database connection timeout." }, "incident": { "assignees": [ { "html_url": "https://acme.pagerduty.com/users/PTUXL6G", "id": "PTUXL6G", "self": "https://api.pagerduty.com/users/PTUXL6G", "summary": "User 123", "type": "user_reference" } ], "created_at": "2020-04-09T15:16:27Z", "escalation_policy": { "html_url": "https://acme.pagerduty.com/escalation_policies/PUS0KTE", "id": "PUS0KTE", "self": "https://api.pagerduty.com/escalation_policies/PUS0KTE", "summary": "Default", "type": "escalation_policy_reference" }, "html_url": "https://acme.pagerduty.com/incidents/PGR0VU2", "id": "PGR0VU2", "incident_key": "d3640fbd41094207a1c11e58e46b1662", "number": 2, "self": "https://api.pagerduty.com/incidents/PGR0VU2", "service": { "html_url": "https://acme.pagerduty.com/services/PF9KMXH", "id": "PF9KMXH", "self": "https://api.pagerduty.com/services/PF9KMXH", "summary": "API Service", "type": "service_reference" }, "status": "acknowledged", "teams": [ { "html_url": "https://acme.pagerduty.com/teams/PFCVPS0", "id": "PFCVPS0", "self": "https://api.pagerduty.com/teams/PFCVPS0", "summary": "Engineering", "type": "team_reference" } ], "title": "A little bump in the road", "type": "incident", "urgency": "high" } }, "timestamp": "2026-01-19T12:00:00Z", "type": "pagerduty.incident.annotated" } ``` ## On Incident Status Update **Trigger key:** `pagerduty.onIncidentStatusUpdate` The On Incident Status Update trigger starts a workflow execution when PagerDuty incident status changes. ### Use Cases - **Status tracking**: Track incident status changes and update systems - **Workflow automation**: Trigger workflows when incidents are acknowledged or resolved - **Notification systems**: Notify teams about status updates - **Integration workflows**: Sync status changes with external systems ### Configuration - **Service**: Select the PagerDuty service to monitor for status updates ### Event Data Each status update event includes: - **event**: Event type (incident.status_updated) - **incident**: Complete incident information including current status - **status**: New incident status - **service**: Service information - **assignments**: Current incident assignments ### Webhook Setup This trigger automatically sets up a PagerDuty webhook subscription when configured. The subscription is managed by SuperPlane and will be cleaned up when the trigger is removed. ### Example Data ```json { "data": { "agent": { "html_url": "https://acme.pagerduty.com/users/PLH1HKV", "id": "PLH1HKV", "self": "https://api.pagerduty.com/users/PLH1HKV", "summary": "Tenex Engineer", "type": "user_reference" }, "incident": { "html_url": "https://acme.pagerduty.com/incidents/PGR0VU2", "id": "PGR0VU2", "self": "https://api.pagerduty.com/incidents/PGR0VU2", "summary": "A little bump in the road", "type": "incident_reference" }, "status_update": { "created_at": "2026-01-19T12:30:00Z", "id": "P1234567", "message": "We have identified the issue and are working on a fix.", "sender": { "html_url": "https://acme.pagerduty.com/users/PLH1HKV", "id": "PLH1HKV", "self": "https://api.pagerduty.com/users/PLH1HKV", "summary": "Tenex Engineer", "type": "user_reference" } } }, "timestamp": "2026-01-19T12:30:00Z", "type": "pagerduty.incident.status_update_published" } ``` ## Acknowledge Incident **Component key:** `pagerduty.acknowledgeIncident` The Acknowledge Incident component acknowledges an existing PagerDuty incident. ### Use Cases - **Incident response**: Acknowledge an incident to stop escalations and indicate someone is working on it - **Automated acknowledgement**: Automatically acknowledge incidents based on workflow conditions - **Integration workflows**: Acknowledge incidents when related events occur in other systems ### Configuration - **Incident ID**: The ID of the incident to acknowledge (e.g., A12BC34567...) - **From Email**: Email address of a valid PagerDuty user (required for App OAuth, optional for API tokens) ### Behavior When an incident is acknowledged, escalations are paused and the incident status changes to "acknowledged". The incident will remain acknowledged until it is resolved or re-triggered. ### Output Returns the acknowledged incident object with all current information. ### Example Output ```json { "data": { "incident": { "assigned_via": "escalation_policy", "assignments": [ { "assignee": { "html_url": "https://subdomain.pagerduty.com/users/PXPGF42", "id": "PXPGF42", "self": "https://api.pagerduty.com/users/PXPGF42", "summary": "Earline Greenholt", "type": "user_reference" }, "at": "2015-11-10T00:31:52Z" } ], "created_at": "2015-10-06T21:30:42Z", "escalation_policy": { "html_url": "https://subdomain.pagerduty.com/escalation_policies/PT20YPA", "id": "PT20YPA", "self": "https://api.pagerduty.com/escalation_policies/PT20YPA", "summary": "Another Escalation Policy", "type": "escalation_policy_reference" }, "first_trigger_log_entry": { "html_url": "https://subdomain.pagerduty.com/incidents/PT4KHLK/log_entries/Q02JTSNZWHSEKV", "id": "Q02JTSNZWHSEKV", "self": "https://api.pagerduty.com/log_entries/Q02JTSNZWHSEKV?incident_id=PT4KHLK", "summary": "Triggered through the API", "type": "trigger_log_entry_reference" }, "html_url": "https://subdomain.pagerduty.com/incidents/PT4KHLK", "id": "PT4KHLK", "incident_key": "baf7cf21b1da41b4b0221008339ff357", "incident_number": 1234, "last_status_change_at": "2015-10-06T21:38:23Z", "last_status_change_by": { "html_url": "https://subdomain.pagerduty.com/users/PXPGF42", "id": "PXPGF42", "self": "https://api.pagerduty.com/users/PXPGF42", "summary": "Earline Greenholt", "type": "user_reference" }, "priority": { "id": "P53ZZH5", "self": "https://api.pagerduty.com/priorities/P53ZZH5", "summary": "P2", "type": "priority_reference" }, "resolved_at": null, "self": "https://api.pagerduty.com/incidents/PT4KHLK", "service": { "html_url": "https://subdomain.pagerduty.com/service-directory/PWIXJZS", "id": "PWIXJZS", "self": "https://api.pagerduty.com/services/PWIXJZS", "summary": "My Mail Service", "type": "service_reference" }, "status": "acknowledged", "summary": "[#1234] The server is on fire.", "teams": [ { "html_url": "https://subdomain.pagerduty.com/teams/PQ9K7I8", "id": "PQ9K7I8", "self": "https://api.pagerduty.com/teams/PQ9K7I8", "summary": "Engineering", "type": "team_reference" } ], "title": "The server is on fire.", "type": "incident", "updated_at": "2015-10-06T21:40:23Z", "urgency": "high" } }, "timestamp": "2026-01-19T12:00:00Z", "type": "pagerduty.incident" } ``` ## Annotate Incident **Component key:** `pagerduty.annotateIncident` The Annotate Incident component adds a note to an existing PagerDuty incident. ### Use Cases - **Status updates**: Add progress updates to an incident - **Investigation notes**: Document findings during incident investigation - **Handoff information**: Leave notes for the next responder - **Resolution details**: Document the root cause and resolution steps ### Configuration - **Incident ID**: The ID of the incident to annotate (e.g., A12BC34567...) - **Content**: The note content to add to the incident (supports expressions) - **From Email**: Email address of a valid PagerDuty user (required for App OAuth, optional for API tokens) ### Output Returns the incident object with all current information. ### Example Output ```json { "data": { "incident": { "assigned_via": "escalation_policy", "assignments": [ { "assignee": { "html_url": "https://subdomain.pagerduty.com/users/PXPGF42", "id": "PXPGF42", "self": "https://api.pagerduty.com/users/PXPGF42", "summary": "Earline Greenholt", "type": "user_reference" }, "at": "2015-11-10T00:31:52Z" } ], "created_at": "2015-10-06T21:30:42Z", "escalation_policy": { "html_url": "https://subdomain.pagerduty.com/escalation_policies/PT20YPA", "id": "PT20YPA", "self": "https://api.pagerduty.com/escalation_policies/PT20YPA", "summary": "Another Escalation Policy", "type": "escalation_policy_reference" }, "first_trigger_log_entry": { "html_url": "https://subdomain.pagerduty.com/incidents/PT4KHLK/log_entries/Q02JTSNZWHSEKV", "id": "Q02JTSNZWHSEKV", "self": "https://api.pagerduty.com/log_entries/Q02JTSNZWHSEKV?incident_id=PT4KHLK", "summary": "Triggered through the API", "type": "trigger_log_entry_reference" }, "html_url": "https://subdomain.pagerduty.com/incidents/PT4KHLK", "id": "PT4KHLK", "incident_key": "baf7cf21b1da41b4b0221008339ff357", "incident_number": 1234, "incident_type": { "name": "major_incident" }, "last_status_change_at": "2015-10-06T21:38:23Z", "last_status_change_by": { "html_url": "https://subdomain.pagerduty.com/users/PXPGF42", "id": "PXPGF42", "self": "https://api.pagerduty.com/users/PXPGF42", "summary": "Earline Greenholt", "type": "user_reference" }, "priority": { "id": "P53ZZH5", "self": "https://api.pagerduty.com/priorities/P53ZZH5", "summary": "P2", "type": "priority_reference" }, "resolved_at": null, "self": "https://api.pagerduty.com/incidents/PT4KHLK", "service": { "html_url": "https://subdomain.pagerduty.com/service-directory/PWIXJZS", "id": "PWIXJZS", "self": "https://api.pagerduty.com/services/PWIXJZS", "summary": "My Mail Service", "type": "service_reference" }, "status": "acknowledged", "summary": "[#1234] The server is on fire.", "teams": [ { "html_url": "https://subdomain.pagerduty.com/teams/PQ9K7I8", "id": "PQ9K7I8", "self": "https://api.pagerduty.com/teams/PQ9K7I8", "summary": "Engineering", "type": "team_reference" } ], "title": "The server is on fire.", "type": "incident", "updated_at": "2015-10-06T21:40:23Z", "urgency": "high" } }, "timestamp": "2026-01-19T12:00:00Z", "type": "pagerduty.incident" } ``` ## Create Incident **Component key:** `pagerduty.createIncident` The Create Incident component creates a new incident in PagerDuty. ### Use Cases - **Alert escalation**: Create incidents from monitoring alerts - **Error tracking**: Automatically create incidents when errors are detected - **Manual incident creation**: Create incidents from workflow events - **Integration workflows**: Create incidents from external system events ### Configuration - **Title**: A succinct description of the incident (required, supports expressions) - **Description**: Additional details about the incident (optional, supports expressions) - **Urgency**: Incident urgency level (high or low) - **Service**: Select the PagerDuty service to create the incident in - **From Email**: Email address of a valid PagerDuty user (required for App OAuth, optional for API tokens) ### Output Returns the created incident object including: - **id**: Incident ID - **incident_number**: Human-readable incident number - **status**: Current incident status - **urgency**: Incident urgency - **service**: Service information - **created_at**: Incident creation timestamp ### Example Output ```json { "data": { "incident": { "assigned_via": "escalation_policy", "assignments": [ { "assignee": { "html_url": "https://subdomain.pagerduty.com/users/PXPGF42", "id": "PXPGF42", "self": "https://api.pagerduty.com/users/PXPGF42", "summary": "Earline Greenholt", "type": "user_reference" }, "at": "2015-11-10T00:31:52Z" } ], "created_at": "2015-10-06T21:30:42Z", "escalation_policy": { "html_url": "https://subdomain.pagerduty.com/escalation_policies/PT20YPA", "id": "PT20YPA", "self": "https://api.pagerduty.com/escalation_policies/PT20YPA", "summary": "Another Escalation Policy", "type": "escalation_policy_reference" }, "first_trigger_log_entry": { "html_url": "https://subdomain.pagerduty.com/incidents/PT4KHLK/log_entries/Q02JTSNZWHSEKV", "id": "Q02JTSNZWHSEKV", "self": "https://api.pagerduty.com/log_entries/Q02JTSNZWHSEKV?incident_id=PT4KHLK", "summary": "Triggered through the API", "type": "trigger_log_entry_reference" }, "html_url": "https://subdomain.pagerduty.com/incidents/PT4KHLK", "id": "PT4KHLK", "incident_key": "baf7cf21b1da41b4b0221008339ff357", "incident_number": 1234, "incident_type": { "name": "major_incident" }, "last_status_change_at": "2015-10-06T21:38:23Z", "last_status_change_by": { "html_url": "https://subdomain.pagerduty.com/users/PXPGF42", "id": "PXPGF42", "self": "https://api.pagerduty.com/users/PXPGF42", "summary": "Earline Greenholt", "type": "user_reference" }, "priority": { "id": "P53ZZH5", "self": "https://api.pagerduty.com/priorities/P53ZZH5", "summary": "P2", "type": "priority_reference" }, "resolved_at": null, "self": "https://api.pagerduty.com/incidents/PT4KHLK", "service": { "html_url": "https://subdomain.pagerduty.com/service-directory/PWIXJZS", "id": "PWIXJZS", "self": "https://api.pagerduty.com/services/PWIXJZS", "summary": "My Mail Service", "type": "service_reference" }, "status": "triggered", "summary": "[#1234] The server is on fire.", "teams": [ { "html_url": "https://subdomain.pagerduty.com/teams/PQ9K7I8", "id": "PQ9K7I8", "self": "https://api.pagerduty.com/teams/PQ9K7I8", "summary": "Engineering", "type": "team_reference" } ], "title": "The server is on fire.", "type": "incident", "updated_at": "2015-10-06T21:40:23Z", "urgency": "high" } }, "timestamp": "2026-01-19T12:00:00Z", "type": "pagerduty.incident" } ``` ## Escalate Incident **Component key:** `pagerduty.escalateIncident` The Escalate Incident component escalates an existing PagerDuty incident to a specific escalation level within its current escalation policy. ### Important: High-Urgency Incidents Only **This action only works on high-urgency incidents.** Low-urgency incidents cannot be escalated in PagerDuty. If you need to reassign a low-urgency incident, use the "Reassign Escalation Policy" action instead. ### What is Escalation? In PagerDuty, an escalation policy defines a chain of responders: - **Level 1**: Primary on-call (e.g., the assigned engineer) - **Level 2**: Secondary responder (e.g., team lead) - **Level 3**: Tertiary responder (e.g., manager) - And so on... Escalating an incident moves it to a higher level, notifying the responders at that level immediately instead of waiting for the automatic escalation timeout. ### Use Cases - **Manual escalation**: Escalate when the current responder cannot resolve the issue - **Automated escalation**: Automatically escalate based on workflow conditions (e.g., incident age) - **Skip levels**: Jump directly to a higher level for critical situations ### Configuration - **Incident ID**: The ID of the incident to escalate (e.g., A12BC34567...) - **Escalation Level**: The level to escalate to (1-10). This is the level number within the incident's current escalation policy. - **From Email**: Email address of a valid PagerDuty user (required for App OAuth, optional for API tokens) ### Output Returns the escalated incident object with all current information. ### Example Output ```json { "data": { "incident": { "assigned_via": "escalation_policy", "assignments": [ { "assignee": { "html_url": "https://subdomain.pagerduty.com/users/PUSER02", "id": "PUSER02", "self": "https://api.pagerduty.com/users/PUSER02", "summary": "Manager Smith", "type": "user_reference" }, "at": "2015-10-06T21:42:00Z" } ], "created_at": "2015-10-06T21:30:42Z", "escalation_policy": { "html_url": "https://subdomain.pagerduty.com/escalation_policies/PT20YPA", "id": "PT20YPA", "self": "https://api.pagerduty.com/escalation_policies/PT20YPA", "summary": "Another Escalation Policy", "type": "escalation_policy_reference" }, "first_trigger_log_entry": { "html_url": "https://subdomain.pagerduty.com/incidents/PT4KHLK/log_entries/Q02JTSNZWHSEKV", "id": "Q02JTSNZWHSEKV", "self": "https://api.pagerduty.com/log_entries/Q02JTSNZWHSEKV?incident_id=PT4KHLK", "summary": "Triggered through the API", "type": "trigger_log_entry_reference" }, "html_url": "https://subdomain.pagerduty.com/incidents/PT4KHLK", "id": "PT4KHLK", "incident_key": "baf7cf21b1da41b4b0221008339ff357", "incident_number": 1234, "last_status_change_at": "2015-10-06T21:42:00Z", "last_status_change_by": { "html_url": "https://subdomain.pagerduty.com/users/PXPGF42", "id": "PXPGF42", "self": "https://api.pagerduty.com/users/PXPGF42", "summary": "Earline Greenholt", "type": "user_reference" }, "priority": { "id": "P53ZZH5", "self": "https://api.pagerduty.com/priorities/P53ZZH5", "summary": "P2", "type": "priority_reference" }, "resolved_at": null, "self": "https://api.pagerduty.com/incidents/PT4KHLK", "service": { "html_url": "https://subdomain.pagerduty.com/service-directory/PWIXJZS", "id": "PWIXJZS", "self": "https://api.pagerduty.com/services/PWIXJZS", "summary": "My Mail Service", "type": "service_reference" }, "status": "triggered", "summary": "[#1234] The server is on fire.", "teams": [ { "html_url": "https://subdomain.pagerduty.com/teams/PQ9K7I8", "id": "PQ9K7I8", "self": "https://api.pagerduty.com/teams/PQ9K7I8", "summary": "Engineering", "type": "team_reference" } ], "title": "The server is on fire.", "type": "incident", "updated_at": "2015-10-06T21:42:00Z", "urgency": "high" } }, "timestamp": "2026-01-19T12:00:00Z", "type": "pagerduty.incident" } ``` ## List Incidents **Component key:** `pagerduty.listIncidents` The List Incidents component queries PagerDuty for open incidents and routes execution based on urgency levels. ### Use Cases - **Health checks**: Check for active incidents and route based on severity - **Incident monitoring**: Monitor incident status across services - **Automated response**: Trigger workflows based on incident presence - **Reporting**: Collect incident data for reporting or analysis ### Configuration - **Services**: Optional list of services to filter incidents (leave empty to get incidents from all services) ### Output Channels - **Clear**: No open incidents found - **Low**: Only low urgency incidents found - **High**: One or more high urgency incidents found ### Output Returns a list of open incidents with: - **id**: Incident ID - **incident_number**: Human-readable incident number - **status**: Incident status (triggered, acknowledged) - **urgency**: Incident urgency (low, high) - **title**: Incident title - **service**: Service information - **assignments**: Current assignments ### Example Output ```json { "data": { "incidents": [ { "acknowledgements": [], "assignments": [ { "assignee": { "html_url": "https://example.pagerduty.com/users/PUSER01", "id": "PUSER01", "summary": "John Doe", "type": "user_reference" }, "at": "2024-01-15T12:00:00Z" } ], "created_at": "2024-01-15T12:00:00Z", "description": "The production server is experiencing critical issues", "escalation_policy": { "html_url": "https://example.pagerduty.com/escalation_policies/PABCDEF", "id": "PABCDEF", "summary": "Default Escalation Policy", "type": "escalation_policy_reference" }, "html_url": "https://example.pagerduty.com/incidents/PT4KHLK", "id": "PT4KHLK", "incident_number": 1234, "priority": { "id": "P1PRIORITY", "summary": "P1", "type": "priority_reference" }, "service": { "html_url": "https://example.pagerduty.com/services/PX123456", "id": "PX123456", "summary": "Production API", "type": "service_reference" }, "status": "triggered", "title": "Server is on fire", "updated_at": "2024-01-15T12:00:00Z", "urgency": "high" }, { "acknowledgements": [ { "acknowledger": { "html_url": "https://example.pagerduty.com/users/PUSER01", "id": "PUSER01", "summary": "John Doe", "type": "user_reference" }, "at": "2024-01-15T12:35:00Z" } ], "assignments": [ { "assignee": { "html_url": "https://example.pagerduty.com/users/PUSER01", "id": "PUSER01", "summary": "John Doe", "type": "user_reference" }, "at": "2024-01-15T12:30:00Z" } ], "created_at": "2024-01-15T12:30:00Z", "description": "Database connections are timing out", "escalation_policy": { "html_url": "https://example.pagerduty.com/escalation_policies/PABCDEF", "id": "PABCDEF", "summary": "Default Escalation Policy", "type": "escalation_policy_reference" }, "html_url": "https://example.pagerduty.com/incidents/PT4KHLM", "id": "PT4KHLM", "incident_number": 1235, "priority": { "id": "P2PRIORITY", "summary": "P2", "type": "priority_reference" }, "service": { "html_url": "https://example.pagerduty.com/services/PX123456", "id": "PX123456", "summary": "Production API", "type": "service_reference" }, "status": "acknowledged", "title": "Database connection issues", "updated_at": "2024-01-15T12:35:00Z", "urgency": "high" } ], "total": 2 }, "timestamp": "2024-01-15T13:00:00Z", "type": "pagerduty.incidents.list" } ``` ## List Log Entries **Component key:** `pagerduty.listLogEntries` The List Log Entries component retrieves all log entries (audit trail) for a PagerDuty incident. ### Use Cases - **Audit trail**: Access complete incident history for compliance or review - **Timeline reconstruction**: Build a detailed timeline of all incident activity - **Incident analysis**: Analyze escalation patterns and response times - **Forensics**: Review all actions taken during an incident ### Configuration - **Incident ID**: The ID of the incident to list log entries for (e.g., A12BC34567...) - **Limit**: Maximum number of log entries to return (default: 100) ### Output Returns a list of log entries with: - **id**: Log entry ID - **type**: The type of log entry (e.g., trigger_log_entry, acknowledge_log_entry, annotate_log_entry) - **summary**: A summary of what happened - **created_at**: When the log entry was created - **agent**: The agent (user or service) that caused the log entry - **channel**: The channel through which the action was performed ### Example Output ```json { "data": { "log_entries": [ { "agent": { "html_url": "https://acme.pagerduty.com/services/PLH1HKV", "id": "PLH1HKV", "summary": "API Service", "type": "service_reference" }, "channel": { "type": "api" }, "created_at": "2024-01-15T10:00:00Z", "id": "Q02JTSNZWHSEKV", "summary": "Triggered through the API", "type": "trigger_log_entry" }, { "agent": { "html_url": "https://acme.pagerduty.com/users/PUSER01", "id": "PUSER01", "summary": "John Smith", "type": "user_reference" }, "channel": { "type": "web_ui" }, "created_at": "2024-01-15T10:15:00Z", "id": "Q02JTSNZWHSEKW", "summary": "Acknowledged by John Smith", "type": "acknowledge_log_entry" }, { "agent": { "html_url": "https://acme.pagerduty.com/users/PUSER01", "id": "PUSER01", "summary": "John Smith", "type": "user_reference" }, "channel": { "type": "web_ui" }, "created_at": "2024-01-15T10:30:00Z", "id": "Q02JTSNZWHSEKX", "summary": "John Smith added a note", "type": "annotate_log_entry" } ], "total": 3 }, "timestamp": "2024-01-15T11:00:00Z", "type": "pagerduty.log_entries.list" } ``` ## List Notes **Component key:** `pagerduty.listNotes` The List Notes component retrieves all notes (timeline entries) for a PagerDuty incident. ### Use Cases - **Incident review**: Review all notes added to an incident - **Timeline reconstruction**: Build a timeline of incident updates - **Audit trail**: Access the history of notes for compliance or review - **Note analysis**: Process or analyze notes for patterns or keywords ### Configuration - **Incident ID**: The ID of the incident to list notes for (e.g., A12BC34567...) ### Output Returns a list of notes with: - **id**: Note ID - **content**: The note content - **created_at**: When the note was created - **user**: The user who created the note - **channel**: The channel through which the note was created ### Example Output ```json { "data": { "notes": [ { "channel": { "type": "web_ui" }, "content": "Investigation started. Checking server logs for anomalies.", "created_at": "2024-01-15T10:30:00Z", "id": "PVL9NF8", "user": { "html_url": "https://acme.pagerduty.com/users/PLH1HKV", "id": "PLH1HKV", "summary": "John Smith", "type": "user_reference" } }, { "channel": { "type": "web_ui" }, "content": "Root cause identified: memory leak in the cache service. Deploying fix now.", "created_at": "2024-01-15T10:45:00Z", "id": "PVL9NF9", "user": { "html_url": "https://acme.pagerduty.com/users/PLH1HKV", "id": "PLH1HKV", "summary": "John Smith", "type": "user_reference" } }, { "channel": { "type": "api" }, "content": "Fix deployed successfully. Monitoring for stability.", "created_at": "2024-01-15T11:00:00Z", "id": "PVL9NFA", "user": { "html_url": "https://acme.pagerduty.com/users/PLH1HKW", "id": "PLH1HKW", "summary": "Jane Doe", "type": "user_reference" } } ], "total": 3 }, "timestamp": "2024-01-15T11:05:00Z", "type": "pagerduty.notes.list" } ``` ## Resolve Incident **Component key:** `pagerduty.resolveIncident` The Resolve Incident component resolves an existing PagerDuty incident. ### Use Cases - **Incident closure**: Resolve an incident when the issue has been fixed - **Automated resolution**: Automatically resolve incidents based on recovery signals - **Integration workflows**: Resolve incidents when related events occur in other systems ### Configuration - **Incident ID**: The ID of the incident to resolve (e.g., A12BC34567...) - **From Email**: Email address of a valid PagerDuty user (required for App OAuth, optional for API tokens) - **Resolution Notes**: Optional notes about the resolution (saved to incident description) ### Behavior When an incident is resolved, the incident status changes to "resolved" and all escalations stop. If resolution notes are provided, they will be saved to the incident description. ### Output Returns the resolved incident object with all current information. ### Example Output ```json { "data": { "incident": { "assigned_via": "escalation_policy", "assignments": [], "created_at": "2015-10-06T21:30:42Z", "escalation_policy": { "html_url": "https://subdomain.pagerduty.com/escalation_policies/PT20YPA", "id": "PT20YPA", "self": "https://api.pagerduty.com/escalation_policies/PT20YPA", "summary": "Another Escalation Policy", "type": "escalation_policy_reference" }, "first_trigger_log_entry": { "html_url": "https://subdomain.pagerduty.com/incidents/PT4KHLK/log_entries/Q02JTSNZWHSEKV", "id": "Q02JTSNZWHSEKV", "self": "https://api.pagerduty.com/log_entries/Q02JTSNZWHSEKV?incident_id=PT4KHLK", "summary": "Triggered through the API", "type": "trigger_log_entry_reference" }, "html_url": "https://subdomain.pagerduty.com/incidents/PT4KHLK", "id": "PT4KHLK", "incident_key": "baf7cf21b1da41b4b0221008339ff357", "incident_number": 1234, "last_status_change_at": "2015-10-06T21:45:00Z", "last_status_change_by": { "html_url": "https://subdomain.pagerduty.com/users/PXPGF42", "id": "PXPGF42", "self": "https://api.pagerduty.com/users/PXPGF42", "summary": "Earline Greenholt", "type": "user_reference" }, "priority": { "id": "P53ZZH5", "self": "https://api.pagerduty.com/priorities/P53ZZH5", "summary": "P2", "type": "priority_reference" }, "resolved_at": "2015-10-06T21:45:00Z", "self": "https://api.pagerduty.com/incidents/PT4KHLK", "service": { "html_url": "https://subdomain.pagerduty.com/service-directory/PWIXJZS", "id": "PWIXJZS", "self": "https://api.pagerduty.com/services/PWIXJZS", "summary": "My Mail Service", "type": "service_reference" }, "status": "resolved", "summary": "[#1234] The server is on fire.", "teams": [ { "html_url": "https://subdomain.pagerduty.com/teams/PQ9K7I8", "id": "PQ9K7I8", "self": "https://api.pagerduty.com/teams/PQ9K7I8", "summary": "Engineering", "type": "team_reference" } ], "title": "The server is on fire.", "type": "incident", "updated_at": "2015-10-06T21:45:00Z", "urgency": "high" } }, "timestamp": "2026-01-19T12:00:00Z", "type": "pagerduty.incident" } ``` ## Snooze Incident **Component key:** `pagerduty.snoozeIncident` The Snooze Incident component temporarily pauses notifications for an acknowledged PagerDuty incident. ### Use Cases - **Temporary acknowledgement**: Snooze an incident while investigating - **Scheduled follow-up**: Re-trigger the incident after a specified time - **Avoid escalation**: Prevent escalation while work is in progress ### Configuration - **Incident ID**: The ID of the incident to snooze (must be in acknowledged state) - **Duration**: How long to snooze the incident (1 hour, 4 hours, 8 hours, or 24 hours) - **From Email**: Email address of a valid PagerDuty user (required for App OAuth, optional for API tokens) ### Behavior When an incident is snoozed, it will remain in the acknowledged state and no further notifications will be sent. After the snooze duration expires, the incident will return to a triggered state and notifications will resume. Note: Reassigning a snoozed incident will cancel the snooze timer. ### Output Returns the snoozed incident object with all current information. ### Example Output ```json { "data": { "incident": { "assigned_via": "escalation_policy", "assignments": [ { "assignee": { "html_url": "https://subdomain.pagerduty.com/users/PXPGF42", "id": "PXPGF42", "self": "https://api.pagerduty.com/users/PXPGF42", "summary": "Earline Greenholt", "type": "user_reference" }, "at": "2015-11-10T00:31:52Z" } ], "created_at": "2015-10-06T21:30:42Z", "escalation_policy": { "html_url": "https://subdomain.pagerduty.com/escalation_policies/PT20YPA", "id": "PT20YPA", "self": "https://api.pagerduty.com/escalation_policies/PT20YPA", "summary": "Another Escalation Policy", "type": "escalation_policy_reference" }, "first_trigger_log_entry": { "html_url": "https://subdomain.pagerduty.com/incidents/PT4KHLK/log_entries/Q02JTSNZWHSEKV", "id": "Q02JTSNZWHSEKV", "self": "https://api.pagerduty.com/log_entries/Q02JTSNZWHSEKV?incident_id=PT4KHLK", "summary": "Triggered through the API", "type": "trigger_log_entry_reference" }, "html_url": "https://subdomain.pagerduty.com/incidents/PT4KHLK", "id": "PT4KHLK", "incident_key": "baf7cf21b1da41b4b0221008339ff357", "incident_number": 1234, "last_status_change_at": "2015-10-06T21:38:23Z", "last_status_change_by": { "html_url": "https://subdomain.pagerduty.com/users/PXPGF42", "id": "PXPGF42", "self": "https://api.pagerduty.com/users/PXPGF42", "summary": "Earline Greenholt", "type": "user_reference" }, "priority": { "id": "P53ZZH5", "self": "https://api.pagerduty.com/priorities/P53ZZH5", "summary": "P2", "type": "priority_reference" }, "resolved_at": null, "self": "https://api.pagerduty.com/incidents/PT4KHLK", "service": { "html_url": "https://subdomain.pagerduty.com/service-directory/PWIXJZS", "id": "PWIXJZS", "self": "https://api.pagerduty.com/services/PWIXJZS", "summary": "My Mail Service", "type": "service_reference" }, "status": "acknowledged", "summary": "[#1234] The server is on fire.", "teams": [ { "html_url": "https://subdomain.pagerduty.com/teams/PQ9K7I8", "id": "PQ9K7I8", "self": "https://api.pagerduty.com/teams/PQ9K7I8", "summary": "Engineering", "type": "team_reference" } ], "title": "The server is on fire.", "type": "incident", "updated_at": "2015-10-06T21:40:23Z", "urgency": "high" } }, "timestamp": "2026-01-19T12:00:00Z", "type": "pagerduty.incident" } ``` ## Update Incident **Component key:** `pagerduty.updateIncident` The Update Incident component modifies an existing PagerDuty incident. ### Use Cases - **Status updates**: Update incident status (acknowledge, resolve) - **Priority management**: Change incident priority - **Assignment**: Assign incidents to users or escalation policies ### Configuration - **Incident ID**: The ID of the incident to update (e.g., A12BC34567...) - **From Email**: Email address of a valid PagerDuty user (required for App OAuth, optional for API tokens) - **Status**: Update incident status (acknowledged, resolved) - **Priority**: Update incident priority (select from available priorities) - **Title**: Update incident title (optional, supports expressions) - **Description**: Update incident description (optional, supports expressions) - **Escalation Policy**: Change escalation policy (optional) - **Assignees**: Assign to specific users (optional) ### Output Returns the updated incident object with all current information. ### Example Output ```json { "data": { "incident": { "assigned_via": "escalation_policy", "assignments": [ { "assignee": { "html_url": "https://subdomain.pagerduty.com/users/PXPGF42", "id": "PXPGF42", "self": "https://api.pagerduty.com/users/PXPGF42", "summary": "Earline Greenholt", "type": "user_reference" }, "at": "2015-11-10T00:31:52Z" } ], "created_at": "2015-10-06T21:30:42Z", "escalation_policy": { "html_url": "https://subdomain.pagerduty.com/escalation_policies/PT20YPA", "id": "PT20YPA", "self": "https://api.pagerduty.com/escalation_policies/PT20YPA", "summary": "Another Escalation Policy", "type": "escalation_policy_reference" }, "first_trigger_log_entry": { "html_url": "https://subdomain.pagerduty.com/incidents/PT4KHLK/log_entries/Q02JTSNZWHSEKV", "id": "Q02JTSNZWHSEKV", "self": "https://api.pagerduty.com/log_entries/Q02JTSNZWHSEKV?incident_id=PT4KHLK", "summary": "Triggered through the API", "type": "trigger_log_entry_reference" }, "html_url": "https://subdomain.pagerduty.com/incidents/PT4KHLK", "id": "PT4KHLK", "incident_key": "baf7cf21b1da41b4b0221008339ff357", "incident_number": 1234, "incident_type": { "name": "major_incident" }, "last_status_change_at": "2015-10-06T21:38:23Z", "last_status_change_by": { "html_url": "https://subdomain.pagerduty.com/users/PXPGF42", "id": "PXPGF42", "self": "https://api.pagerduty.com/users/PXPGF42", "summary": "Earline Greenholt", "type": "user_reference" }, "priority": { "id": "P53ZZH5", "self": "https://api.pagerduty.com/priorities/P53ZZH5", "summary": "P2", "type": "priority_reference" }, "resolved_at": null, "self": "https://api.pagerduty.com/incidents/PT4KHLK", "service": { "html_url": "https://subdomain.pagerduty.com/service-directory/PWIXJZS", "id": "PWIXJZS", "self": "https://api.pagerduty.com/services/PWIXJZS", "summary": "My Mail Service", "type": "service_reference" }, "status": "acknowledged", "summary": "[#1234] The server is on fire.", "teams": [ { "html_url": "https://subdomain.pagerduty.com/teams/PQ9K7I8", "id": "PQ9K7I8", "self": "https://api.pagerduty.com/teams/PQ9K7I8", "summary": "Engineering", "type": "team_reference" } ], "title": "The server is on fire.", "type": "incident", "updated_at": "2015-10-06T21:40:23Z", "urgency": "high" } }, "timestamp": "2026-01-19T12:00:00Z", "type": "pagerduty.incident" } ``` #### Perplexity Source URL: https://docs.superplane.com/components/perplexity Run AI agents with Perplexity import { CardGrid, LinkCard } from "@astrojs/starlight/components"; ## Actions ## Run Agent **Component key:** `perplexity.runAgent` The Run Agent component uses Perplexity's Agent API to run AI agents that can search the web and fetch URLs. ### Use Cases - **Research and synthesis**: Ask complex questions that require gathering and synthesizing information from multiple sources - **Automated analysis**: Run AI-powered analysis on web content - **Content generation with citations**: Generate text grounded in real-time web sources ### Configuration - **Preset**: Agent preset to use (fast-search, pro-search, deep-research, advanced-deep-research). When set, model is ignored. - **Model**: Model to use when no preset is specified - **Input**: The prompt or question for the agent (supports expressions) - **Instructions**: Optional system-level instructions - **Web Search**: Enable the web_search tool (default: true) - **Fetch URL**: Enable the fetch_url tool (default: true) ### Output Returns the agent response including: - **text**: The generated text response - **citations**: Source citations from web results - **model**: The model used - **usage**: Token and cost usage information ### Example Output ```json { "data": { "citations": [ { "type": "citation", "url": "https://example.com/ai-news" }, { "type": "citation", "url": "https://example.com/research" } ], "id": "resp_1234567890", "model": "openai/gpt-5.2", "status": "completed", "text": "Recent developments in AI include significant advances in reasoning capabilities and safety research...", "usage": { "cost": { "total_cost": 0.05 }, "input_tokens": 3681, "output_tokens": 780, "total_tokens": 4461 } }, "timestamp": "2026-01-19T12:00:00Z", "type": "perplexity.agent.response" } ``` #### Prometheus Source URL: https://docs.superplane.com/components/prometheus Monitor alerts from Prometheus and Alertmanager import { CardGrid, LinkCard } from "@astrojs/starlight/components"; ## Triggers ## Actions ## Instructions ### Connection Configure this integration with: - **Prometheus Base URL**: URL of your Prometheus server (e.g., `https://prometheus.example.com`) - **Alertmanager Base URL** (optional): URL of your Alertmanager instance (e.g., `https://alertmanager.example.com`). Required for Silence components. If omitted, the Prometheus Base URL is used. - **API Auth**: `none`, `basic`, or `bearer` for API requests - **Webhook Secret** (recommended): If set, Alertmanager must send `Authorization: Bearer ` on webhook requests ### Alertmanager Setup (manual) The trigger setup panel in SuperPlane shows the generated webhook URL. Use the On Alert trigger setup instructions in the workflow sidebar for the exact `alertmanager.yml` snippet. After editing config, reload Alertmanager (for example `POST /-/reload` when lifecycle reload is enabled). ## On Alert **Trigger key:** `prometheus.onAlert` The On Alert trigger starts a workflow execution when Alertmanager sends alerts to SuperPlane. ### What this trigger does - Receives Alertmanager webhook payloads - Optionally validates bearer auth when **Webhook Secret** is configured - Emits one event per matching alert as `prometheus.alert` - Filters by selected statuses (`firing` and/or `resolved`) ### Configuration - **Statuses**: Required list of alert statuses to emit - **Alert Names**: Optional exact `alertname` filters ### Alertmanager setup (manual) When the node is saved, SuperPlane generates a webhook URL shown in the trigger setup panel. Copy that URL into your Alertmanager receiver. Receiver registration in upstream Alertmanager is config-based (not API-created by SuperPlane). Use the setup instructions shown in the workflow sidebar for the exact `alertmanager.yml` snippet. After updating Alertmanager config, reload it (for example `POST /-/reload` when lifecycle reload is enabled). ### Example Data ```json { "data": { "annotations": { "description": "Demo alert from local Prometheus setup", "summary": "SuperPlane test alert is firing" }, "commonAnnotations": { "description": "Demo alert from local Prometheus setup", "summary": "SuperPlane test alert is firing" }, "commonLabels": { "alertname": "SuperplaneTestAlert", "severity": "warning" }, "endsAt": "0001-01-01T00:00:00Z", "externalURL": "http://localhost:9093", "fingerprint": "aac3b474e2c0658c", "generatorURL": "http://fd66aa456472:9090/graph?g0.expr=vector%281%29\u0026g0.tab=1", "groupKey": "{}:{alertname=\"SuperplaneTestAlert\"}", "groupLabels": { "alertname": "SuperplaneTestAlert" }, "labels": { "alertname": "SuperplaneTestAlert", "severity": "warning" }, "receiver": "superplane", "startsAt": "2026-02-12T16:08:39Z", "status": "firing" }, "timestamp": "2026-02-12T16:18:03.362582388Z", "type": "prometheus.alert" } ``` ## Create Silence **Component key:** `prometheus.createSilence` The Create Silence component creates a silence in Alertmanager (`POST /api/v2/silences`) to suppress matching alerts. ### Configuration - **Matchers**: Required list of matchers. Each matcher has: - **Name**: Label name to match - **Value**: Label value to match - **Is Regex**: Whether value is a regex pattern (default: false) - **Is Equal**: Whether to match equality (true) or inequality (false) (default: true) - **Duration**: Required duration string (e.g. `1h`, `30m`, `2h30m`) - **Created By**: Required name of who is creating the silence - **Comment**: Required reason for the silence ### Output Emits one `prometheus.silence` payload with silence ID, status, matchers, timing, and creator info. ### Example Output ```json { "data": { "comment": "Scheduled maintenance window for database migration", "createdBy": "SuperPlane", "endsAt": "2026-02-12T17:30:00Z", "matchers": [ { "isEqual": true, "isRegex": false, "name": "alertname", "value": "HighLatency" }, { "isEqual": true, "isRegex": false, "name": "severity", "value": "critical" } ], "silenceID": "a1b2c3d4-e5f6-4789-a012-3456789abcde", "startsAt": "2026-02-12T16:30:00Z", "status": "active" }, "timestamp": "2026-02-12T16:30:05.123456789Z", "type": "prometheus.silence" } ``` ## Expire Silence **Component key:** `prometheus.expireSilence` The Expire Silence component expires an active silence in Alertmanager (`DELETE /api/v2/silence/{silenceID}`). ### Configuration - **Silence**: Required silence to expire. Supports expressions so users can reference `$['Create Silence'].silenceID`. ### Output Emits one `prometheus.silence.expired` payload with silence ID and status. ### Example Output ```json { "data": { "silenceID": "a1b2c3d4-e5f6-4789-a012-3456789abcde", "status": "expired" }, "timestamp": "2026-02-12T17:45:10.987654321Z", "type": "prometheus.silence.expired" } ``` ## Get Alert **Component key:** `prometheus.getAlert` The Get Alert component fetches active alerts from Prometheus (`/api/v1/alerts`) and returns the first alert that matches. ### Configuration - **Alert Name**: Required `labels.alertname` value to search for (supports expressions) - **State**: Optional filter (`any`, `firing`, `pending`, `inactive`) ### Output Emits one `prometheus.alert` payload with labels, annotations, state, and timing fields. ### Example Output ```json { "data": { "annotations": { "description": "Demo alert from local Prometheus setup", "summary": "SuperPlane test alert is firing" }, "labels": { "alertname": "SuperplaneTestAlert", "severity": "warning" }, "startsAt": "2026-02-12T16:08:09.000517289Z", "status": "firing", "value": "1e+00" }, "timestamp": "2026-02-12T16:18:05.943610583Z", "type": "prometheus.alert" } ``` ## Get Silence **Component key:** `prometheus.getSilence` The Get Silence component retrieves a silence from Alertmanager (`GET /api/v2/silence/{silenceID}`) by its ID. ### Configuration - **Silence**: Required silence to retrieve (supports expressions, e.g. `{{ $['Create Silence'].silenceID }}`) ### Output Emits one `prometheus.silence` payload with silence ID, status, matchers, timing, and creator info. ### Example Output ```json { "data": { "comment": "Scheduled maintenance window", "createdBy": "SuperPlane", "endsAt": "2026-02-12T17:30:00Z", "matchers": [ { "isEqual": true, "isRegex": false, "name": "alertname", "value": "HighLatency" } ], "silenceID": "a1b2c3d4-e5f6-4789-a012-3456789abcde", "startsAt": "2026-02-12T16:30:00Z", "status": "active" }, "timestamp": "2026-02-12T16:30:05.123456789Z", "type": "prometheus.silence" } ``` ## Query **Component key:** `prometheus.query` The Query component executes an instant PromQL query against Prometheus (`GET /api/v1/query`). ### Configuration - **Query**: Required PromQL expression to evaluate (supports expressions). Example: `up` ### Output Emits one `prometheus.query` payload with the result type and results. ### Example Output ```json { "data": { "result": [ { "metric": { "__name__": "up", "instance": "localhost:9090", "job": "prometheus" }, "value": [ 1708000000, "1" ] } ], "resultType": "vector" }, "timestamp": "2026-02-12T16:30:05.123456789Z", "type": "prometheus.query" } ``` ## Query Range **Component key:** `prometheus.queryRange` The Query Range component executes a range PromQL query against Prometheus (`GET /api/v1/query_range`). ### Configuration - **Query**: Required PromQL expression to evaluate (supports expressions). Example: `up` - **Start**: Required start timestamp in RFC3339 or Unix format (supports expressions). Example: `2026-01-01T00:00:00Z` - **End**: Required end timestamp in RFC3339 or Unix format (supports expressions). Example: `2026-01-02T00:00:00Z` - **Step**: Required query resolution step (e.g. `15s`, `1m`) ### Output Emits one `prometheus.queryRange` payload with the result type and results. ### Example Output ```json { "data": { "result": [ { "metric": { "__name__": "up", "instance": "localhost:9090", "job": "prometheus" }, "values": [ [ 1708000000, "1" ], [ 1708000015, "1" ], [ 1708000030, "1" ] ] } ], "resultType": "matrix" }, "timestamp": "2026-02-12T16:30:05.123456789Z", "type": "prometheus.queryRange" } ``` #### Render Source URL: https://docs.superplane.com/components/render Deploy and manage Render services, and react to Render deploy/build events import { CardGrid, LinkCard } from "@astrojs/starlight/components"; ## Triggers ## Actions ## Instructions 1. **API Key:** Create it in [Render Account Settings -> API Keys](https://dashboard.render.com/u/settings#api-keys). 2. **Workspace (optional):** Use your Render workspace ID (`usr-...` or `tea-...`) or workspace name. Leave empty to use the first workspace available to the API key. 3. **Workspace Plan:** Select **Professional** or **Organization / Enterprise** (used to choose webhook strategy). 4. **Auth:** SuperPlane sends requests to [Render API v1](https://api.render.com/v1/) using `Authorization: Bearer `. 5. **Webhooks:** SuperPlane configures Render webhooks automatically via the [Render Webhooks API](https://render.com/docs/webhooks). No manual setup is required. 6. **Troubleshooting:** Check [Render Dashboard -> Integrations -> Webhooks](https://dashboard.render.com/) and the [Render webhook docs](https://render.com/docs/webhooks). Note: **Plan requirement:** Render webhooks require a Professional plan or higher. ## On Build **Trigger key:** `render.onBuild` The On Build trigger emits build-related Render events for one selected service. ### Use Cases - **Build failure alerts**: Notify your team when builds fail - **Build success hooks**: Trigger follow-up automation after successful builds ### Configuration - **Service**: Required Render service. - **Event Types**: Build event states to listen for. Defaults to `build_ended`. ### Webhook Verification Render webhooks are validated using the secret generated when SuperPlane creates the webhook via the Render API. Verification checks: - `webhook-id` - `webhook-timestamp` - `webhook-signature` (`v1,`) ### Event Data The default output emits payload data fields like `buildId`, `eventId`, `serviceId`, `serviceName`, and `status` (when present). ### Example Data ```json { "data": { "buildId": "bld-cukouhrtq21c73e9scng", "createdAt": "2026-02-05T16:00:00.000000Z", "eventId": "evj-cukouhrtq21c73e9scng", "serviceId": "srv-cukouhrtq21c73e9scng", "serviceName": "backend-api", "status": "failed" }, "timestamp": "2026-02-05T16:00:01.000000Z", "type": "render.build.ended" } ``` ## On Deploy **Trigger key:** `render.onDeploy` The On Deploy trigger emits deploy-related Render events for one selected service. ### Use Cases - **Deploy notifications**: Notify Slack or PagerDuty when deploys succeed/fail - **Post-deploy automation**: Trigger smoke tests after successful deploy completion events - **Release orchestration**: Trigger downstream workflows when deploy stages change ### Configuration - **Service**: Required Render service. - **Event Types**: Deploy event states to listen for. Defaults to `deploy_ended`. ### Webhook Verification Render webhooks are validated using the secret generated when SuperPlane creates the webhook via the Render API. Verification checks: - `webhook-id` - `webhook-timestamp` - `webhook-signature` (`v1,`) ### Event Data The default output emits payload data fields like `deployId`, `eventId`, `serviceId`, `serviceName`, and `status` (when present). ### Example Data ```json { "data": { "createdAt": "2026-02-05T16:00:00.000000Z", "deployId": "dep-cukouhrtq21c73e9scng", "eventId": "evj-cukouhrtq21c73e9scng", "serviceId": "srv-cukouhrtq21c73e9scng", "serviceName": "backend-api", "status": "succeeded" }, "timestamp": "2026-02-05T16:00:01.000000Z", "type": "render.deploy.ended" } ``` ## Cancel Deploy **Component key:** `render.cancelDeploy` The Cancel Deploy component cancels an in-progress deploy for a Render service and waits for it to complete. ### Use Cases - **Automated rollback/abort**: Cancel deploys when health checks fail - **Manual intervention**: Stop a deploy triggered earlier in a workflow ### How It Works 1. Sends a cancel request for the specified deploy via the Render API 2. Waits for the deploy to finish (via deploy_ended webhook and optional polling fallback) 3. Routes execution based on deploy outcome: - **Success channel**: Deploy was cancelled successfully (status is `canceled`) - **Failed channel**: Deploy finished with an unexpected status ### Configuration - **Service**: Render service that owns the deploy - **Deploy ID**: Deploy ID to cancel (supports expressions) ### Output Channels - **Success**: Emitted when the deploy is cancelled successfully - **Failed**: Emitted when the deploy finishes with a non-cancelled status ### Notes - Uses the existing integration webhook for deploy_ended events - Falls back to polling if the webhook does not arrive - Requires a Render API key configured on the integration ### Example Output ```json { "data": { "createdAt": "2026-02-05T16:10:00.000000Z", "deployId": "dep-cukouhrtq21c73e9scng", "finishedAt": "2026-02-05T16:12:00.000000Z", "serviceId": "srv-cukouhrtq21c73e9scng", "status": "canceled", "trigger": "api" }, "timestamp": "2026-02-05T16:12:00.000000Z", "type": "render.deploy" } ``` ## Deploy **Component key:** `render.deploy` The Deploy component starts a new deploy for a Render service and waits for it to complete. ### Use Cases - **Merge to deploy**: Trigger production deploys after a successful GitHub merge and CI pass - **Scheduled redeploys**: Redeploy staging services on schedules or external content changes - **Chained deploys**: Deploy service B when service A finishes successfully ### How It Works 1. Triggers a new deploy for the selected Render service via the Render API 2. Waits for the deploy to complete (via deploy_ended webhook and optional polling fallback) 3. Routes execution based on deploy outcome: - **Success channel**: Deploy completed successfully - **Failed channel**: Deploy failed or was cancelled ### Configuration - **Service**: Render service to deploy - **Clear Cache**: Clear build cache before deploying ### Output Channels - **Success**: Emitted when the deploy completes successfully - **Failed**: Emitted when the deploy fails or is cancelled ### Notes - Uses the existing integration webhook for deploy_ended events (same as On Deploy trigger) - Falls back to polling if the webhook does not arrive - Requires a Render API key configured on the integration ### Example Output ```json { "data": { "createdAt": "2026-02-05T16:10:00.000000Z", "deployId": "dep-cukouhrtq21c73e9scng", "finishedAt": "2026-02-05T16:15:00.000000Z", "serviceId": "srv-cukouhrtq21c73e9scng", "status": "succeeded" }, "timestamp": "2026-02-05T16:15:00.000000Z", "type": "render.deploy.finished" } ``` ## Get Deploy **Component key:** `render.getDeploy` The Get Deploy component fetches a deploy for a Render service. ### Use Cases - **Status checks**: Inspect deploy status and timestamps - **Debugging**: Fetch deploy metadata after receiving an event ### Configuration - **Service**: Render service that owns the deploy - **Deploy ID**: Deploy ID to retrieve (supports expressions) ### Output Emits a `render.deploy` payload containing deploy fields like `deployId`, `status`, `trigger`, and timestamps when available. ### Example Output ```json { "data": { "commit": { "createdAt": "2026-02-05T16:09:30.000000Z", "id": "1a2b3c4d5e6f", "message": "Release v1.2.3" }, "createdAt": "2026-02-05T16:10:00.000000Z", "deployId": "dep-cukouhrtq21c73e9scng", "finishedAt": "2026-02-05T16:15:00.000000Z", "image": { "ref": "registry.example.com/backend-api:1a2b3c4d", "sha": "sha256:4f7c2d7f0bb27e2f8d4d9b3d2b3a1a9a3b2c1d0e" }, "serviceId": "srv-cukouhrtq21c73e9scng", "startedAt": "2026-02-05T16:10:10.000000Z", "status": "live", "trigger": "api" }, "timestamp": "2026-02-05T16:15:00.000000Z", "type": "render.deploy" } ``` ## Get Service **Component key:** `render.getService` The Get Service component fetches details for a Render service. ### Use Cases - **Service inspection**: Fetch current service configuration, metadata, and custom domains - **Workflow context**: Use service fields to drive branching decisions in later steps ### Configuration - **Service**: Render service to retrieve ### Output Emits a `render.service` payload containing service fields like `serviceId`, `serviceName`, `type`, `dashboardUrl`, `suspended`, and `customDomains`. ### Example Output ```json { "data": { "createdAt": "2026-02-05T15:00:00.000000Z", "customDomains": [ { "id": "cdm-abc123xyz456", "name": "app.example.com", "serviceId": "srv-cukouhrtq21c73e9scng", "verificationStatus": "verified" } ], "dashboardUrl": "https://dashboard.render.com/web/srv-cukouhrtq21c73e9scng", "serviceId": "srv-cukouhrtq21c73e9scng", "serviceName": "backend-api", "suspended": "not_suspended", "type": "web_service", "updatedAt": "2026-02-05T16:00:00.000000Z" }, "timestamp": "2026-02-05T16:05:00.000000Z", "type": "render.service" } ``` ## Purge Cache **Component key:** `render.purgeCache` The Purge Cache component requests a build cache purge for a Render service. ### Use Cases - **Cache reset**: Force a clean rebuild when you suspect stale dependencies or build artifacts - **Operational tooling**: Provide a one-click cache purge in incident response workflows ### Configuration - **Service**: Render service whose build cache should be purged ### Output Emits a `render.cache.purge.requested` payload with `serviceId` and a `status` field indicating the request was accepted. ### Example Output ```json { "data": { "serviceId": "srv-cukouhrtq21c73e9scng", "status": "accepted" }, "timestamp": "2026-02-05T16:20:00.000000Z", "type": "render.cache.purge.requested" } ``` ## Rollback Deploy **Component key:** `render.rollbackDeploy` The Rollback Deploy component triggers a rollback deploy for a Render service and waits for it to complete. ### Use Cases - **Automated recovery**: Roll back after detecting errors in a new deploy - **One-click rollback**: Trigger rollbacks from an incident workflow ### How It Works 1. Triggers a rollback deploy for the selected Render service via the Render API 2. Waits for the deploy to complete (via deploy_ended webhook and optional polling fallback) 3. Routes execution based on deploy outcome: - **Success channel**: Deploy completed successfully (status is `live`) - **Failed channel**: Deploy failed or was cancelled ### Configuration - **Service**: Render service to roll back - **Deploy ID**: The deploy ID to roll back to (supports expressions) ### Output Channels - **Success**: Emitted when the rollback deploy completes successfully - **Failed**: Emitted when the rollback deploy fails or is cancelled ### Notes - Uses the existing integration webhook for deploy_ended events - Falls back to polling if the webhook does not arrive - Includes `rollbackToDeployId` in the output payload for reference - Requires a Render API key configured on the integration ### Example Output ```json { "data": { "createdAt": "2026-02-05T16:18:00.000000Z", "deployId": "dep-cukouhrtq21c73e9scng", "rollbackToDeployId": "dep-cukouhrtq21c73e9scnf", "serviceId": "srv-cukouhrtq21c73e9scng", "status": "build_in_progress", "trigger": "rollback" }, "timestamp": "2026-02-05T16:18:00.000000Z", "type": "render.deploy" } ``` ## Add Custom Domain **Component key:** `render.service.addCustomDomain` The Add Custom Domain component adds a custom domain to a Render service. ### Use Cases - **Blue/green deployments**: Add the live domain to the new (green) service as part of a traffic switch - **Domain management**: Automate custom domain provisioning as part of a deployment workflow ### How It Works 1. Adds the custom domain to the selected Render service 2. When **Wait For Verification** is enabled, triggers Render DNS verification and retrieves the latest custom domain status 3. Continues polling by re-triggering verification and checking `verificationStatus` until Render reports `verified` or `failed` ### Configuration - **Service**: Render service to add the domain to - **Domain Name**: The custom domain name (e.g., `app.example.com`) - **Wait For Verification**: When enabled, waits for DNS verification before completing ### Output Emits a `render.customDomain.added` payload with `id`, `name`, `serviceId`, and `verificationStatus`. ### Example Output ```json { "data": { "id": "cdm-abc123xyz456", "name": "app.example.com", "serviceId": "srv-cukouhrtq21c73e9scng", "verificationStatus": "verified" }, "timestamp": "2026-02-05T16:25:00.000000Z", "type": "render.customDomain.added" } ``` ## Remove Custom Domain **Component key:** `render.service.removeCustomDomain` The Remove Custom Domain component removes a custom domain from a Render service. ### Use Cases - **Blue/green deployments**: Remove the live domain from the old (blue) service before adding it to the new one - **Domain cleanup**: Automate domain removal as part of a decommission or rotation workflow ### Configuration - **Service**: Render service to remove the domain from - **Domain Name**: The custom domain name to remove (e.g., `app.example.com`) ### Output Emits a `render.customDomain.removed` payload with `name` and `serviceId`. ### Example Output ```json { "data": { "name": "app.example.com", "serviceId": "srv-cukouhrtq21c73e9scng" }, "timestamp": "2026-02-05T16:25:00.000000Z", "type": "render.customDomain.removed" } ``` ## Update Env Var **Component key:** `render.updateEnvVar` The Update Env Var component updates a Render service environment variable. ### Use Cases - **Rotate secrets**: Generate a new value for an env var (for example, API tokens) and optionally emit it - **Configuration changes**: Update non-secret environment values as part of a workflow ### Configuration - **Service**: Render service that owns the env var - **Key**: Env var key to update - **Value Strategy**: - `Set value`: provide the `Value` field - `Generate value`: request Render to generate a new value - **Value**: New env var value (sensitive). Required when using `Set value` - **Emit Value**: When enabled, include the env var `value` in output. Disabled by default to avoid leaking secrets. ### Output Emits a `render.envVar.updated` payload with `serviceId`, `key`, and a `valueGenerated` boolean. The `value` field is only included when `emitValue` is enabled. ### Example Output ```json { "data": { "key": "DATABASE_URL", "serviceId": "srv-cukouhrtq21c73e9scng", "valueGenerated": false }, "timestamp": "2026-02-05T16:25:00.000000Z", "type": "render.envVar.updated" } ``` #### Rootly Source URL: https://docs.superplane.com/components/rootly Manage and react to incidents in Rootly import { CardGrid, LinkCard } from "@astrojs/starlight/components"; ## Triggers ## Actions ## On Incident **Trigger key:** `rootly.onIncident` The On Incident trigger starts a workflow execution when Rootly incident events occur. ### Use Cases - **Incident automation**: Automate responses to incident events - **Notification workflows**: Send notifications when incidents are created or resolved - **Integration workflows**: Sync incidents with external systems - **Post-incident actions**: Trigger follow-up workflows when incidents are mitigated or resolved ### Configuration - **Events**: Select which incident events to listen for (created, updated, mitigated, resolved, cancelled, deleted) ### Event Data Each incident event includes: - **event**: Event type (incident.created, incident.updated, etc.) - **incident**: Complete incident information including title, summary, severity, status ### Webhook Setup This trigger automatically sets up a Rootly webhook endpoint when configured. The endpoint is managed by SuperPlane and will be cleaned up when the trigger is removed. ### Example Data ```json { "data": { "event": "incident.created", "incident": { "id": "abc123-def456", "mitigated_at": null, "resolved_at": null, "severity": "sev2", "started_at": "2026-01-19T12:00:00Z", "status": "started", "summary": "The API response times have increased significantly across all endpoints.", "title": "API latency spike detected", "url": "https://app.rootly.com/incidents/abc123-def456" } }, "timestamp": "2026-01-19T12:00:00Z", "type": "rootly.onIncident" } ``` ## On Incident Timeline Event **Trigger key:** `rootly.onIncidentTimelineEvent` The On Incident Timeline Event trigger starts a workflow execution when Rootly incident timeline events are created or updated. Only events with kind "event" are emitted. ### Use Cases - **Note automation**: Run workflows when investigation notes are added - **Timeline sync**: Sync incident timeline events to Slack or external systems - **Annotation tracking**: Track updates to incident annotations - **Audit logging**: Capture timeline events for compliance or reporting ### Configuration - **Incident Status**: Optional filter by incident status (open, resolved, etc.) - **Severity**: Optional filter by incident severity - **Service**: Optional filter by service name - **Team**: Optional filter by team name - **Event Source**: Optional filter by event source (web, api, system) - **Visibility**: Optional filter by event visibility (internal or external) ### Event Data Each incident event includes: - **id**: Event ID - **event**: Event content - **event_raw**: Raw event content - **event_id**: Webhook event ID - **event_type**: Event type (incident_event.created or incident_event.updated) - **kind**: Event kind - **source**: Event source - **visibility**: Event visibility - **occurred_at**: When the event occurred - **created_at**: When the event was created - **updated_at**: When the event was last updated - **issued_at**: When the webhook was issued - **incident_id**: Incident ID - **incident**: Incident information ### Webhook Setup This trigger automatically sets up a Rootly webhook endpoint when configured. The endpoint is managed by SuperPlane and will be cleaned up when the trigger is removed. ### Example Data ```json { "data": { "created_at": "2026-02-22T09:46:23.868-08:00", "event": "Investigation started, will update accordingly", "event_id": "b3065ca8-69a6-4781-b6b4-94d6f0317ccf", "event_raw": "Investigation started, will update accordingly", "event_type": "incident_event.created", "id": "56f7b488-e3c5-4091-9bb4-cf132007f98c", "incident": { "id": "64c39fde-1626-4f78-874e-9db91c0639d3", "services": [ "UI - User Profile Block" ], "severity": "sev2", "status": "mitigated", "teams": [ "Customer Relations" ], "title": "new remake from main" }, "incident_id": "64c39fde-1626-4f78-874e-9db91c0639d3", "issued_at": "2026-02-22T09:46:24.018-08:00", "kind": "event", "occurred_at": "2026-02-22T09:46:23.868-08:00", "source": "web", "updated_at": "2026-02-22T09:46:23.868-08:00", "visibility": "internal" }, "timestamp": "2026-02-22T17:46:40.603539728Z", "type": "rootly.onIncidentTimelineEvent" } ``` ## Create Event **Component key:** `rootly.createEvent` The Create Event component adds a timeline event (note/annotation) to a Rootly incident. ### Use Cases - **Investigation notes**: Add detailed investigation notes to the incident timeline - **Status updates**: Post automated status updates as workflows progress - **Cross-system sync**: Sync comments from external tools into the incident timeline ### Configuration - **Incident ID**: The Rootly incident UUID to add the event to (required, supports expressions) - **Event**: The note/annotation text (required, supports expressions) - **Visibility**: Internal or external visibility (optional, default per Rootly) ### Output Returns the created incident event with: - **id**: Event ID - **event**: Event content - **visibility**: Event visibility - **occurred_at**: Event timestamp - **created_at**: Creation timestamp ### Example Output ```json { "data": { "created_at": "2026-02-10T07:34:35.902-8:00", "event": "Investigation update: database connections stabilized.", "id": "a2d32bb7-0417-4d0d-8483-a583c3-7853", "occurred_at": "2026-02-10T07:34:35.902-8:00", "visibility": "internal" }, "timestamp": "2026-02-10T15:34:36.09877478Z", "type": "rootly.incident.event" } ``` ## Create Incident **Component key:** `rootly.createIncident` The Create Incident component creates a new incident in Rootly. ### Use Cases - **Alert escalation**: Create incidents from monitoring alerts - **Error tracking**: Automatically create incidents when errors are detected - **Manual incident creation**: Create incidents from workflow events - **Integration workflows**: Create incidents from external system events ### Configuration - **Title**: A succinct description of the incident (required, supports expressions) - **Summary**: Additional details about the incident (optional, supports expressions) - **Severity**: Incident severity level (optional, supports expressions) ### Output Returns the created incident object including: - **id**: Incident ID - **title**: Incident title - **status**: Current incident status - **severity**: Incident severity - **started_at**: Incident creation timestamp - **url**: Link to the incident in Rootly ### Example Output ```json { "data": { "id": "abc123-def456", "severity": "sev1", "started_at": "2026-01-19T12:00:00Z", "status": "started", "summary": "Users are experiencing slow database queries and connection timeouts.", "title": "Database connection issues", "url": "https://app.rootly.com/incidents/abc123-def456" }, "timestamp": "2026-01-19T12:00:00Z", "type": "rootly.incident" } ``` ## Get Incident **Component key:** `rootly.getIncident` The Get Incident component retrieves a single incident from Rootly by ID, including related resources. ### Use Cases - **Incident enrichment**: Fetch full incident details including services, groups, and action items - **Status checks**: Check the current status and severity of an incident - **Post-incident analysis**: Retrieve incident timeline events and action items - **Cross-system sync**: Get incident data to sync with external systems ### Configuration - **Incident ID**: The ID of the incident to retrieve (required, supports expressions) ### Output Returns the incident object including: - **id**: Incident ID - **sequential_id**: Sequential incident number - **title**: Incident title - **slug**: URL-friendly incident identifier - **status**: Current incident status - **summary**: Incident summary - **severity**: Incident severity slug - **url**: Link to the incident in Rootly - **started_at**: When the incident started - **mitigated_at**: When the incident was mitigated - **resolved_at**: When the incident was resolved - **user**: User who created the incident - **started_by**: User who started the incident - **services**: Affected services - **groups**: Associated groups - **events**: Incident timeline events - **action_items**: Follow-up action items ### Example Output ```json { "data": { "action_items": [ { "id": "ai-001", "status": "open", "summary": "Investigate root cause of latency increase" } ], "events": [ { "created_at": "2026-01-19T12:00:00Z", "id": "evt-001", "kind": "incident_created", "visibility": "internal" } ], "groups": [ { "id": "grp-001", "name": "Backend Team", "slug": "backend-team" } ], "id": "abc123-def456", "mitigated_at": "2026-01-19T12:30:00Z", "resolved_at": null, "sequential_id": 42, "services": [ { "id": "svc-001", "name": "Production API", "slug": "production-api" } ], "severity": "sev1", "slug": "api-latency-spike-detected", "started_at": "2026-01-19T12:00:00Z", "started_by": { "email": "john@example.com", "full_name": "John Doe", "id": "user-002" }, "status": "mitigated", "summary": "The API response times have increased significantly across all endpoints.", "title": "API latency spike detected", "url": "https://app.rootly.com/incidents/abc123-def456", "user": { "email": "jane@example.com", "full_name": "Jane Smith", "id": "user-001" } }, "timestamp": "2026-01-19T12:05:00Z", "type": "rootly.incident" } ``` ## Update Incident **Component key:** `rootly.updateIncident` The Update Incident component updates an existing incident in Rootly. ### Use Cases - **Status updates**: Update incident status when new information arrives - **Severity changes**: Adjust severity based on impact assessment - **Service association**: Attach affected services to an incident - **Team assignment**: Assign teams to respond to an incident - **Metadata updates**: Add labels to categorize incidents ### Configuration - **Incident ID**: The UUID of the incident to update (required, supports expressions) - **Title**: Update the incident title (optional, supports expressions) - **Summary**: Update the incident summary (optional, supports expressions) - **Status**: Update the incident status (optional) - **Sub-Status**: Update the incident sub-status (optional, required by some Rootly accounts when changing status) - **Severity**: Update the incident severity level (optional) - **Services**: Services to attach to the incident (optional) - **Teams**: Teams to attach to the incident (optional) - **Labels**: Key-value labels for the incident (optional) ### Output Returns the updated incident object including: - **id**: Incident UUID - **sequential_id**: Sequential incident number - **title**: Incident title - **slug**: URL-friendly slug - **status**: Current incident status - **updated_at**: Last update timestamp ### Example Output ```json { "data": { "id": "abc123-def456", "mitigated_at": "2026-01-19T13:30:00Z", "sequential_id": 42, "severity": "sev1", "slug": "database-connection-issues", "started_at": "2026-01-19T12:00:00Z", "status": "mitigated", "summary": "Root cause identified. Connection pool exhausted.", "title": "Database connection issues - Updated", "updated_at": "2026-01-19T13:30:00Z", "url": "https://app.rootly.com/incidents/abc123-def456" }, "timestamp": "2026-01-19T13:30:00Z", "type": "rootly.incident" } ``` #### Semaphore Source URL: https://docs.superplane.com/components/semaphore Run and react to your Semaphore workflows import { CardGrid, LinkCard } from "@astrojs/starlight/components"; ## Triggers ## Actions ## On Pipeline Done **Trigger key:** `semaphore.onPipelineDone` The On Pipeline Done trigger starts a workflow execution when a Semaphore pipeline completes. ### Use Cases - **Pipeline orchestration**: Chain workflows together based on pipeline completion - **Status monitoring**: Monitor CI/CD pipeline results - **Notification workflows**: Send notifications when pipelines succeed or fail - **Post-processing**: Process artifacts or results after pipeline completion ### Configuration - **Project**: Select the Semaphore project to monitor - **Refs**: Optional ref filters (for example `refs/heads/main`) - **Results**: Optional pipeline result filters (for example `passed`, `failed`) - **Pipelines**: Optional pipeline file filters (for example `.semaphore/semaphore.yml`, `.semaphore/production/deploy.yml`) ### Event Data Each pipeline done event includes: - **pipeline**: Pipeline information including ID, state, and result - **workflow**: Workflow information including ID and URL - **project**: Project information - **result**: Pipeline result (passed, failed, stopped, etc.) - **state**: Pipeline state (done) ### Webhook Setup This trigger automatically sets up a Semaphore webhook when configured. The webhook is managed by SuperPlane and will be cleaned up when the trigger is removed. ### Example Data ```json { "data": { "blocks": [ { "jobs": [ { "id": "00000-00000-00000-00000-00000", "index": 0, "name": "Report result to SuperPlane", "result": "passed", "status": "finished" } ], "name": "Block #1", "result": "passed", "result_reason": "test", "state": "done" } ], "organization": { "id": "00000000-0000-0000-0000-000000000000", "name": "test" }, "pipeline": { "created_at": "2026-01-19T12:00:00Z", "done_at": "2026-01-19T12:00:00Z", "error_description": "", "id": "00000000-0000-0000-0000-000000000000", "name": "Initial Pipeline", "pending_at": "2026-01-19T12:00:00Z", "queuing_at": "2026-01-19T12:00:00Z", "result": "passed", "result_reason": "test", "running_at": "2026-01-19T12:00:00Z", "state": "done", "stopping_at": "1970-01-01T00:00:00Z", "working_directory": ".semaphore", "yaml_file_name": "semaphore.yml" }, "project": { "id": "00000000-0000-0000-0000-000000000000", "name": "test" }, "repository": { "slug": "test/test", "url": "https://github.com/test/test" }, "revision": { "branch": { "commit_range": "0000000000000000000000000000000000000000^...0000000000000000000000000000000000000000", "name": "test" }, "commit_message": "Merge branch 'test' into test", "commit_sha": "0000000000000000000000000000000000000000", "pull_request": null, "reference": "refs/heads/test", "reference_type": "branch", "sender": { "avatar_url": "https://avatars2.githubusercontent.com/u/0000000000000000000000000000000000000000?s=460\u0026v=4", "email": "test@test.com", "login": "test" }, "tag": null }, "version": "1.0.0", "workflow": { "created_at": "2026-01-19T12:00:00Z", "id": "00000000-0000-0000-0000-000000000000", "initial_pipeline_id": "00000000-0000-0000-0000-000000000000" } }, "timestamp": "2026-01-19T12:00:00Z", "type": "semaphore.pipeline.done" } ``` ## Get Pipeline **Component key:** `semaphore.getPipeline` The Get Pipeline component fetches a Semaphore pipeline by its ID and returns its current state, result, and metadata. ### Use Cases - **Pipeline status checking**: After Run Workflow starts a pipeline, fetch its status to decide when to proceed - **Pipeline lookup**: Look up the result of a specific pipeline from event data to get full details - **Conditional deployment**: Build a status-check step that verifies a pipeline before triggering dependent actions ### Configuration - **Pipeline ID**: The Semaphore pipeline ID (supports expressions, e.g. `{{ event.pipeline.id }}`) ### Output Returns the pipeline object including: - Pipeline ID (ppl_id) - Pipeline name - Workflow ID (wf_id) - State (e.g. running, done) - Result (e.g. passed, failed) ### Example Output ```json { "data": { "branch_name": "main", "commit_message": "feat: add new feature", "commit_sha": "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2", "created_at": "2026-01-22T15:32:47.000000Z", "done_at": "2026-01-22T15:32:56.000000Z", "error_description": "", "name": "Initial Pipeline", "ppl_id": "00000000-0000-0000-0000-000000000000", "project_id": "22222222-2222-2222-2222-222222222222", "promotion_of": "", "result": "passed", "result_reason": "test", "running_at": "2026-01-22T15:32:48.000000Z", "state": "done", "terminated_by": "", "wf_id": "11111111-1111-1111-1111-111111111111", "working_directory": ".semaphore", "yaml_file_name": "semaphore.yml" }, "timestamp": "2026-01-22T15:32:56.061430218Z", "type": "semaphore.pipeline" } ``` ## Run Workflow **Component key:** `semaphore.runWorkflow` The Run Workflow component triggers a Semaphore CI/CD workflow and waits for it to complete. ### Use Cases - **CI/CD orchestration**: Trigger builds and deployments from SuperPlane workflows - **Pipeline automation**: Run Semaphore pipelines as part of workflow automation - **Multi-stage deployments**: Coordinate complex deployment pipelines - **Workflow chaining**: Chain multiple Semaphore workflows together ### How It Works 1. Creates and starts a Semaphore workflow with the specified pipeline file and parameters 2. Waits for the pipeline to complete (monitored via webhook and polling) 3. Routes execution based on pipeline result: - **Passed channel**: Pipeline completed successfully - **Failed channel**: Pipeline failed or was cancelled ### Configuration - **Project**: Select the Semaphore project containing the workflow - **Pipeline File**: Path to the pipeline YAML file (e.g., `.semaphore/pipeline.yml`) - **Ref**: Git reference to run the workflow on (branch, tag, or commit SHA) - **Commit SHA**: Optional specific commit SHA to run (if not provided, uses latest from ref) - **Parameters**: Optional workflow parameters as key-value pairs (supports expressions) ### Output Channels - **Passed**: Emitted when pipeline completes successfully - **Failed**: Emitted when pipeline fails or is cancelled ### Notes - The component automatically sets up webhook monitoring for pipeline completion - Falls back to polling if webhook doesn't arrive - Can be cancelled, which will stop the running Semaphore workflow ### Example Output ```json { "data": { "blocks": [ { "jobs": [ { "id": "00000-00000-00000-00000-00000", "index": 0, "name": "Job #1", "result": "passed", "status": "finished" } ], "name": "Block #1", "result": "passed", "result_reason": "test", "state": "done" } ], "organization": { "id": "00000000-0000-0000-0000-000000000000", "name": "test" }, "pipeline": { "created_at": "2026-01-22T15:32:47Z", "done_at": "2026-01-22T15:32:55Z", "error_description": "", "id": "00000000-0000-0000-0000-000000000000", "name": "Initial Pipeline", "pending_at": "2026-01-22T15:32:48Z", "queuing_at": "2026-01-22T15:32:48Z", "result": "passed", "result_reason": "test", "running_at": "2026-01-22T15:32:48Z", "state": "done", "stopping_at": "1970-01-01T00:00:00Z", "working_directory": ".semaphore", "yaml_file_name": "semaphore.yml" }, "project": { "id": "00000000-0000-0000-0000-000000000000", "name": "test" }, "repository": { "slug": "test/test", "url": "https://github.com/test/test" }, "revision": { "branch": { "commit_range": "0000000000000000000000000000000000000000^...0000000000000000000000000000000000000000", "name": "test" }, "commit_message": "test", "commit_sha": "0000000000000000000000000000000000000000", "pull_request": null, "reference": "refs/heads/test", "reference_type": "branch", "sender": { "avatar_url": "https://example.com/avatar.png", "email": "test@test.com", "login": "test" }, "tag": null }, "version": "1.0.0", "workflow": { "created_at": "2026-01-22T15:32:47Z", "id": "00000000-0000-0000-0000-000000000000", "initial_pipeline_id": "00000000-0000-0000-0000-000000000000" } }, "timestamp": "2026-01-22T15:32:56.061430218Z", "type": "semaphore.workflow.finished" } ``` #### SendGrid Source URL: https://docs.superplane.com/components/sendgrid Send transactional and marketing email with SendGrid import { CardGrid, LinkCard } from "@astrojs/starlight/components"; ## Triggers ## Actions ## Instructions ### Connection Configure the SendGrid integration in SuperPlane with: - **API Key**: SendGrid API key with Mail Send and Mail Settings Read scopes - **Default From Email**: Required sender email address for SendGrid actions - **Default From Name**: Optional sender name for SendGrid actions ### Actions and Triggers The SendGrid base integration establishes API access. Actions and triggers will be documented here once they are available. ## On Email Event **Trigger key:** `sendgrid.onEmailEvent` The On Email Event trigger emits events when SendGrid posts delivery or engagement events to your webhook. ### Use Cases - **Bounce handling**: Stop sending to bounced addresses and notify your team - **Delivery confirmations**: Trigger follow-ups when critical notifications are delivered - **Engagement tracking**: Update CRM records when recipients open or click emails ### Configuration - **Event Types**: Optional filter for specific SendGrid events (processed, delivered, bounce, open, click, etc.) - **Category Filter**: Optional list of predicates (`equals`, `notEquals`, `matches` regex) ### Webhook Verification SuperPlane configures the SendGrid Event Webhook via API and enables Signed Event Webhook by default. The verification key is stored automatically. Verification uses: - `X-Twilio-Email-Event-Webhook-Signature` header - `X-Twilio-Email-Event-Webhook-Timestamp` header - Raw request body (no transformations) ### Event Data Each event includes fields such as `event`, `email`, `timestamp`, `sg_event_id`, `sg_message_id`, `category` and event-specific properties like `reason`, `response`, `url`, `bounce_classification`. ### Example Data ```json { "data": { "category": [ "order-confirmation" ], "email": "recipient@example.com", "event": "delivered", "response": "250 OK", "sg_event_id": "ZGVmYXVsdC1ldmVudC1pZA", "sg_message_id": "YWJjMTIzX2RlZmF1bHRfbXNnX2lk", "timestamp": 1700000000 }, "timestamp": "2026-02-04T12:00:00Z", "type": "sendgrid.email.event" } ``` ## Create or Update Contact **Component key:** `sendgrid.createOrUpdateContact` Create or update a contact in SendGrid using the Marketing Contacts API. ### Use Cases - **Signup sync**: Add new signups to SendGrid lists for onboarding or newsletters - **CRM sync**: Keep SendGrid contacts updated from your CRM or database - **Post-purchase follow-up**: Add buyers to follow-up campaigns ### Configuration - **Email**: Contact email address (unique identifier) - **First Name**: Optional contact first name - **Last Name**: Optional contact last name - **List IDs**: Optional SendGrid list IDs to add the contact to - **Custom Fields**: Optional custom fields map (must exist in SendGrid) ### Output Channels - **Default**: Emitted when SendGrid accepts the upsert request - **Failed**: Emitted when validation fails or the API request is rejected ### Notes - Requires a SendGrid API key with Marketing Contacts permissions ### Example Output ```json { "data": { "email": "recipient@example.com", "jobId": "job-123", "status": "202 Accepted", "statusCode": 202 }, "timestamp": "2026-02-04T12:00:00Z", "type": "sendgrid.contact.upserted" } ``` ## Send Email **Component key:** `sendgrid.sendEmail` Send a single email via SendGrid's Mail Send API. ### Use Cases - **Notifications**: Send alert or notification emails when workflows fail or complete - **Receipts**: Send order confirmations or receipts from workflow runs - **Reports**: Deliver scheduled digests or reports to stakeholders ### Configuration - **To**: Recipient email address(es), comma-separated - **Subject**: Email subject line - **Sending Mode**: Choose text, HTML, or dynamic template - **Text Body**: Email body content (plain text) - **HTML Body**: Email body content (HTML) - **CC**: CC recipients, comma-separated - **BCC**: BCC recipients, comma-separated - **From Name**: Optional sender display name override - **From Email**: Optional sender email override (must be verified in SendGrid) - **Reply-To**: Reply-to email address - **Template ID**: SendGrid dynamic template ID (e.g. `d-xxxxxxxx`) - **Template Data**: JSON object of template substitution variables - **Categories**: Optional comma-separated list of category names. SendGrid attaches these to the message for tracking and filtering in the Email Activity feed and for use with the Event Webhook (e.g. to filter events by category in an On Email Event trigger). ### Output Channels - **Default**: Emitted when SendGrid accepts the message - **Failed**: Emitted when validation fails or the API request is rejected ### Notes - Requires a SendGrid API key configured on the integration - When using a template, SendGrid may override the subject and body ### Example Output ```json { "data": { "messageId": "YzQ2ODAtMTg5NC0xMWVmLTk0NGYtNTZlYjU5OGY4Y2Q3", "status": "202 Accepted", "statusCode": 202, "subject": "Your receipt is ready", "to": [ "recipient@example.com" ] }, "timestamp": "2026-02-04T12:00:00Z", "type": "sendgrid.email.sent" } ``` #### Sentry Source URL: https://docs.superplane.com/components/sentry React to issue events and manage issues and metric alerts in Sentry import { CardGrid, LinkCard } from "@astrojs/starlight/components"; ## Triggers ## Actions ## Instructions **Setup steps:** 1. Create a [personal auth token](https://sentry.io/settings/account/api/auth-tokens/) in Sentry with the permissions below. Copy the token. > **Token Permissions:** > Project -> `Read` · Releases -> `Read & Write` (`project:releases`) · Team -> `Read` · Issue & Event -> `Read & Write` · Organization -> `Read & Write` 2. In Sentry, go to **Settings → Integrations → Custom Integrations → Create New Integration → Internal Integration**. 3. Name it (e.g. `SuperPlane`), leave **Webhook URL** empty, and save. Copy the **Client Secret** shown on the bottom of the integration page. 4. Fill in **Sentry URL**, **User Token**, **Integration Name**, and **Client Secret** below, then save. SuperPlane configures the webhook and subscribes to issue events automatically. ## On Issue Event **Trigger key:** `sentry.onIssue` The On Issue Event trigger starts a workflow execution when Sentry sends issue webhooks for the connected organization. ### Use Cases - **Escalation workflows**: react when a new issue is created in Sentry - **Triage automation**: assign follow-up actions when issues are assigned or resolved - **Cross-tool sync**: mirror Sentry issue state changes into incident or ticketing systems ### Configuration - **Project**: Optionally limit the trigger to a single Sentry project - **Actions**: Select which issue actions should trigger the workflow ### Event Data The trigger emits the full Sentry webhook payload, including: - **action**: the issue event action - **data.issue**: the Sentry issue object - **actor**: the user or team that triggered the event when available ### Setup This trigger uses the webhook URL configured on your Sentry internal integration. SuperPlane verifies each webhook signature using your Sentry client secret before routing the event to matching triggers. ### Example Data ```json { "data": { "action": "created", "actor": { "id": "789", "name": "Person", "type": "user" }, "data": { "issue": { "assignedTo": { "id": "789", "name": "Person", "type": "user" }, "culprit": "SentryCustomError(frontend/src/util)", "firstSeen": "2022-04-04T18:17:18.320000Z", "id": "123", "lastSeen": "2022-04-04T18:17:18.320000Z", "level": "error", "permalink": "https://your-org.sentry.io/issues/123/", "project": { "id": "456", "name": "ipe", "slug": "ipe" }, "shortId": "IPE-1", "status": "unresolved", "substatus": "new", "title": "Error #1: This is a test error!", "web_url": "https://your-org.sentry.io/issues/123/" } }, "installation": { "uuid": "7a485448-a9e2-4c85-8a3c-4f44175783c9" }, "resource": "issue", "timestamp": "2022-04-04T18:17:18.320000Z" }, "timestamp": "2022-04-04T18:17:18.320000Z", "type": "sentry.issue" } ``` ## Create Alert **Component key:** `sentry.createAlert` The Create Alert component creates a Sentry metric alert rule for a selected project. ### Use Cases - **Coverage automation**: create alert rules automatically after provisioning a service - **Policy enforcement**: ensure critical projects always have baseline metric alerts - **Release safety**: create release-specific alert rules after deploy workflows ### Configuration - **Project**: Sentry project that owns the metric alert rule - **Name**: Alert rule name shown in Sentry - **Aggregate**: Metric expression such as `count()` - **Query**: Optional event search query to narrow the alert - **Time Window**: Evaluation window in minutes - **Threshold Type**: Whether the threshold fires above or below the configured value - **Environment**: Optional environment filter - **Event Types**: Event types included in the alert evaluation - **Critical / Warning**: Thresholds and notification targets for each trigger level. Select the target type first, then choose a Sentry user or team. ### Output Returns the created Sentry metric alert rule, including triggers, actions, and project association. ### Example Output ```json { "data": { "aggregate": "count()", "dataset": "events", "dateCreated": "2026-03-26T09:15:00Z", "dateModified": "2026-03-26T09:15:00Z", "environment": "production", "eventTypes": [ "default", "error" ], "id": "19436", "name": "SuperPlane metric alert example", "organizationId": "4511070267441152", "owner": null, "projects": [ "go-gin" ], "query": "environment:production", "queryType": 0, "resolveThreshold": null, "thresholdType": 0, "timeWindow": 60, "triggers": [ { "actions": [ { "alertRuleTriggerId": "28750", "dateCreated": "2026-03-26T09:15:00Z", "id": "26870", "inputChannelId": null, "integrationId": null, "priority": null, "sentryAppId": null, "targetIdentifier": "4346509", "targetType": "user", "type": "email" } ], "alertRuleId": "19436", "alertThreshold": 5, "dateCreated": "2026-03-26T09:15:00Z", "id": "28750", "label": "critical", "resolveThreshold": 2, "thresholdType": 0 } ] }, "timestamp": "2026-03-26T09:15:00Z", "type": "sentry.alertRule" } ``` ## Create Deploy **Component key:** `sentry.createDeploy` The Create Deploy component marks a deploy against an existing Sentry release. ### Use Cases - **Deployment tracking**: record when a release reaches staging or production - **Release automation**: pair with Create Release in CI/CD canvases - **Operational context**: give Sentry deployment timing and environment information for later triage ### Configuration - **Project**: Optional Sentry project to associate with the deploy - **Release**: Select the existing Sentry release to deploy - **Environment**: The target environment, such as staging or production - **Name**: Optional deploy name - **Deploy URL**: Optional URL for the deployment - **Started At**: Optional deployment start time - **Finished At**: Optional deployment finish time ### Output Returns the created deploy record, including environment, timestamps, URL, and release version. ### Example Output ```json { "data": { "dateFinished": "2026-03-25T10:24:12.000Z", "dateStarted": "2026-03-25T10:20:00.000Z", "environment": "production", "id": "1234567", "name": "Deploy #42", "projects": [ "go-gin" ], "releaseVersion": "2026.03.25", "url": "https://example.com/deploys/42" }, "timestamp": "2026-03-25T10:24:12.000Z", "type": "sentry.deploy" } ``` ## Create Release **Component key:** `sentry.createRelease` The Create Release component registers a new release in Sentry for a selected project. ### Use Cases - **Release tracking**: create a release after a build or deploy succeeds - **Commit association**: attach commits and refs so Sentry can correlate new issues with code changes - **Post-deploy automation**: feed the created release into downstream deployment and monitoring steps ### Configuration - **Project**: Select the Sentry project this release applies to - **Version**: The release version identifier - **Ref**: Optional commit or tag reference for the release - **Release URL**: Optional URL for the release, build, or changelog - **Commits**: Optional commit metadata to associate with the release - **Refs**: Optional repository head/previous commit refs for release comparison ### Output Returns the created Sentry release object, including version, associated projects, deploy count, and release metadata. ### Example Output ```json { "data": { "commitCount": 2, "dateCreated": "2026-03-25T10:12:55.109Z", "dateReleased": "2026-03-25T10:15:00.000Z", "deployCount": 0, "id": 2, "newGroups": 0, "projects": [ { "name": "go-gin", "slug": "go-gin" } ], "ref": "6ba09a7c53235ee8a8fa5ee4c1ca8ca886e7fdbb", "shortVersion": "2026.03.25", "url": "https://github.com/superplanehq/superplane/releases/tag/2026.03.25", "version": "2026.03.25" }, "timestamp": "2026-03-25T10:15:00.000Z", "type": "sentry.release" } ``` ## Delete Alert **Component key:** `sentry.deleteAlert` The Delete Alert component deletes an existing Sentry metric alert rule. ### Use Cases - **Alert cleanup**: remove obsolete rules after a service is retired - **Policy rotation**: delete temporary alert rules after a rollout is complete - **CRUD completion**: pair with alert listing and update workflows ### Configuration - **Project**: Optional project to narrow alert rule selection - **Alert Rule**: Metric alert rule to delete ### Output Returns the deleted alert ID and name so downstream steps can record the removal. ### Example Output ```json { "data": { "deleted": true, "id": "19436", "name": "SuperPlane metric alert example" }, "timestamp": "2026-03-26T09:25:00Z", "type": "sentry.alertDeleted" } ``` ## Get Alert **Component key:** `sentry.getAlert` The Get Alert component retrieves a Sentry metric alert rule and returns its full configuration. ### Use Cases - **Conditional logic**: inspect alert thresholds and projects before taking action - **Alert enrichment**: include alert configuration in downstream notifications or tickets - **Auditing**: fetch a specific metric alert rule for verification or reporting ### Configuration - **Project**: Optional project to narrow alert selection - **Alert Rule**: The metric alert rule to retrieve ### Output Returns the selected metric alert rule, including projects, query, thresholds, triggers, and action details. ### Example Output ```json { "data": { "aggregate": "count()", "createdBy": { "email": "washington@example.com", "name": "Washington" }, "dataset": "events", "dateCreated": "2026-03-25T10:00:00Z", "dateModified": "2026-03-25T10:05:00Z", "environment": "production", "eventTypes": [ "error" ], "id": "177412243058", "name": "High error rate in production", "owner": "team:42", "projects": [ "backend" ], "query": "event.type:error environment:production", "timeWindow": 60, "triggers": [ { "actions": [ { "id": "394280", "inputChannelId": "#alerts", "targetIdentifier": "30489048931789", "targetType": "specific", "type": "slack" } ], "alertThreshold": 100, "id": "294385908", "label": "critical" } ] }, "timestamp": "2026-03-25T10:05:00Z", "type": "sentry.alertRule" } ``` ## Get Issue **Component key:** `sentry.getIssue` The Get Issue component retrieves a Sentry issue and enriches it with recent events for downstream routing and escalation. ### Use Cases - **Routing decisions**: inspect assignee, status, project, and issue frequency before branching - **Escalation context**: include recent events and tags in notifications or ticket creation - **Release correlation**: check whether an issue is already tied to a release before actioning it ### Configuration - **Issue**: Select the Sentry issue to retrieve ### Output Returns the Sentry issue object including: - issue metadata such as title, status, assignee, tags, and frequency stats - recent issue events for additional context ### Example Output ```json { "data": { "assignedTo": { "id": "42", "name": "Platform", "type": "team" }, "count": "7", "events": [ { "dateCreated": "2026-03-24T13:03:56Z", "eventID": "evt_1", "id": "evt_1", "message": "RuntimeError: SuperPlane trigger validation test 008", "platform": "other", "tags": [ { "key": "environment", "value": "production" } ], "title": "RuntimeError: SuperPlane trigger validation test 008" } ], "id": "106740394", "numComments": 0, "permalink": "https://washington-x2.sentry.io/issues/106740394/", "priority": "high", "project": { "id": "4511070273339472", "name": "go-gin", "slug": "go-gin" }, "shortId": "GO-GIN-G", "stats": { "24h": [ [ 1711270800, 7 ] ] }, "status": "unresolved", "tags": [ { "key": "environment", "value": "production" }, { "key": "level", "value": "error" } ], "title": "RuntimeError: SuperPlane trigger validation test 008", "userCount": 3, "web_url": "https://washington-x2.sentry.io/issues/106740394/" }, "timestamp": "2026-03-24T13:03:56Z", "type": "sentry.issue" } ``` ## List Alerts **Component key:** `sentry.listAlerts` The List Alerts component lists Sentry metric alert rules for the connected organization. ### Use Cases - **Alert audits**: review metric alert coverage for an organization or project - **Conditional workflows**: branch based on whether matching alert rules already exist - **Reporting**: feed alert rule inventories into downstream notification or documentation steps ### Configuration - **Project**: Optional Sentry project to filter alert rules ### Output Returns an object containing the list of matching metric alert rules and their configuration details. ### Example Output ```json { "data": { "alerts": [ { "aggregate": "count()", "dataset": "events", "dateCreated": "2026-03-25T10:00:00Z", "dateModified": "2026-03-25T10:05:00Z", "environment": "production", "eventTypes": [ "error" ], "id": "177412243058", "name": "High error rate in production", "owner": "team:42", "projects": [ "backend" ], "query": "event.type:error environment:production", "timeWindow": 60, "triggers": [ { "actions": [ { "id": "394280", "inputChannelId": "#alerts", "targetIdentifier": "30489048931789", "targetType": "specific", "type": "slack" } ], "alertThreshold": 100, "id": "294385908", "label": "critical" } ] } ] }, "timestamp": "2026-03-25T10:05:00Z", "type": "sentry.alertRules" } ``` ## Update Alert **Component key:** `sentry.updateAlert` The Update Alert component updates an existing Sentry metric alert rule. ### Use Cases - **Threshold tuning**: adjust thresholds after an incident review - **Ownership updates**: redirect alert notifications to a different user or team - **Environment changes**: tighten or loosen alert conditions for a new rollout ### Configuration - **Project**: Optional project to narrow alert rule selection or replace the rule's project - **Alert Rule**: Existing Sentry alert rule to update - **Name / Aggregate / Query / Time Window / Threshold Type / Environment / Event Types**: Optional overrides for the existing rule - **Critical / Warning**: Optional updates to trigger thresholds and notification targets. Select the target type first, then choose a Sentry user or team. ### Output Returns the updated Sentry metric alert rule after the change is applied. ### Example Output ```json { "data": { "aggregate": "count()", "dataset": "events", "dateCreated": "2026-03-26T09:15:00Z", "dateModified": "2026-03-26T09:25:00Z", "environment": "production", "eventTypes": [ "error" ], "id": "19436", "name": "SuperPlane metric alert example", "organizationId": "4511070267441152", "owner": null, "projects": [ "go-gin" ], "query": "environment:production level:error", "queryType": 0, "resolveThreshold": null, "thresholdType": 0, "timeWindow": 30, "triggers": [ { "actions": [ { "alertRuleTriggerId": "28750", "dateCreated": "2026-03-26T09:15:00Z", "id": "26870", "inputChannelId": null, "integrationId": null, "priority": null, "sentryAppId": null, "targetIdentifier": "4346509", "targetType": "user", "type": "email" } ], "alertRuleId": "19436", "alertThreshold": 10, "dateCreated": "2026-03-26T09:15:00Z", "id": "28750", "label": "critical", "resolveThreshold": 3, "thresholdType": 0 } ] }, "timestamp": "2026-03-26T09:25:00Z", "type": "sentry.alertRule" } ``` ## Update Issue **Component key:** `sentry.updateIssue` The Update Issue component updates an existing issue in Sentry. ### Use Cases - **Resolve issues automatically** after a remediation workflow succeeds - **Reopen issues** when a related deployment regresses - **Route ownership** by assigning issues to a user or team - **Escalate triage** by changing issue priority - **Mark issues reviewed** after automation handles the first response - **Manage visibility and subscriptions** for follow-up workflows ### Configuration - **Issue**: Select the Sentry issue to update - **Status**: Optional new issue status - **Priority**: Optional issue priority - **Assigned To**: Optional assignee from the selected issue's Sentry project - **Seen**: Optional reviewed flag for the connected user - **Public**: Optional issue sharing visibility - **Subscribed**: Optional workflow subscription for the connected user ### Output Returns the updated Sentry issue object. ### Example Output ```json { "data": { "assignedTo": { "id": "789", "name": "Person", "type": "user" }, "culprit": "SentryCustomError(frontend/src/util)", "firstSeen": "2022-04-04T18:17:18.320000Z", "id": "123", "lastSeen": "2022-04-04T18:17:18.320000Z", "level": "error", "permalink": "https://your-org.sentry.io/issues/123/", "project": { "id": "456", "name": "ipe", "slug": "ipe" }, "shortId": "IPE-1", "status": "resolved", "substatus": "resolved", "title": "Error #1: This is a test error!", "web_url": "https://your-org.sentry.io/issues/123/" }, "timestamp": "2022-04-04T18:17:18.320000Z", "type": "sentry.issue" } ``` #### ServiceNow Source URL: https://docs.superplane.com/components/servicenow Manage and react to incidents in ServiceNow import { CardGrid, LinkCard } from "@astrojs/starlight/components"; ## Actions ## Instructions Requires a ServiceNow instance with OAuth API access. Before creating OAuth credentials, enable client credentials grant on your instance: - Go to **System Properties** (sys_properties_list.do) and search for: - **Name**: glide.oauth.inbound.client.credential.grant_type.enabled - (Important: the property name ends with **enabled**) - If it does not exist, create it with: - **Application Scope**: Global - **Type**: true | false - **Value**: true Then configure OAuth: - Go to **System OAuth > Inbound Integrations** - Create a new integration with **OAuth - Client Credentials Grant** - Copy the generated **Client ID** and **Client Secret** - Assign required permissions to the integration account: - **itil** role (required for incident read/write) - Optionally **admin** if broader scoped access is needed - Optionally enable **Web Service Access Only** on the integration account to restrict it to API-only use. ## Create Incident **Component key:** `servicenow.createIncident` The Create Incident component creates a new incident in ServiceNow using the Table API. ### Use Cases - **Alert escalation**: Create incidents from monitoring alerts - **Error tracking**: Automatically create incidents when errors are detected - **Manual incident creation**: Create incidents from workflow events - **Integration workflows**: Create incidents from external system events ### Required Permissions The ServiceNow integration account needs: - **itil** role — grants read/write access to the Incident table ### Configuration - **Short Description**: A brief summary of the incident (required, supports expressions) - **Description**: Detailed description of the incident (optional, supports expressions) - **Urgency**: Incident urgency level (1-High, 2-Medium, 3-Low) - **Impact**: Incident impact level (1-High, 2-Medium, 3-Low) - **Category**: Incident category (select from list) - **Subcategory**: Incident subcategory (depends on the selected category) - **Assignment Group**: The group responsible for resolving the incident (select from list) - **Assigned To**: The user assigned to resolve the incident (select from list) - **Caller**: The user reporting the incident (select from list) ### Output Returns the created incident object from the ServiceNow Table API, including: - **sys_id**: Unique identifier - **number**: Human-readable incident number (e.g. INC0010001) - **state**: Current incident state - **short_description**: Incident summary - **created_on**: Creation timestamp ### Example Output ```json { "data": { "active": "true", "activity_due": "2026-02-21 18:00:00", "additional_assignee_list": "c1a2b3d4e5f60718293a4b5c6d7e8f90", "approval": "not requested", "approval_history": "", "approval_set": "", "assigned_to": "46d44a1b2f123010a9ad2572f699b6a7", "assignment_group": "8a5055c9c61122780043563ef53438e3", "business_duration": "1970-01-01 02:15:00", "business_impact": "Moderate impact affecting internal users", "business_service": "Email Service", "business_stc": "2", "calendar_duration": "1970-01-01 03:00:00", "calendar_stc": "3", "caller_id": "6816f79cc0a8016401c5a33be04be441", "category": "inquiry", "cause": "User mailbox quota exceeded", "caused_by": "", "child_incidents": "0", "close_code": "", "close_notes": "", "closed_at": "", "closed_by": "", "cmdb_ci": "3f8a9d12db2310108f5d5e1234567890", "comments": "User reported inability to send emails.", "comments_and_work_notes": "", "company": "Acme Corp", "contact_type": "email", "contract": "Standard IT Support", "correlation_display": "", "correlation_id": "EXT-EMAIL-20260220-001", "delivery_plan": "", "delivery_task": "", "description": "User cannot send or receive emails since this morning. Outlook shows mailbox full error.", "due_date": "2026-02-21 18:00:00", "escalation": "0", "expected_start": "2026-02-20 17:30:00", "follow_up": "2026-02-22 10:00:00", "group_list": "", "hold_reason": "", "impact": "2", "incident_state": "2", "knowledge": "false", "location": "São Paulo - Office 3rd Floor", "made_sla": "true", "notify": "1", "number": "INC0010456", "opened_at": "2026-02-20 17:00:06", "opened_by": { "link": "https://dev194606.service-now.com/api/now/table/sys_user/6816f79cc0a8016401c5a33be04be441", "value": "6816f79cc0a8016401c5a33be04be441" }, "order": "", "origin_id": "", "origin_table": "", "parent": "", "parent_incident": "", "priority": "3", "problem_id": "", "reassignment_count": "1", "reopen_count": "0", "reopened_by": "", "reopened_time": "", "resolved_at": "", "resolved_by": "", "rfc": "", "route_reason": "", "service_offering": "Corporate Email - Exchange Online", "severity": "3", "short_description": "User unable to send emails - mailbox full", "sla_due": "2026-02-21 18:00:00", "state": "2", "subcategory": "email", "sys_class_name": "incident", "sys_created_by": "admin", "sys_created_on": "2026-02-20 17:00:06", "sys_domain": { "link": "https://dev194606.service-now.com/api/now/table/sys_user_group/global", "value": "global" }, "sys_domain_path": "/", "sys_id": "5fd8a0b983c332104005f7efeeaad999", "sys_mod_count": "3", "sys_tags": "email,quota,user-issue", "sys_updated_by": "it.support", "sys_updated_on": "2026-02-20 18:45:22", "task_effective_number": "INC0010456", "time_worked": "5400", "universal_request": "", "upon_approval": "proceed", "upon_reject": "cancel", "urgency": "2", "user_input": "Cannot send emails since 9 AM.", "watch_list": "manager@acme.com,it-team@acme.com", "work_end": "", "work_notes": "Mailbox cleaned and quota increased to 100GB. Issue under monitoring.", "work_notes_list": "", "work_start": "2026-02-20 17:30:00" }, "timestamp": "2026-02-20T18:45:25.123456789Z", "type": "servicenow.incident" } ``` ## Get Incident **Component key:** `servicenow.getIncident` Fetch a single ServiceNow incident by selecting it from the dropdown ### Example Output ```json { "data": { "category": "Network", "impact": "2", "number": "INC0010001", "priority": "3", "short_description": "Server is unresponsive", "state": "1", "subcategory": "DNS", "sys_created_on": "2026-01-19 12:00:00", "sys_id": "a1b2c3d4e5f6g7h8i9j0", "sys_updated_on": "2026-01-19 12:00:00", "urgency": "2" }, "timestamp": "2026-01-19T12:00:00Z", "type": "servicenow.incident" } ``` #### Slack Source URL: https://docs.superplane.com/components/slack Send and react to Slack messages and interactions import { CardGrid, LinkCard } from "@astrojs/starlight/components"; ## Triggers ## Actions ## Instructions You can install the Slack app without the **Bot Token** and **Signing Secret**. After installation, follow the setup prompt to create the Slack app and add those values. ## On App Mention **Trigger key:** `slack.onAppMention` The On App Mention trigger starts a workflow execution when the Slack app is mentioned in a message. ### Use Cases - **Slash commands**: Process commands from Slack messages - **Bot interactions**: Create interactive Slack bots - **Team workflows**: Trigger workflows from Slack conversations - **Notification processing**: Process and respond to mentions ### Configuration - **Channel**: Optional channel filter - if specified, only mentions in this channel will trigger (leave empty to listen to all channels) ### Event Data Each mention event includes: - **event**: Event information including message text, channel, and timestamp - **user**: User who mentioned the app - **channel**: Channel where the mention occurred - **text**: The message text containing the mention ### Setup This trigger automatically sets up a Slack event subscription when configured. The subscription is managed by SuperPlane and will be cleaned up when the trigger is removed. ### Example Data ```json { "data": { "api_app_id": "A123ABC456", "authed_users": [ "U123ABC456", "U222222222" ], "event": { "channel": "C123ABC456", "event_ts": "1515449522000016", "text": "\u003c@U0LAN0Z89\u003e is it everything a river should be?", "ts": "1515449522.000016", "type": "app_mention", "user": "U061F7AUR" }, "event_id": "Ev123ABC456", "event_time": 123456789, "team_id": "T123ABC456", "token": "XXYYZZ", "type": "event_callback" }, "timestamp": "2026-01-19T12:00:00Z", "type": "slack.app.mention" } ``` ## Send Text Message **Component key:** `slack.sendTextMessage` The Send Text Message component sends a text message to a Slack channel. ### Use Cases - **Notifications**: Send notifications about workflow events or system status - **Alerts**: Alert teams about important events or errors - **Updates**: Provide status updates on long-running processes - **Team communication**: Automate team communications from workflows ### Configuration - **Channel**: Select the Slack channel to send the message to - **Text**: The message text to send (supports expressions and Slack markdown formatting) ### Output Returns metadata about the sent message including channel information. ### Notes - The Slack app must be installed and have permission to post to the selected channel - Supports Slack markdown formatting in message text - Messages are sent as the configured Slack bot user ### Example Output ```json { "data": { "channel": "C123456", "text": "Hello from SuperPlane", "ts": "1700000000.000100", "user": "U123456" }, "timestamp": "2026-01-16T17:56:16.680755501Z", "type": "slack.message.sent" } ``` ## Wait for Button Click **Component key:** `slack.waitForButtonClick` The Wait for Button Click component sends a message to a Slack channel or DM with interactive buttons and waits for the user to click one of the configured buttons. ### Use Cases - **Request approval or input**: Get structured input from a user in Slack before applying or deploying (e.g., Approve / Reject buttons) - **Pause a workflow**: Wait until a human selects an option (e.g., Confirm / Cancel) - **Implement slash-command style flows**: Create interactive flows that need a structured reply via buttons ### Configuration - **Channel**: Slack channel or DM channel name to post to (required) - **Message**: Message text (supports Slack formatting, required) - **Timeout**: Maximum time to wait in seconds (optional) - **Buttons**: Set of 1–4 items, each with name (label) and value (required) ### Output Channels - **Received**: Emits when the user clicks a button; payload includes the selected value and clicker info (when available) - **Timeout**: Emits when no button click is received within the configured timeout ### Behavior - The message is posted with interactive buttons - The workflow pauses until a button is clicked or timeout occurs - Only the first button click is processed; subsequent clicks are ignored - If timeout is not configured, the component waits indefinitely ### Notes - The Slack app must be installed and have permission to post to the selected channel - Supports Slack markdown formatting in message text - Button clicks are processed through Slack's interactive components API ### Example Output ```json { "data": { "clicked_at": "2026-02-10T21:00:00Z", "clicked_by": { "id": "U01234567", "username": "pedro" }, "value": "approve" }, "timestamp": "2026-02-10T21:00:00Z", "type": "slack.button.clicked" } ``` #### SMTP Source URL: https://docs.superplane.com/components/smtp Send emails via any SMTP server import { CardGrid, LinkCard } from "@astrojs/starlight/components"; ## Actions ## Send Email **Component key:** `smtp.sendEmail` The Send Email component sends emails through a configured SMTP server. ### Use Cases - **Notifications**: Send email notifications for workflow events - **Alerts**: Email alerts for errors or important events - **Reports**: Send automated reports via email - **User communications**: Send emails to users as part of workflows ### Configuration - **To**: Recipient email addresses (comma-separated for multiple recipients, supports expressions) - **CC**: Carbon copy recipients (optional, comma-separated) - **BCC**: Blind carbon copy recipients (optional, comma-separated) - **Subject**: Email subject line (supports expressions) - **Body**: Email body content (supports expressions and HTML) - **Is HTML**: Toggle to send HTML-formatted emails - **From Name**: Sender display name (optional, uses app default if not specified) - **From Email**: Sender email address (optional, uses app default if not specified) - **Reply To**: Reply-to email address (optional) ### SMTP Configuration The SMTP server must be configured in the application settings before using this component. Configure: - SMTP host and port - Authentication credentials - TLS/SSL settings - Default sender information ### Output Returns metadata about the sent email including recipients and subject. ### Example Output ```json { "data": { "cc": [], "fromEmail": "sender@example.com", "sentAt": "2025-01-21T12:00:00Z", "subject": "Hello from Superplane", "success": true, "to": [ "recipient@example.com" ] }, "timestamp": "2025-01-21T12:00:00.000000000Z", "type": "smtp.email.sent" } ``` #### Statuspage Source URL: https://docs.superplane.com/components/statuspage Create and manage incidents on your Atlassian Statuspage import { CardGrid, LinkCard } from "@astrojs/starlight/components"; ## Actions ## Instructions To get your API key: Open your Statuspage, click the icon in the top-right corner, select API info, then create an API key. ## Create Incident **Component key:** `statuspage.createIncident` The Create Incident component creates a new realtime or scheduled incident on your Atlassian Statuspage. ### Use Cases - **Realtime incidents**: Create and notify subscribers when an unexpected outage occurs - **Scheduled maintenance**: Schedule maintenance windows with optional reminders and auto-transitions - **Integration workflows**: Create incidents from monitoring alerts or other workflow events ### Configuration - **Page** (required): The Statuspage to create the incident on. Supports expressions for workflow chaining (e.g. {{ $['Create Incident'].data.page_id }}). - **Incident type**: Realtime (active incident) or Scheduled (planned maintenance) - **Name** (required): Short title for the incident - **Body** (optional): Initial message shown as the first incident update - **Status** (realtime): investigating, identified, monitoring, or resolved - **Impact override** (realtime): none, minor, major, or critical - **Components** (optional): List of components and their status. Each item has Component ID (supports expressions) and Status (operational, degraded_performance, partial_outage, major_outage, under_maintenance) - **Scheduled For / Until** (scheduled): Start and end time for scheduled maintenance (ISO 8601, e.g. 2026-02-15T02:00) - **Scheduled timezone** (scheduled): Timezone for the scheduled times (default UTC). Output is converted to UTC for the API. - **Scheduled options** (scheduled): Remind prior, auto in-progress, auto completed - **Deliver notifications** (optional): Whether to send notifications for the initial update (default: true) ### Output Returns the full Statuspage Incident object from the API. The payload has structure { type, timestamp, data } where data is the incident. Common expression paths (use $['Node Name'].data. as prefix): - data.id, data.name, data.status, data.impact - data.shortlink — link to the incident - data.created_at, data.updated_at - data.components — array of affected components - data.incident_updates — array of update messages ### Example Output ```json { "data": { "auto_transition_deliver_notifications_at_end": null, "auto_transition_deliver_notifications_at_start": null, "auto_transition_to_maintenance_state": null, "auto_transition_to_operational_state": null, "components": [ { "automation_email": "component+example123...", "created_at": "2026-02-12T10:30:00.000Z", "description": null, "group": false, "group_id": null, "id": "8kbf7d35c070", "name": "API", "only_show_if_degraded": false, "page_id": "kctbh9vrtdwd", "position": 1, "showcase": true, "start_date": "2026-02-12", "status": "partial_outage", "updated_at": "2026-02-12T10:30:00.000Z" }, { "automation_email": "component+example456...", "created_at": "2026-02-12T10:30:00.000Z", "description": null, "group": false, "group_id": null, "id": "9kbf7d35c071", "name": "Management Portal", "only_show_if_degraded": false, "page_id": "kctbh9vrtdwd", "position": 2, "showcase": true, "start_date": "2026-02-12", "status": "degraded_performance", "updated_at": "2026-02-12T10:30:00.000Z" } ], "created_at": "2026-02-12T10:30:00.000Z", "id": "p31zjtct2jer", "impact": "major", "impact_override": "major", "incident_updates": [ { "affected_components": [ { "code": "8kbf7d35c070", "name": "API", "new_status": "partial_outage", "old_status": "partial_outage" }, { "code": "9kbf7d35c071", "name": "Management Portal", "new_status": "degraded_performance", "old_status": "degraded_performance" } ], "body": "We are investigating reports of slow database queries.", "created_at": "2026-02-12T10:30:00.000Z", "custom_tweet": null, "deliver_notifications": true, "display_at": "2026-02-12T10:30:00.000Z", "id": "upd1", "incident_id": "p31zjtct2jer", "status": "investigating", "tweet_id": null, "twitter_updated_at": null, "updated_at": "2026-02-12T10:30:00.000Z", "wants_twitter_update": false } ], "metadata": {}, "monitoring_at": null, "name": "Database Connection Issues", "page_id": "kctbh9vrtdwd", "postmortem_body": null, "postmortem_body_last_updated_at": null, "postmortem_ignored": false, "postmortem_notified_subscribers": false, "postmortem_notified_twitter": false, "postmortem_published_at": null, "reminder_intervals": null, "resolved_at": null, "scheduled_auto_completed": false, "scheduled_auto_in_progress": false, "scheduled_for": null, "scheduled_remind_prior": false, "scheduled_reminded_at": null, "scheduled_until": null, "shortlink": "https://stspg.io/p31zjtct2jer", "status": "investigating", "updated_at": "2026-02-12T10:30:00.000Z" }, "timestamp": "2026-02-12T10:30:00.000Z", "type": "statuspage.incident" } ``` ## Get Incident **Component key:** `statuspage.getIncident` The Get Incident component fetches the full details of an existing incident on your Atlassian Statuspage. ### Use Cases - **Incident lookup**: Fetch incident details for processing or display - **Workflow automation**: Get incident information to make decisions in workflows - **Timeline enrichment**: Retrieve the incident timeline (incident_updates) for reporting or notifications - **Status checking**: Check incident status before performing actions ### Configuration - **Page** (required): The Statuspage containing the incident. Select from the dropdown, or switch to expression mode for workflow chaining (e.g. {{ $['Create Incident'].data.page_id }}). - **Incident** (required): Incident ID to fetch. Supports expressions for workflow chaining (e.g. {{ $['Create Incident'].data.id }}). ### Output Returns the full Statuspage Incident object from the API. The payload has structure { type, timestamp, data } where data is the incident. Common expression paths (use $['Node Name'].data. as prefix): - data.id, data.name, data.status, data.impact - data.shortlink — link to the incident - data.created_at, data.updated_at, data.resolved_at - data.components — array of affected components - data.incident_updates — array of update messages (timeline), in API order ### Example Output ```json { "data": { "auto_transition_deliver_notifications_at_end": null, "auto_transition_deliver_notifications_at_start": null, "auto_transition_to_maintenance_state": null, "auto_transition_to_operational_state": null, "components": [ { "automation_email": "component+example123...", "created_at": "2026-02-12T10:30:00.000Z", "description": null, "group": false, "group_id": null, "id": "8kbf7d35c070", "name": "API", "only_show_if_degraded": false, "page_id": "kctbh9vrtdwd", "position": 1, "showcase": true, "status": "partial_outage", "updated_at": "2026-02-12T10:30:00.000Z" } ], "created_at": "2026-02-12T10:30:00.000Z", "id": "p31zjtct2jer", "impact": "major", "impact_override": "major", "incident_updates": [ { "affected_components": null, "body": "We are investigating reports of slow database queries.", "created_at": "2026-02-12T10:30:00.000Z", "custom_tweet": null, "deliver_notifications": true, "display_at": "2026-02-12T10:30:00.000Z", "id": "upd1", "incident_id": "p31zjtct2jer", "status": "monitoring", "tweet_id": null, "twitter_updated_at": null, "updated_at": "2026-02-12T10:30:00.000Z", "wants_twitter_update": false }, { "affected_components": [ { "code": "8kbf7d35c070", "name": "API", "new_status": "degraded_performance", "old_status": "operational" } ], "body": "We have identified the problem and are working on a fix.", "created_at": "2026-02-12T10:30:00.000Z", "custom_tweet": null, "deliver_notifications": true, "display_at": "2026-02-12T10:30:00.000Z", "id": "upd2", "incident_id": "p31zjtct2jer", "status": "identified", "tweet_id": null, "twitter_updated_at": null, "updated_at": "2026-02-12T10:30:00.000Z", "wants_twitter_update": false } ], "metadata": {}, "monitoring_at": "2026-02-12T10:30:00.000Z", "name": "Database Connection Issues", "page_id": "kctbh9vrtdwd", "postmortem_body": null, "postmortem_body_last_updated_at": null, "postmortem_ignored": false, "postmortem_notified_subscribers": false, "postmortem_notified_twitter": false, "postmortem_published_at": null, "reminder_intervals": null, "resolved_at": null, "scheduled_auto_completed": false, "scheduled_auto_in_progress": false, "scheduled_for": null, "scheduled_remind_prior": false, "scheduled_reminded_at": null, "scheduled_until": null, "shortlink": "https://stspg.io/p31zjtct2jer", "status": "monitoring", "updated_at": "2026-02-12T10:30:00.000Z" }, "timestamp": "2026-02-12T10:30:00.000Z", "type": "statuspage.incident" } ``` ## Update Incident **Component key:** `statuspage.updateIncident` The Update Incident component updates an existing incident on your Atlassian Statuspage. ### Use Cases - **Status transitions**: Update incident status (e.g. investigating → identified → resolved) - **Maintenance updates**: Transition scheduled maintenance to in progress or completed - **Integration workflows**: Update incidents from monitoring systems or approval workflows ### Configuration - **Page** (required): The Statuspage containing the incident. Select from the dropdown, or switch to expression mode for workflow chaining (e.g. {{ $['Create Incident'].data.page_id }}). - **Incident** (required): Incident ID to update. Supports expressions for workflow chaining (e.g. {{ $['Create Incident'].data.id }}). - **Incident type**: Realtime or Scheduled — determines which status options are shown. You cannot change an incident's type. - **Status** (optional): New status. Options depend on incident type: realtime (investigating, identified, monitoring, resolved) or scheduled (scheduled, in progress, verifying, completed) - **Body** (optional): Update message shown as the latest incident update - **Impact override** (optional, realtime only): Override displayed severity (none, maintenance, minor, major, critical) - **Components** (optional): List of components and their status. Each item has Component ID (supports expressions) and Status (operational, degraded_performance, partial_outage, major_outage, under_maintenance) - **Deliver notifications** (optional): Whether to send notifications for this update (default: true) At least one of Status, Body, Impact override, or Components must be provided. ### Output Returns the full Statuspage Incident object from the API. The payload has structure { type, timestamp, data } where data is the incident. Common expression paths (use $['Node Name'].data. as prefix): - data.id, data.name, data.status, data.impact - data.shortlink — link to the incident - data.created_at, data.updated_at - data.components — array of affected components - data.incident_updates — array of update messages ### Example Output ```json { "data": { "auto_transition_deliver_notifications_at_end": null, "auto_transition_deliver_notifications_at_start": null, "auto_transition_to_maintenance_state": null, "auto_transition_to_operational_state": null, "components": [ { "automation_email": "component+example123...", "created_at": "2026-02-12T10:30:00.000Z", "description": null, "group": false, "group_id": null, "id": "8kbf7d35c070", "name": "API", "only_show_if_degraded": false, "page_id": "kctbh9vrtdwd", "position": 1, "showcase": true, "start_date": "2026-02-12", "status": "partial_outage", "updated_at": "2026-02-12T10:30:00.000Z" }, { "automation_email": "component+example456...", "created_at": "2026-02-12T10:30:00.000Z", "description": null, "group": false, "group_id": null, "id": "9kbf7d35c071", "name": "Management Portal", "only_show_if_degraded": false, "page_id": "kctbh9vrtdwd", "position": 2, "showcase": true, "start_date": "2026-02-12", "status": "degraded_performance", "updated_at": "2026-02-12T10:30:00.000Z" } ], "created_at": "2026-02-12T10:30:00.000Z", "id": "p31zjtct2jer", "impact": "minor", "impact_override": "minor", "incident_updates": [ { "affected_components": null, "body": "We're tracking the problem.", "created_at": "2026-02-12T11:00:00.000Z", "custom_tweet": null, "deliver_notifications": true, "display_at": "2026-02-12T11:00:00.000Z", "id": "upd1", "incident_id": "p31zjtct2jer", "status": "monitoring", "tweet_id": null, "twitter_updated_at": null, "updated_at": "2026-02-12T11:00:00.000Z", "wants_twitter_update": false }, { "affected_components": [ { "code": "8kbf7d35c070", "name": "API", "new_status": "partial_outage", "old_status": "partial_outage" }, { "code": "9kbf7d35c071", "name": "Management Portal", "new_status": "degraded_performance", "old_status": "degraded_performance" } ], "body": "There is a problem.", "created_at": "2026-02-12T10:30:00.000Z", "custom_tweet": null, "deliver_notifications": true, "display_at": "2026-02-12T10:30:00.000Z", "id": "upd2", "incident_id": "p31zjtct2jer", "status": "investigating", "tweet_id": null, "twitter_updated_at": null, "updated_at": "2026-02-12T10:30:00.000Z", "wants_twitter_update": false } ], "metadata": {}, "monitoring_at": "2026-02-12T11:00:00.000Z", "name": "Database Connection Issues", "page_id": "kctbh9vrtdwd", "postmortem_body": null, "postmortem_body_last_updated_at": null, "postmortem_ignored": false, "postmortem_notified_subscribers": false, "postmortem_notified_twitter": false, "postmortem_published_at": null, "reminder_intervals": null, "resolved_at": null, "scheduled_auto_completed": false, "scheduled_auto_in_progress": false, "scheduled_for": null, "scheduled_remind_prior": false, "scheduled_reminded_at": null, "scheduled_until": null, "shortlink": "https://stspg.io/p31zjtct2jer", "status": "monitoring", "updated_at": "2026-02-12T11:00:00.000Z" }, "timestamp": "2026-02-12T11:00:00.000Z", "type": "statuspage.incident" } ``` #### Telegram Source URL: https://docs.superplane.com/components/telegram Send messages and react to events via Telegram bots import { CardGrid, LinkCard } from "@astrojs/starlight/components"; ## Triggers ## Actions ## Instructions To set up Telegram integration: 1. Get a bot token from @BotFather and paste it in the field below 2. Disable privacy mode so the bot can receive messages in groups: send /setprivacy to @BotFather, select your bot, and choose Disable 3. Add the bot to your group or channel Note: if the bot was already in a group before disabling privacy mode, remove and re-add it for the change to take effect. ## On Mention **Trigger key:** `telegram.onMention` The On Mention trigger starts a workflow execution when the Telegram bot is mentioned in a message. ### Use Cases - **Bot commands**: Process commands from Telegram messages - **Bot interactions**: Create interactive Telegram bots - **Team workflows**: Trigger workflows from Telegram conversations - **Notification processing**: Process and respond to mentions ### Configuration - **Chat ID**: Optional chat filter - if specified, only mentions in this chat will trigger (leave empty to listen to all chats) ### Event Data Each mention event includes: - **message_id**: The unique message identifier - **from**: User who mentioned the bot - **chat**: Chat where the mention occurred - **text**: The message text containing the mention - **date**: Unix timestamp of the message ### Setup This trigger automatically sets up a webhook subscription when configured. The subscription is managed by SuperPlane and will be cleaned up when the trigger is removed. ### Example Data ```json { "data": { "chat": { "id": -9876543210, "title": "My Group", "type": "group" }, "date": 1737028800, "entities": [ { "length": 6, "offset": 0, "type": "mention" } ], "from": { "first_name": "John", "id": 111222333, "is_bot": false, "username": "johndoe" }, "message_id": 1234, "text": "@mybot hello!" }, "timestamp": "2026-01-16T12:00:00.000Z", "type": "telegram.message.mention" } ``` ## Send Message **Component key:** `telegram.sendMessage` The Send Message component sends a text message to a Telegram chat. ### Use Cases - **Notifications**: Send notifications about workflow events or system status - **Alerts**: Alert teams about important events or errors - **Updates**: Provide status updates on long-running processes - **Bot interactions**: Send automated responses to users ### Configuration - **Chat ID**: The Telegram chat ID (can be a user, group, or channel) - **Text**: The message text to send - **Parse Mode**: Optional formatting mode (Markdown) ### Output Returns metadata about the sent message including message ID, chat ID, text, and timestamp. ### Notes - The bot must have permission to post messages in the specified chat - For groups and channels, add the bot as a member first - Use parse mode for rich text formatting in your messages - Chat ID can be negative for groups and channels ### Example Output ```json { "data": { "chat_id": -9876543210, "date": 1737028800, "message_id": 1234, "text": "Hello from SuperPlane" }, "timestamp": "2026-01-16T12:00:00.000Z", "type": "telegram.message.sent" } ``` ## Wait for Button Click **Component key:** `telegram.waitForButtonClick` The Wait for Button Click component sends a message to a Telegram chat with inline keyboard buttons and waits for the user to click one of the configured buttons. ### Use Cases - **Request approval or input**: Get structured input from a user in Telegram before applying or deploying (e.g., Approve / Reject buttons) - **Pause a workflow**: Wait until a human selects an option (e.g., Confirm / Cancel) - **Implement interactive flows**: Create interactive flows that need a structured reply via buttons ### Configuration - **Chat ID**: Telegram chat ID (user, group, or channel) to post to (required) - **Message**: Message text (required) - **Timeout**: Maximum time to wait in seconds (optional) - **Buttons**: Set of 1–4 items, each with name (label) and value (required) ### Output Channels - **Received**: Emits when the user clicks a button; payload includes the selected value and clicker info (when available) - **Timeout**: Emits when no button click is received within the configured timeout ### Behavior - The message is posted with inline keyboard buttons - The workflow pauses until a button is clicked or timeout occurs - Only the first button click is processed; subsequent clicks are ignored - If timeout is not configured, the component waits indefinitely ### Notes - The Telegram bot must be added to the chat and have permission to post messages - Button clicks are processed through Telegram's callback query API ### Example Output ```json { "data": { "clicked_at": "2026-02-10T21:00:00Z", "clicked_by": { "id": 123456789, "username": "john" }, "value": "approve" }, "timestamp": "2026-02-10T21:00:00Z", "type": "telegram.button.clicked" } ```