Skip to content
rev0Docs

Bring in work from GitHub, Jira or Slack

Bring in work from GitHub, Jira or Slack when the task already exists there, so an agent can pick it up without you retyping it. You end with the issue on the board in Backlog or To Do, exactly like a ticket you created, and, if you want, the board’s own events flowing back out to a webhook or Slack.

Imports are read only: the board never writes back to Jira, GitHub or Slack.

Each source turns on with its credentials, set in ~/.rev0/.env (or the environment) and read when the board starts. There is no switch in Settings.

SourceWhat it needs
JiraREV0_JIRA_URL, REV0_JIRA_EMAIL and REV0_JIRA_TOKEN (an Atlassian API token).
GitHubThe gh CLI, signed in with gh auth login. No token in the board.
SlackREV0_SLACK_TOKEN, ideally a user token (xoxp-) with the history scopes of the channels you import from, plus users:read and files:read.

Configuration lists every variable. The Sources map in the Knowledge Base shows which source is connected and which still needs setup; see Keep what agents learn.

  1. In the header, open the arrow next to Create (Create or import). On a narrower screen, open More actions instead.
  2. Under Import, pick the source:
    • JIRA: type Issue keys or a JQL query, or tick Also import issues assigned to me.
    • Slack: paste Message link(s) (in Slack, a message’s More actions > Copy link). Tick Import the entire thread to bring the replies, or Combine all links into one ticket.
    • GitHub: on By responsibility, click List my responsibilities (review requests, comments on your pull requests, mentions) and pick some; or on Individual PRs, list a repository’s open pull requests or paste links.
  3. Pick the Column: Backlog parks it, To Do queues it for an agent. It starts on the board’s default for new tickets, like the create form.
  4. Click Import.

Result: each item lands in that column on the board you are looking at, with a chip for its source and a timeline line saying where it came from. Jira comments come along as comments. Importing the same item twice does nothing.

An import in To Do is claimed by the runner like any ticket. One in Backlog waits until you drag it to To Do.

A GitHub import can land in To Do as a command ticket that prepares the item (the prep-github-item skill, which drafts the review or the reply locally and never posts). Two things decide it:

  • Import as: Command in the GitHub import, or the github_autostart setting for every GitHub import;
  • a local clone of the repository, which the ticket then runs in. Without one, the item is parked in Backlog and the import says “No local clone found”.

Neither github_autostart nor the clone mapping has a control in Settings. Write them with the board’s API and your access token:

Terminal window
curl -X PUT http://127.0.0.1:8000/config \
-H "Authorization: Bearer $REV0_AUTH_TOKEN" \
-H "Content-Type: application/json" \
-d '{"github_autostart": true, "github_repos": [{"match": "owner/repo", "path": "/abs/path/to/clone"}]}'

github_repos is the whole list, so send every mapping each time. A repository with no mapping is looked for under REV0_GITHUB_REPOS_ROOT (as <root>/<repo>, then <root>/<owner>/<repo>). REV0_GITHUB_AUTOSTART=1 sets the starting value of github_autostart instead of the call above.

Result: new GitHub items for a repository you have a clone of arrive in To Do and start.

Scheduled imports are a Loop built from the External intake template (see Run work on a schedule). Give the Loop a schedule, then point its read node at the source and its field map at that source’s items:

  • Jira issues assigned to you: read jira / assigned_to_me with with_comments on, and map {"title": "summary", "description": "description", "key": "key", "external_source": "=jira", "external_key": "key", "external_url": "url", "comments": "comments"}. Clear command so they file as plain tasks.
  • Your GitHub responsibilities (review requests, comments on your pull requests, mentions): read github / responsibilities, and map {"title": "summary", "description": "description", "key": "key", "external_source": "=github", "external_key": "key", "external_url": "url", "workdir": "local_clone"}. An item with no local clone is parked in Backlog as a plain task instead of running its command.

The Loop’s status picks the column: todo starts them, backlog leaves them for you. An item already on the board, from an earlier import or any other Loop, is never filed twice.

Result: new work shows up on the board without opening the import.

  1. Open Settings > Connections > Outbound webhooks.

  2. Tick Outbound webhooks and set Webhook URL to your https endpoint.

  3. Optionally set a Signing secret, and Retries per event (3 by default).

  4. Under Outbound webhooks: events, tick the events you want:

    EventSent whenOn by default
    ticket.createdYou or an agent create or import a ticket.Yes
    ticket.status_changedA ticket moves column, including every step of a run.No
    ticket.updatedA ticket’s title, description, priority or tags change.No
    ticket.plan_submittedA plan waits for your review.Yes
    ticket.permission_requestedAn agent asks for a tool.Yes
    ticket.mergedA branch is merged.Yes
    run.failedAn agent run fails.Yes
  5. Click Save changes.

Result: each event is POSTed to your URL as JSON:

{
"event": "ticket.plan_submitted",
"occurred_at": "2026-09-24T11:43:00Z",
"ticket_id": 42,
"board_id": 1,
"data": {
"ticket": {"id": 42, "title": "...", "status": "pending_action", "type": "task",
"mode": "spa_plan", "priority": "medium", "board_id": 1,
"parent_id": null, "branch": "agent/ticket-42", "tags": []}
}
}

data holds the event’s own fields next to that ticket summary. For ticket.created that is created_by; a ticket imported from GitHub, Jira or Slack also carries source, external_key and external_url. Re-importing an issue already on the board sends nothing. The ticket’s description and plan are never sent. Every request carries X-Kanban-Event with the event name. With a signing secret, it also carries X-Kanban-Signature: sha256=<hex>, the HMAC-SHA256 of the exact body with your secret: compute the same on your side and compare before trusting the event.

A delivery times out after 10 seconds. A timeout, a connection error and a 408, 425, 429 or 5xx answer are retried with a growing wait (up to 30 seconds); any other 4xx fails at once.

  1. Open Settings > Connections > Recent deliveries (shown while webhooks are on).

Result: the last events the board tried to send, newest first: a tick or a cross, the event, the ticket, the status code your endpoint answered (or the error), the attempts when there was more than one, and the time it took. The board keeps the last 200.

Set REV0_SLACK_WEBHOOK to a Slack incoming webhook and every new notification posts there once, as [#<id> <title>] <message>. Muted kinds and muted tickets never post. REV0_SLACK_DUE_WEBHOOK sends only Loop results that are due, to their own channel. A Loop’s Slack node posts through REV0_SLACK_WEBHOOK too. See Choose how the board notifies you.

Open GitHub pull requests instead of merging locally

Section titled “Open GitHub pull requests instead of merging locally”

On the Create form, tick Open a GitHub PR when the branch is integrated (and, if you want, Auto-merge the GitHub PR without a review). When the ticket’s repository is on github.com and gh is signed in, integrating the branch then opens a pull request instead of merging it locally. REV0_GITHUB_CREATE_PR=1 ticks it for every new ticket. See Review and merge an agent’s work.

One of REV0_JIRA_URL, REV0_JIRA_EMAIL or REV0_JIRA_TOKEN is missing. Add all three to ~/.rev0/.env and restart the board.

REV0_SLACK_TOKEN is missing. Add it to ~/.rev0/.env and restart the board.

Install the gh CLI on the board’s machine and run gh auth login.

A GitHub item meant to start by itself had no clone to run in, so it was parked in Backlog. Add a github_repos mapping or set REV0_GITHUB_REPOS_ROOT, as in Let GitHub items start by themselves, then drag the ticket to To Do.

Check Recent deliveries. An empty list means no enabled event fired yet, or Webhook URL is blank: nothing is sent until the box is ticked and a URL is set.