How to

How to build an internal helpdesk

Requests arrive by Slack DM, hallway and email, and the person who answers them is whoever was asked. Here is the model behind a helpdesk, the prompts to build it, and what it takes to run it.

The short answer

An internal helpdesk is four parts: one front door with a form per request type, routing based on the type rather than who was asked, a priority derived from impact and urgency instead of chosen by the requester, and a queue with a response target somebody actually owns. The part teams get wrong is the intake form. A generic "describe your problem" box guarantees the first reply is a question, and that round trip is most of the time a ticket takes.

helpdesk.helix-app.ai

Helpdesk

6

Assigned to me

11

Team, unassigned

2

Breaching today

31%

Deflected at intake

Request Type Priority Target Status
IDE-4471 Access to Looker, finance folder Access High Breaches in 2h Assigned
IDE-4468 Laptop will not wake from sleep Hardware Medium 1d 4h In progress
IDE-4465 New starter, 14 Sep, sales Onboarding Medium 3d Assigned
IDE-4462 VPN drops on the fourth floor Network High Breached, 6h Waiting on us
IDE-4459 Expense system rejects a receipt Finance ops Low Paused, waiting on requester Waiting
A sketch of the working queue, sorted the way somebody clearing it would pick up the next thing. The target column counts down rather than reporting a breach afterwards, and the paused row is not counted against the team while it waits on the requester.

What matters here

  • A helpdesk is four parts: one front door, type-based routing, a derived priority, and a queue with an owned response target.
  • Build a form per request type. A generic description box means the first reply is always a question, and that round trip is most of the resolution time.
  • Route on the request type, not on who was asked. Otherwise the helpful person becomes the helpdesk and burns out.
  • Derive priority from impact and urgency. Let requesters choose it and everything is urgent, which is the same as nothing being urgent.
  • Deflect before you queue. If the answer exists in writing, show it at intake rather than paying a person to paste the link.
  • The most valuable report is repeat requests. A helpdesk that only closes tickets faster is still answering the same question forever.

Who this is for

You run IT, ops, finance ops or an internal service team. Requests reach you through Slack, email and someone stopping you in a corridor, and none of it is counted. What you want is one place they arrive, and a number for how long they take.

How it works in practice

What happens between somebody needing something and somebody doing it.

  1. 1

    The request type picks the form

    An access request asks which system and why. A hardware fault asks the asset tag. Each field is a round trip removed.

  2. 2

    Deflection runs before submission

    If the answer is already written down, showing it is cheaper than paying a person to paste the link.

  3. 3

    Routing is by type, not by who was asked

    So the helpful person stops being the helpdesk, and nothing lands in a leaver's name.

  4. 4

    Priority is derived from impact and urgency

    Because a requester-chosen priority is always high, and then the real outage queues behind a printer.

  5. 5

    The clock pauses when you are waiting on the requester

    Counted separately. A target that punishes a team for someone's holiday gets gamed within a fortnight.

  6. 6

    Repeats are reported, not just throughput

    Ten requests a week for the same access is a provisioning problem, and faster resolution never fixes it.

What a helpdesk is made of

A helpdesk is not a ticket table. It is four parts, and the first one determines whether the other three ever get good data.

One front door

A form per request type that asks for what the fixer will need. Access requests need the system and the reason; a laptop fault needs the asset tag and what it does.

Routing on type

The request type decides the queue and the owner, so it does not matter who was asked or who happened to see the message.

A derived priority

Calculated from impact and urgency rather than chosen by the requester, because a requester-chosen priority is always high.

A queue with a target

Response and resolution targets by priority, owned by a team rather than a person, with breaches visible while they can still be fixed.

These prompts start from a Helix project, which is what handles sign-in, credentials and hosting. Start with Helix

The prompts

