semust logo

API Platform

Technical SEO API

Run a comprehensive technical SEO audit on any URL.

Run a comprehensive technical SEO audit on any URL. Checks 27 on-page factors across meta tags, headings, links, images, content, URL structure, and social tags — returns a scored report with actionable issues.

Product page: Technical SEO API.

Authentication

All requests require header-based authentication. Include your API credentials in every request.

HeaderTypeDescription
SEMUST-API-USERstringYour API user's username
SEMUST-API-PASSWORDstringYour API user's password

Create API credentials from the API Access page.

SEMUST-API-USER: your_username
SEMUST-API-PASSWORD: your_password

Request Parameters

Send a application/json body with the following parameters:

Body

urlstringrequired

The URL to audit. Must start with http:// or https:// (e.g., "https://example.com", "https://example.com/page").

render_jsbooleandefault: false

When true, uses a headless browser to render JavaScript before auditing. Use this for SPAs and JS-heavy pages. May increase cost.

proxy_countrystringdefault: null

ISO 3166-1 alpha-2 country code for proxy selection (e.g., "US", "TR", "DE"). Use when the target site geo-blocks requests.

JavaScript Rendering

Enabling render_js uses a headless browser which increases processing time and cost. Only enable it for pages that require JavaScript to render their content (SPAs, React/Vue apps).

{
  "url": "https://example.com",
  "render_js": false,
  "proxy_country": "US"
}

Code Examples

Complete examples showing how to run a Technical SEO audit in different languages.

curl -X POST https://data.semust.com/v1/technical-seo \
  -H "Content-Type: application/json" \
  -H "SEMUST-API-USER: your_username" \
  -H "SEMUST-API-PASSWORD: your_password" \
  -d '{
    "url": "https://example.com",
    "render_js": false
  }'

Response

Returns a JSON object with categorized audit results and a summary score.

Root Response Fields

FieldTypeDescription
successbooleanAlways true on successful response
urlstringThe audited URL
costfloatCredits deducted for this request (USD)
audit_resultsobjectCategorized audit results grouped by category (meta, headings, links, images, content, url_analysis, social)
summaryobjectAggregated statistics: total checks, issues by severity, and overall score

Audit Result Structure

Each audit within a category follows the same structure:

FieldTypeDescription
statusstring"pass", "fail", or "error" — the audit outcome
severitystring"critical", "warning", or "notice" — impact level
issuestringIssue code identifier (only present when status is "fail")
dataobjectAudit-specific data with details about the check (varies per audit)

Summary Object Fields

FieldTypeDescription
total_checksintegerTotal number of audits performed
passed_checksintegerNumber of audits that passed
total_issuesintegerNumber of audits that failed
critical_issuesintegerNumber of critical severity failures
warning_issuesintegerNumber of warning severity failures
notice_issuesintegerNumber of notice severity failures
scoreintegerOverall score (0-100) — percentage of passed checks
{
  "success": true,
  "url": "https://example.com",
  "cost": 0.0012,
  "audit_results": {
    "meta": {
      "title": {
        "status": "fail",
        "severity": "warning",
        "issue": "long_title",
        "data": { "title": "Very Long Page Title...", "length": 66 }
      },
      "meta_description": {
        "status": "pass",
        "severity": "warning",
        "data": { "meta_description": "Page description...", "length": 93 }
      },
      "canonical_url": {
        "status": "pass",
        "severity": "warning",
        "data": { "current_url": "https://example.com", "canonical_url": "https://example.com" }
      },
      "robots_noindex": { "status": "pass", "severity": "critical", "data": {} },
      "viewport": {
        "status": "pass",
        "severity": "critical",
        "data": { "content": "width=device-width, initial-scale=1" }
      }
    },
    "headings": {
      "missing_h1": {
        "status": "pass",
        "severity": "critical",
        "data": { "h1_count": 1, "h1_text": "Welcome" }
      },
      "broken_heading_structure": {
        "status": "fail",
        "severity": "warning",
        "issue": "broken_heading_structure",
        "data": { "total_count": 12, "skipped_levels": 1 }
      }
    },
    "images": {
      "images_without_alt": { "status": "pass", "severity": "warning", "data": { "total_images": 10 } },
      "missing_image_dimensions": {
        "status": "fail",
        "severity": "warning",
        "issue": "missing_image_dimensions",
        "data": { "total_images": 10, "count": 5 }
      }
    },
    "content": {
      "low_word_count": { "status": "pass", "severity": "warning", "data": { "word_count": 684 } },
      "low_html_text_ratio": {
        "status": "fail",
        "severity": "warning",
        "issue": "low_html_text_ratio",
        "data": { "text_to_html_ratio": 8.08 }
      }
    }
  },
  "summary": {
    "total_checks": 27,
    "passed_checks": 23,
    "total_issues": 4,
    "critical_issues": 0,
    "warning_issues": 4,
    "notice_issues": 0,
    "score": 85
  }
}

