How-To Do This
How to build Support Tickets
Turn selected inbound email addresses into durable support-ticket queues inside Universal Inbox.
Support Tickets is a technical support ticketing pattern. This guide turns the product concept into a buildable first release using BuildWithHQ records, pages, workflows, permissions, integrations, AI, and exact-version packaging.
Define the outcome before the screens
Let an account owner enable ticketing on a selected email address, give each new conversation a stable human-readable ticket number, and move the request through assignment and explicit resolution states without creating a second message or permission system.
Treat every name in this blueprint as a starting point. Use the language of the industry you are serving, but preserve clear ownership, status, permission, and audit boundaries.
1. Create the smallest useful data model
In the Developer Console, create or select the SaaS app and model these as application record types and relationships. The page editor composes React components and validated data bindings, which call the platform APIs for these records.
| Record type | What it holds |
|---|---|
| Email channel | The existing inbound ChannelConnection plus the Ticketing switch, short prefix, and next-number allocator. |
| Conversation | The canonical email thread and message history; replies remain on the same source conversation. |
| Inbox ticket | The attention record, stable mailbox-scoped key, assignee, priority, SLA, resolution state, and ActivityVersion. |
| Customer context | The permitted Contact, company, subscription, product, or service records related to the conversation. |
| Resolution evidence | Notes, files, approvals, sent messages, status changes, and correlation/audit history. |
| Knowledge evidence | Permission-aware articles, manuals, policies, and prior records used to prepare an answer. |
Relationship rule: Keep Conversations and Messages canonical. Universal Inbox contributes ticket identity, attention, routing, ownership, SLA, and resolution state, while related customer and product records remain in their native modules.
2. Build the working screens
Start with task-oriented pages instead of a page for every table. The first navigation should contain:
- Support-ticket queue with owner, priority, SLA, channel, and resolution filters.
- Ticket conversation workspace with message history and related customer context.
- Account-owner email settings with a per-address Ticketing checkbox and prefix.
- Knowledge/evidence viewer for grounded support research.
- Resolution, reopen, escalation, and service-level reporting views.
Use Puck for the normal visual experience. Keep stable block identity when using Monaco advanced JSON mode so future template upgrades can merge safely.
3. Set access before adding automation
- Allow only an active tenant account owner to configure mailbox ticketing.
- Derive tenant, SaaS application, user, DataRole, and Location scope from verified server identity.
- Authorize the source Conversation and related records on every read; a ticket number grants no access.
- Require action-specific permission and configured approval for customer-facing or material operations.
User Type menus establish eligible page routes for each audience. They do not grant the records or actions on those pages. The server derives the account, SaaS app, user, DataRole, and location scope from the verified identity on every data request.
4. Add the core workflows
- Ticket-enabled inbound email -> canonical Conversation -> atomically allocated ticket key -> Inbox attention.
- Reply on the same thread -> retain ticket key -> increment ActivityVersion -> invalidate stale preparation.
- Assignment or response -> New/Open/Waiting Customer/Waiting Internal/Snoozed state.
- Resolved or Closed ticket receives a new reply -> reopen and return to attention.
- SLA threshold or exception -> escalate through the same Inbox ownership and audit path.
Make each mutation a narrow, reviewed action with explicit inputs, allowed states, correlation evidence, and an idempotent retry policy where retries are possible. Pages, integrations, and agents all reach the same application service and stored-procedure contract through supported APIs.
5. Connect channels and outside systems
- Use the existing inbound-email connector and delivery worker; do not expose provider credentials to the browser.
- Use Contacts, subscriptions, products, files, and custom records as related context rather than copying them into ticket tables.
- Use Knowledge Core and secured vector retrieval for evidence-backed suggestions.
- Use GoClaw suggestion and action contracts when AI prepares or executes governed work.
Use managed connections, OAuth connectors, inbound endpoints, and webhooks. Put specialized SDKs or private processing behind a declared appliance endpoint; never expose provider credentials to a page.
6. Add AI as a governed layer
AI may classify, summarize, research permitted evidence, and draft a reply. It must apply CanAiReadRecords, tenant, DataRole, and Location security before context assembly, preserve the ActivityVersion stale-context fence, and never send or mutate material state outside the configured approval policy.
- Load the current ticket and only currently permitted related records.
- Retrieve source-cited knowledge through the secured AI/vector path.
- Bind every draft or proposed action to the current Inbox ActivityVersion.
- Route customer-facing or material actions through the canonical suggestion, approval, and execution contracts.
AI and retrieval must apply CanAiReadRecords, tenant, DataRole, field, and location security before context is assembled. Planning and research remain read-only. Customer-facing or material changes use an action suggestion and the configured policy or human approval before execution.
7. Ship one complete vertical slice
Recommended first release: Enable Ticketing for one support email address, receive a new thread, allocate one stable key, assign and reply to it, resolve it, then prove a later reply reopens the same ticket without changing its number.
- Create the minimum record types and seed representative, non-production data.
- Build the primary list/queue and one complete detail page.
- Implement one state-changing workflow and its denial/error states.
- Add the narrowest useful integration or inbound channel.
- Add one permission-aware AI read or suggestion only if it improves that workflow.
- Test as an owner, a normal operator, a restricted user, and an unauthorized user.
8. Validate, package, and operate
- Prove a non-owner cannot read or change mailbox ticketing configuration.
- Send concurrent first messages and prove ticket numbers are unique and monotonically allocated per mailbox.
- Retry ingestion and prove the same Conversation keeps one ticket key.
- Resolve a ticket, receive a reply, and prove it reopens with a higher ActivityVersion.
- Disable Ticketing and prove existing tickets retain identity while new conversations remain ordinary Inbox items.
Publish a reviewed exact version as a template when the pattern is reusable. If you sell it, complete the marketplace preparation checks. Template installs are version snapshots; upstream edits must never silently mutate a tenant copy.
Built-in data path: React components and data bindings call authenticated APIs; typed application services execute reviewed stored procedures and return bounded results with audit and correlation evidence.
Enable ticketing only on addresses that represent a support promise. Keep general mailboxes conversational so the team's Inbox stays useful instead of turning every email into a case.