Rank Tracking Snapshot Comparator
Pricing
from $11.50 / 1,000 rank snapshot compareds
Rank Tracking Snapshot Comparator
Compare two or more SERP snapshots and report position changes, URL swaps, domain movements, feature gains/losses, and query-level volatility
Pricing
from $11.50 / 1,000 rank snapshot compareds
Rating
0.0
(0)
Developer
junipr
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
21 days ago
Last modified
Categories
Share
Compare an earlier and later set of query-ranked URLs. The actor detects position movement, entrants, exits, URL swaps, and result-feature changes while preserving the source evidence behind every comparison.
What you get
Each dataset row represents one query-domain pair and includes:
- baseline and current positions;
- signed
positionDelta, where a positive number is an improvement; - current or most recent URL;
- URL-change detection for the same query and domain;
- feature gained and feature lost flags;
- a bounded volatility score;
- movement type such as
entered,exited,url_swap,improved,major_improvement,declined,major_decline,feature_change, orunchanged; - source URL, evidence, issue code, scan time, and recommendation.
Owned domains are recognized in recommendations so an analyst can distinguish movements that directly affect controlled properties. With reports enabled, the actor writes Markdown, CSV, issue JSON, evidence JSON, run metadata, and a digest artifact to key-value storage.
Required evidence
Supply both baselineSerpResults and currentSerpResults. Each array may contain individual records or snapshot objects with a query and nested results. Every usable record needs:
query;- positive numeric
positionorrank; - public
urlorresultUrl; - optional
domain,resultType, andsourceUrl.
Invalid, missing, zero, or negative positions are ignored. If either side has no accepted records, the actor returns a diagnostic row rather than inferring movement.
Comparison controls:
ownedDomains: domains highlighted as controlled properties.compareFeatures: compare organic versus explicitly typed result features.rankDepth: boundary used to score entrances and exits.movementThresholds.minorand.major: configure movement labels.maxQueries: cap distinct queries.maxSnapshots: cap snapshot containers read from each side.maxResultsPerQuery: cap result records accepted for each query and side.maxComparisons: cap emitted query-domain rows.maxChargeUsd: stop before a paid event would exceed the ceiling.
Example input
{"baselineSerpResults": [{"query": "seo tools","sourceUrl": "https://example.com/serp/seo-tools/previous","results": [{ "position": 5, "url": "https://junipr.io/seo", "resultType": "organic" },{ "position": 2, "url": "https://competitor.example/old-page", "resultType": "organic" }]}],"currentSerpResults": [{"query": "seo tools","sourceUrl": "https://example.com/serp/seo-tools/current","results": [{ "position": 2, "url": "https://junipr.io/seo", "resultType": "organic" },{ "position": 2, "url": "https://competitor.example/new-page", "resultType": "organic" },{ "position": 4, "url": "https://new.example/list", "resultType": "featured_snippet" }]}],"ownedDomains": ["junipr.io"],"compareFeatures": true,"rankDepth": 10,"movementThresholds": { "minor": 2, "major": 5 },"maxQueries": 10,"maxSnapshots": 20,"maxResultsPerQuery": 20,"maxComparisons": 100,"includeReport": true,"maxChargeUsd": 35}
Example output
{"recordType": "rank_tracking_snapshot_comparator","recordName": "seo tools | junipr.io","issueCode": "rank_tracking_snapshot_comparator_rank_change","severity": "medium","query": "seo tools","domain": "junipr.io","url": "https://junipr.io/seo","baselinePosition": 5,"currentPosition": 2,"positionDelta": 3,"urlChanged": false,"featureGained": false,"featureLost": false,"volatilityScore": 30,"movementType": "improved","sourceUrl": "https://example.com/serp/seo-tools/current","scannedAt": "2026-07-10T12:00:00.000Z"}
Comparison semantics
Records are grouped by query and normalized domain. When multiple URLs from a domain appear for the same query, the best position on each side is compared. A different best URL becomes url_swap. A domain seen only in the current evidence becomes entered; one seen only in the baseline becomes exited. The configured rank depth supplies the comparison boundary for those one-sided records.
Feature comparison uses resultType. Organic-to-feature changes set featureGained; feature-to-organic changes set featureLost. Disable compareFeatures when capture providers do not use compatible result-type labels.
The volatility score is a deterministic aid, not a prediction. It combines absolute position movement with bounded additions for URL and feature changes.
Pay-per-event pricing
Platform usage pass-through is off, and charges occur before related output.
| Event | Price |
|---|---|
actor-start | $0.0350 |
rank-snapshot-compared | $0.0115 |
url-position-record-checked | $0.0115 |
rank-change-detected | $0.0225 |
digest-generated | $0.0900 |
executive-report-generated | $0.1800 |
The default maximum charge is $35. Set maxChargeUsd to zero to prevent paid processing and output.
Practical uses
- compare weekly or monthly rank exports from the same provider;
- detect URL swaps after migrations or internal-link changes;
- identify newly visible and disappearing competitor domains;
- track result-feature ownership separately from numeric rank;
- produce a capped movement digest for SEO reporting.
Limits
Use consistent query, locale, device, provider, and collection depth on both sides. The actor compares supplied observations and does not fetch historical rankings or reconstruct missing records. Query-domain grouping intentionally reports the best observed URL for each side.