Skip to main content
All posts
Agents2 min read

Question Results Over Outgoing Webhooks

How Question outcomes can flow back to external systems using PingRoom's outgoing webhook pattern.

Editorial illustration for Question Results Over Outgoing Webhooks

Long polling is useful when an agent is actively waiting.

Outgoing webhooks are useful when a system wants to react later, asynchronously, or from a different worker. The Question protocol should support both. A human answer is an event, and many integrations need that event delivered back to the system that asked.

PingRoom already has outgoing webhooks per room with event filtering and HMAC-signed delivery. Question results should fit that pattern instead of inventing a new callback system.

Event Types

Question lifecycle events should be explicit:

question.answered
question.expired
question.cancelled

Those names preserve the distinction between a negative human answer and no answer. A denial is still question.answered; the chosen option carries the negative value. Expiry is separate.

Answered Payload

An answered event can look like this:

{
  "event": "question.answered",
  "room": {
    "id": "room_123",
    "invite_code": "ABCD12",
    "name": "Deploys"
  },
  "question": {
    "id": "q_123",
    "prompt": "Deploy production now?",
    "state": "answered",
    "correlation_id": "deploy-abc123",
    "reply_to": "workflow:release",
    "data": {
      "commit": "abc123",
      "environment": "production"
    }
  },
  "answer": {
    "value": "approve",
    "label": "Approve",
    "responder": {
      "id": "user_123",
      "display_name": "Mahdi"
    },
    "answered_at": "2026-06-23T12:44:10Z"
  }
}

The receiver should be able to route by event, match by correlation_id, and continue the workflow using answer.value.

Expired Payload

An expired event should have the same envelope but no answer:

{
  "event": "question.expired",
  "question": {
    "id": "q_123",
    "state": "expired",
    "correlation_id": "deploy-abc123"
  },
  "answer": null,
  "reason": "deadline_passed"
}

That lets an external system handle timeout policies cleanly.

Room Event Filters

PingRoom outgoing webhooks already support event filters.

Question events should participate in that same filter. A room owner may want all events, only Pings, only question resolutions, or only specific automation events. Keeping this in the room's outgoing webhook configuration avoids a new integration surface.

Signing And Retries

Outgoing Question events should use the same HMAC signing model as other outgoing webhook deliveries.

The receiver should verify the signature, process idempotently, and return a 2xx response after durable handling. The event should include a stable question id so retries do not create duplicate downstream actions.

Question results are especially sensitive because they may approve real work. A webhook consumer should never treat an unsigned request as authoritative.

Long Polling Plus Webhooks

These two mechanisms are complementary.

Use long polling when the agent process is actively blocked:

ask -> wait -> continue

Use outgoing webhooks when the workflow is event-driven:

ask -> store question id -> receive webhook later -> continue

For critical workflows, use both. Wait for a fast response, but also accept the signed webhook as a recovery path if the agent process restarts.

The Product Rule

Question results should leave PingRoom the same way other room events do: through the existing outgoing webhook system, with clear event names, signed delivery, event filtering, and structured payloads.

That keeps the protocol powerful without making the platform sprawl.

Mahdi Salmanzade

The Ping that cuts through.

Keep reading

Product

Share a Point, Not a Trail

A custom Ping or Question can now carry one deliberately chosen place, with a quiet feed preview, a useful map sheet, and no background location trail.

3 min read
Product

Urgent Is Not Confirmation

Urgent now controls time-sensitive delivery; confirmation asks for a recorded human response. Either can stand alone, and a Ping can carry both when the moment needs both.

3 min read