GoRunner docs
Search or askSearch⌘K

Notifications

Your server hears what happens in your customers’ accounts, from a failed run to a new connection, as signed requests.

Embed · Self-hosted with an Embed license

Use them to email a customer, open a ticket, or count finished runs as they happen. This is everything your server can hear about your customers. Inside your page, the SDK’s events say what happens in the open embed. Event streaming isn’t for customer accounts.

Add a destination

  1. Open Platform › Notifications and press Add a destination….
  2. Enter the Address your server listens on, starting with https://, and a Description.
  3. Under Events to send, tick what it should hear. None is ticked for you.
  4. Press Add the destination and enter your two-factor code.
  5. Press Copy the signing secret. You won’t see it again. The dialog also shows code that checks each request.
Platform › Notifications: a destination that hears 3 events, its last 24 hours, and the Deliveries log below.

Each row says what it hears and how its last 24 hours went, with Send a test. Its menu has Change…, Rotate secret…, Replay failed since…, Turn off and Delete…. An installation has up to 20 destinations.

What if my server is on a private network?

A destination must be a public address. One on the installation’s own machine or private network works only when its operator allows it with OUTBOUND_ALLOW_PRIVATE.

The events

run.failed
A production run of a customer’s workflow failed. A sub-flow’s failure is part of the run that called it.
run.completed
A production run worked. Marked High volume: there can be many a day.
approval.waiting
A run is waiting for someone to approve or reject.
workflow.created
Made new, copied, imported, from a template, by the assistant or by your server.
workflow.changed
Saved, a version brought back, or its variables, tags or folder changed. At most one every 5 minutes for each workflow.
workflow.published
Switched on, or a new version published.
workflow.unpublished
Switched off.
workflow.deleted
Gone from the customer’s account.
connection.created
Added, by a person or your server.
connection.changed
Renamed, or signed in again.
connection.removed
Removed.
connection.expired
The service stopped accepting it. It needs signing in again.

A destination hears only what happens after it was added, and only in your customers’ accounts. Nothing new is noticed in an account while it is suspended or deleted. While the license lacks Embed, nothing is sent; deliveries still within 36 hours go out when it returns.

Do I get new event types after an update?

No. An update never ticks an event for you. All but run.failed, approval.waiting and connection.expired arrived in v2026.10.4. The dialog marks the newer ones New; tick each on the destinations that should hear it. A destination hears it from then on, never what happened before.

The request

A POST with a JSON body in the Standard Webhooks shape. No header carries GoRunner’s name.

json
{
  "id": "6f1c2a90-4b1e-4c55-9b7e-2e0d61f0a2c4",
  "type": "connection.expired",
  "timestamp": "2026-10-01T10:12:40Z",
  "data": {
    "test": false,
    "account": { "id": "acct-bakery", "name": "Bakery Ltd" },
    "workspace": { "id": null },
    "user": { "id": "ada-123" },
    "connection": {
      "id": "c0d1e2f3-0000-4000-8000-000000000001",
      "name": "Invoices sheet",
      "piece": { "id": "googlesheets", "name": "Google Sheets" },
      "managed": false,
      "externalId": null,
      "expiredAt": "2026-10-01T10:12:40Z"
    },
    "route": "/connections?connection=c0d1e2f3-0000-4000-8000-000000000001"
  }
}
What each event carries
Every event
account and user carry your ids. workspace is null for the default one, and user is null when your server or your staff did it. test is true only on a sample. route is the page to open: pass { path: route } to mount() or navigate().
run.failed, run.completed
workflow and run: id, status, trigger, startedAt, firstStartedAt, finishedAt, durationMs. status is worked on run.completed. startedAt is when the run was accepted, firstStartedAt when a worker first started it (null on a run from v2026.10.5 or earlier), and durationMs counts from it. A failed run adds error: message, cut at 2,000 bytes, and step.
approval.waiting
workflow, run and approval: step, title, message, expiresAt, the title and message cut at 1,000 bytes. It never carries the Approve and Reject links.
workflow.*
workflow: id, name, status (draft, live or paused; null once deleted), updatedAt, version. workflow.changed adds changes (saved, version_restored, variables, tags, folder), names the last person who made one, and arrives 30 seconds to 5½ minutes after the change.
connection.*
connection: id, name, piece, and managed and externalId for one your server manages.
Who and when
The workflow.* events, and connection.created, .changed and .removed, carry by: { kind, user } (person, partner, assistant, staff, token or system) and occurredAt.

An event never carries a workflow’s definition or a credential, but it does carry your customers’ names.

Check a request is genuine

Each request has three headers: webhook-id, the same on every try; webhook-timestamp, in Unix seconds; and webhook-signature, v1, then an HMAC-SHA256 of id.timestamp.body with your signing secret (whsec_…).

js
import { Webhook } from "standardwebhooks"

const wh = new Webhook(process.env.GORUNNER_SIGNING_SECRET)
// Throws if the signature is wrong, or the timestamp is
// more than 5 minutes from your clock. rawBody: the body
// exactly as it arrived, before any parsing.
const event = wh.verify(rawBody, {
  "webhook-id": req.headers["webhook-id"],
  "webhook-timestamp": req.headers["webhook-timestamp"],
  "webhook-signature": req.headers["webhook-signature"],
})

Rotate secret… gives a new secret, and the old one keeps working for 24 hours. Meanwhile each request carries both signatures, so a checker with either secret passes.

Delivery and retries

First try
Within about 15 seconds of the event.
Delivered
Any answer from 200 to 299, within 15 seconds.
Retried
Anything else, a redirect included, 7 more times over about 28 hours: after 5 seconds, 5 minutes, 30 minutes, 2 hours, 5 hours, 10 hours and 10 hours. Then it is Failed.
410 Gone
Turns the destination off at once. Nothing is sent to it, not even a test, until you turn it on. What failed meanwhile isn’t resent.
Order
Not guaranteed. Skip an event whose webhook-id you already handled, and drop one older than what you have, by occurredAt or workflow.updatedAt.

Deliveries keeps every delivery for 30 days, with each try and the first 512 bytes of its answer. Open one to see what was sent, and press Replay to send it again. Replay failed since… resends up to 1,000, never one already sent again. Deleting an account deletes its deliveries. Staff read a customer’s full audit trail on Platform › Audit log. A replay keeps the original webhook-id, so your server can tell it already did the work.

Checked against 12d85b3b