Auto-Start Tasks from GitHub Issues

Wire up a GitHub Action that creates a Wallfacer task the moment a label is applied to an issue. The task runs as your account's agent and shows up in the account, ready for the agent to work on.

The mechanism is a single API call: POST /v1/accounts/{account}/tasks with the issue as an attachment and a prompt. The task runs as your account's connected agent (its GitHub identity, its model keys), so you do not resolve or pass any per-person identity. The person whose token drives the automation is recorded as the task's owner; the work itself runs under the agent.

Prerequisites

  • A Wallfacer API token with permission to create tasks. Create one in the app under Settings > API Tokens.
  • An account agent connected to GitHub, so the agent can clone the repo and open pull requests. See GitHub Integration.
  • Your Wallfacer account ID. Fetch it with curl https://api.wallfacer.ai/v1/accounts -H "Authorization: Bearer $WALLFACER_TOKEN".
  • A Wallfacer environment ID for the repository. Tasks use this environment to boot sessions from the prepared snapshot.

Get Your Credentials

You need three values: an API token, your account ID, and an environment ID. Here's where to find each.

API token

Create one in the Wallfacer app. The same flow works on mobile and on the web at app.wallfacer.ai:

  1. Open Settings > API Tokens.
  2. Click Create token. Give it a descriptive name (e.g. github-actions) and grant it a scope that can create tasks, such as tasks:write. Leave the expiration empty for a long-lived automation token, or pick a date if you rotate.
  3. Copy the token value immediately. It's displayed once and never shown again. Treat it like a password.

If you prefer curl over the UI, any existing token with sufficient scope can be used directly.

Account ID

Two ways to grab it:

  • From the API. Lists every account your token can reach:
    curl -s https://api.wallfacer.ai/v1/accounts \
      -H "Authorization: Bearer $WALLFACER_TOKEN" | jq '.data[] | {id, name}'
  • From a URL in the web app. While logged in at app.wallfacer.ai, navigate into the account you want. Every URL under it is scoped to that account, so the segment after /accounts/ in the address bar is the ID:
    https://app.wallfacer.ai/accounts/a1b2c3d4-e5f6-7890-abcd-ef1234567890/tasks
                                account ID: a1b2c3d4-e5f6-7890-abcd-ef1234567890

Environment ID

Use the environment that matches the repository where this workflow runs. Tasks restore from the environment's snapshot when starting sessions.

Same two ways:

  • From the API. Lists environments in the account:
    curl -s "https://api.wallfacer.ai/v1/accounts/$ACCOUNT_ID/environments" \
      -H "Authorization: Bearer $WALLFACER_TOKEN" | jq '.data[] | {id, name, visibility}'
  • From a URL in the web app. Open the environment in the app. The path ends in /environments/<environmentId>:
    https://app.wallfacer.ai/accounts/a1b2c3d4-.../environments/7f6e5d4c-3b2a-1f0e-9d8c-7b6a5f4e3d2c
                                                  environment ID: 7f6e5d4c-3b2a-1f0e-9d8c-7b6a5f4e3d2c

Store Them in GitHub

In your repository (or organization), go to Settings > Secrets and variables > Actions and add:

  • Secret WALLFACER_TOKEN: your API token. This is sensitive; a secret hides it from logs.
  • Variable WALLFACER_ACCOUNT_ID: your account UUID. Not sensitive; a variable lets it appear in logs for easier debugging.
  • Variable WALLFACER_ENVIRONMENT_ID: the environment UUID.

The Workflow

Save as .github/workflows/wallfacer-task.yml in the repository where you want this to run:

name: Start Wallfacer Task

on:
  issues:
    types: [labeled]

