SaaS Startup Founders: Are you talking to the right audience?


I have a confession to make. I am a developer, not a marketer, and in the nearly 4 years that I have been running my startup HR Partner, I have made a ton of mistakes in my ‘go to market’ strategy, and I hope to share a couple of them here with you.

I always naively thought that the coding of my SaaS product would be the hard part, and that the selling part would happen naturally and effortlessly. How wrong I was. In today’s noisy world, with a ton of competitive offerings, getting heard is nearly impossible, and finding people who will like, and more importantly, pay for your offering is painfully difficult.

Probably the biggest mistake we’ve made with our marketing was simply talking and selling to the wrong people. We never really stopped to look at who would be using our product but instead went for the scattergun approach to throw everything at the wall and see what would stick. Let me give you a brief history of what we did.

When I first built HR Partner back around 2016, I decided to release our Beta version to the world via a fanfare splash on the very popular ProductHunt website. It seemed to work, and we actually got hundreds of sign ups out of this one source. “Great!”, I thought - success and endless bags of cash shall now rain down on me.

Wrong. Pretty much 0% of those early signups stuck around. You see, ProductHunt is comprised mainly of programmers, designers and other small startup founders. They are very interested in tech, but have little or no interest in setting up HR policies and procedures, or managing a large team. They signed up purely out of interest sake, but had no reason to actually implement our system at their workplace.

Nevertheless, we doubled down on our failure to learn, and I embarked on a campaign of listing my HR system on various Beta announcement sites such as BetaList. Same results. A flurry of sign ups by curious people, but very little stickiness.

Of course, this spike in signups both times was great for my ego, but I couldn’t see that this was just a vanity metric that did nothing to help us get any real traction.

Next, we went completely broad based, by spending a ton of money on Google Ads. We even worked with a Google consultant to get our keywords and campaign ‘just so’. But while we saw a massive increase in traffic to our website, it didn’t result in many trial signups, and in fact, we got a TON of calls and emails from various employees asking us HR policy and payroll legislation questions! We quickly pulled the plug on this avenue.

At this point, and for the first time in over 6 months of trying, I actually sat down to think about where I was going wrong. It was pretty obvious actually. ProductHunt and BetaList are great sites, but really, they are ideally suited if you have early stage products that are geared to the programmers or designers of this world. Business owners are not renown for adopting concept stage or beta stage software - they want something proven and reliable. Coders and creative people however, are different and can’t wait to try the next shiny thing! We were talking to totally the wrong people.

So I began to think. Who would need HR systems? Well, the obvious answer is “HR Managers”, duh!

Thus began our next marketing push - cold outreach to anyone with the title “HR Manager” on LinkedIn. Initial observations were a mixed bag. We were having some great conversations with a lot of HR Managers on that platform, but very few would actually take the next step and sign up for a trial of HR Partner. It turns out that while these were the right people to talk to, they already had established systems they were happy with, and were not looking to buy.

We were getting closer - the right people, just in the wrong place & time. So how do we get them at the right time? Well, we’ve recently put some marketing effort on business software directories, such as Capterra or G2 Crowd. These are vast directories of SaaS offering that people can go to when, you guessed it, they are evaluating business software that they are thinking of buying.

Now we were getting somewhere. By promoting our offering on these platforms, we started to see a steady uptick of trial sign ups, and more importantly, paying customers.

This is all good news, but there is still so much more learning to be done here. For instance, we are finding that while it is the HR or Operations Managers we are mainly talking to, the actual buying decision is usually made by a different person in the chain.

HR Managers are coming to us with a specific set of problems - for example they may be drowning in paperwork or having trouble keeping employee qualifications and training up to date. Whereas the business owner may have a different set of issues they want solved, such as high turnover, or the high cost of recruiting new employees.

This means that we needed to address both areas. When talking to the HR Manager, we would focus on the problems they were experiencing, but when the decision went back up the line to the person who would sign off on the new software, we had to start from scratch and provide solutions for a whole different set of problems. We essentially had to sell our system twice, to practically two different audiences.

