REST API · v1

SiteGauge API

Programmatic access to your competitor intelligence: pull detected changes, competitors, battlecards and win/loss data straight into your own tools.

Base URLhttps://api.sitegauge.com/api/v1
Versionv1 (stable)
FormatJSON — all requests and responses use application/json
AccessIncluded on every plan

Authentication

All API requests require a Bearer token. Generate API keys from Settings → API Keys. Keys start with vgl_. API access is included on every plan.

curl "https://api.sitegauge.com/api/v1/changes" \
  -H "Authorization: Bearer vgl_your_api_key_here"

A key has full account access. It can read and change everything in your workspace, including billing - treat it like a password. It is shown once on creation; revoke and regenerate it from Settings if it leaks.

Rate limits

Rate limits scale with your plan: up to 60 requests per minute on Free, 120 on Standard, 300 on Pro, and 600 on Business and Enterprise. Exceeding your limit returns HTTP 429; wait for the next minute window and retry.

Errors

Errors return a JSON body of the form { "error": "...", "code": "..." } with a matching HTTP status.

StatusMeaning
401The API key is missing, invalid, revoked, or expired.
402This endpoint needs a higher plan (AI Q&A and profile generation require Pro or Enterprise).
404The resource does not exist in your workspace.
429You exceeded your plan's rate limit (60 to 600 requests per minute, depending on plan).

Changes

GET/changes

Returns a paginated feed of detected changes across your workspace, newest first. Dismissed changes are hidden by default. Each item is the full change record plus its parent monitor, the resulting snapshot, and a signed screenshot URL (extra change fields beyond those shown are also returned).

Query parameters

ParameterTypeDescription
pageintegerPage number, 1-based (default: 1)
pageSizeintegerResults per page, 1-100 (default: 20)
severitystringFilter by LOW, MEDIUM, HIGH or CRITICAL. An invalid value returns 400.
significantbooleantrue / false to filter on significance
dismissedbooleanBy default only non-dismissed changes are returned. Pass true to see dismissed ones, false to force non-dismissed.
categorystringExact match on the change category (e.g. pricing, feature, design)
competitorIdstringFilter to changes on a competitor's pages
tagstringFilter to monitors carrying this tag
typestringComma-separated change types; matches any (e.g. pricing,text_change)
searchstringFree-text search over the URL, display name and AI summary
domainstringScope to monitors on a host, e.g. stripe.com
sortstringscore, page or createdAt (default: createdAt)
orderstringasc or desc (default: desc)

Example request

curl -X GET "https://api.sitegauge.com/api/v1/changes?significant=true&pageSize=5" \
  -H "Authorization: Bearer vgl_your_api_key"

Example response

{
  "data": [
    {
      "id": "chg_abc123",
      "urlId": "url_xyz",
      "severity": "HIGH",
      "isSignificant": true,
      "changeCategory": "pricing",
      "changeScore": 82,
      "importanceScore": 8,
      "aiSummary": "Pricing page updated: Pro plan increased from $49 to $59/mo",
      "changeTypes": ["pricing", "text_change"],
      "isDismissed": false,
      "createdAt": "2026-05-10T09:00:00Z",
      "url": {
        "id": "url_xyz",
        "url": "https://competitor.com/pricing",
        "displayName": "Competitor Pricing",
        "tags": ["pricing"],
        "isCompetitor": true,
        "faviconUrl": "https://cdn.sitegauge.com/favicons/acme.png"
      },
      "toSnapshot": {
        "id": "snap_123",
        "pageTitle": "Pricing - Competitor",
        "metaDescription": "Simple, transparent pricing",
        "statusCode": 200,
        "createdAt": "2026-05-10T09:00:00Z"
      },
      "screenshotUrl": "https://cdn.sitegauge.com/shots/chg_abc123.png"
    }
  ],
  "meta": { "total": 142, "page": 1, "pageSize": 20, "hasMore": true }
}

Competitors

GET/competitors

Returns every competitor in your workspace with its AI profile (if one has been generated) and its tracked pages. Not paginated.

Example request

curl -X GET "https://api.sitegauge.com/api/v1/competitors" \
  -H "Authorization: Bearer vgl_your_api_key"

Example response

{
  "data": [
    {
      "id": "cmp_abc",
      "name": "Acme Corp",
      "domain": "acme.com",
      "description": "Enterprise workflow automation",
      "logoUrl": null,
      "aiProfile": {
        "tagline": "Enterprise workflow automation",
        "industry": "SaaS",
        "pricingModel": "per-seat subscription",
        "targetCustomer": "Mid-market ops teams"
      },
      "aiProfileGeneratedAt": "2026-02-01T00:00:00Z",
      "uptimeEnabled": false,
      "createdAt": "2026-01-15T00:00:00Z",
      "updatedAt": "2026-02-01T00:00:00Z",
      "urls": [
        {
          "id": "url_1",
          "url": "https://acme.com/pricing",
          "displayName": "Acme Pricing",
          "workflow": "COMPETITOR",
          "status": "ACTIVE",
          "lastCrawledAt": "2026-05-10T08:00:00Z",
          "lastChangeAt": "2026-05-10T09:00:00Z"
        }
      ]
    }
  ]
}