jobs:
  start-task:
    # Only run when the trigger label is present.
    if: contains(github.event.issue.labels.*.name, 'wallfacer')
    runs-on: ubuntu-latest
    steps:
      - name: Start a task from the issue
        env:
          WALLFACER_TOKEN: ${{ secrets.WALLFACER_TOKEN }}
          WALLFACER_ACCOUNT_ID: ${{ vars.WALLFACER_ACCOUNT_ID }}
          WALLFACER_ENVIRONMENT_ID: ${{ vars.WALLFACER_ENVIRONMENT_ID }}
          ISSUE_NODE_ID: ${{ github.event.issue.node_id }}
          ISSUE_URL: ${{ github.event.issue.html_url }}
          ISSUE_TITLE: ${{ github.event.issue.title }}
          ISSUE_BODY: ${{ github.event.issue.body }}
        run: |
          set -euo pipefail

          api="https://api.wallfacer.ai/v1"
          auth=(-H "Authorization: Bearer $WALLFACER_TOKEN")

          if [ -z "${WALLFACER_ENVIRONMENT_ID:-}" ]; then
            echo "::error::WALLFACER_ENVIRONMENT_ID is required."
            exit 1
          fi

          # Idempotency key is deterministic per issue so retries and
          # duplicate webhook deliveries don't create duplicate tasks.
          idem=$(printf '%s' "$ISSUE_NODE_ID" | sha256sum | cut -d' ' -f1)

          payload=$(jq -n \
            --arg title "$ISSUE_TITLE" \
            --arg url "$ISSUE_URL" \
            --arg body "$ISSUE_BODY" \
            --arg env "$WALLFACER_ENVIRONMENT_ID" \
            '{
              title: $title,
              prompt: "Resolve the attached GitHub issue.",
              environment_id: $env,
              attachments: [{
                name: $title,
                uri: $url,
                mimeType: "text/markdown",
                text: ("# " + $title + "\n\n" + $url + "\n\n" + $body)
              }]
            }')

          curl -sS -X POST "${auth[@]}" \
            -H "Content-Type: application/json" \
            -H "Idempotency-Key: $idem" \
            -d "$payload" \
            "$api/accounts/$WALLFACER_ACCOUNT_ID/tasks" \
            | jq '{id: .data.id, title: .data.title, created_by: .data.created_by, owner_user_id: .data.owner_user_id}'

How It Works

Trigger. The workflow fires on issues.labeled and the if: guard checks for the trigger label, so the task starts as soon as the label is applied.

Create task. POST /v1/accounts/{account}/tasks with a prompt and an attachment. The attachment gives the agent an inline issue pointer and preserves the GitHub URL as the source reference. The prompt kicks off a session immediately. You do not pass created_by: the task runs as the account's connected agent by default. The token's user is recorded as the task owner.

Idempotency. The Idempotency-Key header is a SHA-256 of the issue's node ID. GitHub sometimes delivers webhooks more than once, and re-labeling can fire the event again. The idempotency key collapses those retries into a single task.

Variations

Different trigger label

Change the if: expression:

if: contains(github.event.issue.labels.*.name, 'needs-agent')

Pick an environment per label or repo

Set WALLFACER_ENVIRONMENT_ID conditionally using GitHub Actions expressions, or branch inside the script based on ${{ github.event.repository.name }}. For multi-repo automations, keep an explicit mapping from repo to environment ID.

Run as a specific agent

If your account has more than one agent and you want a specific one to run the task, add its agent user ID as created_by to the payload. It must be an enabled agent of the account. Omit created_by to use the account's connected agent.

Send a richer prompt

Replace the short prompt with something that includes the body or comments. In the sample workflow, the attachment already includes the issue title, URL, and body, so duplicating the body in the prompt is usually unnecessary.

Caveats

Tasks are account-scoped, not creator-locked. Any member of the account can list, read, and follow up on the task through the public API, regardless of which token created it. If your automation needs to post the resulting PR URL back to the issue later, do it inline in the same workflow run from the POST response, or read the task back with any account token.

The agent needs GitHub connected. The task clones, pushes, and opens pull requests as the account's agent. If the agent has no GitHub token connected, those steps have no credentials. Connect one under Agents first (see GitHub Integration).

Rate limits. Writes are capped at 60 requests per minute per token. Bulk-labeling many issues at once can approach that ceiling. If you expect high volume, batch through a queue or use multiple tokens.

What's Next