Did I say two? We actually discovered that we had a third audience that we had to sell to. These were the actual employees themselves within the organisations who bought HR Partner. Any great HR software is just going to languish if the employees don’t feel comfortable using it. All that the employees wanted to know was - how do I find out how many days leave I have available? How can I request some time off expediently? How can I find the contact email of another employee in a remote office? etc. A totally different set of problems and expectations than the other two audiences we had been dealing with!

Thus we refined our sales and marketing processes to deal with these three distinct audiences that our product had. Sure it is a lot harder to do, and is time consuming, but it has resulted in a far more effective and predictable process now - just by understanding who our audience was, and in our case, who our multiple audiences were that we had to talk to, understand, and solve problems for.

We are still learning and improving, and I am interested in hearing more from other startup founders and business owners out there. How did you find your real audience?

This article was originally written for the Catalysr Blog. I was a member of the Catalysr C18 cohort for migrapreneurs, an experience which was awesome and extremely beneficial to me and my startup. Find out more about them at

Back to classical guitar

It’s been many, many years since I’ve played classical guitar. I learned in high school, from a lovely teacher called Ms. Dunlop, but aside from romancing my wife with some classical numbers when we were courting, I haven’t really played it much in the past couple of decades.

Domenico Scarlatti (pic from Wikipedia)

Domenico Scarlatti (pic from Wikipedia)

Added to that, my classical guitar had its bridge lift off on me many years ago, so I haven’t really had a nylon stringed guitar around the house for a very long time now (Hmm - perhaps it is time to go guitar shopping?) :)

But just this month, I was motivated to dig up some of my old favourite pieces and give them a go again. It was surprising how much I had forgotten, but also surprising was how the muscle memory in my fingers seemed to go back to how I played 20 years ago. While re-learning and practicing, sometimes my mind would wander, and when I snapped back to what I was doing, I realised that my fingers were automatically going to the right frets like they did two decades ago. Over thinking and forcing myself to remember was actually detrimental to that process.

I have a particular affinity for Baroque era pieces. Most of my friends love the Bach Lute Suites, but for me, my favourite composer of the era is Domenico Scarlatti (and to a lesser extent, his father Alessandro). Something about Scarlatti’s pieces are more uplifting that others of that time. The fact that most of them were written as love songs for the countess he was infatuated with probably helps!

Here is my attempt at his Sonata in A minor (K.322) after about a week’s practice. I don’t think Ms. Dunlop would be too happy with my sloppy technique, but I am going to keep practicing to try and get better and smoother.

Getting stuck into design

While I consider myself a ‘full stack’ developer, taking care of everything from the back end to the front end of town, one area that I tend to lack is in my design skills. I am trying to learn more about good graphic and user experience (UX) design principles, so that I can improve the software I write without having to resort to a third party expert every time.

What better way to start than with my flagship SaaS HR product, which is in use by over a thousand people all over the world? Looking at the stats on Google Analytics, I see that the most common screen used on my app is the employee Leave Request screen, which employees of our customers use to ask for time off from their managers.

While we haven’t really heard any real complaints about this screen, I knew we could make it easier for people to use, without too much effort. Here is the original screen:


I thought the blue bordering on this screen made it look a little dated. Plus the title at the top which says “Request Leave or Time Off” seems a little disconnected from the rest of the screen. Lastly, the one bit of feedback we’ve heard from employees was that they would like to see the company leave calendar on here which was useful to them when planning time off.

So, I sat down for a morning, and reworked the screen to remove the borders, and make it look more like a plain paper leave application form:

I removed the top title as it was redundant, and removed the borders around the window. I also squashed the main form down a little to increase white space around it and make it look more like a paper form that the employees would have been used to filling out before.

I also removed a lot of extra words within the form (i.e. the help text below each field) and made them popups that would appear when the user clicked on the ‘?’ icon above each field. Just to make things cleaner and have less word clutter.

At the bottom of the screen, you can see where I have ‘squished’ the old list of leave balances down, which is still readable, and added the company leave calendar to the system.

After some initial testing, I made some finer touches for the final version:

Employee Portal Leave.png

