JavaScript SEO rendering check API API
Compare raw and rendered HTML to see which SEO signals depend on JavaScript. Use this reference to choose an operation and integrate its documented response contract.
Operations
GET /v1/onpage/render-diff
GET
/v1/onpage/render-diff
Credits: 7
Query parameters
| Parameter | Type | required |
|---|---|---|
| url | string | required |
Response fields
| Field | Type |
|---|---|
url |
string |
final_url |
string |
status |
string |
reason |
string | null |
checked_at |
string |
raw |
object |
raw.fetch |
object |
raw.fetch.http_status |
integer | null |
raw.fetch.final_url |
string |
raw.fetch.content_type |
string | null |
raw.fetch.bytes |
integer |
raw.fetch.truncated |
boolean |
raw.fetch.redirect_count |
integer |
raw.fetch.duration_ms |
integer |
raw.fetch.rendered |
boolean |
raw.signals |
object |
raw.signals.title |
string | null |
raw.signals.meta_description |
string | null |
raw.signals.canonical |
string | null |
raw.signals.robots |
string | null |
raw.signals.noindex |
boolean |
raw.signals.h1[] |
string[] |
raw.signals.word_count |
integer |
raw.signals.internal_links |
integer |
raw.signals.external_links |
integer |
raw.signals.structured_data_types[] |
string[] |
raw.signals.hreflang_count |
integer |
raw.signals.lang |
string | null |
rendered |
object |
rendered.fetch |
object |
rendered.fetch.http_status |
integer | null |
rendered.fetch.final_url |
string |
rendered.fetch.content_type |
string | null |
rendered.fetch.bytes |
integer |
rendered.fetch.truncated |
boolean |
rendered.fetch.redirect_count |
integer |
rendered.fetch.duration_ms |
integer |
rendered.fetch.rendered |
boolean |
rendered.signals |
object |
rendered.signals.title |
string | null |
rendered.signals.meta_description |
string | null |
rendered.signals.canonical |
string | null |
rendered.signals.robots |
string | null |
rendered.signals.noindex |
boolean |
rendered.signals.h1[] |
string[] |
rendered.signals.word_count |
integer |
rendered.signals.internal_links |
integer |
rendered.signals.external_links |
integer |
rendered.signals.structured_data_types[] |
string[] |
rendered.signals.hreflang_count |
integer |
rendered.signals.lang |
string | null |
js_dependence |
string | null |
rendered_word_share |
number | null |
differences[] |
object[] |
differences[] |
object |
differences[].field |
string |
differences[].change |
string |
differences[].impact |
string |
differences[].raw |
unknown |
differences[].rendered |
unknown |
issues[] |
string[] |
Example request
curl -H "X-API-Key: $DOMSCAN_API_KEY" "https://domscan.net/v1/onpage/render-diff?url=https%3A%2F%2Fexample.com"const response = await fetch("https://domscan.net/v1/onpage/render-diff?url=https%3A%2F%2Fexample.com", {
headers: { "X-API-Key": process.env.DOMSCAN_API_KEY },
});
const data = await response.json();
console.log(data);import os
import requests
response = requests.get(
"https://domscan.net/v1/onpage/render-diff?url=https%3A%2F%2Fexample.com",
headers={"X-API-Key": os.environ["DOMSCAN_API_KEY"]},
)
print(response.json())package main
import (
"fmt"
"io"
"net/http"
"os"
)
func main() {
req, err := http.NewRequest(http.MethodGet, "https://domscan.net/v1/onpage/render-diff?url=https%3A%2F%2Fexample.com", nil)
if err != nil {
panic(err)
}
req.Header.Set("X-API-Key", os.Getenv("DOMSCAN_API_KEY"))
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
data, err := io.ReadAll(resp.Body)
if err != nil {
panic(err)
}
fmt.Println(resp.Status, string(data))
}require "json"
require "net/http"
uri = URI("https://domscan.net/v1/onpage/render-diff?url=https%3A%2F%2Fexample.com")
request = Net::HTTP::Get.new(uri)
request["X-API-Key"] = ENV.fetch("DOMSCAN_API_KEY")
response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
http.request(request)
end
puts JSON.pretty_generate(JSON.parse(response.body))Example response
{
"url": "https://example.com/shoes/trail-runner",
"final_url": "https://example.com/shoes/trail-runner",
"status": "ok",
"reason": null,
"checked_at": "2026-10-13T12:00:00.000Z",
"raw": {
"fetch": {
"http_status": 200,
"final_url": "https://example.com/shoes/trail-runner",
"content_type": "text/html",
"bytes": 183,
"truncated": false,
"redirect_count": 0,
"duration_ms": 380,
"rendered": false
},
"signals": {
"title": "Example Outdoor",
"meta_description": null,
"canonical": null,
"robots": "noindex",
"noindex": true,
"h1": [],
"word_count": 0,
"internal_links": 0,
"external_links": 0,
"structured_data_types": [],
"hreflang_count": 0,
"lang": "en"
}
},
"rendered": {
"fetch": {
"http_status": 200,
"final_url": "https://example.com/shoes/trail-runner",
"content_type": "text/html",
"bytes": 3535,
"truncated": false,
"redirect_count": 0,
"duration_ms": 4210,
"rendered": true
},
"signals": {
"title": "Trail Running Shoes for Rocky Terrain | Example Outdoor",
"meta_description": "Lightweight trail running shoes with a grippy outsole, rock plate and breathable mesh. Free returns within 30 days on every pair.",
"canonical": "https://example.com/shoes/trail-runner",
"robots": "index, follow",
"noindex": false,
"h1": [
"Trail Running Shoes for Rocky Terrain"
],
"word_count": 122,
"internal_links": 5,
"external_links": 2,
"structured_data_types": [
"AggregateRating",
"Brand",
"BreadcrumbList",
"ListItem",
"Offer",
"Product",
"Rating",
"Review"
],
"hreflang_count": 3,
"lang": "en"
}
},
"js_dependence": "high",
"rendered_word_share": 1,
"differences": [
{
"field": "title",
"change": "changed_by_js",
"impact": "high",
"raw": "Example Outdoor",
"rendered": "Trail Running Shoes for Rocky Terrain | Example Outdoor"
},
{
"field": "meta_description",
"change": "added_by_js",
"impact": "medium",
"raw": null,
"rendered": "Lightweight trail running shoes with a grippy outsole, rock plate and breathable mesh. Free returns within 30 days on every pair."
},
{
"field": "canonical",
"change": "added_by_js",
"impact": "high",
"raw": null,
"rendered": "https://example.com/shoes/trail-runner"
},
{
"field": "robots",
"change": "changed_by_js",
"impact": "high",
"raw": "noindex",
"rendered": "index, follow"
},
{
"field": "noindex",
"change": "removed_by_js",
"impact": "high",
"raw": true,
"rendered": false
}
],
"issues": [
"robots_changed_by_js",
"canonical_changed_by_js",
"h1_requires_js",
"content_requires_js",
"links_require_js",
"structured_data_changed_by_js"
]
}
HTTP status codes
200OK400Bad Request401Unauthorized402Payment Required429Too Many Requests