Chat SDK now supports callback URLs on buttons and modals
Mirrored from Vercel — AI for archival readability. Support the source by reading on the original site.
1 min read
You can now pause a Workflow run on a Chat SDK card and resume it when someone clicks a button. The same flow works for form submissions. Buttons and modals accept a new callbackUrl prop, and the event payload is sent to that endpoint.


To build a card like this, create a workflow webhook and pass its URL to each button's callbackUrl prop inside your <Card> component:
import { createWebhook } from "workflow";import { Card, CardText, Actions, Button } from "chat";
export async function statusReport( thread, content: { title: string; message: string },) {
"use workflow";
using hook = createWebhook<{ action: "approve" | "approve-and-send" | "deny" }>();
await thread.post(
<Card title="Status Report Communications">
<CardText>Title: {content.title}</CardText> <CardText>Message: {content.message}</CardText>
<Actions> <Button callbackUrl={hook.url} id="approve" style="primary"> Approve </Button> <Button callbackUrl={hook.url} id="approve-and-send" style="primary"> Approve & Send </Button> <Button callbackUrl={hook.url} id="deny" style="danger"> Cancel </Button> </Actions>
</Card>
);
const { action } = await hook; if (action === "approve" || action === "approve-and-send") { await sendReport(content); }
}Create an approval card to approve or deny a deployment
For the <Modal> component, the form data is in the payload. callbackUrl works for buttons on most platforms with an official adapter, and for modals on Slack and Teams.
Read the documentation or walkthrough guide to start building.
The Complete Guide to Chat SDK
Learn how Chat SDK works end-to-end: from core concepts to building your first bot to deploying it across Slack, Teams, and more.
Read the guide
Discussion (0)
Sign in to join the discussion. Free account, 30 seconds — email code or GitHub.
Sign in →No comments yet. Sign in and be the first to say something.