Not much that is immediately obvious, but they did make the form seem aesthetically better. I fixed the alignment of text across the form, plus I added a background colour to the form fields themselves so they stood out a little and didn’t make the form look so washed out and overly white.

What do you think? We actually saw an uptick of activity on this form already this week since we put out the update to production, and so far no one has emailed in to complain about anything, which is a good sign IMO.

Because I am all about constant learning and improving, I would love to hear from some experienced designers out there as to how I could make things better.

Building a HelpScout sidebar widget

We recently moved our support system for our HR SaaS over to HelpScout, predominantly as a cost saving exercise. So far our support crew is loving HelpScout, however there were a few key things missing compared to our old support system - mainly extra information about our customers, such as the current plan they are one, and when their subscription expired etc, which were pushed to our old system via API calls.

We investigated HelpScout’s API infrastructure, which was powerful, but would come at an extra cost based on number of users, which was going against our plan to save costs. But then, while perusing the HelpScout documentation, I noticed that they had the ability to add your own custom sidebar widget to the communication screen. No API needed! This sounded perfect.

More digging, and I found out that HelpScout can actually send a WebHook to any address when the communication screen is opened. This is done via a Dynamic App, and the process is explained on their developer website on this page.

In essence, when you open a conversation with a customer, HelpScout will send a packet of information back to your app with the customer details (including their email address), and all your app needs to do is to send back a pre-formatted HTML snippet with any customer information that you think will be useful for your support team to know.

Here is the sidebar on our HelpScout conversation page, showing the information that we pull and can view while talking to our customer:

Ta Da! Our HelpScout mailbox page now has useful info on the right hand side!

Ta Da! Our HelpScout mailbox page now has useful info on the right hand side!

As you can see on the sidebar (on the right hand side), we show the company name that this user registered in our HR system, and the date that their current plan expires. We also show things like the timezone that the user (and the company) have set up, and the number of employees they have versus the limit of employees they can have on their current plan. We also show their Stripe identifiers (in case we need to lookup their account details in there) and the modules that they have activated in our HR system.

This helps us to answer the common questions, such as “When is my subscription renewal due?” or “How many employees can I have on the system?” without having to leave this screen.

Oh, and under the company name we also show a couple of badges that denote whether this user is the ‘Owner’ of the company (i.e. the person who set it up and is paying for it on their credit card), and also whether this company is currently on a paid subscription or in trial mode, or is an expired trial (Yes, we provide support to customer in trial mode!).

In the middle section there, you can see that HelpScout gives us other useful information such as the browser and operating system that the user is using.

How do we set this up? Well, it is actually quite easy and straightforward. Here is a step by step (taken from our own system, which took a couple of hours to set up). Note: You have to be on the HelpScout Standard or Plus plan for this to work, it won’t work on the Basic plan.

Step 1: Set up a custom app in HelpScout

Click on ‘Manage’ then ‘Apps’ from your HelpScout main dashboard.


Then scroll down to the bottom of all the apps on this screen and choose ‘Build a Custom App’


Now click the ‘Create App’ button on the left.


