Skip to main content
A keyword alert fires when a new article matches a query such as "harbour strike" AND (ferry OR port) NOT football. Quivr records each catch as a Match with the words that matched, and sends it to your webhook. The first-party alerts plugin decides the matches.

Prerequisites

  • The alerts plugin pinned. The local stack pins it; elsewhere see Pin a plugin.
  • QUIVR_API_URL and a QUIVR_API_KEY with monitoring:read and monitoring:write, plus content:write to add the test article below.
  • QUIVR_DESTINATION: the id of a webhook destination the operator configured for your Organization. Destinations live in Quivr’s configuration, never in API requests. The local stack’s make env sets one that delivers nowhere.

Write the query

  • Operators are written in capitals; and, or and not in lower case are ordinary words. NOT binds tighter than AND, which binds tighter than OR.
  • Case, accents and punctuation are ignored: greve finds “Grève”.
  • Words match whole, and there is no stemming: strike does not find “strikes”. List the forms you need, strike OR strikes.
  • Terms search the title and body Parts.
  • source:, origin: (client or connector), producer:, connector: and connector_kind: filter on metadata Quivr always has. Other names, such as author:, work once the operator maps them (below).

Turn it into an expression

Quivr stores a query as a JSON tree, which it validates when you save the alert, so a mistake is refused at once instead of silently never matching. The plugin ships the parser. From a quivr-v2 checkout:
An application can also build the tree from a form: all, any and not map to “all of these words”, “any of these words” and “none of these words”.

Save the alert

These requests use a Corpus of their own:
The Saved Query holds the expression and the Corpora it watches:
The Subscription turns it on, with the alerts plugin as evaluator. Give it an owner when the alert belongs to one of your application’s users: Quivr echoes it on every Match and webhook, so you can route each alert, and GET /v0/subscriptions?owner=user-123 lists that user’s alerts.
The alert judges articles that become searchable from now on. Earlier articles are never judged; to see what a query would have caught before saving it, use POST /v0/subscription-previews.

Read what matched

Add an article that matches:
Within seconds a Match appears, with its evidence:
The explanation lists the terms that made the article match and the Parts where each was found. Terms under NOT are never listed. evidence.details has the same facts as JSON.

Receive the webhook

For each Match, Quivr sends a POST to the destination’s URL. The body only references what happened; fetch the Match with GET /v0/matches/{match_id} to read its evidence:
Verify the signature before you parse the body. Requests follow Standard Webhooks: the webhook-signature header holds an HMAC-SHA256 of webhook-id, webhook-timestamp and the raw body, keyed with the secret the operator configured for the destination. Answer with a 2xx status to acknowledge. Timeouts, 408, 429 and 5xx answers are retried with exponential backoff, from 1 second up to 5 minutes, for 24 hours; any other answer stops the retries. Delivery is at least once, and a retry sends the same event_id and the same bytes, so deduplicate on webhook-id. GET /v0/deliveries/{delivery_id} shows a delivery’s state and its attempts. When an article that matched changes, the Subscription gets a follow-up: match.corrected when a correction still matches (a new Match linked to the earlier one), match.no_longer_matches when it does not, and match.withdrawn when the article is withdrawn.

Change or stop an alert

Filter on your own metadata

Names such as author or category depend on where your sources put that information, usually in a Version extension. The operator maps each name to a JSON Pointer in the alerts pin’s configuration:
QUIVR_CONFIG
A list field matches when one of its values does. A name the operator has not mapped never matches, and the plugin logs a warning.

Timing

A keyword alert is decided as soon as the article becomes searchable, before its vectors are computed. Set {"wait_for_enrichment": true} in the Subscription’s evaluator.configuration to wait for them. To match articles by subject rather than by words, use described alerts.