Audit Checks (27 Total)

Meta Tags (8)

AuditSeverityDescription
titlecriticalChecks for missing, too short (≤10 chars), or too long (>60 chars) title tag
meta_descriptionwarningChecks for missing, too short (<50 chars), or too long (>160 chars) meta description
canonical_urlwarningChecks for missing, multiple, or mismatched canonical URL
robots_noindexcriticalDetects noindex directive in robots or googlebot meta tags
viewportcriticalChecks for missing or invalid viewport meta tag (must include width=device-width)
missing_langwarningChecks that the HTML tag has a lang attribute
noindex_canonical_conflictcriticalDetects conflict when page has both noindex and canonical URL
hreflangwarningValidates hreflang implementation: lang codes, x-default, self-referential tags

Headings (4)

AuditSeverityDescription
missing_h1criticalChecks that the page has at least one H1 tag
multiple_h1_tagswarningChecks that the page has exactly one H1 tag (not multiple)
duplicate_h1_tagswarningChecks that H1 tags don't have identical text
broken_heading_structurewarningValidates heading hierarchy (H1→H2→H3) with no skipped levels or empty headings
AuditSeverityDescription
empty_anchor_textwarningChecks that anchor tags have text content (not empty)
non_descriptive_anchorsnoticeChecks for non-descriptive anchor text like "click here" or "read more"
internal_links_nofollowwarningChecks that internal links don't have nofollow attribute
too_many_internal_linkswarningWarns if page has too many internal links (threshold varies)
too_many_external_linkswarningWarns if page has too many external links (threshold: 100)

Images (2)

AuditSeverityDescription
images_without_altwarningChecks that images have alt attributes for accessibility
missing_image_dimensionswarningChecks that images have width and height attributes (prevents CLS)

Content (4)

AuditSeverityDescription
low_word_countwarningChecks that main content has at least 200 words
low_html_text_ratiowarningChecks that text-to-HTML ratio is above 10%
lorem_ipsumnoticeDetects placeholder "lorem ipsum" text in page content
page_sizewarningChecks HTML size (<3MB) and DOM element count (<1500)

URL Analysis (2)

AuditSeverityDescription
http_urlcriticalChecks that the URL uses HTTPS, not HTTP
long_urlnoticeWarns if URL exceeds 75 characters

Social Tags (2)

AuditSeverityDescription
open_graphwarningChecks for required Open Graph tags: og:title, og:description, og:image, og:url, og:type
twitter_cardnoticeChecks for Twitter Card meta tags: card, title, description, image

Error Codes

All errors return a JSON object with a human-readable message and an error code.

HTTPCodeMeaning
400INVALID_REQUESTRequest body is malformed or missing required fields
400URL_REQUIREDThe url field is required
400INVALID_URLInvalid URL format or scheme — must start with http:// or https://
401INVALID_API_KEYAuthentication failed — invalid username or password
402INSUFFICIENT_CREDITSYour account does not have enough credits
500INTERNAL_ERRORAn internal server error occurred
502AUDIT_FAILEDFailed to audit the target URL
502TARGET_BLOCKEDTarget website actively blocks automated access (403 Forbidden)
502TARGET_UNREACHABLETarget is unreachable — DNS failure, connection timeout, or network error
502SCRAPE_FAILEDScraping failed — general error fetching the page
504TIMEOUTThe request timed out (max 2 minutes)
{
  "error": "Your account does not have enough credits",
  "code": "INSUFFICIENT_CREDITS"
}

Credits & Rate Limits

Credits

Each request consumes credits from your balance. Cost varies based on the render_js parameter (JS rendering costs more). Failed requests are automatically refunded.

Rate Limits

Requests are subject to per-minute and per-day limits based on your plan. Exceeding limits returns HTTP 429.

Last updated: 2026-08-22