Skip to main content

GETTING STARTED WITH LINEAR IN SWAMP

In this tutorial, we will connect Swamp to Linear. We pull the @hivemq/linear extension and create a behavior named linear that reads its API key from a vault. Then we record our Linear teams and workflow states as data and file a first Linear issue from the command line.

What we will build

By the end we will have:

  • a behavior named linear of type @hivemq/linear
  • team and workflowState resources recorded in the repository
  • a new issue in Linear titled First issue filed from Swamp

Prerequisites

  • Swamp installed (see Install Swamp)
  • Signed in with swamp auth login
  • A terminal open in a Swamp repository created with swamp repo init
  • A Linear personal API key

Pull the extension

First, we pull the extension that provides the @hivemq/linear behavior type:

swamp extension pull @hivemq/linear

You will see output like:

INF extension·pull: Pulling "@hivemq/linear"@"2026.03.30.14"
INF extension·pull: Identity verified: "@hivemq/linear"@"2026.03.30.14"
INF extension·pull: Pulled "@hivemq/linear"@"2026.03.30.14"
INF extension·pull: Extracted 6 files:

The @hivemq/linear behavior type is now available in this repository. It has one required global argument, apiKey, and an optional defaultTeamId. Its methods are createIssue, listTeams, listProjects and listStates.

Store the API key

Next, we put the Linear personal API key in a vault named linear, under the key api-key. The Storing Secrets tutorial shows how to store a value in a vault. It also shows how to check that the value is there with swamp vault list-keys without displaying it.

The key stays in the vault. In the next step, the behavior refers to it with an expression.

Create the behavior

Now we create a behavior named linear of type @hivemq/linear, as described in Create and Run a Behavior. We set its required apiKey global argument to a vault expression rather than to the key itself, so the definition holds:

globalArguments:
  apiKey: "${{ vault.get('linear', 'api-key') }}"

Notice that the definition contains only the vault expression. Swamp resolves it each time a method runs and redacts the key from the output.

List the teams

Now we ask Linear which teams the key can see:

swamp behavior run linear listTeams

This command calls the Linear API with the key from the vault and records each team it returns as a team resource.

The run output lists the data it produced. Find the team where the first issue should go and copy its ID. In the next two steps, replace TEAM_ID with that ID.

List the workflow states

Next, we record the workflow states of that team:

swamp behavior run linear listStates --input teamId=TEAM_ID

This command fetches the team's workflow states, such as Backlog, In Progress and Done, and records each one as a workflowState resource.

Create the first issue

Finally, we file an issue in the team:

swamp behavior run linear createIssue \
  --input "title=First issue filed from Swamp" \
  --input "description=Created with the @hivemq/linear behavior" \
  --input teamId=TEAM_ID \
  --input 'priority:json=3'

This command creates the issue in Linear with the given title, description and priority, and records it as an issue resource. Open the team in Linear and you will see First issue filed from Swamp in its list of issues.

Notice that priority uses the :json= suffix. This passes the value as the number 3 rather than the string "3".

What we built

We pulled the @hivemq/linear extension and stored a Linear API key in a vault. We created a behavior that reads the key with vault.get(), recorded our teams and workflow states as Swamp data, and filed a first Linear issue from the Swamp CLI.