Competitor Tracker & Co. Docs

Getting started

How Competitor Tracker & Co. works end to end, then your first API request in under ten minutes: authenticate, subscribe to a competitor, read its changes.

This page does two things: it explains how the whole thing flows, then walks you through your first call. Read the flow first. It tells you what to expect after you subscribe, which is the part most people miss.

How it works

You hand us a competitor URL. From there:

The thing to expect: you will not see changes the instant you subscribe. We need two copies of a page to report a difference. On subscribe we grab today's copy and, at the same time, try to pull a roughly six-month-old capture from the Wayback Machine to use as the older copy.

  • Archive copy found — your first weekly analysis is a real diff against six-month-old content.
  • No usable archive copy — the first analysis records skipped_first_snapshot (nothing to compare yet), and the next weekly run produces the first real diff.

After that, we re-check every subscribed competitor once a week and record what changed. You read those changes over the API, or have them pushed to email recipients and webhooks. Subscribing a competitor costs one coin per month — see Billing.

What we mean

We narrate these docs in the voice of our lead detective, C. T. Lucky. A few of his words map to plain API concepts:

Lucky's wordPlain meaning
tailingOur weekly crawl-and-compare of a competitor's pages.
a case / subjectA competitor you've subscribed to track.
the packOur AI agents that do the crawling, diffing and writing.
dossier / reportThe detected changes we hand back, as JSON.

Plain words mean plain things everywhere else: token, scope, endpoint, status code.

How you authenticate

Every call to /v1/* needs a credential. There are two kinds, for two situations:

You're building…UseYou send
An app that signs a person inOAuth2Authorization: Bearer <token>
A script, cron job or AI agentAPI keyX-API-Key: <key>

Both hit the same endpoints. What a credential is allowed to do is set by its scopes and the member's role. The samples below use an API key — the fastest way to a working call, with no sign-in flow to wire up. Mint one on the API keys page.

Make your first call

Set the base URL and your key:

export CT_API="https://api.competitortracker.io/v1"
export CT_API_KEY="<your-api-key>"

1. Subscribe a competitor

This points the pack at a competitor URL. One subscription per URL.

curl -X POST "$CT_API/competitors" \
  -H "X-API-Key: $CT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com",
    "displayName": "Example Inc",
    "trackedCategories": ["pricing_changes", "product_changes"]
  }'
const res = await fetch(`${process.env.CT_API}/competitors`, {
  method: "POST",
  headers: {
    "X-API-Key": process.env.CT_API_KEY,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    url: "https://example.com",
    displayName: "Example Inc",
    trackedCategories: ["pricing_changes", "product_changes"],
  }),
});
const competitor = await res.json();
import os, requests

res = requests.post(
    f"{os.environ['CT_API']}/competitors",
    headers={"X-API-Key": os.environ["CT_API_KEY"]},
    json={
        "url": "https://example.com",
        "displayName": "Example Inc",
        "trackedCategories": ["pricing_changes", "product_changes"],
    },
)
competitor = res.json()
body, _ := json.Marshal(map[string]any{
    "url":               "https://example.com",
    "displayName":       "Example Inc",
    "trackedCategories": []string{"pricing_changes", "product_changes"},
})
req, _ := http.NewRequest("POST", os.Getenv("CT_API")+"/competitors", bytes.NewReader(body))
req.Header.Set("X-API-Key", os.Getenv("CT_API_KEY"))
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)

A success is 201 Created with the new subscription. Using OAuth2 instead? Swap the header for -H "Authorization: Bearer $CT_TOKEN" and everything else is the same.

2. List what you track

curl "$CT_API/competitors" -H "X-API-Key: $CT_API_KEY"

The response carries items and a nextCursor. Pass it back as ?cursor=... to page through.

3. Read detected changes

Once two snapshots of a page exist (see the flow above), changes show up here:

curl "$CT_API/changes?since=2026-05-01T00:00:00.000Z" \
  -H "X-API-Key: $CT_API_KEY"

since is built for digest jobs: pass your last-run timestamp and you get only what's new.

4. Read an error

Every 4xx carries the same envelope:

{
  "code": "ValidationError",
  "message": "Request failed schema validation.",
  "resolution": "Check the request body, query and path parameters against /openapi.json and retry."
}

code is stable and safe to branch on. resolution is the next concrete step.

Where to go next

Pointing an AI agent at us? The whole site is available as plain text at /llms-full.txt, and the MCP server exposes these endpoints as tools.

On this page