ChatGPT App
ChatGPT App widgets
InterviewRoom, UpgradeCheckout, and QueueStatus — what each widget does, when it mounts, and how the user interacts with it.
Last updated
Three widgets ship with the ChatGPT App. Each binds to one tool result and renders inline in the chat surface. Here's what each does and when it mounts.
InterviewRoomWidget
Mounts when: jobbydev_interview_room_url returns successfully with a Daily.co URL.
What it does:embeds the Daily.co video iframe in the message bubble, handles mic / camera permissions, and shows a live network-quality indicator. The user's side of the interview happens entirely inside ChatGPT.
Includes a fallback path for when the OpenAI Apps SDK CSP review forbids the Daily.co iframe — in that case the widget downgrades to a clickable "Open interview room" button that opens Jobby.dev in a new tab.
UpgradeCheckoutWidget
Mounts when: jobbydev_create_upgrade_checkout is called with mode: "embedded" and returns a client_secret.
What it does: mounts Stripe Embedded Checkout with the session client_secret. Card entry, 3DS challenge, and success / failure all happen inline.
Hosted-mode checkouts (the default) don't mount a widget — the recruiter clicks through to a Stripe-hosted page in their browser. Pass mode: "embedded" explicitly when you want the inline experience.
QueueStatusWidget
Mounts when: jobbydev_queue_status returns with the user actively in a queue.
What it does:shows the user's position, estimated wait, and live event details. Refreshes every ~10 seconds via polling until the queue position changes to matched, at which point the QueueStatus widget unmounts and the InterviewRoom widget takes over.
Polling is conservative because every poll is a billable MCP tool invocation. Once SSE notifications ship (P1 follow-up), the widget switches to push-driven and the polling fallback can be removed.
Widget content types
OpenAI Apps SDK uses tool-result content types to dispatch to the right widget. The full mapping:
application/json+jobbydev_interview_room→ InterviewRoomapplication/json+jobbydev_upgrade_checkout→ UpgradeCheckoutapplication/json+jobbydev_queue_status→ QueueStatus
If a tool result carries a different content type (or no content type), the App falls back to the default JSON renderer in ChatGPT.
Theming
Widgets respect ChatGPT's light / dark theme via CSS variables. Custom Jobby.dev branding (amber accent, monospace terminal-feel typography) layers on top in dark theme; widgets inherit ChatGPT's defaults in light theme to feel native.
Accessibility
Every interactive control is keyboard-navigable; the iframe embeds (Daily.co, Stripe Embedded Checkout) handle their own accessibility. The widget shells emit ARIA labels for screen readers describing the state transitions (queue → matched → interview).