AnswerLineStart free

, Analytics · Agencies · Fundamentals

Competitive analysis template with a data source for every row

A competitive analysis template is a fixed grid of questions you answer the same way for every competitor, with the source and date of each answer written next to it. The source column is what makes it useful: without it, a template mixes last year’s pricing, a salesperson’s impression and a ranking checked this morning, and nobody can tell which is which. Copy the tables below, keep one file per competitor plus a summary, and refresh each section on the cadence at the end.

Source labels used throughout:

0. Header

Field Value Source
Competitor Manual
Domains and aliases Main site, blog, docs, country sites, product names Their site
Segment they lead with Their site (homepage headline)
Analyst Manual
Last full review YYYY-MM-DD Manual
Markets covered in this file e.g. US, UK, DE Manual

Fill in the domains and aliases row first. Every automated row matches on it, so a competitor whose docs live on a separate domain will look invisible in search unless that domain is listed.

1. Positioning

Question Their answer Evidence Source Checked
Who do they say it is for? Homepage headline, quote Their site
Main problem they claim to solve Their site
Top three differentiators they claim Their site
Named competitors on their comparison pages URL Their site
Category term they use for themselves Their site
How reviewers summarise them Review site excerpts Public pages
How Google’s knowledge panel describes them knowledgeGraph.type, knowledgeGraph.attributes[] Query: brand name API: Google Search
How ChatGPT describes them when asked directly First two sentences of text Prompt: “What is ?” API: ChatGPT

The last two rows show the gap between what a company says and what search engines and assistants repeat. When ChatGPT’s description of a rival lags their current positioning, start with the pages it cites (sources[].url) to see which outdated descriptions it is drawing on.

2. Pricing and packaging

Question Their answer Source Checked
Is pricing published? Yes / No / Partly Their site
Pricing model (per seat, usage, flat, tiered) Their site
Entry plan price and limits Their site
Most prominent plan Their site
Free plan or trial, and its limits Their site
Annual discount Their site
Add-ons sold separately Their site
Prices seen in sales cycles, if different Manual (CRM, sales notes)
Recent price change and date Their site, news via API: Google News newsResults[]
Price shown in shopping results (physical products) shoppingCards[].price.raw, ads[].price.raw by store API: Google Search

Rule: if pricing is not published, write “Not published” rather than a remembered number. A price from a sales call goes in its own row with the date and deal context.

3. Product

Capability Us (0–3) Them (0–3) Evidence Source Checked
Capability A Docs URL Their site
Capability B Changelog entry Their site
Integrations that matter to our buyers Integration directory Their site, public pages (marketplaces)
Security and compliance claims Trust page Their site
API and developer experience Docs, trial Their site, manual
Onboarding time claimed Their site, manual (trial)
Recent launches (last 90 days) Changelog, news Their site, API: Google News

Score only what you can link. A capability that exists “according to a prospect” is a lead to verify, not a 2.

4. Organic search presence

Fill from a fixed keyword set, tagged by group, for each market in the header. All rows below come from POST /v1/monitor/google (task type GOOGLE).

Metric Definition Field Value Checked
Category keywords in top 10 Keywords where any of their domains ranks ≤ 10 ÷ keywords tracked organicResults[].link, position, page
Comparison keywords in top 10 Same, over “vs” and “alternatives” keywords organicResults[].link
Share of SERP (organic) Their top-10 slots ÷ all top-10 slots across the set organicResults[].link
Keywords where they outrank us Their best rank < our best rank organicResults[]
Pages that rank most often Top 5 URLs by keyword count organicResults[].link
Questions they own in People Also Ask PAA items whose link is their domain peopleAlsoAsk[].link
Forum threads about them Threads in the discussion module on their brand query peopleAreSaying[].link
Local pack presence (local businesses) Keywords where they appear in the pack, desktop localResults[].title with location

Not in this section: traffic, search volume and backlinks. The API does not return them. If you need them, add rows sourced from your analytics or a keyword tool, and label those rows as estimates.

5. AI answer presence

Two sources: the Google AI Overview on your keyword set, and assistant answers on a fixed prompt set.

