> For the complete documentation index see https://domscan.net/llms.txt. Markdown versions of every docs page are available by appending .md to the page URL.

Source: https://domscan.net/docs/products/onpage

# On-page SEO audit API API

Audit titles, meta tags, headings, links, images and structured data with an SEO score. Use this reference to choose an operation and integrate its documented response contract.

[View product page](https://domscan.net/onpage-seo-api)

## Operations

GET `/v1/onpage` [View API reference](https://domscan.net/docs/products/onpage#getOnPageAudit)

## GET `/v1/onpage`

Operation: `getOnPageAudit`
Credits and authentication: 2-6
Authentication required

GET /v1/onpage Credits: 2-6

#### Query parameters

| Parameter | Type | required |
| --- | --- | --- |
| url | string | required |
| render | boolean | optional |

#### Response fields

| Field | Type |
| --- | --- |
| `url` | string |
| `final_url` | string |
| `status` | string |
| `reason` | string \| null |
| `checked_at` | string |
| `fetch` | object |
| `fetch.http_status` | integer \| null |
| `fetch.final_url` | string |
| `fetch.content_type` | string \| null |
| `fetch.bytes` | integer |
| `fetch.truncated` | boolean |
| `fetch.redirect_count` | integer |
| `fetch.duration_ms` | integer |
| `fetch.rendered` | boolean |
| `score` | integer \| null |
| `meta` | object |
| `meta.title` | string \| null |
| `meta.title_length` | integer |
| `meta.description` | string \| null |
| `meta.description_length` | integer |
| `meta.canonical` | string \| null |
| `meta.canonical_self_referencing` | boolean \| null |
| `meta.canonical_header` | string \| null |
| `meta.robots` | string \| null |
| `meta.googlebot` | string \| null |
| `meta.x_robots_tag` | string \| null |
| `meta.indexable` | boolean |
| `meta.googlebot_noindex` | boolean |
| `meta.nofollow` | boolean |
| `meta.meta_refresh` | string \| null |
| `meta.duplicate_meta_tags[]` | string[] |
| `meta.lang` | string \| null |
| `meta.viewport` | string \| null |
| `meta.favicon` | string \| null |
| `meta.open_graph` | object |
| `meta.open_graph.title` | string \| null |
| `meta.open_graph.description` | string \| null |
| `meta.open_graph.image` | string \| null |
| `meta.open_graph.url` | string \| null |
| `meta.open_graph.type` | string \| null |
| `meta.twitter` | object |
| `meta.twitter.card` | string \| null |
| `meta.twitter.title` | string \| null |
| `meta.twitter.description` | string \| null |
| `meta.twitter.image` | string \| null |
| `headings` | object |
| `headings.h1[]` | string[] |
| `headings.counts` | object |
| `headings.counts.h1` | integer |
| `headings.counts.h2` | integer |
| `headings.counts.h3` | integer |
| `headings.counts.h4` | integer |
| `headings.counts.h5` | integer |
| `headings.counts.h6` | integer |
| `headings.outline[]` | object[] |
| `headings.outline[]` | object |
| `headings.outline[].level` | integer |
| `headings.outline[].text` | string |
| `content` | object |
| `content.word_count` | integer |
| `content.text_bytes` | integer |
| `content.html_bytes` | integer |
| `content.text_to_html_ratio` | number |
| `links` | object |
| `links.total` | integer |
| `links.internal` | integer |
| `links.external` | integer |
| `links.nofollow` | integer |
| `links.empty_anchor` | integer |
| `links.unresolvable` | integer |
| `images` | object |
| `images.total` | integer |
| `images.missing_alt` | integer |
| `images.empty_alt` | integer |
| `images.missing_dimensions` | integer |
| `images.lazy_loaded` | integer |
| `resources` | object |
| `resources.scripts` | integer |
| `resources.inline_scripts` | integer |
| `resources.stylesheets` | integer |
| `resources.iframes` | integer |
| `resources.mixed_content` | integer |
| `resources.render_blocking_scripts` | integer \| null |
| `resources.render_blocking_stylesheets` | integer \| null |
| `structured_data` | object |
| `structured_data.json_ld` | integer |
| `structured_data.microdata` | integer |
| `structured_data.rdfa` | integer |
| `structured_data.types[]` | string[] |
| `hreflang` | object |
| `hreflang.count` | integer |
| `checks[]` | object[] |
| `checks[]` | object |
| `checks[].id` | string |
| `checks[].status` | string |
| `checks[].severity` | string |
| `checks[].value` | unknown |
| `issues[]` | string[] |
| `caveats[]` | string[] |

#### Example request

```bash
curl -H "X-API-Key: $DOMSCAN_API_KEY" "https://domscan.net/v1/onpage?url=https%3A%2F%2Fexample.com&render=false"
```

```javascript
const response = await fetch("https://domscan.net/v1/onpage?url=https%3A%2F%2Fexample.com&render=false", {
  headers: { "X-API-Key": process.env.DOMSCAN_API_KEY },
});
const data = await response.json();
console.log(data);
```

```python
import os
import requests

response = requests.get(
    "https://domscan.net/v1/onpage?url=https%3A%2F%2Fexample.com&render=false",
    headers={"X-API-Key": os.environ["DOMSCAN_API_KEY"]},
)
print(response.json())
```

```go
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
)

func main() {
	req, err := http.NewRequest(http.MethodGet, "https://domscan.net/v1/onpage?url=https%3A%2F%2Fexample.com&render=false", 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))
}
```

```ruby
require "json"
require "net/http"

uri = URI("https://domscan.net/v1/onpage?url=https%3A%2F%2Fexample.com&render=false")
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

```json
{
  "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",
  "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": 412,
    "rendered": false
  },
  "score": 87,
  "meta": {
    "title": "Trail Running Shoes for Rocky Terrain | Example Outdoor",
    "title_length": 55,
    "description": "Lightweight trail running shoes with a grippy outsole, rock plate and breathable mesh. Free returns within 30 days on every pair.",
    "description_length": 129,
    "canonical": "https://example.com/shoes/trail-runner",
    "canonical_self_referencing": true,
    "canonical_header": null,
    "robots": "index, follow",
    "googlebot": null,
    "x_robots_tag": null,
    "indexable": true,
    "googlebot_noindex": false,
    "nofollow": false,
    "meta_refresh": null,
    "duplicate_meta_tags": [],
    "lang": "en",
    "viewport": "width=device-width, initial-scale=1",
    "favicon": "/favicon.ico",
    "open_graph": {
      "title": "Trail Running Shoes for Rocky Terrain",
      "description": null,
      "image": "https://example.com/images/trail-runner.jpg",
      "url": null,
      "type": null
    },
    "twitter": {
      "card": "summary_large_image",
      "title": null,
      "description": null,
      "image": null
    }
  },
  "headings": {
    "h1": [
      "Trail Running Shoes for Rocky Terrain"
    ],
    "counts": {
      "h1": 1,
      "h2": 1,
      "h3": 0,
      "h4": 1,
      "h5": 0,
      "h6": 0
    },
    "outline": [
      {
        "level": 1,
        "text": "Trail Running Shoes for Rocky Terrain"
      },
      {
        "level": 2,
        "text": "Why runners choose these trail running shoes"
      },
      {
        "level": 4,
        "text": "Sizing"
      }
    ]
  },
  "content": {
    "word_count": 122,
    "text_bytes": 780,
    "html_bytes": 3535,
    "text_to_html_ratio": 0.221
  },
  "links": {
    "total": 7,
    "internal": 5,
    "external": 2,
    "nofollow": 1,
    "empty_anchor": 1,
    "unresolvable": 0
  },
  "images": {
    "total": 3,
    "missing_alt": 1,
    "empty_alt": 0,
    "missing_dimensions": 2,
    "lazy_loaded": 0
  },
  "resources": {
    "scripts": 1,
    "inline_scripts": 0,
    "stylesheets": 1,
    "iframes": 0,
    "mixed_content": 1,
    "render_blocking_scripts": 0,
    "render_blocking_stylesheets": 1
  },
  "structured_data": {
    "json_ld": 2,
    "microdata": 1,
    "rdfa": 0,
    "types": [
      "AggregateRating",
      "Brand",
      "BreadcrumbList",
      "ListItem",
      "Offer",
      "Product",
      "Rating",
      "Review"
    ]
  },
  "hreflang": {
    "count": 3
  },
  "checks": [
    {
      "id": "mixed_content",
      "status": "fail",
      "severity": "high",
      "value": 1
    },
    {
      "id": "heading_hierarchy",
      "status": "warn",
      "severity": "low",
      "value": 1
    },
    {
      "id": "word_count",
      "status": "warn",
      "severity": "medium",
      "value": 122
    },
    {
      "id": "images_alt",
      "status": "warn",
      "severity": "medium",
      "value": 1
    },
    {
      "id": "title_present",
      "status": "pass",
      "severity": "high"
    },
    {
      "id": "h1_present",
      "status": "pass",
      "severity": "high",
      "value": 1
    },
    {
      "id": "render_blocking_resources",
      "status": "warn",
      "severity": "low",
      "value": 1
    }
  ],
  "issues": [
    "mixed_content",
    "heading_hierarchy",
    "word_count",
    "images_alt",
    "images_dimensions",
    "empty_anchor_text",
    "render_blocking_resources"
  ],
  "caveats": []
}
```

#### HTTP status codes

- `200` OK
- `400` Bad Request
- `401` Unauthorized
- `402` Payment Required
- `429` Too Many Requests

## Reference resources

[OpenAPI 3.0](https://domscan.net/v1/openapi.json)
[Postman](https://domscan.net/v1/postman.json)
[MCP](https://domscan.net/mcp-domain-checker)
