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, and so does a web form on your own site. 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, through Amazon SES
  • Web form to ticket
  • Spam, bounces and auto-replies dropped
  • Also by CSV import, 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, your replies, the internal notes and the attachments. A public reply goes to the customer as an email in the same thread. An internal note stays internal: it does not reach the customer and it does not reopen a closed ticket.

  • Replies emailed, threaded
  • Internal notes kept internal
  • 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, a form, a portal, and no chat

The desk is real and the clocks are real. What is missing is a live channel, and any mail provider other than Amazon SES on the way in.

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.

Inbound email is Amazon SES only

Mail reaches the CRM through an Amazon SES receipt rule. There is no IMAP polling and no Gmail or Microsoft 365 connection, so a support address on either of those has to forward to an SES address first. Outbound replies need SES inbound too if you want the customer's answer to come back by email; without it the email asks them to reply in the portal.

There is no chat widget

A web form can open a ticket, but nothing live drops onto your website. There is no chat, no messenger bubble and no WhatsApp or social channel.

Escalation stays inside the CRM

Webhooks can tell another system when a ticket is created, updated or gets a public reply. An escalation is not one of those events, and there is no PagerDuty or Opsgenie integration, so escalation re-assigns and notifies inside the app.

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

Your reply lands in their inbox

A public reply is emailed to the contacts on the ticket with the reply text in it, threaded the way a mail client expects, and tagged with the ticket number in the subject. When they answer from their inbox, the answer comes back onto the same ticket.

  • The reply itself, not just a notice
  • Message-ID, In-Reply-To, References
  • Ticket tag in the subject
  • Answers thread back in

A form on your site can open a ticket

Build a web form in Settings, set it to create tickets, and paste it onto your support page. The sender is matched to a contact by email, or one is created, and the ticket is routed and put on the SLA clock exactly as an emailed one would be.

  • Priority and type set by you, not the visitor
  • Contact matched or created
  • Routing rules apply
  • Same spam controls as lead forms

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

A help center anyone can read

Turn it on in Settings and your approved, published articles appear at /help-center/your-name on your own CRM domain, with no sign-in. Readers can search it, each article links related ones, and a sitemap lists every article so search engines can find them.

  • Off until an admin turns it on
  • Approved and published articles only
  • Search and related articles
  • Its own sitemap for search engines

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: an escalation is not a webhook event and there is no paging integration, so nothing wakes anyone up in another tool on its own.

Can people find our answers without signing in?

Yes, if you want them to. The public help center is off by default; an admin turns it on and picks the address it lives at. From then on every article that is both approved and published is readable by anyone at that address, searchable there, and listed in a sitemap for search engines. Drafts and unapproved articles never appear. Signed-in customers still get the same articles inside the portal, and the new-request form still suggests them as they type.

Can our support address be a Gmail or Microsoft 365 mailbox?

Not directly. Inbound mail is received through Amazon SES, and that is the only provider built. A Gmail or Microsoft 365 address can forward to your SES address, and replies still go out from the CRM as threaded email that the customer can answer.

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