Skip to main content

Tutorial: Setup Automated Monitoring

This tutorial walks through setting up automated monitoring for your site using projects, tests, build schedules, and webhook notifications.

note

In Lumar's GraphQL schema, Project and TestSuite both implement the BaseProject interface and are effectively the same entity. This tutorial uses project-centric language. Some mutations still use testSuiteId as a parameter name -- pass your project ID to these fields.

Overview

Lumar's monitoring workflow consists of:

  1. Projects -- containers that group tests, builds, and monitoring configuration.
  2. Tests -- individual assertions (e.g., "Broken pages must be below 10").
  3. Build Schedules -- cron-based schedules that automatically trigger builds.
  4. Webhooks -- notifications sent when builds complete.

Step 1: Find or create a project

Query existing monitor projects for your account:

Operation: query GetMonitorProjects($accountId: ObjectID!) { getAccount(id: $accountId) { monitorProjects(first: 10) { nodes { id name lastFinishedCrawl { id status createdAt } } totalCount } } }Variables: { "accountId": "TjAwN0FjY291bnQ3MTU" }Response Example: { "data": { "getAccount": { "monitorProjects": { "nodes": [ { "id": "TjAxMVRlc3RTdWl0ZTEyMw", "name": "Production SEO Suite", "lastFinishedCrawl": { "id": "TjAwNUNyYXdsMTc2NjI0MQ", "status": "Finished", "createdAt": "2025-01-15T10:00:00.000Z" } } ], "totalCount": 1 } } } }
GetMonitorProjectsTry in Explorer
GraphQL
query GetMonitorProjects($accountId: ObjectID!) {
getAccount(id: $accountId) {
monitorProjects(first: 10) {
nodes {
id
name
lastFinishedCrawl {
id
status
createdAt
}
}
totalCount
}
}
}

If you need to create a project, see the Protect documentation for the createTestSuite mutation.

Step 2: Add tests

Tests define the thresholds for your monitoring. You can add both report-level tests and health score tests.

For health score tests:

Operation: mutation CreateHealthScoreTest($input: CreateHealthScoreTestInput!) { createHealthScoreTest(input: $input) { healthScoreTest { absoluteThreshold automaticThresholdEnabled reportCategoryCode severity thresholdPredicate thresholdType } } }Variables: { "input": { "testSuiteId": "TjAxMVRlc3RTdWl0ZTEyMw", "reportCategoryCode": "seo", "absoluteThreshold": 0.8, "thresholdType": "Relative", "relativeThreshold": 10, "severity": "Fail", "automaticThresholdEnabled": false } }Response Example: { "data": { "createHealthScoreTest": { "healthScoreTest": { "absoluteThreshold": 0.8, "automaticThresholdEnabled": false, "reportCategoryCode": "seo", "severity": "Fail", "thresholdPredicate": "GreaterThanOrEqual", "thresholdType": "Relative" } } } }
CreateHealthScoreTestTry in Explorer
GraphQL
mutation CreateHealthScoreTest($input: CreateHealthScoreTestInput!) {
createHealthScoreTest(input: $input) {
healthScoreTest {
absoluteThreshold
automaticThresholdEnabled
reportCategoryCode
severity
thresholdPredicate
thresholdType
}
}
}

For report-level tests, see the Tests documentation.

Step 3: Check build schedules

Review existing build schedules:

Operation: query GetBuildSchedules($accountId: ObjectID!) { getAccount(id: $accountId) { buildSchedules(first: 5) { nodes { id repetitionRate nextRunAt buildScheduleTestSuites(first: 5) { nodes { testSuite { id name } } } } totalCount } } }Variables: { "accountId": "TjAwN0FjY291bnQ3MTU" }Response Example: { "data": { "getAccount": { "buildSchedules": { "nodes": [ { "id": "TjAzN0J1aWxkU2NoZWR1bGUx", "repetitionRate": "Weekly", "nextRunAt": "2025-01-20T00:00:00.000Z", "buildScheduleTestSuites": { "nodes": [ { "testSuite": { "id": "TjAxMVRlc3RTdWl0ZTEyMw", "name": "Production SEO Suite" } } ] } } ], "totalCount": 1 } } } }
GetBuildSchedulesTry in Explorer
GraphQL
query GetBuildSchedules($accountId: ObjectID!) {
getAccount(id: $accountId) {
buildSchedules(first: 5) {
nodes {
id
repetitionRate
nextRunAt
buildScheduleTestSuites(first: 5) {
nodes {
testSuite {
id
name
}
}
}
}
totalCount
}
}
}

Build schedules use cron expressions. Common examples:

ScheduleCron Expression
Every Monday at midnight0 0 * * 1
Daily at 6am0 6 * * *
Every 6 hours0 */6 * * *
First of every month0 0 1 * *