Paste these into Claude Code, Codex or Cursor in order. Each one leaves you with something that runs, so you can stop after any step.

  1. One front door, with a form per request type

    Because a generic description box guarantees a round trip.

    In this Helix project, build me an internal helpdesk.
    
    A request record: requester, request type, description, priority, status,
    assigned team, assigned person, created and resolved timestamps, and the
    conversation history.
    
    Then a form per request type, and this is the part that matters. Do not
    give me one description box.
    
    An access request asks which system, which access level, for how long,
    and the business reason. A hardware fault asks the asset tag, what
    happens and when it started. A new starter asks the start date, the role,
    the manager and which systems they need.
    
    Every field a form asks for is a question the fixer does not have to ask
    later. A generic box means the first reply is always "which system?",
    and that round trip is most of the time the ticket takes.
    
    Let me add and edit request types without a redeploy, because the list
    changes constantly and it is the thing everyone else wants to change.
    
    I sign in through Helix, so do not build a login page. Read the signed-in
    user from the runtime. And do not put any key or connection string in the
    code: if this needs to reach another system, tell me and I will create the
    connection in my workspace.

    Worth knowing. Fields on an intake form are not bureaucracy. Each one removes a round trip, and round trips are where the days go.

  2. Route on the type, not on who was asked

    Or the helpful person becomes the helpdesk.

    Now route on the request type rather than on who received the message.
    
    Each type maps to a team, and each team has members and a rota. Assignment
    goes to the team first, then to a person, so nothing sits in a queue with
    no owner and nothing lands in a leaver's name.
    
    Derive priority from two things the requester does not choose: impact,
    meaning how many people are affected and whether they are blocked, and
    urgency, meaning whether there is a deadline. Let me set the matrix.
    
    Do not let the requester pick the priority. Given the option everything
    is high, which is the same as nothing being high, and then the real
    outage is in a queue behind a printer.
    
    Add deflection at intake. When somebody starts a request, search existing
    documentation and recently resolved requests, and show the likely answer
    before they submit. If the answer already exists in writing, showing it is
    cheaper than paying a person to paste the link.
    
    Track how often deflection worked. That is the number that decides
    whether the documentation is worth writing.
  3. A queue people can actually work from

    Sorted the way a person picks up the next thing.

    Build the working view, and design it for the person clearing the queue
    rather than the person reporting on it.
    
    Their own assigned requests first, then their team's unassigned, sorted
    by priority and by how close each is to breaching its target.
    
    Every request shows the requester, what they asked, everything the form
    collected, and the history in one place. No tab switching to answer a
    question.
    
    Common actions in one click: reply, reassign, ask the requester for
    something and pause the clock, resolve with a note.
    
    Set response and resolution targets by priority, and show a countdown
    while it can still be met rather than a breach report afterwards. Pause
    the clock when you are waiting on the requester, and count that time
    separately, because a queue that punishes a team for a requester's
    holiday gets gamed within a fortnight.
    
    Give it a search that covers resolved requests too. Half of helpdesk work
    is finding how this was fixed last time.
  4. Report on repeats, not just throughput

    Because closing the same ticket faster forever is not progress.

    Last, the reporting, and lead with the thing that reduces volume rather
    than the thing that measures speed.
    
    Group requests by what they were actually about and show the most
    frequent. Ten access requests a week for the same system is a
    provisioning problem, not a helpdesk problem, and it is invisible when
    you only count resolution time.
    
    Then show volume by type and team over time, time to first response and
    to resolution by priority, the proportion breaching target, deflection
    rate, and reopened requests. Reopened is the honest quality measure,
    because it counts the ones marked resolved that were not.
    
    Show volume by requesting team as well. One department generating four
    times its share usually means something is broken upstream that nobody
    has connected to the ticket count.
    
    A helpdesk that only gets faster is still answering the same question
    forever. The repeats report is the one that changes anything.
  5. Connect it to real systems

    The step that turns a working prototype into something with your data in it.

    Now connect it to the systems we actually run, so it works on real data
    rather than the rows you seeded.
    
    Anything in angle brackets is a placeholder. Swap it for whatever we use
    instead, and have the app name the connection it wants rather than assume
    a vendor, so changing my mind later is a config change and not a rewrite.
    
    <Slack>. Raise a request from where people already ask, and reply in the
    thread. This is the single biggest determinant of whether anyone uses it.
    
    <Okta>. Identify the requester, read their team and manager so the form
    does not ask, and provision the access a request approves.
    
    <Gmail>. Accept requests by email and reply from the ticket, because some
    people will never use a form.
    
    <Jira>. Escalate a request that turns out to be a bug or a change, with
    the history attached rather than retyped.
    
    <Notion>. Search the internal documentation at intake, which is what makes
    deflection work rather than being a nice idea.
    
    <Workday>. Read the joiner and leaver feed, so onboarding requests arrive
    before somebody remembers to raise one.
    
    <Jamf>. Read device state for a hardware request, so the fixer can see the
    machine rather than ask about it.
    
    <Snowflake>. Push resolved requests into the warehouse, which is how
    repeat analysis across a year becomes a query.
    
    Only write where I have said to write. Everything else is read only.
    
    Do not write a key, a token or a connection string anywhere in the code,
    and do not ask me to paste one. Tell me which connections you need and I
    will create each as an authentication in my Helix workspace. Reference
    them by alias.

    Worth knowing. Every name in angle brackets is a placeholder for whatever you run. Helix holds the credential as a workspace authentication, so the app references an alias and never the secret itself.

  6. Ship it

    The last step of every build: a URL, and the right people on it.

    Deploy my app.

    Worth knowing. Your assistant runs helix deploy underneath and the app comes back as a URL. Everyone in the company will use this, so set Access Control before sharing.