Fill in the following fields (explained below the graphic).

  • App Name - can be anything you like but I would suggest calling it the same as the app you are linking to.

  • Content Type - make sure you change this to ‘Dynamic Content’.

  • Callback URL - This will be the URL we will create next, that HelpScout will call to extract the data from your app.

  • Secret Key - This is the confidential key that HelpScout and your app will use to verify that the callback above IS in fact being called from HelpScout and not via some nefarious infiltrator trying to steal your customer information. Make sure you use a hard to guess key (Tip: I highly recommend using RandomKeyGen to create one for you to choose from).

  • Debug Mode - Leave this off for now.

  • Mailboxes - Nominate the mailboxes in HelpScout that the customer information will be sent to (i.e. you may want it in your Support chat windows that are triggered by your paying users, but not on your Website chat box where your sales team talks to leads not in your system.

Hit ‘Save’ to save this custom app to your HelpScout system.

Step 2: Create the webhook endpoint in your app

Ok, now head over to your app to create the endpoint that HelpScout will call whenever you open the nominated Mailbox communication screen.

I will show you the snippet from our own website, which uses Ruby (not Rails, but rather a Sinatra based DSL framework).


The concept is pretty much the same in any language, and I will step you through the various stages.

Line 1 is setting up a POST endpoint called ‘/sendinfotohelpscout’ - this is the same name endpoint as we set up in the ‘Callback URL’ in Step 1 above. Note that this has to be a POST handler, and not a normal GET handler. Note also above that we had to nominate to turn OFF cross-site protection via the ‘csrf_protection => false’ flag. This is because we don’t normally allow external sites from our own domain to POST information to our app for security purposes, however in this case, we have to allow HelpScout to post to this particular endpoint.

Line 2 is calculating the SHA1 signature hash of the body contents received in this request, using the same ‘Secret Key’ as we set up in Step 1 above. Note that for best practice, we store the secret key in an environment variable called ‘HELPSCOUT-SIGNATURE-KEY’ rather than embed it in our code.

Line 3 then compares the signature (which is sent by HelpScout is a request header field called ‘HTTP-X-HELPSCOUT-SIGNATURE’) with the one we generated above. If they match, then we know that this is a legitimate POST from HelpScout, if they don’t, then we can safely ignore this request and jump straight to Line 15 where we return a 403 (Unauthorised) response.

Line 5 tells our app to return any content generate as a JSON file rather than HTML. Then Line 6 extracts out the JSON data that is posted to our system so that we can parse the customer’s email. Here is a sample of the JSON packet that is sent to our app from HelpScout.

ticket: {
   id: 12345,
   number: 56789,
   subject: "Help me!"
customer: {
   id: 54321,
   fname: "Fred",
   lname: "Smith",
   email: "",
   emails: [""]
mailbox: {
   id: 87654,

The bit we are after is in ‘customer -> email’, so in Line 8, we try and fetch a record from the User data table where the user’s email is contained in this JSON field. Note: You can find by other information such as the user name or ID, but in our case, the Email address of the customer is a unique field in our User table, so we used that.

If we successfully find the user, then we return the sidebar HTML snippet in Line 10, otherwise we send back a ‘Not found’ message in Line 12.

Please note that the returned HTML or error message has to be contained within a JSON message like:

{"html": “This is the return error or HTML stream”}

That’s it for the Callback endpoint - only 17 lines of code!

Step 3: The sidebar snippet

You can see in the code snippet in Step 2 above that if the User is found in our system via their email, then our app renders an HTML snippet called ‘integrations/third-party/helpscout-feed’. This is not an entire HTML page, but rather a small snippet consisting of <UL> and <LI> directives. Here is a shortened example of an ERB script to generate the snippet:

<ul class="c-sb-list c-sb-list--two_line">
  <li class="c-sb-list-item">
    <span class="c-sb-list-item__label">
      Customer Since
      <span class="c-sb-list-item__text">
        <%= @user.signup_date.strftime("%d/%m/%Y") %>
  <li class="c-sb-list-item">
    <span class="c-sb-list-item__label">
      No. of Employees
      <span class="c-sb-list-item__text">
        <%= @user.employee_count %>
<% if @user.trial_expired? -%>
    <span class="badge yellow">Trial Expired!</span>
<% end -%>

Don’t worry too much about the various CSS classes on here such as ‘c-sb-list’ or ‘c-sb-list-item’ etc. These all affect how the information will be displayed in the sidebar, and are explained in full on this page. And remember that we don’t need the <HTML> or <BODY> etc. tags wrapped around this snippet, so please be sure to generate a partial snippet that doesn’t use your default site application layout. (You can see in our code above that we specified the :layout => false directive in line 10 which prevents the system from wrapping the snippet in the application look and feel.

Feel free to embed whatever customer information you would like in the snippet. You can even create collapsible sections, and use icons. See the Advanced Style Guide Components for the CSS classes that you will need to do this.

That is it! Once you have saved and deployed the new chunk of code for the endpoint (and the ERB snippet that it returns) to your server, you should be able to open a conversation from one of your users, and your sidebar should be populated like ours is right at the top of this post.

Do you have any creative ideas as to how we can present information on this sidebar? If so, I would love to hear from you in the comments below!