majr-app Audit API

Fetch one URL (SSRF-guarded) and score its technical SEO + AI-readiness signals.

Operations 1

POST /v1/audit Fetch one URL and score its technical SEO + AI-readiness signals (0..1 +… #

Documentation

Specifications

Schemas & Data

Other Resources

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/majr-app:majr-app-audit-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Discovery needs no key. Ratings and market analysis are Pro.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

majr-app-audit-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: AI SEO Audit API
  description: 'Generates AI SEO machinery: production-ready robots.txt, sitemap.xml, the page

    `` block (title/description/canonical/Open Graph + schema.org JSON-LD), and llms.txt.

    Separately audits one page. **Machinery only** — page content and keyword strategy stay

    with the caller, and nothing is persisted.


    - **Auth:** `Authorization: Bearer ` on every `/v1/*` call.

    - **Errors:** RFC 7807 `application/problem+json`; request content is never echoed back. A `503`

    with `Retry-After` means auth is not judgeable yet — it is never a verdict on your key.

    - **GEO default:** generated robots.txt explicitly welcomes AI crawlers (`allow_ai: true`).

    - **Audit scope:** a *technical SEO* audit of one page — 13 deterministic checks, equally

    weighted in `score`, of which two are AI-readiness signals (`json_ld`, `ssr_text`). It does not read

    your llms.txt, and it reads your robots.txt only to ask whether this path is disallowed — your

    AI-crawler policy earns no credit, so a perfect score is not a GEO/AEO verdict. Exact

    pass conditions for every check: `GET /llms.txt`.

    - **Which problem do you have:** alongside `score`, every audit returns `findable` (http_200,

    indexable, crawlable — is the page unreachable, or does it carry a block the audit observed? fix

    these first) and `citable` (the remaining ten — can an engine extract and attribute the page

    once reached?).

    - **Agent quickstart:** `GET /llms.txt`.'
  version: 1.7.3
servers:
- url: https://seo.majr.app
tags:
- name: Audit
  description: Fetch one URL (SSRF-guarded) and score its technical SEO + AI-readiness signals.
paths:
  /v1/audit:
    post:
      tags:
      - Audit
      summary: Fetch one URL and score its technical SEO + AI-readiness signals (0..1 +…
      operationId: auditPage
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AuditRequest'
        required: true
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AuditResponse'
        '401':
          description: Missing or invalid bearer token
          content:
            application/problem+json:
              schema:
                properties:
                  type:
                    type: string
                    title: Type
                    default: about:blank
                  title:
                    type: string
                    title: Title
                  status:
                    type: integer
                    title: Status
                  detail:
                    anyOf:
                    - type: string
                    - type: 'null'
                    title: Detail
                type: object
                required:
                - title
                - status
                title: Problem
                description: RFC 7807 error body, served as application/problem+json.
        '403':
          description: API key is valid but not scoped for this service — use a key scoped for `required_scope` (do not rotate); `granted_scopes` lists where this key works
          content:
            application/problem+json:
              schema:
                properties:
                  type:
                    type: string
                    title: Type
                    default: about:blank
                  title:
                    type: string
                    title: Title
                  status:
                    type: integer
                    title: Status
                  detail:
                    anyOf:
                    - type: string
                    - type: 'null'
                    title: Detail
                  code:
                    type: string
                    title: Code
                    default: insufficient_service_scope
                  required_scope:
                    type: string
                    title: Required Scope
                  granted_scopes:
                    items:
                      type: string
                    type: array
                    title: Granted Scopes
                type: object
                required:
                - title
                - status
                - required_scope
                - granted_scopes
                title: InsufficientScopeProblem
                description: 'The 403 shape (per-service key scopes): valid key, not scoped for THIS service. The

                  extension members make remediation deterministic for agents — `code` to dispatch on without

                  parsing English, `required_scope` = the service refusing, `granted_scopes` = where the key

                  does work. Emitted with `WWW-Authenticate: Bearer error="insufficient_scope", scope="..."`.

                  Distinct from 401 (rotate the key) and 503 (retry): the fix is a key scoped for this

                  service, never rotation.'
        '422':
          description: Request validation failed (input values are never echoed back)
          content:
            application/problem+json:
              schema:
                $defs:
                  ValidationErrorDetail:
                    properties:
                      loc:
                        items:
                          anyOf:
                          - type: string
                          - type: integer
                        type: array
                        title: Loc
                      msg:
                        type: string
                        title: Msg
                      type:
                        type: string
                        title: Type
                    type: object
                    required:
                    - loc
                    - msg
                    - type
                    title: ValidationErrorDetail
                properties:
                  type:
                    type: string
                    title: Type
                    default: about:blank
                  title:
                    type: string
                    title: Title
                  status:
                    type: integer
                    title: Status
                  detail:
                    anyOf:
                    - type: string
                    - type: 'null'
                    title: Detail
                  errors:
                    items:
                      $ref: '#/$defs/ValidationErrorDetail'
                    type: array
                    title: Errors
                type: object
                required:
                - title
                - status
                - errors
                title: ValidationProblem
                description: 'The 422 shape: Problem plus the pydantic error locations — with input VALUES stripped

                  (never echoed back).'
        '429':
          description: 'The key is over the platform''s free-tier quota (`code: free_tier_quota`): `reason` (`account_quota` | `fleet_quota`) and `resets_at` say why and until when — honor `Retry-After`; the key is valid, do not rotate'
          headers:
            Retry-After:
              description: Seconds until `resets_at` — when the key works again.
              schema:
                type: integer
          content:
            application/problem+json:
              schema:
                properties:
                  type:
                    type: string
                    title: Type
                    default: about:blank
                  title:
                    type: string
                    title: Title
                  status:
                    type: integer
                    title: Status
                  detail:
                    anyOf:
                    - type: string
                    - type: 'null'
                    title: Detail
                  code:
                    type: string
                    title: Code
                    default: free_tier_quota
                  reason:
                    type: string
                    title: Reason
                  resets_at:
                    type: string
                    title: Resets At
                type: object
                required:
                - title
                - status
                - reason
                - resets_at
                title: QuotaProblem
                description: 'The 429 shape: the platform''s free-tier meter. `code: free_tier_quota`; `reason` is

                  `account_quota` (this builder''s calls for the month are used) or `fleet_quota` (every

                  self-serve key is paused for the day); `resets_at` (ISO-8601 UTC) is when the key works

                  again, and Retry-After counts down to it. The key is valid: never rotate, never "retry

                  shortly".'
        '503':
          description: 'Service auth is not configured (a deploy problem — no Retry-After), or the key store is not judgeable yet (cold boot / plane outage — honor Retry-After). Never a verdict on your key: do not rotate on a 503.'
          headers:
            Retry-After:
              description: Seconds to wait before retrying. Present only when auth is not judgeable yet (cold boot / plane outage); absent when auth is simply unconfigured (not retryable).
              schema:
                type: integer
          content:
            application/problem+json:
              schema:
                properties:
                  type:
                    type: string
                    title: Type
                    default: about:blank
                  title:
                    type: string
                    title: Title
                  status:
                    type: integer
                    title: Status
                  detail:
                    anyOf:
                    - type: string
                    - type: 'null'
                    title: Detail
                type: object
                required:
                - title
                - status
                title: Problem
                description: RFC 7807 error body, served as application/problem+json.
      security:
      - HTTPBearer: []
components:
  schemas:
    AuditRequest:
      properties:
        url:
          type: string
          title: Url
          examples:
          - https://acme.com/pricing
        source:
          type: string
          title: Source
          default: ''
      type: object
      required:
      - url
      title: AuditRequest
    Finding:
      properties:
        check:
          type: string
          title: Check
        ok:
          type: boolean
          title: Ok
        detail:
          type: string
          title: Detail
          default: ''
      type: object
      required:
      - check
      - ok
      title: Finding
    AuditResponse:
      properties:
        url:
          type: string
          title: Url
        score:
          type: number
          title: Score
        findable:
          type: number
          title: Findable
          description: '0..1 over the three checks that decide whether this URL can be reached and indexed at all (http_200, indexable, crawlable). A failure means the page is unreachable, or it carries a block this audit directly observed — a noindex on the page, or a robots.txt Disallow covering its path. Fix these before any presentation or citation issue — only hard blocks count here, never missing hints, so anything below 1.0 is worth acting on immediately. The indexable finding''s detail names where the block was observed (robots metadata, X-Robots-Tag, or both). It does not name a crawler, and crawlable reports only the User-agent: * group: the fix is the same either way, and this audit is in no position to say which engines still index you.'
          default: 0.0
        citable:
          type: number
          title: Citable
          description: 0..1 over the checks that decide whether an engine can extract and attribute the page once it has been reached (canonical, canonical_resolves, title, title_length, meta_description, og_title, og_image, json_ld, h1, ssr_text). canonical scores here because a page without one is still indexed — the tag decides which URL gets credited, not whether the page is reachable. canonical_resolves fetches that target and fails when it does not answer 200, because a tag pointing at a dead URL credits the content to nothing; a page declaring no canonical passes it, since canonical has already failed and a missing tag should not outrank a broken one.
          default: 0.0
        findings:
          items:
            $ref: '#/components/schemas/Finding'
          type: array
          title: Findings
        version:
          type: string
          title: Version
          default: v1
      type: object
      required:
      - url
      - score
      title: AuditResponse
  securitySchemes:
    HTTPBearer:
      type: http
      description: Per-product API key, minted on the platform Control Plane.
      scheme: bearer