Skip to Content
GuidesAlerts

Alerts

An alert tells you that the AI assistants got something wrong about the brand, or that something moved: a price hallucination (a model quotes a price that is not the catalogue’s), a wrong availability (a model says in stock / out of stock against the store), a visibility drop (the share fell between two weekly samplings) a new competitor cited on several queries, an invented spec (a model gives the product a characteristic its identity sheet does not state — claimed.specs lists them), or, for a physical establishment, wrong establishment facts (wrong_local_fact: a model states an address or a phone number that is not the one declared on the market — claimed.address / claimed.phone, claimed.wrong says which), or an SEO regression (seo_regression: between two SEO crawls of the market, a key page went into error, got a noindex, lost its Product schema, title tag, meta description or canonical, or robots.txt blocks a search bot — claimed.signal, claimed.pages[{url, before, after}], claimed.count, claimed.bots; one alert per signal and market, with no model nor query, resolved by itself on the crawl that finds the pages healthy again). The first two, wrong_local_fact and the blocking SEO regressions (error, noindex, schema, robots) are critical: a shopper may buy — or not — on a false promise.

Skoup opens one alert per incident: if the same wrong price comes back the next week, the open alert gathers the new occurrences instead of opening another one. Each alert carries its proof — the claim (claimed) against the catalogue (truth), per model.

Statuses of an alert

newseentreatedresolvedignored
An alert may skip seen, and may be ignored from new, seen or treated. resolved and ignored are final. resolved is never set by hand: only a verification re-sampling that no longer finds the claim sets it.

The loop is: you fix the cause (the price in the store, the stock, the product page), you treat the alert, then you verify it. Verifying re-asks the alert’s query to every model: if the claim is gone, the alert becomes resolved; if it is still there, it stays treated with persisted: true.

I want to…

I want to…Call
List the open critical alertsGET /v1/brands/{brand}/alerts?status=open&severity=critical
List the price hallucinations on FranceGET /v1/brands/{brand}/alerts?kind=price_hallucination&market=FR
Read one alert and its proofGET /v1/brands/{brand}/alerts/{alert}
Say the fix is madePOST /v1/brands/{brand}/alerts/{alert}/treat
Ignore an alertPOST /v1/brands/{brand}/alerts/{alert}/dismiss
Check the fix nowPOST /v1/brands/{brand}/alerts/{alert}/verify — quota Skoup-Quota-Verifications

status=open means new, seen and treated. Scopes: alerts:read, alerts:write. Events: alert.created, alert.updated (status change, with previous_attributes), alert.resolved.

Scenario: warn a client when a price hallucination appears

Subscribe an endpoint to alert.created, keep only price hallucinations, and send the proof to your client.

if (event.type === 'alert.created' && event.data.object.kind === 'price_hallucination') { const alert = event.data.object await notifyClient(alert.brand, { // `product` is null when the AI priced the brand without naming an offer. subject: alert.product?.title ?? 'the brand', // A range: from `price` to `price_max`; `period` says what the price buys. claimed: [alert.claimed?.price, alert.claimed?.price_max].filter(Boolean), truth: [alert.truth?.min, alert.truth?.max], period: alert.truth?.period, currency: alert.truth?.currency, }) }

Once the price is fixed in the store, close the loop:

curl -X POST https://api.skoup.ai/v1/brands/br_034PJIMnN3EOTCU3TMUdLS/alerts/alrt_031CQlTxUKUOFYaHSd3kBY/treat \ -H "Authorization: Bearer skoup_test_4eC39HqLyjWDarjtT1zdp7dc" curl -X POST https://api.skoup.ai/v1/brands/br_034PJIMnN3EOTCU3TMUdLS/alerts/alrt_031CQlTxUKUOFYaHSd3kBY/verify \ -H "Authorization: Bearer skoup_test_4eC39HqLyjWDarjtT1zdp7dc"

verify answers 202 when a re-sampling starts (200 when one is already running); the verdict arrives later as alert.resolved, or alert.updated with persisted: true.

Pitfalls

  • An SEO regression has no model nor query. first_seen_at is the end of the crawl that saw it, query and model are null, occurrences is 0: the proof is in claimed.pages. POST …/verify does not apply; it resolves on the next crawl (alert.resolved).
  • A quoted price is not always one number. claimed.price_kind is exact, range (from price to price_max), from or approximate; claimed.period (month, year, once) and claimed.unit (flat, per_user) say what it buys. A range that overlaps the real pricing opens no alert; a yearly price is only compared when the offer declares its price_annual.
  • A price alert may be about no product. When the AI prices the brand without naming an offer, claimed.scope is brand, product is null and truth is the envelope of every active offer (truth.min – truth.max, truth.offers). There is one per market, never one per plan.
  • Only a wrong exact price on a named offer is critical. A range, an approximation or a brand price that misses the pricing is medium; the severity of an open alert may rise, never fall.
  • truth.open_ended: an add-on on quote leaves the pricing open upwards; only a price under truth.min is then wrong.
  • Verify only a treated alert, otherwise the call answers 422.
  • Verifications are rationed: 10 per brand per rolling 24 hours, and one per query per hour. When the quota is spent, verify answers 422 quota_exceeded; read Skoup-Quota-Verifications (limit, remaining, reset) before retrying.
  • Transitions are one-way: a resolved or ignored alert cannot be reopened — if the incident comes back, a new alert opens.
  • An invented spec comes after the others: it is read in the Perception judgement, which ends after the sampling. It only exists for a product with an identity sheet, and its verification waits for that judgement too.
  • Establishment facts only exist for a local brand with a tracked establishment that declares an address or a phone; one alert per establishment (location: id, name, city); hours are reported (claimed.hours), never judged.
  • close_reason: rejudged: Skoup closed the alert itself because the claim no longer counts as wrong (a range that holds the pricing, for instance). It is ignored, comes through alert.updated — never alert.resolved — and cannot be restored.
  • Test mode: treat and verify answer like in live mode on the sandbox, but nothing is kept and no re-sampling runs.
Last updated on