A ticket (ticket) has a number (data.name, 8 letters and digits), a reporter (reportedBy name, reportedByEmail), a title and description, a priority (low, medium, high, urgent) and a status: new, open, inprogress, pending, blocked, done, canceled. Every ticket, however it is raised, emails its reporter that it was received. Tickets are always made and changed through the ticket service, never as a plain record.
Ask first
- Where do customers raise tickets? The website's support page, their account page, by email, or staff on the phone.
- Which mailbox should replies go to? One the business reads, e.g.
support@…. - Who works tickets? The staff (by email). Who gets told about urgent ones.
- Kinds of ticket? E.g. Billing, Technical. These are ticket types with their own fields.
- The words of the received / updated emails, if the defaults won't do.
Steps
1. Email Accounts: the reply mailbox
Ticket emails go out with Reply-To set to the business's inbound mailbox, and each one carries a line with [ticket id: <sk>]. When the customer replies, the mail sync files the reply on that ticket (it also matches #<number> in the subject). A reply to a ticket that is done reopens it (status open, with the comment "Reopened: customer replied").
The inbound mailbox is a mailbox connected under Integrations (/integration-config: IMAP or Microsoft) with incoming sync on. With none, ticket emails have no Reply-To, and replies go nowhere the system reads.
Email never opens a new ticket. An email that matches no ticket is filed as a message, not a ticket.
Hands on: the mailbox's address.
Check: the mailbox is listed and receiving (/email-accounts, /integration-config). If there is none, say so: tickets still work, but customers' email replies won't reach them.
2. Tickets: types and the SLA workflow
Open Tickets (/tickets).
- Kinds of ticket are the ticket collection's types (
GET /crm/tickets/collectionslists them). The site's form asks the fields of the type the customer picks. - The Workflows tab (
/tickets?tab=workflows) makes theticket-supportworkflow the first time it opens: New → In progress → Waiting on customer → Resolved. A first answer is due in 4 hours and a resolution 2 days after work starts; the Owner is told when either is a day late. Moving a ticket's status moves its stage, and the other way round.
There is no queue and no auto-assign setting. Staff take tickets.
Hands on: the ticket type ids (collectionId), if any.
Check: the Tickets list opens and the Workflows tab shows ticket-support.
3. Message Templates: the ticket emails (optional)
The ticket service sends four emails:
| When | Template | To | variant |
|---|---|---|---|
| a ticket is raised (every way) | ticket-created | the reporter | created |
| its status changes | ticket-status-update | the reporter | status-update |
| it is assigned | ticket-assigned | the assignee | assigned |
| staff reply with no written body | ticket-reply | the address given | reply |
To use the business's own words, create a messagetemplate with datatype: "ticket", the same variant, deliveryType: "email", a subject and html. The business's own template is used before the default. A ticket of one type looks for a template with that type in subschema, and falls back to the default when there is none. Ticket fields are {{data.ticket.name}} (the number), {{data.ticket.title}}, {{data.ticket.status}}, {{data.ticket.priority}}.
Hands on: the template sks.
Check: open each one (/message-template?openId=<sk>); its test send goes to the person, not a customer.
4. Site pages: where customers raise and follow tickets
Turn on the site's Ticket feature: on the Active Site card's Features panel, or in the site record's data.features as { "feature": "ticket", "enabled": true, "page": "support" }. Then:
/support(or the page named) shows the ticket form. A signed-in customer's ticket is filed under their account (POST /client-data/tickets, withcollectionIdfor the type); a visitor's goes by their email (POST /crm/tickets/email/create/<email>) and keeps only the title, description, name and phone./account/ticketslists a signed-in customer's own tickets.
A customer always gets priority: "medium" and channel: "web"; they can't set them.
Stop: turning the feature on publishes a support page on the live site. Confirm with the person.
Hands on: the support page's address.
Check: open /support on the site; the form shows the ticket types.
5. Automation: alert someone about urgent tickets
Build it as in Automation when a record is added or updated, as a draft:
- trigger:
database_changewith{ datatype: "ticket", operation: "created", whereField: "data.priority", whereValue: "urgent" } - steps:
create_taskwithtitle: "Urgent ticket #{{data.name}}: {{data.title}}",description: "{{data.reportedBy}} ({{data.reportedByEmail}}): {{data.description}}",priority: "urgent",assignedTo: "<person's email>". The task belongs to the ticket and the assignee gets a notice.
Customers raise tickets as medium. Only staff, the AI or an automation (create_ticket) make urgent ones, so for customer tickets trigger on all new tickets and leave out the where.
- Status changes don't trigger automations. The status, assign, priority, escalate and bulk buttons, workflow stage moves and email reopens all save without firing
updated. "When a ticket is closed, send a survey" can't be built on the record trigger. Say so. ticket_updated,ticket_resolvedand the automation stepupdate_ticketdo nothing.ticket_createdworks (it iscreatedonticket).
Stop: show the trigger and the task, wait for yes, then call_appengine POST /automation/start/<sk>.
Hands on: the automation's sk.
Check: GET /automation/<sk>/monitor shows triggerRegistered: true.
6. Tickets: work a ticket
| Job | Call | Sends |
|---|---|---|
| raise one for a customer (phone, chat) | create_record on ticket with title, description, reportedBy, reportedByEmail, priority | ticket-created to the reporter |
| list | GET /crm/tickets/list?status=&priority=&assignTo=&search=&page= | nothing |
| take it / give it | PATCH /crm/tickets/assign/<sk> { "assignTo": "<username>" } ("" gives it back) | ticket-assigned to the assignee |
| answer the customer | POST /crm/tickets/reply/<sk> { "to": "<reportedByEmail>", "subject": "Re: #<number> <title>", "html": "<the answer>" } | that email, with the Reply-To and the ticket line |
| internal note | POST /crm/tickets/comments/<sk> { "message": "…" } | nothing; customers never see it |
| change status | PATCH /crm/tickets/status/<sk> { "status": "done", "resolution": { "summary": "…" } } (also takes closed, resolved, in_progress, reopen) | ticket-status-update to the reporter |
| raise priority | POST /crm/tickets/escalate/<sk> { "reason": "…" } | nothing |
On screen: Tickets (/tickets?openId=<sk>), Messages tab (&recordTab=messages) for the thread. Take it assigns the ticket to you and sets it inprogress.
Stop: a reply and a status change email the customer. Show the words and the address, and wait for yes.
Check: raise one test ticket with the person's own email as reporter. It arrives with its number, the task appears if it was urgent, a reply reaches them with the ticket line, and their reply by email shows on the Messages tab. Close it with done.
When it's done
Tell the person:
- where customers raise tickets (the page) and where they follow them (
/account/tickets); - the reply mailbox, or that there is none;
- which emails go out, and which templates are the business's own;
- the urgent-ticket automation and whether it is on;
- the SLA workflow's times.
Open Tickets.
What it can't do yet
- No automation on a status change. See the warning in step 5.
- Customers can't reply on the site. They reply by email; the site's track page (
/support/<number>) shows no details. - The links in the customer emails point to
/tickets/<id>on the site, which isn't a page. Tell customers to use/account/tickets. - A visitor's ticket loses its type and any extra fields (only title, description, name and phone are kept).
- No first-response time is recorded from a reply; the SLA timers come only from the workflow.
assignToholds a username, so assigning by a username that isn't an email may send the assignee no email.- Customers can delete their own tickets.
Don'ts
- Don't create or change tickets with plain record writes; use the ticket calls (or
create_recordonticket, which goes through the ticket service). - Don't save a ticket in full (
POST /crm/tickets/updatewithsk) to change one field: it emails the reporter a status update on every save. - Don't promise "we'll email you when it's fixed" unless someone will set the status to
done. - Don't build on
update_ticket,ticket_updatedorticket_resolved.