// aiProfile is null until you run generate-profile; its keys are AI-written and vary.
POST/competitors

Add a competitor. Returns 409 if the domain is already tracked in your workspace.

Request body

ParameterTypeDescription
name*stringDisplay name
domain*stringRoot domain, e.g. acme.com
descriptionstringOptional short description
logoUrlstringOptional logo URL

Example request

curl -X POST "https://api.sitegauge.com/api/v1/competitors" \
  -H "Authorization: Bearer vgl_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"name": "Acme Corp", "domain": "acme.com"}'

Example response

{
  "data": {
    "id": "cmp_new",
    "name": "Acme Corp",
    "domain": "acme.com",
    "description": null,
    "logoUrl": null,
    "aiProfile": null,
    "createdAt": "2026-05-10T10:00:00Z"
  }
}
GET/competitors/:id

Fetch a single competitor, including all of its tracked pages.

Example request

curl -X GET "https://api.sitegauge.com/api/v1/competitors/cmp_abc" \
  -H "Authorization: Bearer vgl_your_api_key"

Example response

{
  "data": {
    "id": "cmp_abc",
    "name": "Acme Corp",
    "domain": "acme.com",
    "aiProfile": { "tagline": "Enterprise workflow automation" },
    "urls": [
      { "id": "url_1", "url": "https://acme.com/pricing", "status": "ACTIVE", "crawlFrequency": "DAILY" }
    ]
  }
}
PATCH/competitors/:id

Update a competitor's name, description or logo. The domain cannot be changed once set.

Request body

ParameterTypeDescription
namestringNew display name
descriptionstringNew description
logoUrlstringNew logo URL

Example request

curl -X PATCH "https://api.sitegauge.com/api/v1/competitors/cmp_abc" \
  -H "Authorization: Bearer vgl_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"description": "Enterprise workflow automation, US-based"}'

Example response

{ "data": { "success": true } }
DELETE/competitors/:id

Delete a competitor. Its tracked pages are unlinked from the competitor, not deleted. Returns 204 No Content.

Example request

curl -X DELETE "https://api.sitegauge.com/api/v1/competitors/cmp_abc" \
  -H "Authorization: Bearer vgl_your_api_key"

Example response

HTTP/1.1 204 No Content
POST/competitors/:id/ask

Ask a natural-language question about a competitor. The AI answers from their recent significant changes. Requires a Pro or Enterprise plan (402 otherwise).

Request body

ParameterTypeDescription
question*stringYour question, 1-500 characters

Example request

curl -X POST "https://api.sitegauge.com/api/v1/competitors/cmp_abc/ask" \
  -H "Authorization: Bearer vgl_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"question": "Did they raise prices recently?"}'

Example response

{
  "data": {
    "answer": "Yes - their pricing page changed 12 days ago. The Pro plan increased from $49 to $59/mo and they removed the legacy Starter tier."
  }
}
POST/competitors/:id/generate-profile

Generate or refresh a competitor's AI profile from their site and recent changes. Requires a Pro or Enterprise plan (402 otherwise). The returned profile keys are AI-written and vary.

Example request

curl -X POST "https://api.sitegauge.com/api/v1/competitors/cmp_abc/generate-profile" \
  -H "Authorization: Bearer vgl_your_api_key"

Example response

{
  "data": {
    "profile": {
      "tagline": "Enterprise workflow automation",
      "industry": "SaaS",
      "targetCustomer": "Mid-market operations teams",
      "keyProducts": ["Workflow Builder", "Analytics"],
      "pricingModel": "per-seat subscription",
      "strengthSummary": "Deep integrations and enterprise controls."
    }
  }
}

Battlecards

GET/battlecards

Returns your battlecards, newest first, each with its competitor and creator. `sections` is a free-form object; the AI may include positioning, ourStrengths, theirWeaknesses, commonObjections, useCases and talkingPoints. `generatedBy` is the id of the user who created the card (the same user in `creator`).

Query parameters

ParameterTypeDescription
competitorIdstringOptional. Filter to one competitor; omit to return all battlecards.

Example request

curl -X GET "https://api.sitegauge.com/api/v1/battlecards?competitorId=cmp_abc" \
  -H "Authorization: Bearer vgl_your_api_key"

Example response

