Smarter Local SEO Pricing
The truth is, the preceding article I “authored” on this topic, (https://localclienttakeover.com/the-5-step-process-for-smart-local-seo-pricing/) that was published in 2019 is actually quite a bit older. For the OG Local Client Takeover crew, they might recognize those price matrices from one of my free courses from a few years prior. No need to read between the lines on this one, that content is old and outdated as heck. I also can’t remember if I actually wrote that article or if it was just created using my old pricing videos as a guideline.
I rediscovered this article whilst cleaning up and rewriting some Web20 Ranker email sequences and had two emotions simultaneously; one feeling I experienced was nostalgia because that system of pricing worked really well during our sales process at my first agency. The second, and maybe more visceral reaction was, “Ewww”, this needs to be redone and brought into the 2020s.
My goal is to produce some updated and “better” downloadable content you can plug into the pricing process of your agency, but from an actual content perspective, I want to step away from presenting you with an overly structured matrix that you’re expected to smush your products into as opposed to some philosophies and ideas you can use to improve what you are currently using.
Let’s begin with a bit of an update on the old strategy I demonstrated in the v1 of this post.
The foundation of this pricing strategy is still viable. The simple but somewhat sound logic relies on two truths, the first being that in more populous areas there will be higher demand for services based on the increased volume of need for said services as a municipality grows its citizens.
Secondly, we assume that the higher ticket the sale becomes the more a business can pay to acquire a customer.
A personal injury attorney focusing on fatal car accidents is going to enjoy a larger payout than their counterpart which focuses on general premise liability. Both will have a higher threshold for acquisition costs than a residential concrete contractor. A concrete contractor that does large commercial pours and/or decorative applications will outspend the former residential concrete outfit and both will be capable of outspending a dog walker in terms of raw marketing budget.
Hopefully, that wasn’t too many rapid-fire examples, but I think it does a good job of explaining the logic of this old matrix. Larger areas (more people = more demand for products and services) and higher ticket services will both play into overall competitiveness and budgetary considerations.
CAVEAT: The above strategy possesses some glaring imperfections that we need to explore and that is the fringe circumstances that exist in certain scenarios which this binary cookie-cutter system will not identify, thus making the system produce pricing you will not necessarily love.
A perfect example of this is a situation that arose in my agency not long ago when a deal was being worked with an HVAC contractor. The company served some smaller suburbs and municipalities in Arizona. Using a cookie-cutter pricing matrix led to a number that was not truly indicative of the competition. Considering Arizona’s temperature can rival that of hell (love dry heat though) and people not having air conditioning can literally have fatal results, the demand is inflated externally from the system we just made.
There is an example of a weekend spike in calls for one of our clients during a winter storm. Looking at long-term trends in an area for commercial keywords and identifying the patternistic nature of those seasonal spikes can help inform your pricing for that niche and geo. When that type of money is available in somewhat reliable spurts business owners know that and the best businesses, or those that want to be the best, will be prepared to pay to get a piece of that pie.
Being outspent and outperformed is far too common in SEO, so avoid it upfront by trying to identify these irregularities in volume or market demand that would cause your competitors’ budgets to be higher.
Another great example is tourist destinations and their effects on many niches, even some that may seem extremely odd. I’m not suggesting that a place like Gettysburg, PA is competitive at all in terms of ranking, but looking at population numbers ( <10,000 people ) doesn’t tell the whole story that some businesses, specifically retail, and hospitality, should be considering marketing to the ~1,000,000 tourists that come through the historic town with their wallets wide open.
It probably feels like I spent this entire first section tearing down this pricing model. Curveball incoming. I still think a system not unlike this one will take new and smaller agencies a long way. I billed over 3m per year in my first agency with this exact imperfect pricing model.
I wanted to take this a step further and recreate our free pricing sheet download and make it easier for all of you to use out of the box and to customize if any of you wanted to go that route. Once you download the sheet, let’s open it up and start to familiarize ourselves with the components that make it work and the math behind each cog.
The interface is simple enough; we are faced with two drop-downs that offer niche and population selections and based on our behind-the-scenes math, it will spit out a number to quote your prospective client.
Please note that the population drop down is simple enough. The niche is a bit more “detailed” but I added a search feature in the cell itself so you do not need to scroll through thousands of GBP categories to find what you are looking for.
Just start typing in your main category and the list will filter to present you with the best options.
Simple enough.
Now that you understand the simple interface let’s dive into the mechanics of the sheet so you can make it your own so it fits your agency’s pricing strategy as opposed to being forced to pivot into the constrained defaults of this sheet.
If you navigate over to the “var” sheet you will see most of the original variables have been removed. The niche modifier math is now handled via calling the gbp_cats sheet and in a future update additional locations will be managed with a simple integer input and the math will happen on the Google Script side.
If this is the first time you are hearing of this sheet please disregard it.
Start by adjusting your base cost in var!B2. This is the minimum base cost of your service and overhead. Every agency will be different. This number will be used to calculate the data in B5 of the main sheet. Feel free to also tinker with the population percentage modifiers if you do not agree with the ones in there.
IMPORTANT: if you change percentages ANYWHERE in this workbook you MUST keep the format the same as it appears now. If it changes it will affect the math in Google Script and provide inaccurate products and sums.
If we slide over to the gbp_cats page you will see a massive list of GBP categories, a competition score of 1-4, 1 being the least competitive and 4 being the most, and then a competition modifier in the form of a percentage in gbp_cat!C:C.
There is a lot to digest here. There are two ways to modify these source numbers to truly make this sheet your own. DO NOT try to modify column C directly. Those percentages are informed by Google Scripts. You can:
- Change the 1-4 score in gbp_cats!B:B. This will automatically update column C with the new percentage that is tied to the competition score called out in the code base.
- You can modify the system and change how the scoring works completely.
The first option is self-explanatory so we will dig through the second and I will show you how to do it.
Navigate to Extensions > Apps Script
The “assignPercentages” function is right at the top and modifying it is super simple.
Modify the return values of the score being read from gbp_cats!B:B and save the sheet.
Final Thoughts on the Pricing Calculator
If you would like to trim down the gbp_cats sheet to fit the niches you work in then you should. Tweak the modifiers, and play with your base rate. Take some time and make it your own. It will serve as a valuable resource to your agency as long as you keep in mind the nuance I explained at the start of this post as it pertains to pricing SEO.
ROI-Based Pricing Strategies
If you want to close more deals and present yourself as a bit different solution, a better solution, then basing your pricing off of a projected value using some conservative and realistic estimates can go a long way.
In this section, I will show you how to build your own and give you an example to see how it works. A copy of the sheet will be included in the downloadable content available through this post.
If you want to swipe or build one just like mine you will need a Keywords Everywhere API key. You can certainly use any platform you would like and build yours in a different way but in this demonstration we will stick with KE.
- Whether you want to just download your own copy or build from scratch, you will need to begin by clicking on the extensions tab and selecting “Apps Script”
2. If you are building from scratch, drop the code snippet below into the “Code.gs” file. NOTE: If you swiped my sheet then please skip step 3.
const API_KEY = 'ENTER YOUR API KEY';
const API_ENDPOINT = 'https://api.keywordseverywhere.com/v1/get_keyword_data';
/**
* Register spreadsheet menu.
*/
function onOpen() {
var ui = SpreadsheetApp.getUi();
ui.createMenu('Call KE API')
.addItem('Call Keywords Everywhere API and display results','callKeApi')
.addToUi();
}
/**
* Make an API request to the Keywords Everywhere API and display the results.
*/
function callKeApi() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var activeRange = SpreadsheetApp.getActiveRange();
var col = activeRange.getColumn() + 1;
var row = activeRange.getRow();
if(activeRange.getWidth() > 1){
throw new Error( "Please select a single column" );
}
var selectedKeywords = activeRange.getValues();
if(row == 1){
//Remove the first keyword assuming it's part of the header row
selectedKeywords.shift();
} else {
row --;
}
selectedKeywords = selectedKeywords.map(function(row){
return row[0];
});
//Remove empty rows
requestKeywords = selectedKeywords.filter(function(kw){
return kw != '';
});
//Remove duplicates
requestKeywords = [...new Set(requestKeywords)];
if(requestKeywords.length == 0){
throw new Error( "Please select some keywords" );
}
var formData = {
'dataSource': 'gkp',
'country': 'us',
'currency': 'USD',
'kw[]': requestKeywords
};
var headers = {
'Authorization': `Bearer ${API_KEY}`,
'Accept': 'application/json',
};
var options = {
'method' : 'post',
'payload' : queryfy(formData),
'headers': headers
};
var response = UrlFetchApp.fetch(API_ENDPOINT, options);
var json = response.getContentText();
var parsedJson = JSON.parse(json);
if(!parsedJson.data.length){
return;
}
resultMap = {};
parsedJson.data.forEach(function(elem, i){
resultMap[elem.keyword] = elem;
});
var output = [];
var header = null;
var trend = null;
selectedKeywords.forEach(function(kw,i) {
var elem = resultMap[kw];
if(!elem){
output.push([]);
return;
}
if(header === null || trend.length < elem.trend.length){
header = ["Volume", "CPC", "Competition"];
elem.trend.forEach(function(trendItem, j){
header.push("Trend (" + trendItem.month + " " + trendItem.year + ")");
});
trend = elem.trend;
}
var dataRow = [elem.vol, elem.cpc.currency + elem.cpc.value, elem.competition];
elem.trend.forEach(function(trendItem, j){
dataRow.push(trendItem.value);
});
output.push(dataRow);
});
output.unshift(header);
var h = output.length;
var w = output[0].length;
for(var i = 5; i < w; i++){
sheet.setColumnWidth(i + col - 1, 150);
}
for(var i = 0; i < h; i++){
while(output[i].length < w){
output[i].push("")
}
}
sheet.getRange(row, col, h, w).clearContent();
sheet.getRange(row, col, h, w).setValues(output);
sheet.getRange(row, col - 1, 1, w + 1).setFontWeight('bold');
}
/**
* Convert a JavaScript object to a HTTP query string.
*/
function queryfy(obj){
return Object.keys(obj).reduce(function(p, e, i) {
return p + (i == 0 ? "?" : "&") +
(Array.isArray(obj[e]) ? obj[e].reduce(function(str, f, j) {
return str + e + "=" + encodeURIComponent(f) + (j != obj[e].length - 1 ? "&" : "")
},"") : e + "=" + encodeURIComponent(obj[e]));
},"")
}
3. Enter your API key
Click the save icon and click “run”.
4. Follow the instructions in Column Y to add your keywords and populate the rest of the sheet to build your projections and ROI potential
NOTE: My copy of the sheet includes pricing for PPL (pay per lead). You can remove this section or add sections as you please.
NOTE 2: You will need to find out your potential client’s close rate and LTV during your discovery call. I love this strategy as opposed to using estimated benchmarks because then the numbers will be conservative outputs based on THEIR business data. It makes the projections and the sale seem very personalized and real.
It is a smart idea to have some form of productized cost models built out that you have used successfully to rank so you are not just shooting in the dark based on their numbers. The idea of charging only based on your client’s success is leaving a lot of room for error. This leads us right into the next section…
Cost Modeling for Your Agency
A book could be written on this subject but I will try and keep it concise.
This can be challenging when operating with limited data as it pertains to the actual cost of ranking websites and GBP. There is no sugar-coated way to say, “You have to know what you are doing and have a pretty good idea of how much that costs”. I will do my best to guide you through creating one or refine your current model.
There are a few simple ways of tackling a cost model and I believe we will probably stay in that lane. We have been pivoting to completely custom pricing and cost modeling based on a large input of client-specific data but I don’t recommend that until you have a very mature process and a trove of ranking and technical SEO work completed to understand what items can create a variance in cost and an average delta of changes across a large sum of campaigns.
For that reason let’s keep it simple and one day when I feel our system can be a bit more plug-and-play we shall share it, perchance.
In the meantime, you can download this sheet with our new pricing content bundle or build your own.
You will need to customize this sheet to fit your needs. This is an example of deciding what percent of the retainer needs to be dedicated to each item to generate results. You can completely disregard this if you would prefer just entering static hard costs and building your campaign model in that way. You can remove the entire “% Allowance per item” column and remove the formulas in “B:B” to change how you develop your campaign cost column.
In this cost model, we included paying a second-month commission to our account executive and SDR for the close. Maybe you pay your sales staff differently. Depending on where you are with your agency growth maybe you have no sales commission overhead.
Make this sheet fit your existing model of fulfillment and in the “Campaign Builder” tab you can identify your gross profit on a per-month basis and create “worst-case scenario models”. I included a worst-case model from our agency in the sheet and highlighted it yellow so we can see what our margin is if the client churns immediately after the second month and we still are responsible for the sales team’s commission.
You can build a few of these models yourself so you understand different situations that might arise as you grow to new heights.
Quick Last-Minute Pricing Strategies
Here are some ideas to include in these processes to get the most of out of any model of pricing:
Create a minimum monthly retainer to work with your agency.
Eliminate, or at least drastically reduce, the possibility of undercharging or being caught with the proverbial egg on your face when it comes to pricing by just having some minimal standards in place. This can sometimes be difficult in itself because of a lack of niche knowledge or a good cost breakdown of what it costs you to rank different competition levels of properties.
Develop a pre-sale audit process that you run properties through beforehand to avoid surprising circumstances.
I still stand by the fact that if you enter into an agreement blind, even if your pricing strategy was technically sound, you are opening yourself up to a ton of disorganization and mismanagement.
Auditing systems have been something we have been developing, optimizing, and testing for a long time. I developed a few standard operating procedures for smaller pre-sale audits ranging on a spectrum from fully automated software reports (meh) to 90-minute audits with templated outputs to create very large reports for your team and client to view.
Identifying things that are going to require a larger budget or setup fee during your pricing process is critical to avoiding operating on razor-thin margins throughout the campaign, or worst, losing money on the deal.
We are testing the viability of releasing some version of these audits as a product for agencies but regardless if that ever sees the light, expect some content on our auditing processes in the future.
Setup fees
The key to having a good setup fee, in my humble opinion, is to not just stick an arbitrary number onto your pricing just in an attempt to drum up revenue. You can of course do as you please but if you are charging a setup fee for simple SEO action items that most other agencies are doing as part of their onboarding process and regular billing; the optics of that are going to be tough to hard sell around.
The waiving of setup fees has also become so commonplace in agency sales processes that it seems most businesses seeing them almost expect them to be removed when it comes time to ink the deal.
I found that having an itemized list of what the setup entails or some documentation around the justification of the setup fee.
Sometimes we slide a setup fee into our packages for SaaS setup, a suite of tools for the client to use, and outline everything they are getting and what we are doing. But, nevertheless, we usually end up waiving it for people signing up for SEO packages.
Bundling
We have invested a lot of focus on bundling software into our digital services packages. At the very least it allows business owners to consolidate their business tools and in all cases they save money. We sweeten the deal by letting them know that when bundling with our services we will also manage the SaaS for them in a concierge way.
Consider it as a signup bonus, value stack, upsell, or whatever floats your boat.
Pre-Pay
Establishing discounts based on quarterly/yearly billing can be a mutually beneficial situation for both the business owners looking to save a few bucks and defer tax responsibilities as well as injecting some additional capital into the agency. This is most popular during the end of the fiscal year as people look to dump cash so as not to needlessly pay taxes on money decaying in a bank account. Having said that, offering the deals, especially quarterly, will yield results and should always be considered.
Luck is for the Uniformed and the Unprepared
This ran a bit longer than expected and turned into me spending some time coding a new sheet for people to use, but I am very proud of how this turned out. I have seen many veteran agencies not have great pricing strategies or cost models in place so I am confident this post will help more than just beginners but am excited for newbies to get a solid foundation right out of the gate.
Take some time and make these downloads your own. Let the data from your costs dictate pricing and profits and ensure you are providing great results in a healthy and sustainable way. It will take some refinement but this is a great resource for you to take advantage of and leverage.
Feedback is always appreciated and we will work hard to circle back with some updates and upgrades before waiting 4 years again this time.
Thank you and enjoy!