Skip to content
All posts
Agents5 min read

The Full Potential of the Question Protocol

One primitive, a question a human answers with a tap, covers deploy gates, environment routing, team decisions, and typed replies. Here is everything it unlocks, and how to reach it from the SDK, the CLI, and MCP.

An agent can do almost anything now. The bottleneck was never capability. It was consent.

Somewhere in every real workflow there is a step the agent should not take alone: ship to production, spend the money, pick the branch, delete the record. The agent knows what it wants to do. It just needs a human to say yes, or to choose between four options, or to type a value it can't guess.

That moment is the Question Protocol. An agent asks. A human answers with one tap from the lock screen. The answer routes back. No dashboard, no chat, no waiting on someone to notice a Slack message. The decision endpoint is already in their pocket.

This post is about the whole range of it, not the data model, not the state machine (those have their own posts), but what you can actually build.

One primitive, four shapes

A question is a prompt plus a small set of answers. That single shape stretches further than it looks.

The binary gate. Omit the options and you get Approve / Deny, two buttons, side by side, always visible on the lock screen without expanding the notification. This is the fast path, and it is most of the value. "Deploy 1.4.0 to production?" resolves in the two seconds it takes to glance at a phone.

The router. Two to four options turn a question into a switch. "Which environment?" → Production · Staging · Cancel. The agent branches on the answer instead of guessing. One primary option carries the brand strike; a destructive one goes quiet red.

The typed answer. Sometimes there is no menu; the agent needs a value only the human has. Invite a short typed reply and the answer comes back as text: a version string, a reason, a name. Still one interaction, still from the notification.

The team decision. Scope a question to the room instead of a person and anyone eligible can answer. First valid tap wins; everyone else's screen updates to show it resolved. "Who's taking the on-call handoff?" is one question to a room, not five DMs.

Four shapes, one wire contract. The agent that speaks one speaks all of them.

The answer is machine-readable, both ways

A human sees buttons. The agent sees structure.

Every question can carry a data object, a correlation_id, and a reply_to. The correlation id is echoed on every surface the answer touches, the long-poll result, the list endpoint, the outgoing webhook. So an agent that fired a hundred questions doesn't have to remember which was which; it matches the resolution back by id and keeps moving.

That is what makes this a protocol and not a UI. The human end is a tap. The machine end is a request and a response with stable field names. An agent framework, an SDK, or a CLI can all speak it without knowing anything about phones.

Three outcomes that mean three things

This is the part people skip, and it's the part that makes the protocol trustworthy.

A resolved question is answered, expired, or cancelled, and they are not interchangeable. "The human said no" is an answered question whose chosen value happens to be the negative option, a real decision. "The human never saw it" is expired, silence, not rejection. "The asker changed its mind" is cancelled. An agent that treats a timeout like a denial will do the wrong thing; an agent that treats it like an approval will do something worse. Every question has a deadline, and when it lapses the protocol says so plainly.

In your stack today

The protocol ships in the tools you already reach for.

From a shell, it's an exit code. The CLI turns a human decision into a gate you can put in a pipeline:

if [ "$(pingroom ask --token "$PINGROOM_TOKEN" --room ab12cd --wait \
      -p 'Deploy 1.4.0 to production?')" = approve ]; then
  ./deploy-prod.sh
fi

ask --wait blocks until someone taps, prints the chosen value to stdout, and encodes the outcome in the exit status, 0 answered, 3 expired, 4 cancelled. A build step now waits on a person without a webhook server or a polling script.

From code, it's a typed call. The SDK wraps ask, wait, list, and cancel:

const q = await pr.questions.ask('ab12cd', {
  prompt: 'Which environment should I deploy?',
  options: [
    { value: 'prod', label: 'Production', style: 'primary' },
    { value: 'staging', label: 'Staging' },
    { value: 'cancel', label: 'Cancel', style: 'danger' },
  ],
  responder_scope: 'room',
  ttl: 600,
});

const answered = await pr.questions.waitForAnswer(q.id);
if (answered.state === 'answered') {
  deployTo(answered.answer.value); // 'prod' | 'staging' | 'cancel'
}

From an assistant, it's a tool. Over MCP, ask_question and wait_for_answer are just capabilities your agent already has, so Claude, Cursor, or your own runtime can ask you something mid-task and wait for the tap, the same as any other tool call.

And when you don't want to hold a connection open at all, the resolution arrives as an outgoing webhook, filtered by the room's event settings, carrying the same shape as every other surface.

Approvals were the seed

If you've used PingRoom approvals, you've already used this. An approval is the two-option question, Approve / Deny, and it still works exactly as before, because it now runs on the question machinery underneath. Nothing to migrate. Reach for approvals when the answer is yes or no; reach for questions the moment you need a third option, a typed reply, or a room to decide.

Why it's built to be a standard

The field names are stable. The states are four and they are final. The options are a value and a label. The contract is versioned and additive; new capabilities never rename what exists. Two options are documented as the fast path so real questions resolve from the lock screen, not a buried notification.

None of that is accidental. A primitive only becomes infrastructure if a third party can implement against it from the spec alone and trust it not to move. The Question Protocol is written to be adopted by an SDK we didn't write, a framework we've never seen, an agent that just wants to ask a person something and get an answer back it can act on.

The full potential is small to describe and large to use: every decision an agent shouldn't make alone becomes a tap. Autonomy with a hand on the wheel. That's the whole idea.

Read the full specification, or just pingroom ask your first question.

Mahdi Salmanzade

The Ping that cuts through.

Keep reading

Product

PingRoom v1.2: Questions Are Here

Our biggest update yet. Connected agents and integrations can now ask questions in your rooms, answer from the lock screen with one tap, first response wins. Plus an interactive Watch widget, room folders, free templates, every sound free, link Pings, and more.

2 min read
Product

PingRoom v1.2: Rooms, Organized

The biggest update since launch: Organized Rooms, a first-room journey for new signups, link attachments on Pings, an interactive Watch widget, and every sound now free.

2 min read