{
  "data": [
    {
      "id": "bc_xyz",
      "competitorId": "cmp_abc",
      "title": "Acme Corp Battlecard",
      "isPublished": true,
      "sections": {
        "positioning": "We win on ease-of-use and faster onboarding.",
        "ourStrengths": ["No per-seat pricing", "SOC 2 certified"],
        "theirWeaknesses": ["Complex setup", "No free trial"],
        "talkingPoints": ["Lead with time-to-value"]
      },
      "generatedBy": "8f14e45f-ceea-467a-9e0f-1c2d3b4a5e6f",
      "createdAt": "2026-05-01T00:00:00Z",
      "updatedAt": "2026-05-09T08:00:00Z",
      "competitor": { "id": "cmp_abc", "name": "Acme Corp", "domain": "acme.com" },
      "creator": { "fullName": "Jordan Lee", "email": "jordan@yourco.com" }
    }
  ]
}
GET/battlecards/:id

Fetch a single battlecard, including the competitor's AI profile.

Example request

curl -X GET "https://api.sitegauge.com/api/v1/battlecards/bc_xyz" \
  -H "Authorization: Bearer vgl_your_api_key"

Example response

{
  "data": {
    "id": "bc_xyz",
    "competitorId": "cmp_abc",
    "title": "Acme Corp Battlecard",
    "isPublished": true,
    "sections": { "positioning": "..." },
    "competitor": { "id": "cmp_abc", "name": "Acme Corp", "domain": "acme.com", "aiProfile": { "industry": "SaaS" } },
    "creator": { "fullName": "Jordan Lee" }
  }
}
POST/battlecards/generate

AI-generates a battlecard for a competitor from their profile and recent changes. The title is set automatically ("<Competitor> Battlecard"). Returns 201 with the created record (no nested relations).

Request body

ParameterTypeDescription
competitorId*stringThe competitor to build a card for

Example request

curl -X POST "https://api.sitegauge.com/api/v1/battlecards/generate" \
  -H "Authorization: Bearer vgl_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"competitorId": "cmp_abc"}'

Example response

{
  "data": {
    "id": "bc_new",
    "competitorId": "cmp_abc",
    "title": "Acme Corp Battlecard",
    "sections": { "positioning": "...", "ourStrengths": ["..."] },
    "isPublished": false,
    "generatedBy": "8f14e45f-ceea-467a-9e0f-1c2d3b4a5e6f",
    "createdAt": "2026-05-10T10:00:00Z",
    "updatedAt": "2026-05-10T10:00:00Z"
  }
}
PUT/battlecards/:id

Update a battlecard's title, sections, or published state.

Request body

ParameterTypeDescription
titlestringNew title
sectionsobjectReplacement sections object (free-form)
isPublishedbooleanPublish or unpublish the card

Example request

curl -X PUT "https://api.sitegauge.com/api/v1/battlecards/bc_xyz" \
  -H "Authorization: Bearer vgl_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"isPublished": true}'

Example response

{
  "data": { "id": "bc_xyz", "title": "Acme Corp Battlecard", "isPublished": true, "sections": { "positioning": "..." } }
}
DELETE/battlecards/:id

Delete a battlecard. Returns 204 No Content.

Example request

curl -X DELETE "https://api.sitegauge.com/api/v1/battlecards/bc_xyz" \
  -H "Authorization: Bearer vgl_your_api_key"

Example response

HTTP/1.1 204 No Content

Win / Loss

GET/win-loss

Returns win/loss records (newest first) plus aggregate stats. Note: `stats` is always computed across your whole workspace and ignores the competitorId / outcome filters, which apply only to `data` and `total`.

Query parameters

ParameterTypeDescription
competitorIdstringFilter records by competitor
outcomestringWIN, LOSS, DRAW or NO_DECISION
pageintegerPage number (default: 1)
pageSizeintegerResults per page, 1-100 (default: 20)

Example request

curl -X GET "https://api.sitegauge.com/api/v1/win-loss?outcome=WIN" \
  -H "Authorization: Bearer vgl_your_api_key"

Example response

{
  "data": [
    {
      "id": "wl_abc",
      "competitorId": "cmp_abc",
      "outcome": "WIN",
      "opportunityName": "ACME vs Us - Q2 Enterprise Deal",
      "dealSizeUsd": 48000,
      "closeDate": "2026-04-30T00:00:00Z",
      "ourStrengths": ["Better support", "Easier onboarding"],
      "theirStrengths": ["Lower headline price"],
      "reasonNotes": "Won on support SLA.",
      "crmId": "0061t00000xyz",
      "createdAt": "2026-05-01T00:00:00Z",
      "competitor": { "id": "cmp_abc", "name": "Acme Corp", "domain": "acme.com" },
      "creator": { "fullName": "Jordan Lee", "email": "jordan@yourco.com" }
    }
  ],
  "total": 17,
  "stats": {
    "total": 17, "wins": 12, "losses": 5, "draws": 0, "noDecision": 0,
    "avgDealSize": 41000,
    "byCompetitor": [
      { "competitorId": "cmp_abc", "competitorName": "Acme Corp", "wins": 8, "losses": 2, "total": 10 }
    ]
  }
}
POST/win-loss

