Help desk & ticketing
Nobody finds out you missed it from the customer.
Support goes wrong quietly. A ticket sits over a weekend against a clock that was counting the weekend, an owner leaves and their queue stays assigned to them, and the first anyone hears about the commitment is the email asking why nobody replied. Oneop counts working minutes, escalates before the deadline rather than after it, and tells you which promise is about to go.
And when you open the ticket, the person who wrote in is already a person: their orders, their invoices, their previous tickets and the article that answers this one are on the screen, because the help desk sits in the same system as the rest of the business.
No credit card. Free plan, 2 seats.
1
Minute at a time — the granularity the breach deadline is walked at
7
Ticket states and five priorities, validated as a closed vocabulary
5
Ways mail can arrive, all funnelling through one ingest path
0
Tickets that fire their breach automation twice
3
Context lookups beside every ticket, and none of them is a model
Five ways in. One queue at the end of them.
Support arrives however the customer feels like sending it: a reply to a mailbox you already run, a form on the site, a chat that stopped being a chat, a portal login. The part that matters is what happens next — whether all of that becomes one queue with one set of rules, or four places to remember to look.
- Every path runs the same on-create pipelineAgent, portal, inbound mail, chatbot handoff and the public form all call one function, so the SLA stamp and the ticket-created automations cannot be something only the mail path gets.
- Mail can reach you five different waysPoll an IMAP mailbox, forward to an address we host, post a webhook, or let Postmark or SendGrid deliver it parsed. All five funnel into one ingest path — there is no second implementation to drift.
- A reply threads back into the same ticketPublic replies go out from your own connected mailbox with the message id and references headers set, so the customer's client keeps the conversation together. Internal notes are never emailed.
- The same message never opens two ticketsDedup is scoped to your workspace and backed by a unique index — deliberately scoped, because the sender controls the message id.
Mail arrives
IMAP poll, forward, webhook, Postmark or SendGrid InboundOne ingest path
Sender resolved, message id checked against your workspaceTicket created
SLA deadline stamped in working minutes, created-automations runIn the queue
Owned, prioritised, on a clock that skips your weekend
What the queue actually enforces
Four mechanisms below, in the order a support lead worries about them — and in two places, the boundary of the mechanism rather than a nicer sentence about it.
Fixed point 1
A ticket's state and its owner are both closed sets
Seven states and five priorities, validated as a vocabulary rather than accepted as free text — and when an update is refused, the allowed values come back with the error, so an integration finds out what it should have sent.
What is enforced
- The vocabularySeven states, five priorities, and a helpful near-miss: "in-progress" with a hyphen is normalised rather than rejected.
- The ownerMust exist, be active, and be a member of your workspace — a valid user id belonging to somebody else's is refused, and so is a teammate who has been deactivated.
- The historyEvery change writes an audit row naming the field, what it was and what it became. That is the fifth beat of the story: the service history is what you have left when the person who handled it has moved on.
And what is not
- There is no transition graphAny state can move to any state. A closed ticket can go back to open, and nothing stops it — so if reopening needs a rule at your company, that rule is a person or an automation, not the API.
- No mergeTwo tickets about the same thing stay two tickets. §4.4 says what is genuinely enforced instead.
| Update | At a glance | Result |
|---|---|---|
| Status "in-progress", with a hyphen | A near-miss spelling | Accepted — normalised to in_progress |
| Status "waiting" | Reasonable-sounding | Refused — the seven allowed values come back |
| Owner: a user from another workspace | A valid user id | Refused — not a member here |
| Owner: a teammate who left last month | Was on your team | Refused — deactivated |
| A closed ticket moved back to open | A reopen | Accepted — there is no transition graph |
The last row is the one worth knowing before you buy. Plenty of help desks imply a state machine they do not have; this one does not have one and says so.
Fixed point 2
The deadline is walked one working minute at a time
Not "four hours from now" with a note that weekends do not count. The breach timestamp is computed by stepping forward a minute at a time from the moment the ticket was created, and each step asks three questions before it counts: is this a working day, is this a working minute, is this date on your holiday list. All three are evaluated in your workspace's own timezone rather than the server's — which is what lets a team in Dubai and a team in Toronto share one help desk and get the same promise honoured.
Escalation runs on the same footing. A sweep works out the level a ticket should be at from how long it has been open against your rules, and acts only if that is higher than the level already recorded — so it raises, and never re-raises. It hands the ticket to the deepest matched rule that names someone, records the reason, and notifies both the person who had it and the manager taking it on.
And a breach is a condition, not a drum: each breached ticket is claimed with a guarded write that only succeeds while nothing has claimed it, so the automation behind it fires once and only once. Being chased hourly is a delay step inside that automation, not the same trigger firing five times.
Escalation ladder · idempotent 5-min sweep
| Situation | Detail | What happens |
|---|---|---|
| A rule matches the priority | Exact match, active, yours | Deadline stamped in working minutes |
| Two rules match | Both active, same priority | The most recently created one wins |
| No rule matches | That priority has none | No deadline at all — none is invented |
| The deadline passes | Still unresolved | Breach automation fires once, ever |
| Priority changed later | After creation | The stamped deadline stands |
Row three is the one most systems get wrong by inventing a default. A ticket with no matching rule carries no deadline, rather than a deadline nobody agreed to.
Fixed point 3
You resolve it with the customer's record on the screen
The reason a support agent asks a customer to repeat themselves is almost never that they did not care. It is that the answer is in a different system. Because the help desk shares a database with the CRM, the order book and the ledger, three lookups run beside every ticket — and it is worth being precise that none of them is a model.
What appears beside the ticket
- Who they are, commerciallyTheir CRM contact and their finance customer, matched on the email address on the ticket — resolved when you open it rather than stored, so a contact created afterwards still connects.
- What else is open for themUp to six related open tickets: same requester first, then same company, then a shared tag, each carrying the reason it was surfaced.
- What already answers thisUp to five knowledge base articles, ranked by a weighted keyword count over the ticket's subject, description and tags — a title or tag hit outweighs a body hit.
And what it refuses to guess
- An ambiguous name is not a linkWith no email address it will match on name — but it fetches two candidates and returns nothing if both come back. Two customers called Dana Kim are never silently merged into one account.
- Nothing is fabricatedNo match returns an empty result and a one-click create, not a plausible-looking record. An article list with no keyword hits comes back empty rather than padded with the five newest.
Customer
Related open tickets
Suggested articles
Fixed point 4
One duplicate rule, enforced. The rest is a person looking.
Help desks like to talk about deduplication. Here is the whole of what is actually enforced in Oneop: a message id already seen in your workspace does not open a second ticket, and a unique index in the database makes that true even when two copies of the same mail arrive at the same moment on two different transports.
That index is scoped to your workspace on purpose. A message id is chosen by whoever sent the mail, so a single global constraint would let one sender's duplicate quietly block a completely different company's legitimate ticket — which is exactly the defect the current scoping replaced.
Everything else in this area is assistance rather than a rule, and calling it more than that would be the sort of small overstatement that makes the rest of this page harder to believe. Related tickets are surfaced for a human to judge. There is no merge. Reopening is not restricted. Where a rule would help you, build it in the automation engine, where you can see it and turn it off.
| Behaviour | Status |
|---|---|
| The same email opening two tickets | Prevented — unique index, scoped to your workspace |
| Spotting a duplicate raised by phone and by mail | Surfaced for a person, not enforced |
| Merging two tickets into one | Not a feature |
| Restricting who may reopen a closed ticket | Not enforced by the API |
Three of these four are a "no". Being told which is which now is worth more than finding out in month two.
Connected with Oneop
The customer writing in is already a customer here
Their contact record, their orders, their invoices, their shipments and their previous conversations are in the same database as the ticket — which is why the resolution screen can show you the order without an integration, and why a survey score lands back on the account rather than in a reporting tool nobody opens.
- CRMCustomer and commercial context follows the work.
- Live chatConversations become part of customer context.
- Inventory & warehouseSales and operations work from the same product and order context.
- AI chatbotAI responds using permitted business context.
- AutomationA trigger in one module can act in another without an integration between them.
The other 6 modules sit on the same record, and reach Help desk the same way:
- SequencesOutreach works from CRM and customer context under controlled automation.
- Project managementSold work becomes delivery without rebuilding customer context.
- ReportingEvery module is already a reportable dataset, so nothing has to be exported to be measured.
- FinanceOperational transactions continue into financial records.
- AI agentsAI acts on the same records people do, under limits that are published rather than described.
- AI governanceWhatever AI touches in any other module is metered on the same path first.
Beyond the four
A knowledge base the ticket screen can actually search
Articles with categories, tags and an active flag, scored against the ticket in front of you. Publishing one is what makes the next twenty tickets shorter, which is the only reason a help desk has a knowledge base at all.
Canned replies that resolve before you see them
Inserting a saved reply substitutes the customer name, company, ticket number, subject, priority and your own name against the real record first. An unknown placeholder is blanked rather than left showing braces, so what the agent reads is exactly what the customer gets.
Satisfaction that survives the survey
One invite per ticket per active trigger, ever — re-resolving does not re-ask. The link is 32 random bytes stored as a hash with a fourteen-day life; an unknown token is a 404, an expired one a 410, an answered one a 409. No customer email, or an unpublished survey, and nothing is sent.
Attachments that are not public URLs
Up to five files per comment, ten megabytes each, in private storage rather than behind a guessable link. If object storage is not configured the endpoint returns a 503 instead of quietly dropping the file.
A reply draft grounded in the thread
Genuinely AI. The model is given the subject, the customer and their company, the priority, the original message and the last eight public turns — never the internal notes — and instructed not to invent order numbers, refunds or policies it was not given. It returns a draft into your composer. It cannot send.
An auto-responder that still asks a human
Genuinely AI, and nothing happens until you switch it on. Once you do, an inbound mail produces a grounded draft that is queued as a real approval rather than sent — a mailbox can opt into auto-send, and either way the call is metered against your workspace. Risk context lives on one page, linked below, not scattered through this one.
Those last two are the only AI in the help desk. How the models are governed, metered and constrained is one page: AI governance.
The mailbox you already run, and the systems that say who wrote in
Most support teams do not want a new address. Connect the Google or Microsoft mailbox you have, poll any IMAP account, or let Postmark or SendGrid deliver mail already parsed. The last three are the ones that make the resolution screen worth opening: the store the order came from, and the CRM the account lives in.
See all integrations- Google Workspace
- Microsoft 365
- IMAP / SMTP
- Postmark
- SendGrid
- WordPress
- Shopify
- HubSpot
For the technical evaluator
The three mechanisms above that are easiest to claim and hardest to build — the working minute walk, the escalation sweep and the inbound path — in the detail you would need to check them.
How the clock, the sweep and the inbound path actually work
The clock. A breach deadline is produced by stepping forward from the ticket's creation time one minute at a time, incrementing a counter only when the minute falls on a working day, inside working hours, and not on a configured holiday. Each of those tests is applied to the cursor shifted into the workspace's own timezone offset rather than to server time. The walk carries a guard of one year's worth of minutes; if a configuration made the target unreachable — a working week with no working days, say — it stops and falls back to plain elapsed time rather than looping. Working days, hours, timezone and holidays live in the workspace's settings document, so changing them needs no migration, and a missing or malformed value falls back to Monday–Friday 09:00–17:00 instead of throwing.
Which rule applies. A rule must be active, belong to your workspace, and match the ticket's priority exactly; where several qualify the most recently created wins. The deadline itself prefers the rule's resolution target, falling back to first response and then to the escalation threshold. The stamp is written only into an empty field, which makes the whole on-create pipeline safely repeatable and also means a later priority change does not move a deadline that has already been communicated. If no rule matches, the ticket carries no deadline. Every entry point in this layer swallows its own errors by design: an SLA misconfiguration must never be able to stop a customer's ticket being created.
The sweep. Breach automation is claimed rather than triggered. The sweep issues a single conditional update that sets the fired-at stamp only while it is still null and the ticket is still yours; a run that gets zero rows back knows another run already claimed it and moves on. That is what makes a breach a one-shot condition under concurrent workers. Escalation uses the mirror-image discipline: the target level is computed from how many of your rules have elapsed, and the sweep acts only when that exceeds the level already recorded, so it raises and never re-raises. It assigns to the deepest matched rule that names a user, records the reason, and notifies both the previous assignee and the escalation manager, deduplicated when they are the same person. The scheduler runs the breach sweep and the escalation sweep on alternate passes rather than both at once.
The inbound path. Five transports — an IMAP poller, a forwarding SMTP server, a generic HTTP webhook, Postmark Inbound and SendGrid Inbound Parse — converge on one ingest function, and the feature switch is the first line of it, so a workspace with email-to-ticket off routes mail to an unrouted bucket rather than half-processing it. IMAP hosts are checked against the outbound egress guard before a socket opens, and each sync is bounded both by a message ceiling and by a stored cursor so a reconnect cannot replay a mailbox. Deduplication is a check against the message ids already seen in your workspace, backed by a unique index on the pair; that index was deliberately narrowed from a global one, because a message id is set by the sender and a global constraint let one sender's duplicate block another workspace's mail. One honest gap: a message arriving with no message id header at all is given a generated one, and so cannot be deduplicated against anything.
Scope. Tickets, comments, audit rows, SLA rules, escalation rules, knowledge base articles, canned replies, survey tokens and inbound mail records all carry the workspace they belong to, and no query crosses that boundary. Ticket identifiers exposed to a customer portal are random rather than sequential, so a URL does not disclose how many tickets you handle.
What it costs
Tickets, the shared inbox, live chat, the chatbot and the knowledge base are on every plan including Free — a help desk you cannot use until you upgrade is not a help desk. What the plan changes is how many articles you can publish, whether satisfaction surveys are collected, and whether SLA rules, escalation and the AI Copilot are available.
See full pricing| Plan | Tickets & shared inbox | Knowledge base articles | Satisfaction surveys | SLA rules & escalation | AI Copilot |
|---|---|---|---|---|---|
| Free $0 | Included | 10 | Not included | Not included | Not included |
| Starter $19 | Included | 100 | Included | Not included | Not included |
| Pro $59 | Included | 500 | Included | Included | Included |
| Business $129 | Included | 2,000 | Included | Included | Included |
Frequently asked
Does the SLA clock run overnight and at weekends?
Not unless you tell it to. A breach deadline is walked forward one working minute at a time from the moment the ticket is created — skipping days outside your working week, minutes outside your working hours, and dates on your holiday list — and every one of those tests is made against your workspace’s own timezone rather than the server’s. The default is Monday to Friday, 09:00 to 17:00, and you can change the days, the hours, the timezone and the holidays per workspace without a migration. If you would rather count raw elapsed time, that is a setting too.
What happens to a ticket whose priority has no SLA rule?
It gets no deadline. That is deliberate and worth being blunt about: a rule has to be active, belong to your workspace, and match the priority exactly, and if none does, the ticket carries no breach timestamp rather than a made-up one. Where two rules match, the most recently created wins. The deadline is stamped once, when the ticket is created, and changing the priority afterwards does not restamp it — so if you re-prioritise as policy, set the rules up before you rely on the clock.
Can a breach fire the same automation twice?
No. The sweep claims a ticket with a single guarded update that only succeeds while the fired-at column is still empty; a second tick reading the same ticket gets zero rows back and skips it. A breach is treated as a one-shot condition rather than a repeating event, which is why "chase every hour until someone answers" is built as a delay step inside the automation rather than by firing the trigger again. Escalation works the same way in the other direction: the sweep computes the level the ticket should be at and acts only if that is higher than the level already recorded, so it raises and never re-raises.
Can I merge two tickets, or stop duplicates being created?
There is no merge feature, and we would rather say so than imply one. What is genuinely enforced is inbound email dedup: a message id already seen in your workspace does not open a second ticket, backed by a unique index scoped to the workspace — deliberately scoped, because a message id is set by the sender and a global constraint would let one sender’s duplicate block another workspace’s legitimate mail. Beyond that, the ticket screen surfaces up to six likely-related open tickets from the same requester, then the same company, then a shared tag, so a person can spot the duplicate. That is a lookup, not a rule.
Which parts of this are actually AI?
Two. The reply draft, which is given the subject, customer, company, priority, original message and the last eight public turns — never your internal notes — and is instructed not to invent order numbers, refunds or policies; it writes into your composer and has no ability to send. And the auto-responder, which does nothing until you switch it on and then queues its draft as a human approval rather than sending it. Both are metered against your workspace’s AI credits. The three things that look like AI and are not: related-ticket detection is a SQL scan, article suggestions are a weighted keyword count, and the customer lookup is an exact match. Calling those AI would make the two real ones harder to believe.
How does a ticket know who the customer is?
It resolves the link when you open the ticket rather than storing one, so a contact created after the ticket arrived still connects. With an email address it matches your CRM contacts and your finance customers case-insensitively. Without one it will match on name only if exactly one record matches — it fetches two candidates and returns nothing when both come back, so two people sharing a name are never silently linked to the wrong account. When there is no match you get an empty result and a one-click create, not an invented one.
Put your support mailbox on a clock that counts working minutes.
The free plan takes a forwarded email. Or book a walkthrough and we will show you a Friday afternoon ticket landing on Monday morning, an escalation that raises exactly once, and a resolution screen with the customer's order already on it.
Free forever · 2 seats · No credit card