How To

Rollbar Automation with Native Tools: Deploys, RQL, Webhooks

The native Rollbar error-response setup, built in order: deploy tracking first, then severity routing, RQL investigation queries, resolve-in-version and webhooks. It ends at the honest ceiling: rules route items, but nobody reads the stack trace for you.

9 min read
Cover Image for Rollbar Automation with Native Tools: Deploys, RQL, Webhooks

Rollbar Automation with Native Tools: Deploys, RQL, Webhooks

If you set up one piece of Rollbar automation this week, make it the deploy notification. It's five lines in your deploy script, and from then on every error carries a version. You stop asking "did the release break this?" and start reading the answer off the item page. Everything else in this guide builds on it.

Part one walked the error-triage reality: item graveyards, spikes versus new versus reactivated items, grouping gone wrong, and deploy tracking as the most underused signal in the product. This part is hands-on. You'll build a DIY error-response workflow with only Rollbar's native features: notification rules, the Deploy API, RQL, item statuses, webhooks and the Versions view. If you want the whole journey first, read the three-step CloudThinker × Rollbar overview.

Budget an afternoon and work feature by feature. The order matters, because most of these features are only as good as the version data underneath them.

01Version

Deploys

code_version on every occurrence and a deploy record from CI.

02Route

Rules

New, reactivated and spiking items go to different places.

03Ask

RQL

Saved queries for noise, deploy autopsy and blast radius.

04Close

Resolve in version

Reactivations only fire for code at or after the fix.

05Stream

Webhooks

Item events as JSON for tickets and your own scripts.

The native setup in build order. Each step depends on the one before it, and deploy tracking comes first.

Feature 1: Notification rules that route by severity, not by existence

Rollbar's default behavior, notify on every new item, is how Slack channels get muted. The fix is per-channel rules with filters, configured under Settings, Notifications, then the channel (docs).

Each channel (Slack, email, PagerDuty, webhook and others) gets its own rule set. The triggers that matter:

TriggerWhat it fires onWhere it should go
New ItemFirst occurrence of a new fingerprintTeam Slack channel
Reactivated ItemA resolved item occurs againTeam Slack channel, higher urgency
High Occurrence RateAn item exceeds N occurrences in M minutesPagerDuty or on-call
10^th OccurrenceOccurrence counts hitting powers of tenOptional; chronic-item radar
DeployA deploy is reportedDeploys channel
Every OccurrenceEvery single eventAlmost never a human channel

A routing setup that survives contact with production:

  1. New Item to #eng-errors, with filters environment equals production and level greater than or equal to error. Warnings and staging noise never page anyone.
  2. Reactivated Item to the same channel, with no level filter. A reactivation means a fix didn't hold, which is always worth a person's look (the argument from part one).
  3. High Occurrence Rate to PagerDuty, with a threshold in the spirit of "50 occurrences in 5 minutes" for a mid-market service. This is your "the release is on fire" wire.
  4. Every Occurrence to nowhere, unless it feeds a machine (see webhooks below).

Filters can also match on item title, filename and framework. That's useful for sending payment-path errors to the team that owns payments instead of a shared channel everyone has learned to ignore.

Feature 2: Deploy tracking, the five lines that pay for themselves

Deploy tracking does two jobs. It timestamps releases on every graph, and it lets Rollbar attribute occurrences to a code_version so you can see which release introduced an error (docs).

Step one: make your SDK report the version. In server SDKs this is one line of config. In Node:

const Rollbar = require('rollbar');
const rollbar = new Rollbar({
  accessToken: process.env.ROLLBAR_TOKEN,
  environment: 'production',
  code_version: process.env.GIT_SHA, // the line that makes deploys correlatable
});

Step two: report the deploy itself from CI, using a post_server_item project access token. With curl (API reference):

curl https://api.rollbar.com/api/1/deploy \
  -H "X-Rollbar-Access-Token: $ROLLBAR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "environment": "production",
    "revision": "'"$(git rev-parse HEAD)"'",
    "rollbar_username": "deploy-bot",
    "local_username": "'"$(whoami)"'",
    "comment": "release '"$(git describe --tags --always)"'",
    "status": "started"
  }'

