Skip to content
Support desk

A helpdesk that lives next to your CRM data

Mail arrives, becomes a ticket, and already knows which account it came from and what they bought. Two SLA clocks that understand your working week, and a library built from answers you have already given.

Unlimited agents, no per-seat fee. MIT licensed, self-host it anywhere.

One thread, and the clocks beside it

The customer's mail, your replies, the internal notes and every field change, in the order they happened.

  • Internal A note the customer never sees Marked internal, it stays off the correspondence and does not count as a reply. It also cannot reopen a ticket you have already closed, which a customer's own reply can.
  • Clocks First response and resolution, separately Both are set from the priority when the ticket is raised, both are counted in business hours, and both stop while the ticket sits in Pending.
  • Reopen A late reply brings it back If the customer writes again inside the window your org sets, the ticket returns to Pending and the assignee is told, instead of the message landing on something nobody is watching.
[ APP.BOTTLECRM.IO/TICKETS/:ID ]
End to end

Arrive, triage, resolve, capture

A ticket's job is not only to get closed. It is to leave the team able to answer it faster next time.

Arrive

Mail to your support address becomes a ticket. Replies thread onto the ticket they belong to instead of starting a new one, and the sender is matched to a contact you already have.

  • Email to ticket
  • Replies thread automatically
  • Spam, bounces and auto-replies dropped
  • Also by API or by hand

Triage

A routing rule picks the owner: round-robin through a group, whoever is least busy, or a named person. Priority sets both SLA clocks the moment the ticket is created.

  • Round-robin, least-busy or direct
  • Priority sets the clocks
  • Type: question, incident or problem
  • Tags and teams

Resolve

One timeline carries the customer emails, the internal notes and the attachments. An internal note stays internal: it does not reach the customer and it does not reopen a closed ticket.

  • Internal notes kept internal
  • Attachments on the thread
  • Suggested articles as you type a reply
  • Every field change audited

Capture

Promote the answer into the solutions library, where it goes through draft, reviewed and approved before anyone relies on it. Then the customer gets asked how it went.

  • Ticket to solution
  • Draft, reviewed, approved
  • Linked back to the tickets it solved
  • CSAT survey after close
Read this before you adopt

Email in, email out, and nothing else

The desk is real and the clocks are real. What is missing is every channel that is not email, and every route out to another system.

The portal reads and replies, it does not carry files

A customer can read the thread, reply to it and raise a new request. They cannot attach a file to any of that, so a screenshot still has to come by email, where it does attach to the ticket properly. This is the one thing people expect from the portal that is not there yet.

The help centre needs a sign-in

A customer who signs in to the portal can search your published articles, and the new-request form offers matching ones before they send it. None of it is reachable without signing in, though: no anonymous browsing, nothing for a search engine to index, and no article link you can put on your website. It deflects the customers you already have, not the ones looking for you.

There is no embeddable form or chat widget

Nothing here drops onto your website. Tickets arrive by email, through the API, or because someone typed them in. If you want a contact form on your site, it has to post to the API itself.

Nothing calls out to another system

No outbound webhooks, so no case.created, no case.escalated, and no bridge to PagerDuty or Opsgenie. Escalation re-assigns and notifies inside the CRM. If you need a page out to an on-call tool, you would poll the API for it.

Priority, and no separate severity

A ticket has one priority: low, normal, high or urgent. There is no second severity axis and no matrix crossing the two. Both SLA targets come from the priority alone, and you can override either on an individual ticket.

What is built

The parts that decide whether a desk works

This is the desk: what happens to one ticket. Running the whole queue is a separate story.

Boards, merges, approvals and the numbers

Two clocks, not one

Every ticket carries a first-response target and a resolution target, both set from its priority. Urgent starts at one hour to first reply and four to resolve; low starts at a day and three days.

  • First response and resolution
  • Defaults per priority
  • Override either per ticket
  • Breach flagged on the record

The clock respects your working week