To create or manage build schedules, see the Build Schedules documentation.

Step 4: Trigger a build manually (optional)

You can trigger a build immediately without waiting for the schedule:

Operation: mutation CreateAndRunBuild($input: CreateAndRunBuildInput!) { createAndRunBuild(input: $input) { build { id status createdAt } } }Variables: { "input": { "testSuiteId": "TjAxMVRlc3RTdWl0ZTEyMw" } }Response Example: { "data": { "createAndRunBuild": { "build": { "id": "TjAxMkJ1aWxkNDU3", "status": "Queued", "createdAt": "2025-01-15T10:00:00.000Z" } } } }
CreateAndRunBuildTry in Explorer
GraphQL
mutation CreateAndRunBuild($input: CreateAndRunBuildInput!) {
createAndRunBuild(input: $input) {
build {
id
status
createdAt
}
}
}

Step 5: Set up webhooks

Configure Slack notifications so your team is alerted when builds complete:

Operation: mutation CreateSlackWebhook($input: CreateSlackWebhookInput!) { createAutomatorSlackWebhook(input: $input) { slackWebhook { id url alertTypes createdAt } } }Variables: { "input": { "testSuiteId": "TjAxMVRlc3RTdWl0ZTEyMw", "url": "https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX", "alertTypes": ["Pass", "Warning", "Fail"] } }Response Example: { "data": { "createAutomatorSlackWebhook": { "slackWebhook": { "id": "TjAzN1NsYWNrV2ViaG9vazE", "url": "https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX", "alertTypes": ["Pass", "Warning", "Fail"], "createdAt": "2025-01-15T10:00:00.000Z" } } } }
CreateSlackWebhookTry in Explorer
GraphQL
mutation CreateSlackWebhook($input: CreateSlackWebhookInput!) {
createAutomatorSlackWebhook(input: $input) {
slackWebhook {
id
url
alertTypes
createdAt
}
}
}

Or set up an API callback webhook:

Operation: mutation CreateWebhook($input: CreateWebhookInput!) { createWebhook(input: $input) { webhook { id url alertTypes webhookTemplateType createdAt } } }Variables: { "input": { "testSuiteId": "TjAxMVRlc3RTdWl0ZTEyMw", "url": "https://example.com/api/lumar-webhook", "alertTypes": ["Pass", "Warning", "Fail"], "webhookTemplateType": "MSTeams" } }Response Example: { "data": { "createWebhook": { "webhook": { "id": "TjAzN1dlYmhvb2sx", "url": "https://example.com/api/lumar-webhook", "alertTypes": ["Pass", "Warning", "Fail"], "webhookTemplateType": "MSTeams", "createdAt": "2025-01-15T10:00:00.000Z" } } } }
CreateWebhookTry in Explorer
GraphQL
mutation CreateWebhook($input: CreateWebhookInput!) {
createWebhook(input: $input) {
webhook {
id
url
alertTypes
webhookTemplateType
createdAt
}
}
}

Step 6: Review results

After a build completes, query the project's test results:

Operation: query GetTestResults($testSuiteId: ObjectID!) { node(id: $testSuiteId) { ... on TestSuite { id name builds(first: 1, orderBy: [{ field: createdAt, direction: DESC }]) { nodes { id status createdAt testResults(first: 10) { nodes { id passed reportTemplate { code name } absoluteThreshold reportTotalRows severity } totalCount } } } } } }Variables: { "testSuiteId": "TjAxMVRlc3RTdWl0ZTEyMw" }Response Example: { "data": { "node": { "id": "TjAxMVRlc3RTdWl0ZTEyMw", "name": "Production SEO Suite", "builds": { "nodes": [ { "id": "TjAxMkJ1aWxkNDU2", "status": "Finished", "createdAt": "2025-01-15T10:00:00.000Z", "testResults": { "nodes": [ { "id": "TjAxM1Rlc3RSZXN1bHQ3ODk", "passed": true, "reportTemplate": { "code": "broken_pages", "name": "Broken Pages" }, "absoluteThreshold": 5.0, "reportTotalRows": 2.0, "severity": "Fail" } ], "totalCount": 1 } } ] } } } }
GetTestResultsTry in Explorer
GraphQL
query GetTestResults($testSuiteId: ObjectID!) {
node(id: $testSuiteId) {
... on TestSuite {
id
name
builds(first: 1, orderBy: [{ field: createdAt, direction: DESC }]) {
nodes {
id
status
createdAt
testResults(first: 10) {
nodes {
id
passed
reportTemplate {
code
name
}
absoluteThreshold
reportTotalRows
severity
}
totalCount
}
}
}
}
}
}

Next steps