Metric Definition Endpoint and field Value Checked
AI Overview citation rate Keywords whose AI Overview cites their domain ÷ keywords with an AI Overview Google Search + include.aioverview: aioverview.citationPills[].domain
AI Overview presence on set Keywords with non-null aioverview ÷ keywords Google Search: aioverview
ChatGPT mention rate Answers naming them ÷ answers sampled ChatGPT: entities[].name, text
ChatGPT first-named rate Answers naming them first ÷ answers naming any tracked brand ChatGPT: text
ChatGPT citation share Their URLs in sources[] ÷ all source URLs ChatGPT: sources[].url
Other assistants mention rate Answers whose text names them ÷ answers sampled Gemini, Copilot, Grok: text
Most cited page of theirs URL cited most across engines sources[].url

entities[] exists only on ChatGPT; for other engines, match brand names and aliases in text. Sample each prompt several times per period, because answers vary between runs. AI share of voice has the full metric set.

6. News and announcements

News rows use the Google News endpoint.

Question Value Source Checked
Articles in the last 30 days Count of distinct link API: Google News newsResults[].link
Publishers covering them Distinct source values API: Google News newsResults[].source
Funding, acquisition, leadership news Headlines with date API: Google News newsResults[].title, date; confirm on their press page
Launches announced Their site (press, changelog)
Hiring signals Roles and teams they hire for Public pages (their careers page, job boards)
Customer wins they publicise Their site (case studies)

Headlines are leads. Confirm material facts on the competitor’s own press page or filings before they go in a board summary.

7. Paid search and ads

Metric Definition Endpoint and field Value Checked
Bids on our brand Share of samples on our brand query with their ad Google Search: ads[].domain
Bids on their own brand Share of samples on their brand query with their ad Google Search: ads[].domain
Category ad presence Keywords × samples with their ad ÷ keywords × samples Google Search: ads[].domain
Top-of-page share Their blockPosition: top ads ÷ all top ads observed Google Search: ads[].blockPosition
Active ad messages Distinct title + description pairs this period Google Search: ads[].title, ads[].description
Shopping ads by store Samples with a sponsored card from their store Google Search: ads[].store where type is SHOPPING_CARD
Ads in ChatGPT answers Prompts where their brand ad was rendered ChatGPT + include.ads: ads[].brand.name, ads[].rendered
Creatives across Google surfaces What they ran, by region Manual: Google’s Ads Transparency Center

Spend, bids and click data are not observable in any of these. Report presence rates, not “they spend more”.

Filling the automated rows

One batch per run covers sections 4, 5 and 7 for a keyword and prompt set. A minimal TypeScript submitter with fetch:

const API = "https://api.answerline.dev";
const headers = { Authorization: `Bearer ${process.env.API_KEY}`, "Content-Type": "application/json" };
const webhook = { url: "https://intel.example.com/hooks/template" };
const day = new Date().toISOString().slice(0, 10);

type Kw = { id: string; text: string; market: string; aio: boolean };
type Prompt = { id: string; text: string; market: string };

function tasks(keywords: Kw[], prompts: Prompt[], adSamples = 3) {
  const out: object[] = [];
  for (const k of keywords) {
    for (let s = 0; s < adSamples; s++) {
      out.push({
        taskType: "GOOGLE",
        idempotencyKey: `tpl:${k.id}:${k.market}:${day}:${s}`,
        webhook,
        payload: {
          query: k.text,
          country: k.market,
          ...(k.aio && s === 0 ? { include: { aioverview: { markdown: false } } } : {}),
        },
      });
    }
  }
  for (const p of prompts) {
    out.push({
      taskType: "CHATGPT",
      idempotencyKey: `tpl:${p.id}:${p.market}:${day}`,
      webhook,
      payload: { prompt: p.text, country: p.market },
    });
  }
  return out;
}

async function submit(all: object[]) {
  for (let i = 0; i < all.length; i += 500) {
    const res = await fetch(`${API}/v1/async/task/batch`, {
      method: "POST",
      headers,
      body: JSON.stringify(all.slice(i, i + 500)),
    });
    if (!res.ok) throw new Error(`batch ${i}: ${res.status}`);
    const body = await res.json();
    for (const r of body.results) if (!r.success) console.warn(r.index, r.error?.code);
  }
}

