SWIRLS_
Connections

Actions and the catalog

Typed provider operations installed with swirls add. Browse the integration catalog, install action blocks, generate them from any API spec, and request new providers.

What it is. An action block declares a typed provider operation: the HTTP transport plus input and output JSON schemas and the OAuth scopes the call needs. Actions never hold credentials; they pair with a connection at run time.

Use it when a workflow or agent calls a third-party API and you want the call typed, scoped, and reviewable in the file instead of hidden in a fetch.

Works with type: integration nodes, connections, and the swirls add CLI command.

The integration catalog

The catalog at swirls.ai/catalog lists every curated action you can install. Today it covers four providers:

ProviderActionsCoverage
Slack1Post messages to channels, DMs, and conversations.
GitHub8Repos, issues, and pull requests.
Linear7Issues, comments, teams, and viewer.
Microsoft Graph106Mail, calendar, contacts, OneDrive, OneNote, Teams, and SharePoint.

These are the providers with curated actions today, not the limit of what Swirls can reach. The same brokered OAuth framework supports any provider: Discord and LinkedIn are already brokered for channels, swirls add generates actions from any OpenAPI or GraphQL spec, and self-managed connections cover any API you hold credentials for. See Request a provider below.

Install actions with one command:

swirls add slack                # every curated Slack action
swirls add linear create_issue  # one Linear action
swirls add microsoft send_mail list_calendar_events

swirls add writes action blocks to swirls/integrations/<provider>/ and records source, version, and checksum in swirls.lock.json. Override the registry with --registry or SWIRLS_REGISTRY_URL.

Action blocks

Installed actions are ordinary .swirls blocks. You can read them, review them in a PR, and write your own by hand.

action slack_post_message {
  label: "Post message"
  provider: slack
  method: POST
  path: "/chat.postMessage"
  encoding: form
  scopes: ["chat:write"]
  input: @json { { "type": "object", "required": ["channel", "text"], "properties": { "channel": { "type": "string" }, "text": { "type": "string" } } } }
  output: @json { { "type": "object", "required": ["ok"], "properties": { "ok": { "type": "boolean" } } } }
}
FieldTypeRequiredDescription
provideridentifierYesMust match the bound connection's provider.
methodidentifierYesGET, POST, PUT, DELETE, or PATCH.
pathstringYesProvider API path (leading / optional). Supports {param} substitution from the input.
encodingidentifierNojson (default), form, query, or raw.
documentstringNoGraphQL query or mutation (requires method: POST; not combined with input/output).
input / outputschemaNoInline @json, object literal, or a bare schema name. Drives typed params and node output.
scopesstring arrayNoOAuth scopes the action needs.
label, descriptionstringNoDisplay metadata.

raw encoding sends the content input verbatim as the request body, with an optional contentType input setting the MIME type. The Microsoft Graph file-upload actions use it.

GraphQL actions carry a pre-authored document instead of input and output schemas; the LSP types them from the schema.graphql sidecar that swirls add writes beside the actions.

Using an action in a workflow

A type: integration node names a connection and an action. Deploy inlines the transport and schemas from the action block, so params: and the node output are checked against them.

connection team_slack {
  label: "Team Slack"
  provider: slack
}

node post_slack {
  type: integration
  label: "Post to Slack"
  connection: team_slack
  action: slack_post_message
  params: @ts {
    return {
      channel: context.nodes.root.output.channel,
      text: context.nodes.root.output.text,
    }
  }
}

The platform issues a short-lived provider token for the bound account and proxies the call. No provider credentials exist in the file, the vault, or the node. Full node reference: integration nodes.

Any API, not just the catalog

swirls add also accepts a URL. Point it at an OpenAPI or GraphQL spec and it generates the same typed action artifacts the catalog ships:

swirls add https://api.linear.app/graphql --only viewer
swirls add https://petstore.example.com/openapi.json

URL imports scaffold a connection file once if one is missing. Pair the generated actions with a self-managed connection (base_url plus auth) and the runtime calls your API with credentials from the project vault.

Request a provider

Managed OAuth for a provider we don't broker yet is a request away:

  1. Declare the connection anyway: connection my_crm { provider: salesforce }. Validation warns that the provider is not in the catalog but the file still passes swirls doctor.
  2. Deploy with git push or swirls deploy. The slot appears on the project's Connections page.
  3. Click Request support on the slot and tell us which scopes or capabilities you need. We prioritize enabling it and follow up by email.

Prefer to talk first? Email [email protected] with the provider name. Self-managed connections work immediately in the meantime, so a request never blocks shipping.

Common mistakes

  • Setting method: or path: on a node that uses action:. The action block owns the transport.
  • Editing installed action files in place and re-running swirls add. The checksum in swirls.lock.json tracks the installed version; copy the block out under a new name if you want to customize it.
  • Combining document with input/output. GraphQL actions type through the schema.graphql sidecar, not inline schemas.
  • Calling the provider with fetch from a code node. Code nodes never see connection credentials; use an integration node.

Further reading

On this page