SLA deadlines are counted in business hours against a calendar your org defines, so a ticket that arrives at 6pm on Friday is not already late by Monday. Close the office for a public holiday and the clocks stop.

  • Org business-hours calendar
  • Holidays included
  • 24/7 if you set no calendar
  • Applies to both clocks

Waiting on the customer stops the clock

Move a ticket to Pending and the elapsed time stops accumulating against the SLA. Move it back and it resumes. Time spent waiting on someone outside your team is not time you were slow.

  • Pause on Pending
  • Resumes on the way back
  • Paused seconds stored on the ticket
  • Handled server-side, not in the UI

Email that behaves like a mailbox

The inbound pipeline decides three things: drop it, thread it onto an existing ticket, or open a new one. Every message is recorded, including the dropped ones, so nobody has to guess what happened to an email.

  • Threading by reference and subject
  • Contact resolved or created
  • Dropped mail still recorded
  • One row per message, always

Customers can check without asking you

A customer signs in to your support portal with a six digit code you email them, and sees the requests they are named on: the status, the thread, and a box to reply in. They can raise a new one there too. Nothing they see needs an account in your CRM.

  • Sign in with an emailed code
  • Only their own requests
  • Reply, or raise a new one
  • Emailed when you reply or the status changes

What your team says to each other stays there

The portal is a narrower view of the ticket, not the same page with fields hidden. Internal notes are never loaded for it. Assignment, SLA counters, tags and your colleagues names are not in the response at all, and a reply from your side is attributed to Support rather than to whoever typed it.

  • Internal notes never sent
  • Your team appears as Support
  • One customer cannot read another
  • Per organisation, no shared login

A library that has to be approved

Solutions are written from real resolutions and move through draft, reviewed and approved before publication. Each one links back to the tickets it came from, and search covers the title and the body.

  • Promoted from a ticket
  • Draft, reviewed, approved, published
  • Linked to its tickets
  • Per-org, never shared across tenants

You find out whether it worked

Half an hour after a ticket closes, the contact gets a one-to-five rating link. If the ticket has been reopened by then the survey is skipped, because asking how it went while it is still going is worse than not asking.

  • Sent 30 minutes after close
  • One to five, one click
  • Skipped if reopened
  • Rolls up per agent
Questions

The ones that decide it

Check for yourself

The SLA rules, the inbound pipeline and the escalation task are all in the open repository.

Can customers see their own tickets?

Yes. They go to your portal, type their email address, and we send them a six digit code that signs them in for a day. From there they see the requests they are named on, read the thread, reply, and raise a new one. Two limits worth knowing: they cannot attach a file, and they see only their own requests, so a colleague at the same company does not automatically get to read a ticket they were not put on. Email still works exactly as before for anyone who prefers it, and replies thread back onto the ticket automatically.

How does the SLA clock handle nights and weekends?

Both clocks are counted in business hours against a calendar your organisation defines, including public holidays, so a ticket raised at 6pm on Friday is not eight hours late by Saturday morning. Set no calendar and the clocks run 24/7. Separately, moving a ticket to Pending pauses the clock entirely, so waiting on the customer does not count against you.

What actually happens when an SLA is about to breach?

A background task scans open tickets every five minutes. When one crosses its configured threshold, the escalation rule attached to it fires: it can re-assign to another person or team and notify inside the app. It stays inside the CRM. There is no outbound webhook and no paging integration, so nothing wakes anyone up in another tool.

How good is the solutions search?

Honest answer: it is a substring match on the title and the body, not a ranked full-text index, and an earlier version of this page named PostgreSQL full-text search that is not in use. It works well on a library of a few hundred articles and will feel blunt on several thousand. The suggester that offers articles while an agent types a reply runs on the same match.

Stop paying by the agent

Put the whole support team on it without counting seats, on your own database. Host it yourself, or let MicroPyramid run it.

MIT licensed No per-agent fee 100% data ownership