Sample 0 carries the AI Overview and feeds organic rows; samples 1 and 2 only add ad observations. Verify webhook signatures before storing results (how). Competitor SEO tracking covers the storage model and change detection.

Cost

Credits per async task: Google Search 3, plus 2 with the AI Overview; ChatGPT 5; Google News 3. For 100 keywords with 3 samples per run (AI Overview on the first) and 30 ChatGPT prompts, run weekly: (100 × 5 + 200 × 3 + 30 × 5) × 4 = 5,000 credits a month. Adding 10 Google News queries weekly adds 120. See pricing.

Scoring

Score each competitor per dimension on 0 to 3, with written criteria so two analysts arrive at the same number.

Dimension 0 1 2 3 Weight
Positioning overlap with us Different buyer Adjacent buyer Same buyer, different use case Same buyer and use case 3
Pricing pressure Much more expensive Somewhat more Similar Cheaper for the same job 2
Product parity on our top capabilities Missing most Covers some Covers most Covers all, plus extras 3
Organic search presence Rarely top 10 Under 20% of set 20–50% of set Over 50% of set 2
AI answer presence Rarely named or cited Named in some samples Named in most samples Named first in most samples 2
News momentum No coverage Occasional Regular Frequent, tier-one publishers 1
Paid search aggression No ads observed Own brand only Category terms Our brand terms 1

Threat score = Σ(score × weight) ÷ Σ(3 × weight), from 0 to 1. The thresholds in the search and AI rows are examples; set yours after the first full run so the scale spreads competitors out.

Rules that keep scores honest:

  1. Every score links to the evidence row it came from.
  2. Two people score independently; differences over one point get discussed, not averaged.
  3. A score cannot change without a new evidence row and date.
  4. Report the threat score with the per-dimension scores beside it. A single number hides why.

Refresh cadence

Section Cadence Trigger for an early refresh Method
0. Header Quarterly Rebrand, acquisition, new domain Manual
1. Positioning Quarterly Homepage or messaging change Manual; API rows monthly
2. Pricing Monthly Price-change news, sales reports Manual check of their site
3. Product Monthly Launch announcement Manual, changelog review
4. Organic search Weekly Core update, rival content push API, scheduled batch
5. AI answers Weekly, repeated samples Rival launch, pricing change API, scheduled batch
6. News Daily to weekly Funding or M&A rumours API, scheduled batch; confirm manually
7. Ads Several samples per week, daily for brand terms Seasonal campaigns API, scheduled batch
Scoring Monthly Any section change of 2+ points Manual

Monitoring cadence goes deeper on how often AI answers need sampling. For which tools fill the manual rows, see competitive intelligence tools by job, and for 18 ready questions with their exact fields, competitive intelligence examples.

Pitfalls

The metric definitions behind sections 4, 5 and 7 are on the competitor analysis page. To start collecting, see the quickstart.

Questions

What should a competitive analysis template include?

Positioning, pricing and packaging, product capabilities, organic search presence, AI answer presence, news and announcements, and paid search. Each row should name where its value comes from and when it was last checked, so readers can tell observed facts from opinions.

How often should a competitive analysis be updated?

Match the refresh to how fast each section changes: search and ad rows weekly or more often, AI answer rows weekly with repeated samples, pricing and product monthly or on announcement, positioning quarterly.

How do I score competitors objectively?

Score each dimension on a fixed 0 to 3 scale with written criteria per level, weight dimensions by how much they affect your deals, and keep the evidence link next to every score. Two people scoring independently and reconciling reduces bias.

Which rows can be filled automatically?

Rows derived from Google results, Google News and AI answers can be filled from API responses: organic positions, ad presence, AI Overview citations, brands named in ChatGPT answers and news sources. Pricing, product depth and positioning still need reading the competitor's site and manual judgement.

Does the template need traffic or search volume data?

It helps for prioritising keywords, but those numbers come from other sources such as your analytics or a keyword tool. SERP and AI answer data show presence, not traffic or volume.

Try it on your own prompts

500 free credits a month, no card. One POST returns the answer, sources and citations as JSON.

Keep reading