# Technical SEO Audit Tool (`axiomworks/website-seo-audit-tool`) Actor

Review technical SEO signals across a website or a supplied set of URLs. Each HTML page record includes titles, headings, canonicals, indexability directives, redirect details, links, image alt gaps, schema types and rule-based issue codes. Uses plain HTTP without a browser or API key.

- **URL**: https://apify.com/axiomworks/website-seo-audit-tool.md
- **Developed by:** [Axiom Works](https://apify.com/axiomworks) (community)
- **Categories:** SEO tools, Marketing
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.79 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

**Returns:** one row per web page with `finalUrl`, `statusCode`, `title`, `metaDescription`, `h1`, `canonical`, `noindex`, `wordCount` and a list of `issues`.
**Input:** `{"startUrls": [{"url": "https://www.example.com/"}], "maxDepth": 1, "maxPages": 50}`
**Best for:** technical SEO audits for clients, pre-launch and post-migration checks, monitoring titles, canonicals and indexability across a site.

```json
{
    "finalUrl": "https://www.python.org/",
    "statusCode": 200,
    "title": "Welcome to Python.org",
    "titleLength": 21,
    "h1Count": 5,
    "canonical": null,
    "isIndexable": true,
    "issues": ["title_too_short", "meta_description_too_short", "multiple_h1", "missing_canonical", "redirected"]
}
```

### What does Website SEO Audit Tool do?

Website SEO Audit Tool is an on-page SEO checker and site crawler. Give it a website URL and it follows the internal links breadth-first, fetches each page over plain HTTP and returns one record per HTML page with the on-page SEO data an audit needs: the title and meta description with their lengths, H1 and H2 headings, the canonical URL and whether it points to the page itself, robots meta and X-Robots-Tag directives, whether robots.txt disallows the path, hreflang alternates, the html lang attribute, Open Graph and Twitter card tags, viewport and charset, the HTTP status with the full redirect chain and response time, image counts and missing alt text, a boilerplate-free word count, schema.org types from JSON-LD and microdata, and internal, external and nofollow link counts.

Every record also carries a list of plain issue codes such as `missing_meta_description`, `multiple_h1`, `canonical_mismatch`, `noindex` or `http_404`, so you can sort and filter a whole site in a spreadsheet without reading HTML. There is no made-up score: each code comes from a fixed, documented rule (see the FAQ).

It works on any public website. You can crawl a site from its homepage, or set `maxDepth` to 0 and paste a list of URLs to audit just those pages. No login, no API key and no browser are needed. Use it as a website SEO audit API, a scheduled regression check, or a tool for AI agents.

### What data can you get from a website SEO audit?

| Field | Description | Example |
|---|---|---|
| `id` | Stable ID: the first 16 hex characters of the SHA-1 of `finalUrl` | `1ab11d99cba1c395` |
| `url` | URL as requested (normalised start URL or the internal link followed) | `https://python.org/` |
| `finalUrl` | URL after redirects; same as `sourceUrl` | `https://www.python.org/` |
| `statusCode` | HTTP status of the final response | `200` |
| `redirectCount` | Number of redirect hops | `1` |
| `redirectChain` | `{url, statusCode}` for each 3xx hop; empty when no redirect | `[{"url": "https://python.org/", "statusCode": 301}]` |
| `contentType` | MIME type of the response | `text/html` |
| `responseTimeMs` | Time to fetch the page, redirects included | `60` |
| `htmlSizeBytes` | Size of the decoded HTML | `52282` |
| `depth` | Crawl depth, 0 for start URLs | `0` |
| `title` | Text of `<title>`; null when missing | `Welcome to Python.org` |
| `titleLength` | Characters in the title (0 when missing) | `21` |
| `metaDescription` | Content of the meta description; null when missing | `The official home of the Python Programming Language` |
| `metaDescriptionLength` | Characters in the meta description | `52` |
| `metaKeywords` | Content of meta keywords; null when missing | `Python programming language ...` |
| `h1`, `h2` | Text of every H1 and H2 on the page | `["Functions Defined", ...]` |
| `h1Count`, `h2Count`, `h3Count` | Number of H1, H2 and H3 elements | `5`, `9`, `0` |
| `canonical` | Absolute URL from `<link rel=canonical>`; null when missing | `https://www.mozilla.org/en-US/` |
| `canonicalMatches` | true when the canonical equals `finalUrl`; null without a canonical | `true` |
| `robotsMeta` | Content of `<meta name=robots>` | `noindex` |
| `xRobotsTag` | X-Robots-Tag response header | `noindex` |
| `robotsTxtDisallowed` | true when robots.txt disallows the path for `User-agent: *` | `false` |
| `noindex`, `nofollow` | Directives found in robots meta or X-Robots-Tag | `false` |
| `isIndexable` | Status 200, not noindex, canonical absent or self-referencing | `true` |
| `lang` | Value of `<html lang>` | `en` |
| `hreflang`, `hreflangCount` | `{lang, href}` alternates and their number | `85` |
| `ogTitle`, `ogDescription`, `ogImage` | Open Graph tags | `https://www.python.org/static/opengraph-icon-200x200.png` |
| `twitterCard` | Content of `twitter:card` | `summary` |
| `viewport`, `charset` | Viewport meta and declared charset | `width=device-width, initial-scale=1.0`, `utf-8` |
| `imagesTotal`, `imagesMissingAlt` | Number of `<img>` and of those without a non-empty alt | `22`, `17` |
| `imagesMissingAltSrc` | Up to 10 absolute src URLs of images missing alt | `["https://www.mozilla.org/media/..."]` |
| `wordCount` | Words in the body text with navigation, header, footer, aside, scripts and styles removed | `409` |
| `schemaTypes` | schema.org types from JSON-LD and microdata | `["WebSite", "SearchAction"]` |
| `internalLinksCount`, `externalLinksCount`, `nofollowLinksCount` | Unique links to the same site, to other hosts, and with rel=nofollow | `64`, `63`, `0` |
| `internalLinks`, `externalLinks` | Up to 20 unique link URLs of each kind | `["https://www.python.org/jobs/", ...]` |
| `issues`, `issueCount` | Detected issue codes and how many | `["multiple_h1", "missing_canonical"]`, `2` |
| `scrapedAt` | When the page was audited (ISO 8601) | `2026-10-20T00:20:35.701Z` |
| `sourceUrl` | The audited page | `https://www.python.org/` |

At the end of each run the key-value store also gets a `SUMMARY` record: the start URLs, pages crawled, pages with issues, a count per issue code, the URLs skipped because they were not HTML (PDF, XML, images) and the URLs that gave no response, with the reason.

### How to use Website SEO Audit Tool

1. Open the Actor in Apify Console and go to the Input tab.
2. In **Start URLs**, enter the site to audit, for example `[{"url": "https://www.example.com/"}]`. A bare host such as `example.com` works too.
3. Set **Crawl depth**: 0 audits only the URLs you gave, 1 also audits the pages they link to, 2 goes one level further.
4. Set **Maximum pages to fetch** and **Maximum results** to the size of the audit you want. Both are shared by all start URLs.
5. Click **Start**. Records appear in the Output tab as pages are audited.
6. Use the **SEO audit** view for the key columns, or export everything as JSON, CSV, Excel, XML or HTML.

Tips:

1. To audit a list of landing pages, paste them all into Start URLs and set Crawl depth to 0. Each URL becomes one record, including pages that answer 404 or 500.
2. Exclude sections you do not care about with **Exclude URL patterns**, for example `/tag/` or `\?page=`.
3. Leave the proxy off for most sites. If a start page answers 403, 429 or 503, the Actor retries it once through Apify Proxy datacenter and then residential IPs on its own.
4. Turn on **Respect robots.txt** if you want the crawl to stay out of disallowed sections. The `robotsTxtDisallowed` field is reported either way.

### Input

| Field | Type | Required | Description |
|---|---|---|---|
| `startUrls` | array | Yes (or `url` / `urls` / `startUrl`) | Pages to start from, as `{"url": ...}` objects or plain strings. Full URLs or bare hosts. |
| `maxDepth` | integer | No | Link levels to follow, 0-10, default 1. 0 = URL-list mode. |
| `maxPages` | integer | No | Pages fetched across all start URLs, 1-10000, default 50. |
| `maxItems` | integer | No | Records returned across all start URLs, 1-100000, default 50. |
| `includeSubdomains` | boolean | No | Treat subdomains as internal, default false. |
| `respectRobotsTxt` | boolean | No | Skip links disallowed by robots.txt, default false. |
| `excludeUrlPatterns` | array of strings | No | Regular expressions; matching internal links are not crawled. |
| `maxRedirects` | integer | No | Redirect hops to follow per page, 0-30, default 10. |
| `requestTimeoutSecs` | integer | No | Seconds to wait for each response, 3-120, default 15. |
| `maxConcurrency` | integer | No | Pages fetched in parallel, 1-20, default 3 (at most 2 per host). |
| `userAgent` | string | No | Custom User-Agent; default is desktop Chrome. |
| `proxyConfiguration` | object | No | Proxy for all requests. Default: none, with an automatic Apify Proxy retry for blocked start pages. |

```json
{
    "startUrls": [{ "url": "https://www.mozilla.org/en-US/" }],
    "maxDepth": 1,
    "maxPages": 25,
    "maxItems": 25,
    "includeSubdomains": false,
    "respectRobotsTxt": false,
    "excludeUrlPatterns": ["/wp-admin/"],
    "proxyConfiguration": { "useApifyProxy": false }
}
```

### Output

Real records from a local run: the python.org homepage reached through a redirect, and a test page that answers 404 with noindex. Some fields are left out here for space.

```json
[
    {
        "id": "1ab11d99cba1c395",
        "url": "https://python.org/",
        "finalUrl": "https://www.python.org/",
        "statusCode": 200,
        "redirectCount": 1,
        "redirectChain": [{ "url": "https://python.org/", "statusCode": 301 }],
        "contentType": "text/html",
        "responseTimeMs": 60,
        "htmlSizeBytes": 52282,
        "depth": 0,
        "title": "Welcome to Python.org",
        "titleLength": 21,
        "metaDescription": "The official home of the Python Programming Language",
        "metaDescriptionLength": 52,
        "h1": ["Functions Defined", "All the Flow You’d Expect", "Compound Data Types", "Intuitive Interpretation", "Quick & Easy to Learn"],
        "h1Count": 5,
        "h2Count": 9,
        "canonical": null,
        "canonicalMatches": null,
        "robotsTxtDisallowed": false,
        "noindex": false,
        "isIndexable": true,
        "lang": "en",
        "hreflangCount": 0,
        "ogTitle": "Welcome to Python.org",
        "ogImage": "https://www.python.org/static/opengraph-icon-200x200.png",
        "viewport": "width=device-width, initial-scale=1.0",
        "charset": "utf-8",
        "imagesTotal": 1,
        "imagesMissingAlt": 0,
        "wordCount": 409,
        "schemaTypes": ["WebSite", "SearchAction"],
        "internalLinksCount": 64,
        "externalLinksCount": 63,
        "issues": ["title_too_short", "meta_description_too_short", "multiple_h1", "missing_canonical", "redirected"],
        "issueCount": 5,
        "scrapedAt": "2026-10-20T00:20:35.701Z",
        "sourceUrl": "https://www.python.org/"
    },
    {
        "id": "9c72b15b852b8684",
        "url": "https://crawler-test.com/robots_protocol/non_200_with_noindex",
        "finalUrl": "https://crawler-test.com/robots_protocol/non_200_with_noindex",
        "statusCode": 404,
        "redirectCount": 0,
        "title": "Non-200 with Noindex",
        "titleLength": 20,
        "h1Count": 0,
        "robotsMeta": "noindex",
        "noindex": true,
        "isIndexable": false,
        "wordCount": 4,
        "issues": ["title_too_short", "missing_meta_description", "missing_h1", "missing_canonical", "noindex", "thin_content", "missing_viewport", "missing_html_lang", "http_404"],
        "issueCount": 9,
        "sourceUrl": "https://crawler-test.com/robots_protocol/non_200_with_noindex"
    }
]
```

### How much does it cost to run a website SEO audit?

Website SEO Audit Tool is charged per result: one result is one audited page. You pay only for the records returned, and `maxItems` caps how many there can be, so a run never costs more than you planned. Pages that give no response and non-HTML files are not records and are not charged. See the Pricing tab for the current price.

### Use with AI agents (MCP)

Connect Website SEO Audit Tool to Claude, Cursor or any MCP client through the Apify MCP server:

```json
{
    "mcpServers": {
        "apify": {
            "url": "https://mcp.apify.com/?tools=axiomworks/website-seo-audit-tool"
        }
    }
}
```

Example prompts:

1. "Audit https://www.example.com/ two levels deep and list every page with a missing meta description or more than one H1."
2. "Check these 10 landing pages with crawl depth 0 and tell me which ones are not indexable and why."
3. "Crawl our blog, find pages under 300 words, and suggest which ones to merge."

### Integrations and API

Run Website SEO Audit Tool from your own code with the Apify API. Set `APIFY_TOKEN` to your Apify API token (send it in the `Authorization` header, never in the URL).

**Python**

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_API_TOKEN>")
run = client.actor("axiomworks/website-seo-audit-tool").call(run_input={
    "startUrls": [{"url": "https://www.example.com/"}],
    "maxDepth": 1,
    "maxPages": 50,
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["finalUrl"], item["statusCode"], item["issues"])
```

**JavaScript**

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: '<YOUR_API_TOKEN>' });
const run = await client.actor('axiomworks/website-seo-audit-tool').call({
    startUrls: [{ url: 'https://www.example.com/' }],
    maxDepth: 1,
    maxPages: 50,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
```

**cURL**

```bash
curl -X POST "https://api.apify.com/v2/acts/axiomworks~website-seo-audit-tool/run-sync-get-dataset-items" \
  -H "Authorization: Bearer $APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"startUrls": [{"url": "https://www.example.com/"}], "maxDepth": 0}'
```

The Integrations tab connects the Actor to Make, Zapier, n8n, Google Sheets, Slack and webhooks, so a scheduled audit can drop its results into a sheet or alert you when new issues appear.

### FAQ

**Which rules produce the issue codes?**
`missing_title`; `title_too_long` (over 60 characters) and `title_too_short` (under 30); `missing_meta_description`; `meta_description_too_long` (over 160) and `meta_description_too_short` (under 70); `missing_h1` and `multiple_h1`; `missing_canonical` and `canonical_mismatch` (canonical is not the page's own final URL); `noindex`; `robots_txt_disallowed`; `images_missing_alt`; `thin_content` (under 300 words); `redirected`; `not_https`; `missing_viewport`; `missing_html_lang`; and `http_<status>` for any status other than 200. They are fixed thresholds, not a judgement about rankings, so treat them as a checklist.

**How is the word count calculated?**
The body text is taken after removing scripts, styles, `noscript`, `template`, `svg`, `nav`, `header`, `footer` and `aside` elements, then split on whitespace. It is a heuristic: a site that puts its main content inside a `<header>` or `<nav>` gets a lower count.

**Does it render JavaScript?**
No. It reads the HTML the server sends, which is what most search engine crawlers see first. Content that only appears after JavaScript runs is not counted.

**Which links count as internal?**
Links whose host, ignoring a leading `www.`, equals the host the start URL lands on. A start URL `python.org` that redirects to `www.python.org` makes both internal. Subdomains such as `docs.python.org` count as external unless you turn on `includeSubdomains`. A link that redirects to another site is audited (status and redirect chain) but its own links are not followed.

**Why did my run return 0 results?**
The start URL gave no HTTP response (the host does not exist, refused the connection, timed out, or redirected too many times), or it is not an HTML page (a PDF or XML file). The status message names the URL and the reason, and the `SUMMARY` record lists every skipped or failed URL. A page that answers 404 or 500 still gets a record with its status.

**Is robots.txt obeyed?**
By default the crawl reports robots.txt (`robotsTxtDisallowed`) without obeying it, so you can see blocked pages that are still linked. Set `respectRobotsTxt` to true to keep the crawl out of disallowed paths.

**Can I schedule it?**
Yes. Save your input as a task and add a weekly schedule, then compare the `SUMMARY` issue counts between runs.

### Is it legal to audit websites with a crawler?

Website SEO Audit Tool reads only publicly available pages, the same HTML any visitor's browser receives, and does not log in or bypass access controls. It crawls politely and can respect robots.txt on request. You are responsible for how you use the results and for having the right to audit the sites you crawl; when pages contain personal data, data protection laws such as the GDPR may apply. This is not legal advice.

Website SEO Audit Tool is an independent tool. It is not affiliated with, endorsed by or sponsored by any of the websites it audits, including the sites used in the examples above.

### Related Actors

| Actor | What it does |
|---|---|
| [Sitemap URL Extractor](https://apify.com/axiomworks/sitemap-url-extractor) | Lists every URL in a site's sitemaps, a good start list for a URL-list audit |
| [Link Status Checker](https://apify.com/axiomworks/broken-link-checker) | Checks links for broken or redirecting targets |
| [PageSpeed Insights Checker](https://apify.com/axiomworks/pagespeed-insights-checker) | Gets Core Web Vitals and Lighthouse scores for pages |

### Feedback

Found a bug or need a field that isn't here? Open an issue on the Issues tab and we'll look at it.

# Actor input Schema

## `startUrls` (type: `array`):

Websites or pages to audit, as \[{"url": "https://www.example.com/"}] or plain strings. Full URLs or bare hosts ('python.org', https:// is added). Each start URL defines its site: links to the same host (www. ignored) are internal. A dead host gives no record and is named in the status message; a page that answers 404 is audited with statusCode 404. Also accepted as the keys url, urls or startUrl.

## `maxDepth` (type: `integer`):

How many link levels to follow from each start URL, 0-10, default 1. 0 audits only the given URLs (URL-list mode); 1 adds the internal pages they link to; 2 the pages those link to, and so on. Only internal links of pages that answered 200 are followed.

## `maxPages` (type: `integer`):

Maximum number of pages fetched across all start URLs, 1-10000, default 50. Counts every fetch, including non-HTML responses and pages that gave no response, so it bounds run time.

## `maxItems` (type: `integer`):

Maximum number of page records to return across all start URLs, 1-100000, default 50. The run stops as soon as this many records are saved, and you are charged only for records returned.

## `includeSubdomains` (type: `boolean`):

Default false. When true, blog.example.com counts as internal to example.com: it is crawled and counted in internalLinksCount. When false, subdomain links count as external.

## `respectRobotsTxt` (type: `boolean`):

Default false. When true, internal links that the site's robots.txt disallows for User-agent: \* are not crawled (start URLs are always fetched). The robotsTxtDisallowed field is reported for every page either way.

## `excludeUrlPatterns` (type: `array`):

Regular expressions (case-insensitive), one per line; internal links matching any of them are not crawled, e.g. '/wp-admin/' or '?page='. Default: none. Start URLs are always audited.

## `maxRedirects` (type: `integer`):

Redirect hops to follow per page, 0-30, default 10. A page that redirects more often gives no record and is listed in the SUMMARY record's pageErrors.

## `requestTimeoutSecs` (type: `integer`):

Seconds to wait for each response, 3-120, default 15. A page that times out twice gives no record and is listed in the SUMMARY record's pageErrors.

## `maxConcurrency` (type: `integer`):

Pages fetched in parallel, 1-20, default 3. At most 2 requests run at once per host, 300-600 ms apart, so a single site is crawled politely whatever this is set to.

## `userAgent` (type: `string`):

User-Agent header to send, e.g. to audit what a specific client sees. Leave empty for the default desktop Chrome User-Agent.

## `proxyConfiguration` (type: `object`):

Proxy for all requests, default none (direct). Without a proxy, a start page that answers 403/429/503 is retried once through Apify Proxy datacenter, then residential; other blocked pages are recorded with their status. Pick a proxy here to send every request through it.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://www.mozilla.org/en-US/"
    }
  ],
  "maxDepth": 1,
  "maxPages": 5,
  "maxItems": 5,
  "includeSubdomains": false,
  "respectRobotsTxt": false,
  "excludeUrlPatterns": [],
  "maxRedirects": 10,
  "requestTimeoutSecs": 15,
  "maxConcurrency": 3,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `overview` (type: `string`):

Dataset with one item per audited page, overview view.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "startUrls": [
        {
            "url": "https://www.mozilla.org/en-US/"
        }
    ],
    "maxDepth": 1,
    "maxPages": 5,
    "maxItems": 5,
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("axiomworks/website-seo-audit-tool").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "startUrls": [{ "url": "https://www.mozilla.org/en-US/" }],
    "maxDepth": 1,
    "maxPages": 5,
    "maxItems": 5,
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("axiomworks/website-seo-audit-tool").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "startUrls": [
    {
      "url": "https://www.mozilla.org/en-US/"
    }
  ],
  "maxDepth": 1,
  "maxPages": 5,
  "maxItems": 5,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call axiomworks/website-seo-audit-tool --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,axiomworks/website-seo-audit-tool"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/0hU5KLGSLgGSXPKcD/builds/XtBXSgJ0D5mRAycOn/openapi.json
