New to Kestra?
Use blueprints to kickstart your first workflows.
Run a canary search against Algolia and alert Slack the instant a query that should always match comes back empty.
An Algolia index that silently goes empty - a broken reindex job, an
accidental bulk delete, a sync pipeline that stopped halfway - produces
no error on its own; the search API still responds 200 OK, it just
returns zero hits. Customers see a blank results page long before anyone
notices in a dashboard. This blueprint runs a canary search on a schedule
and alerts Slack the moment a query that should reliably match comes back
under a configured threshold, or the index target itself is unreachable.
periodic_canary_search (io.kestra.plugin.core.trigger.Schedule) runs every 15 minutes, explicitly passing index_name, canary_query, and min_expected_hits through its own inputs: block so the flow is self-contained when the trigger fires. Shipped disabled so a manual run can be verified first.probe_canary_search (io.kestra.plugin.algolia.Search) issues a single read-only query against the target index and captures Algolia's own nbHits total match count.evaluate_index_health (io.kestra.plugin.core.flow.If) branches on whether nbHits meets or exceeds min_expected_hits.then (HEALTHY): log_index_healthy records the pass.else (INDEX_EMPTY_OR_DEGRADED): alert_index_unhealthy reports the shortfall to Slack with the exact hit count and threshold.log_audit_complete always runs last, printing the final nbHits regardless of which branch fired.errors block alerts Slack separately if the search call itself throws - a deleted index, an invalid application ID or API key, or an unreachable API - deliberately kept distinct from an empty-but-existing index, since the two failure modes need different fixes.INDEX_EMPTY_OR_DEGRADED, handled by the If branch) and "index target itself is gone or credentials are wrong" (handled by the flow-level errors block) - two different incidents that call for different responses.min_expected_hits threshold so a seeded heartbeat record (or any query known to always match at least N records) can be audited precisely, not just checked for "any result at all."io.kestra.plugin.algolia.Search, a plugin with no prior blueprint coverage of its read path in this repository (the one existing Algolia blueprint covers index sync, not search availability).Search task used for monitoring rather than for building search UI.Algolia has no built-in "alert me if this query stops matching" primitive - its own dashboard shows search analytics and index size, but nothing that proactively watches a specific query's hit count over time. Kestra supplies the schedule, the HEALTHY/INDEX_EMPTY_OR_DEGRADED classification as a first-class branch, the execution history showing exactly when the canary first failed, and a clear separation between "empty index" and "unreachable index" failure modes.
ALGOLIA_APP_ID / ALGOLIA_API_KEY secrets).Local testing: Algolia is a hosted SaaS search service with no official self-hosted or Docker emulator - the Search task always calls the real Algolia API. A free, no-credit-card account is sufficient to exercise this blueprint end to end; no paid enterprise tier or portal account is required.
ALGOLIA_APP_ID / ALGOLIA_API_KEY: credentials for io.kestra.plugin.algolia.Search, matching the plugin's own documented example usage of secret('ALGOLIA_APP_ID') / secret('ALGOLIA_API_KEY').SLACK_WEBHOOK_URL: Slack incoming webhook used by alert_index_unhealthy and the errors block.SECRET_, base64-encoded - for example SECRET_ALGOLIA_API_KEY=$(echo -n '<your-api-key>' | base64) - and read back in flows with {{ secret('NAME') }}.index_name (STRING, default <your-algolia-index>, must be replaced): the index audited.canary_query (STRING, default ""): the query text expected to reliably match. An empty string matches every record in the index (the Search task's own documented default behavior), making it the simplest possible canary - any result at all proves the index is reachable and non-empty.min_expected_hits (INT, default 1): the floor nbHits must meet or exceed to be classified HEALTHY.outputs.probe_canary_search.nbHits (Integer): Algolia's own total match count for the query (verified field from the Search task's Output class).outputs.probe_canary_search.hits (List): up to hitsPerPage matching records themselves, capped at 1 in this blueprint since only the count is used for classification.ALGOLIA_APP_ID, ALGOLIA_API_KEY, and SLACK_WEBHOOK_URL secrets.canary_query left empty and confirm log_index_healthy fires with nbHits matching your record count.canary_query to a term you know does not exist, or min_expected_hits above your real record count, and re-run to confirm alert_index_unhealthy fires.index_name to a nonexistent index and re-run to confirm the errors block fires separately from the HEALTHY/INDEX_EMPTY_OR_DEGRADED branches.periodic_canary_search once you trust the check against your real index.index_name / canary_query pairs with io.kestra.plugin.core.flow.Loop to audit every index in an Algolia application in one run.Search task with a numericFilters param (for example updatedAt > <N minutes ago>) to additionally audit ingestion freshness, not just index non-emptiness - kept out of this sentinel since it depends on a schema attribute this blueprint cannot assume exists.io.kestra.plugin.core.flow.Subflow when INDEX_EMPTY_OR_DEGRADED fires, behind an explicit approval gate.nbHits reflects total matches across the whole index, not just the returned page. hitsPerPage: 1 keeps the response small without affecting the count used for classification - verified directly from the Search task's source, which reads response.getNbHits() independently of hitsPerPage.canary_query matches everything, which is the weakest possible canary - it only proves the index is non-empty, not that any particular record type is present. For a stronger check, seed a dedicated heartbeat record with a unique, stable attribute value and query for that instead.nbHits/hits output fields, and the empty-query-matches-all behavior are taken verbatim from the Algolia plugin's own source and Javadoc - but no Kestra engine was run to execute this flow end to end.