What it connects to

A helpdesk sits in the middle of everything, so it meets people where they already ask and acts where the work happens.

  • Slack

    Raise a request from where people already ask, and reply in the thread. This is the single biggest determinant of whether anyone uses it.

  • Okta

    Identify the requester, read their team and manager so the form does not ask, and provision the access a request approves.

  • Gmail

    Accept requests by email and reply from the ticket, because some people will never use a form.

  • Jira

    Escalate a request that turns out to be a bug or a change, with the history attached rather than retyped.

  • Notion

    Search the internal documentation at intake, which is what makes deflection work rather than being a nice idea.

  • Workday

    Read the joiner and leaver feed, so onboarding requests arrive before somebody remembers to raise one.

  • Jamf

    Read device state for a hardware request, so the fixer can see the machine rather than ask about it.

  • Snowflake

    Push resolved requests into the warehouse, which is how repeat analysis across a year becomes a query.

Each line says whether the app reads, writes or both. Anything not described as writing should be read only.

Named systems are the ones most teams actually run, not a list of the only ones that work. Swap in whatever you use.

Each connection is an authentication in your Helix workspace, referenced by alias. The app names the connection it wants and never holds the credential, so nothing here ends up in your code and any of it can be rotated or revoked without a redeploy.

Running it for real

The build gets you a working helpdesk. Everyone in the company files into it and some requests carry sensitive detail, so it needs to be run properly.

AI Deployment

Get it to a URL people can open

One command takes the app from your assistant to a live address, so the people who need it get a link rather than instructions for running it locally.

App Security

Put your identity provider in front of it

Everybody files a request and only the assigned team should read one. SSO plus scoped access is what keeps an HR or payroll request out of general view.

App Security

Connect the system of record with managed credentials

Reading the directory to know who someone's manager is, and writing to the systems you provision, needs real access. Granting it to the app rather than pasting a key into it means it can be rotated or revoked without a redeploy.

App Registry

Put a name on it

Every app carries a named owner and an entry IT can see, so the tool does not become nobody's problem when the person who built it changes role.

Cost Management

Know what it costs to run

Per-app spend visibility, with budgets and caps, so an internal tool cannot quietly become a line item nobody can explain.

Questions people ask

What is an internal helpdesk?

One front door for internal requests: a form per request type that collects what the fixer needs, routing based on the type rather than who was asked, a priority derived from impact and urgency, and a queue with response targets somebody owns.

Why a form per request type?

Because every field is a question the fixer does not have to ask later. A generic description box means the first reply is always a clarifying question, and that round trip is most of the time a ticket takes.

Why not let requesters set priority?

Because given the option everything is high, which is the same as nothing being high. Derive it from impact and urgency instead, and the real outage stops sitting behind a printer.

What is deflection and is it worth it?

Searching documentation and recently resolved requests at intake and showing the likely answer before somebody submits. It is worth it if you measure it: the deflection rate is what tells you whether writing the documentation paid for itself.

What is the most useful report?

Repeat requests grouped by what they were actually about. Ten access requests a week for the same system is a provisioning problem, and no amount of faster resolution fixes it.

Can I build this without an engineering team?

Yes. The prompts here are written for Claude Code, Codex or Cursor and stage the build. The judgement calls are your request types and your priority matrix, and both should be small at first and grow from real requests.

Last reviewed September 2026.

Build it, then run it properly

Helix is the governed runtime for AI-built apps. Deploy what you build, put SSO in front of it, connect it to your systems with managed credentials, and give it a named owner.