The response includes a deploy_id. For long deploys, PATCH it when you finish, so the timeline shows real deploy windows instead of instants:

curl -X PATCH "https://api.rollbar.com/api/1/deploy/$DEPLOY_ID" \
  -H "X-Rollbar-Access-Token: $ROLLBAR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"status": "succeeded"}'

If your pipeline is Node-based, rollbar-cli wraps the same call (and handles source map uploads for browser projects):

npx rollbar-cli notify-deploy \
  --access-token "$ROLLBAR_TOKEN" \
  --environment production \
  --revision "$(git rev-parse HEAD)"

Then turn on the Deploy notification trigger for a #deploys channel. When a High Occurrence Rate page lands three minutes after a deploy message, the correlation is right there in the channel history.

Make sure the SHA in the SDK config and the SHA in the deploy call are the same string. A short SHA in one place and a full SHA in the other breaks every version lookup that follows.

Feature 3: RQL, investigation queries instead of scrolling

RQL is Rollbar's SQL dialect over raw occurrence data (Dashboard, then RQL, docs). It's the difference between clicking through fifty item pages and asking one question.

The noise census: which items dominated production in the last 24 hours.

SELECT item.counter, item.title, count(*)
FROM item_occurrence
WHERE environment = 'production'
  AND timestamp >= unix_timestamp() - 86400
GROUP BY item.counter, item.title
ORDER BY count(*) DESC
LIMIT 20

The deploy autopsy: everything the release with SHA 9f2c1ab has produced. This only works because Feature 2 populates code_version.

SELECT item.counter, item.title, count(*)
FROM item_occurrence
WHERE environment = 'production'
  AND code_version = '9f2c1ab'
GROUP BY item.counter, item.title
ORDER BY count(*) DESC

The blast-radius check: is item #4211 one retry loop or a thousand unhappy users?

SELECT person.id, count(*)
FROM item_occurrence
WHERE item.counter = 4211
  AND timestamp >= unix_timestamp() - 3600
GROUP BY person.id
ORDER BY count(*) DESC

Read the result as a test of two hypotheses. A short person list with huge counts is a retry loop. A long list with a count of 1 each is an incident. The same move works for the other usual suspects: group by server.host to test "one bad host", by request.url to test "one bad endpoint", by client.javascript.browser to test "one bad browser", and by code_version to test "one bad release". Each query takes seconds, and each one rules a reading in or out. Save the ones you reuse; RQL supports saved queries per project.

Feature 4: Item statuses that make "resolved" mean something

Items are active, resolved, muted or archived. The status workflow only pays off when combined with deploy tracking: resolve an item in a version (docs). On the item page, use the status dropdown's Resolve, in version option and enter the fixing SHA. From then on, occurrences from older versions (stragglers, hosts that haven't upgraded) won't reactivate the item. Only an occurrence from a version at or after the fix does. Without this, reactivation alerts cry wolf and get muted. With it, a reactivation really means "the fix didn't fix it."

You can drive the same workflow from CI, resolving the items your release notes claim to fix:

# Item IDs differ from the visible counter, so translate first
curl -s "https://api.rollbar.com/api/1/item_by_counter/4211" \
  -H "X-Rollbar-Access-Token: $ROLLBAR_READ_TOKEN"

# Then resolve with a write-scope token
curl -X PATCH "https://api.rollbar.com/api/1/item/$ITEM_ID" \
  -H "X-Rollbar-Access-Token: $ROLLBAR_WRITE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"status": "resolved", "resolved_in_version": "9f2c1ab"}'

Two habits complete the loop. Use mute (not resolve) for known-noisy items you've decided not to fix, so they stay queryable without alerting. And assign an owner to anything left active. An unowned active item is part one's graveyard forming in real time.

Feature 5: Webhooks, occurrence data as an event stream

The webhook channel (Settings, Notifications, Webhook, docs) POSTs JSON to your endpoint for the same triggers as any channel. That makes the machine-facing triggers you'd never route to Slack useful. A new_item payload looks like this:

{
  "event_name": "new_item",
  "data": {
    "item": {
      "id": 987654321,
      "counter": 4212,
      "environment": "production",
      "level": 40,
      "title": "TypeError: Cannot read properties of undefined",
      "total_occurrences": 1,
      "last_occurrence": {
        "code_version": "9f2c1ab",
        "request": { "url": "https://api.example.com/v2/checkout" }
      }
    }
  }
}

Other event_name values include reactivated_item, item_velocity (High Occurrence Rate), exp_repeat_item and deploy. Typical DIY builds on top: auto-create a Jira ticket for every production new_item at error level, post item_velocity events into an incident-management flow, or cross-reference the code_version in the payload against your deploy log and comment the suspect diff link into the ticket. That last one is the closest DIY gets to automated investigation, and it's a script you now own, patch and debug forever.

A minimal receiver that does the cross-reference looks like this. It's the shape most teams end up with:

# deploy_log and jira are your own clients; REPO_URL is your repository's web URL
@app.post("/rollbar")
def rollbar_hook(event: dict):
    if event["event_name"] not in ("new_item", "reactivated_item"):
        return
    item = event["data"]["item"]
    sha = item["last_occurrence"].get("code_version")
    prev = deploy_log.previous(sha)  # your CI's deploy history
    diff_url = f"{REPO_URL}/compare/{prev}...{sha}" if prev else None
    jira.create_issue(
        summary=f"[{item['environment']}] {item['title']}",
        description=f"Rollbar #{item['counter']}\nDiff: {diff_url}",
    )

Notice what it can't do. It can link the diff, but it can't read it, and it can't tell whether the error is in that diff at all.

Feature 6: The Versions view, regression review in one screen

Versions in the project nav shows each code_version with its deploy metadata, new items, reactivated items and occurrence trend (docs). It's the release-health review nobody schedules. After each deploy, one glance answers "did this version introduce anything new, and did it bring back anything old?" Two or more reactivated items on a fresh version is the classic bad-merge signature, so check it before the next deploy buries the evidence. The view runs entirely on Features 2 and 4. Without code_version and resolve-in-version it stays empty.


The ceiling: rules route items, nobody reads the stack trace for you

Run this whole setup and you'll have something much better than the defaults: severity-routed alerts, version-stamped errors, saved investigation queries, honest reactivations and a webhook stream feeding your ticketing. You should build it. You should also see its ceiling clearly.

01Rules

Route, not reason

A perfectly filtered alert still arrives as a title and a link.

02Correlation

Still by hand

Trace, diff and deploy log get joined by a person, mid-incident.

03Thresholds

Drift

Rates tuned for today are wrong after the next traffic doubling.

04Scripts

Become a product

The ticket bot and diff commenter need an owner forever.

What the native setup can't do. The teal cell is the one that costs the most engineer-hours.

Rules route; they don't reason. A perfectly filtered New Item alert still lands as a title and a link. Deciding whether it's a retry loop or an incident takes the RQL pass above, done by a person, every time.

Correlation is manual at the exact moment it's needed. The deploy timestamp and the error spike sit on the same graph, but reading the stack trace, opening the deploy diff and connecting a frame to a changed line takes 20 to 40 minutes of engineer attention per incident, usually at the worst possible time.

Thresholds drift. The occurrence-rate numbers you pick today are wrong after the next traffic doubling, and re-tuning them is a chore that reliably loses to feature work.

The webhook scripts become a product. The Jira integration and the diff-commenting bot need someone to maintain them, and that someone is you.

The underlying reason is the same in all four. Every native feature is deterministic: it does the same thing for every item that matches a filter. Investigation isn't deterministic. The next question depends on what the last query returned. The setup detects and routes; investigation and response still run on engineer-hours.

What comes next

Everything after the alert can be delegated: reading the trace, correlating the deploy, naming the likely cause, proposing the fix or rollback. CloudThinker connects to Rollbar read-only, watches new and reactivated items and occurrence spikes, and investigates them with the same evidence you'd use. It acts within Auto Mode, so you decide what runs on its own and what waits for approval, and escalation stays intact. That's part three of this series. To see a single item carried from triage to a merged, verified fix, read the Rollbar full-lifecycle deep dive.

Or see it on your own project first: Try CloudThinker free with 100 premium credits and no card required.

rollbarobservabilityerrortrackingerrortriagedeploytrackingautomation