Tutorial: Track SEO Health Over Time
This tutorial shows how to use health scores, trends, segments, and tests to monitor your site's SEO performance over time.
Step 1: Get the current health score
After a crawl finishes, query the overall SEO health score:
- Query
- Variables
- Response
- cURL
query GetOverallHealth($crawlId: ObjectID!) {
getCrawl(id: $crawlId) {
id
status
healthScores(reportCategoryCodes: ["seo"]) {
healthScore
reportCategoryCode
}
}
}
{
"crawlId": "TjAwNUNyYXdsMTU4MzI0NQ"
}
{
"data": {
"getCrawl": {
"id": "TjAwNUNyYXdsMTU4MzI0NQ",
"status": "Finished",
"healthScores": [
{
"healthScore": 85.4,
"reportCategoryCode": "seo"
}
]
}
}
}
curl -X POST -H "Content-Type: application/json" -H "apollographql-client-name: docs-example-client" -H "apollographql-client-version: 1.0.0" -H "x-auth-token: YOUR_API_SESSION_TOKEN" --data '{"query":"query GetOverallHealth($crawlId: ObjectID!) { getCrawl(id: $crawlId) { id status healthScores(reportCategoryCodes: [\"seo\"]) { healthScore reportCategoryCode } } }","variables":{"crawlId":"TjAwNUNyYXdsMTU4MzI0NQ"}}' https://api.lumar.io/graphql
The health score is a value from 0 to 100, calculated from the pass/fail results of all health score tests in the seo report category.
Step 2: View health score trends
Track how your health score changes across crawls to identify improvements or regressions:
- Query
- Variables
- Response
- cURL
query GetHealthTrend($crawlId: ObjectID!) {
getHealthScoreTrendForCrawl(crawlId: $crawlId, first: 5) {
nodes {
crawlId
healthScores {
healthScore
reportCategoryCode
}
}
totalCount
}
}
{
"crawlId": "TjAwNUNyYXdsMTU4MzI0NQ"
}
{
"data": {
"getHealthScoreTrendForCrawl": {
"nodes": [
{
"crawlId": "TjAwNUNyYXdsMTU4MzI0Mw",
"healthScores": [
{
"healthScore": 80.1,
"reportCategoryCode": "seo"
}
]
},
{
"crawlId": "TjAwNUNyYXdsMTU4MzI0NQ",
"healthScores": [
{
"healthScore": 85.4,
"reportCategoryCode": "seo"
}
]
}
],
"totalCount": 2
}
}
}
curl -X POST -H "Content-Type: application/json" -H "apollographql-client-name: docs-example-client" -H "apollographql-client-version: 1.0.0" -H "x-auth-token: YOUR_API_SESSION_TOKEN" --data '{"query":"query GetHealthTrend($crawlId: ObjectID!) { getHealthScoreTrendForCrawl(crawlId: $crawlId, first: 5) { nodes { crawlId healthScores { healthScore reportCategoryCode } } totalCount } }","variables":{"crawlId":"TjAwNUNyYXdsMTU4MzI0NQ"}}' https://api.lumar.io/graphql
This returns historical health scores ordered by crawl, allowing you to chart the trend over time.
Step 3: Monitor segment health
Segments let you track health scores for specific sections of your site. For example, monitor your blog pages separately from product pages.
First, create a segment (if you do not have one):
- Mutation
- Variables
- Response
- cURL
mutation CreateCrawlUrlSegment($input: CreateCrawlUrlSegmentInput!) {
createCrawlUrlSegment(input: $input) {
segment {
id
name
group
crawlUrlFilter
createdAt
}
}
}
{
"input": {
"projectId": "TjAwN1Byb2plY3Q2MTMy",
"name": "Blog Pages",
"group": "Content",
"crawlUrlFilter": { "url": { "contains": "/blog/" } }
}
}
{
"data": {
"createCrawlUrlSegment": {
"segment": {
"id": "TjAyMVNlZ21lbnQx",
"name": "Blog Pages",
"group": "Content",
"crawlUrlFilter": { "url": { "contains": "/blog/" } },
"createdAt": "2025-01-15T10:00:00.000Z"
}
}
}
}
curl -X POST -H "Content-Type: application/json" -H "apollographql-client-name: docs-example-client" -H "apollographql-client-version: 1.0.0" -H "x-auth-token: YOUR_API_SESSION_TOKEN" --data '{"query":"mutation CreateCrawlUrlSegment($input: CreateCrawlUrlSegmentInput!) { createCrawlUrlSegment(input: $input) { segment { id name group crawlUrlFilter createdAt } } }","variables":{"input":{"projectId":"TjAwN1Byb2plY3Q2MTMy","name":"Blog Pages","group":"Content","crawlUrlFilter":{"url":{"contains":"/blog/"}}}}}' https://api.lumar.io/graphql
Then query the health score for that segment:
- Query
- Variables
- Response
- cURL
query GetSegmentHealth($crawlId: ObjectID!, $segmentId: ObjectID!) {
getCrawl(id: $crawlId) {
healthScore(reportCategoryCode: "seo", segmentId: $segmentId) {
healthScore
reportCategoryCode
segmentId
}
}
}
{
"crawlId": "TjAwNUNyYXdsMTU4MzI0NQ",
"segmentId": "TjAyMVNlZ21lbnQx"
}
{
"data": {
"getCrawl": {
"healthScore": [
{
"healthScore": 88.2,
"reportCategoryCode": "seo",
"segmentId": "TjAyMVNlZ21lbnQx"
}
]
}
}
}
curl -X POST -H "Content-Type: application/json" -H "apollographql-client-name: docs-example-client" -H "apollographql-client-version: 1.0.0" -H "x-auth-token: YOUR_API_SESSION_TOKEN" --data '{"query":"query GetSegmentHealth($crawlId: ObjectID!, $segmentId: ObjectID!) { getCrawl(id: $crawlId) { healthScore(reportCategoryCode: \"seo\", segmentId: $segmentId) { healthScore reportCategoryCode segmentId } } }","variables":{"crawlId":"TjAwNUNyYXdsMTU4MzI0NQ","segmentId":"TjAyMVNlZ21lbnQx"}}' https://api.lumar.io/graphql
Step 4: Set up health score tests
Health score tests define the thresholds that determine whether your health score is acceptable. Create tests to enforce minimum standards:
- Mutation
- Variables
- Response
- cURL
mutation CreateHealthScoreTest($input: CreateHealthScoreTestInput!) {
createHealthScoreTest(input: $input) {
healthScoreTest {
absoluteThreshold
automaticThresholdEnabled
reportCategoryCode
severity
thresholdPredicate
thresholdType
}
}
}
{
"input": {
"testSuiteId": "TjAxMVRlc3RTdWl0ZTEyMw",
"reportCategoryCode": "seo",
"absoluteThreshold": 0.8,
"thresholdType": "Relative",
"relativeThreshold": 10,
"severity": "Fail",
"automaticThresholdEnabled": false
}
}
{
"data": {
"createHealthScoreTest": {
"healthScoreTest": {
"absoluteThreshold": 0.8,
"automaticThresholdEnabled": false,
"reportCategoryCode": "seo",
"severity": "Fail",
"thresholdPredicate": "GreaterThanOrEqual",
"thresholdType": "Relative"
}
}
}
}
curl -X POST -H "Content-Type: application/json" -H "apollographql-client-name: docs-example-client" -H "apollographql-client-version: 1.0.0" -H "x-auth-token: YOUR_API_SESSION_TOKEN" --data '{"query":"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}}}' https://api.lumar.io/graphql
When a health score test fails, it will be flagged in build results and can trigger webhook notifications.
Step 5: Automate with builds and alerts
To track health automatically:
- Create a build schedule to run Protect builds on a regular cadence (see Setup Automated Monitoring).
- Configure webhooks to receive alerts when health score tests fail (see Webhooks).
- Query test results after each build to see which tests passed and which failed.
Interpreting health scores
| Score Range | Interpretation |
|---|---|
| 90--100 | Excellent. Site meets or exceeds best practices. |
| 70--89 | Good. Some areas for improvement. |
| 50--69 | Needs attention. Significant issues present. |
| Below 50 | Critical. Major issues affecting site health. |
Next steps
- Health Scores guide -- full reference for health score queries and tests.
- Segments guide -- managing URL segments for granular monitoring.
- Report Templates Overview -- understand which reports contribute to health scores.