Log a win/loss record. `closeDate` must be a full ISO 8601 datetime. Returns 201.

Request body

ParameterTypeDescription
competitorId*stringThe competitor this deal was against
outcome*stringWIN, LOSS, DRAW or NO_DECISION
closeDate*stringISO 8601 datetime, e.g. 2026-04-30T00:00:00Z
opportunityNamestringDeal / opportunity name
dealSizeUsdintegerDeal size in USD
ourStrengthsstring[]Why we won / where we were strong
theirStrengthsstring[]Where the competitor was strong
reasonNotesstringFree-text notes
crmIdstringExternal CRM record id

Example request

curl -X POST "https://api.sitegauge.com/api/v1/win-loss" \
  -H "Authorization: Bearer vgl_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"competitorId": "cmp_abc", "outcome": "WIN", "closeDate": "2026-04-30T00:00:00Z", "dealSizeUsd": 48000}'

Example response

{
  "data": {
    "id": "wl_new",
    "competitorId": "cmp_abc",
    "outcome": "WIN",
    "dealSizeUsd": 48000,
    "closeDate": "2026-04-30T00:00:00Z",
    "createdAt": "2026-05-10T10:00:00Z",
    "competitor": { "id": "cmp_abc", "name": "Acme Corp" }
  }
}
PUT/win-loss/:id

Update a win/loss record. The competitor cannot be reassigned.

Request body

ParameterTypeDescription
outcomestringWIN, LOSS, DRAW or NO_DECISION
opportunityNamestringDeal / opportunity name
dealSizeUsdintegerDeal size in USD
closeDatestringISO 8601 datetime
ourStrengthsstring[]Why we won / where we were strong
theirStrengthsstring[]Where the competitor was strong
reasonNotesstringFree-text notes
crmIdstringExternal CRM record id

Example request

curl -X PUT "https://api.sitegauge.com/api/v1/win-loss/wl_abc" \
  -H "Authorization: Bearer vgl_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"reasonNotes": "Confirmed: won on support SLA."}'

Example response

{ "data": { "id": "wl_abc", "outcome": "WIN", "reasonNotes": "Confirmed: won on support SLA." } }
DELETE/win-loss/:id

Delete a win/loss record. Returns 204 No Content.

Example request

curl -X DELETE "https://api.sitegauge.com/api/v1/win-loss/wl_abc" \
  -H "Authorization: Bearer vgl_your_api_key"

Example response

HTTP/1.1 204 No Content

Saved Intel

GET/bookmarks

Returns the changes you (the key's owner) have bookmarked, newest first. Bookmarks are per-user within a workspace.

Query parameters

ParameterTypeDescription
pageintegerPage number (default: 1)
pageSizeintegerResults per page, 1-100 (default: 20)

Example request

curl -X GET "https://api.sitegauge.com/api/v1/bookmarks" \
  -H "Authorization: Bearer vgl_your_api_key"

Example response

{
  "data": [
    {
      "id": "bk_abc",
      "changeId": "chg_abc123",
      "note": "Follow up with pricing team",
      "createdAt": "2026-05-08T12:00:00Z",
      "change": {
        "id": "chg_abc123",
        "severity": "HIGH",
        "isSignificant": true,
        "changeCategory": "pricing",
        "aiSummary": "Pricing page updated...",
        "changeTypes": ["pricing"],
        "createdAt": "2026-05-08T09:00:00Z",
        "url": {
          "url": "https://competitor.com/pricing",
          "displayName": "Competitor Pricing",
          "competitor": { "name": "Acme Corp" }
        }
      }
    }
  ],
  "total": 7
}
POST/bookmarks

Bookmark a change. This is an upsert: calling it again for the same change updates the note (posting with no note clears it). Returns 201 with the flat bookmark record.

Request body

ParameterTypeDescription
changeId*stringThe change to bookmark
notestringOptional private note, max 500 characters

Example request

curl -X POST "https://api.sitegauge.com/api/v1/bookmarks" \
  -H "Authorization: Bearer vgl_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"changeId": "chg_abc123", "note": "Follow up with pricing team"}'

Example response

{
  "data": { "id": "bk_abc", "changeId": "chg_abc123", "note": "Follow up with pricing team", "createdAt": "2026-05-08T12:00:00Z" }
}
DELETE/bookmarks/:changeId

Remove a bookmark by change id. Idempotent - deleting a change you have not bookmarked still returns 204.

Example request

curl -X DELETE "https://api.sitegauge.com/api/v1/bookmarks/chg_abc123" \
  -H "Authorization: Bearer vgl_your_api_key"

Example response

HTTP/1.1 204 No Content
Need help? Email support@sitegauge.com