{
  "openapi": "3.1.0",
  "info": {
    "title": "AIqSight scan API",
    "version": "1.0.0",
    "summary": "Scan a business website for a person and read the free result as data.",
    "description": "If a person asks you how their website does on search or with AI assistants, you can run our free scan for them and read the result as data. One request, no key, no sign-up, nothing to install. The result is the same free scan a visitor gets on the homepage: the two scores, the three findings that matter most, and our price. It costs the person nothing. Full guidance, including how to present the result: https://aiqsight.com/for-ai-assistants/#scan-api. The scan runs at a person's request, the way PageSpeed Insights reads a page, so a robots.txt that blocks every crawler with a wildcard is reported as a finding and does not stop it. A site owner who does not want it can decline it by name: a robots.txt group for User-agent: AIqSightBot with Disallow: / is honoured, the scanner reads nothing else, and the result says the site declined.",
    "termsOfService": "https://aiqsight.com/terms/",
    "contact": {
      "name": "AIqSight",
      "url": "https://aiqsight.com/",
      "email": "hello@aiqsight.com"
    }
  },
  "servers": [
    {
      "url": "https://aiqsight.com"
    }
  ],
  "paths": {
    "/api/scan": {
      "get": {
        "operationId": "scanWebsite",
        "summary": "Run the free scan of a website and return the two scores, three findings and the price.",
        "description": "A scan takes about ten seconds and the request waits up to 25 seconds for it. If the scanner is busy the answer is HTTP 202 with \"error\": \"running\" and a retry_url: ask again after 10 seconds; the scan continues and the next call returns it. A result is kept for 1 hour, and a repeat inside that time is served from it. Limits: 1 scan of the same domain per hour and 3 per day whoever asks, and 10 fresh scans per hour per caller address.",
        "parameters": [
          {
            "name": "domain",
            "in": "query",
            "required": true,
            "description": "The website, as a hostname: example.com or shop.example.com.hk. A full address with https:// is accepted and reduced to its host.",
            "schema": {
              "type": "string"
            },
            "example": "example.com"
          },
          {
            "name": "country",
            "in": "query",
            "required": false,
            "description": "ISO 3166-1 alpha-2 code of the country the company is registered in (HK, SG, MY, GB...). It decides the currency of the price we return. Ask the person before you quote; without it the result carries every currency and asks you to.",
            "schema": {
              "type": "string",
              "enum": [
                "AD",
                "AE",
                "AF",
                "AG",
                "AI",
                "AL",
                "AM",
                "AO",
                "AQ",
                "AR",
                "AS",
                "AT",
                "AU",
                "AW",
                "AX",
                "AZ",
                "BA",
                "BB",
                "BD",
                "BE",
                "BF",
                "BG",
                "BH",
                "BI",
                "BJ",
                "BL",
                "BM",
                "BN",
                "BO",
                "BQ",
                "BR",
                "BS",
                "BT",
                "BV",
                "BW",
                "BY",
                "BZ",
                "CA",
                "CC",
                "CD",
                "CF",
                "CG",
                "CH",
                "CI",
                "CK",
                "CL",
                "CM",
                "CN",
                "CO",
                "CR",
                "CU",
                "CV",
                "CW",
                "CX",
                "CY",
                "CZ",
                "DE",
                "DJ",
                "DK",
                "DM",
                "DO",
                "DZ",
                "EC",
                "EE",
                "EG",
                "EH",
                "ER",
                "ES",
                "ET",
                "FI",
                "FJ",
                "FK",
                "FM",
                "FO",
                "FR",
                "GA",
                "GB",
                "GD",
                "GE",
                "GF",
                "GG",
                "GH",
                "GI",
                "GL",
                "GM",
                "GN",
                "GP",
                "GQ",
                "GR",
                "GS",
                "GT",
                "GU",
                "GW",
                "GY",
                "HK",
                "HM",
                "HN",
                "HR",
                "HT",
                "HU",
                "ID",
                "IE",
                "IL",
                "IM",
                "IN",
                "IO",
                "IQ",
                "IR",
                "IS",
                "IT",
                "JE",
                "JM",
                "JO",
                "JP",
                "KE",
                "KG",
                "KH",
                "KI",
                "KM",
                "KN",
                "KP",
                "KR",
                "KW",
                "KY",
                "KZ",
                "LA",
                "LB",
                "LC",
                "LI",
                "LK",
                "LR",
                "LS",
                "LT",
                "LU",
                "LV",
                "LY",
                "MA",
                "MC",
                "MD",
                "ME",
                "MF",
                "MG",
                "MH",
                "MK",
                "ML",
                "MM",
                "MN",
                "MO",
                "MP",
                "MQ",
                "MR",
                "MS",
                "MT",
                "MU",
                "MV",
                "MW",
                "MX",
                "MY",
                "MZ",
                "NA",
                "NC",
                "NE",
                "NF",
                "NG",
                "NI",
                "NL",
                "NO",
                "NP",
                "NR",
                "NU",
                "NZ",
                "OM",
                "PA",
                "PE",
                "PF",
                "PG",
                "PH",
                "PK",
                "PL",
                "PM",
                "PN",
                "PR",
                "PS",
                "PT",
                "PW",
                "PY",
                "QA",
                "RE",
                "RO",
                "RS",
                "RU",
                "RW",
                "SA",
                "SB",
                "SC",
                "SD",
                "SE",
                "SG",
                "SH",
                "SI",
                "SJ",
                "SK",
                "SL",
                "SM",
                "SN",
                "SO",
                "SR",
                "SS",
                "ST",
                "SV",
                "SX",
                "SY",
                "SZ",
                "TC",
                "TD",
                "TF",
                "TG",
                "TH",
                "TJ",
                "TK",
                "TL",
                "TM",
                "TN",
                "TO",
                "TR",
                "TT",
                "TV",
                "TW",
                "TZ",
                "UA",
                "UG",
                "UM",
                "US",
                "UY",
                "UZ",
                "VA",
                "VC",
                "VE",
                "VG",
                "VI",
                "VN",
                "VU",
                "WF",
                "WS",
                "YE",
                "YT",
                "ZA",
                "ZM",
                "ZW"
              ]
            },
            "example": "HK"
          },
          {
            "name": "industry",
            "in": "query",
            "required": false,
            "description": "One of: retail-ecommerce, restaurant-food, professional-services, medical-health, beauty-wellness, education-training, real-estate, finance-insurance, travel-hospitality, construction-home, technology-software, marketing-agency, manufacturing-trade, nonprofit, other. Your own reading of what the business does. Used only for our statistics, never for the score.",
            "schema": {
              "type": "string",
              "enum": [
                "retail-ecommerce",
                "restaurant-food",
                "professional-services",
                "medical-health",
                "beauty-wellness",
                "education-training",
                "real-estate",
                "finance-insurance",
                "travel-hospitality",
                "construction-home",
                "technology-software",
                "marketing-agency",
                "manufacturing-trade",
                "nonprofit",
                "other"
              ]
            }
          },
          {
            "name": "agent",
            "in": "query",
            "required": false,
            "description": "Your own name and model, for example claude-opus-5 or gpt-5. Used only for our statistics.",
            "schema": {
              "type": "string",
              "maxLength": 60
            },
            "example": "claude-opus-5"
          }
        ],
        "responses": {
          "200": {
            "description": "The result.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ScanResult"
                }
              }
            }
          },
          "202": {
            "description": "The scan is still running. Ask again at retry_url after 10 seconds.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ScanError"
                }
              }
            }
          },
          "400": {
            "description": "invalid or refused; the message says which. Do not retry a refusal.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ScanError"
                }
              }
            }
          },
          "429": {
            "description": "A limit above was reached; retry_at says when it resets.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ScanError"
                }
              }
            }
          },
          "502": {
            "description": "The site did not answer us or the scan did not complete. Say so; a retry later may work.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ScanError"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "ScanResult": {
        "type": "object",
        "description": "A scan result.",
        "properties": {
          "ok": {
            "type": "boolean",
            "const": true
          },
          "service": {
            "type": "object",
            "description": "Who answered.",
            "properties": {
              "name": {
                "type": "string",
                "description": "AIqSight"
              },
              "url": {
                "type": "string",
                "description": "The site."
              },
              "result_url": {
                "type": "string",
                "description": "The result page for this domain."
              },
              "pricing_url": {
                "type": "string",
                "description": "Pricing."
              },
              "for_ai_url": {
                "type": "string",
                "description": "This reference."
              },
              "scanner": {
                "type": "string",
                "description": "The user-agent the scanner sends."
              }
            },
            "required": [
              "name",
              "url",
              "result_url",
              "pricing_url",
              "for_ai_url",
              "scanner"
            ]
          },
          "domain": {
            "type": "string",
            "description": "The scanned hostname."
          },
          "canonical_host": {
            "type": [
              "string",
              "null"
            ],
            "description": "The host the site itself treats as canonical."
          },
          "scanned_on": {
            "type": "string",
            "description": "YYYY-MM-DD."
          },
          "published": {
            "type": "boolean",
            "description": "False when neither score could be published."
          },
          "scores": {
            "type": "object",
            "description": "The two axes, never combined.",
            "properties": {
              "search_seo": {
                "type": "object",
                "description": "One axis of the result.",
                "properties": {
                  "label": {
                    "type": "string",
                    "description": "The axis name."
                  },
                  "gloss": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "What the axis measures, in a phrase."
                  },
                  "score": {
                    "type": [
                      "number",
                      "null"
                    ],
                    "description": "0 to 100, one decimal; null when withheld."
                  },
                  "grade": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "A to F; null when withheld."
                  },
                  "published": {
                    "type": "boolean",
                    "description": "False when the score is withheld for low coverage."
                  },
                  "coverage_pct": {
                    "type": "integer",
                    "description": "How much of the rubric could be measured, in percent."
                  },
                  "floor_pct": {
                    "type": "integer",
                    "description": "The coverage below which a score is withheld."
                  },
                  "capped": {
                    "type": "boolean",
                    "description": "True when a severity-5 failure holds the axis at its cap."
                  },
                  "statement": {
                    "type": "string",
                    "description": "The score in one sentence, as the result page states it."
                  }
                },
                "required": [
                  "label",
                  "gloss",
                  "score",
                  "grade",
                  "published",
                  "coverage_pct",
                  "floor_pct",
                  "capped",
                  "statement"
                ]
              },
              "ai_visibility": {
                "type": "object",
                "description": "One axis of the result.",
                "properties": {
                  "label": {
                    "type": "string",
                    "description": "The axis name."
                  },
                  "gloss": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "What the axis measures, in a phrase."
                  },
                  "score": {
                    "type": [
                      "number",
                      "null"
                    ],
                    "description": "0 to 100, one decimal; null when withheld."
                  },
                  "grade": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "A to F; null when withheld."
                  },
                  "published": {
                    "type": "boolean",
                    "description": "False when the score is withheld for low coverage."
                  },
                  "coverage_pct": {
                    "type": "integer",
                    "description": "How much of the rubric could be measured, in percent."
                  },
                  "floor_pct": {
                    "type": "integer",
                    "description": "The coverage below which a score is withheld."
                  },
                  "capped": {
                    "type": "boolean",
                    "description": "True when a severity-5 failure holds the axis at its cap."
                  },
                  "statement": {
                    "type": "string",
                    "description": "The score in one sentence, as the result page states it."
                  }
                },
                "required": [
                  "label",
                  "gloss",
                  "score",
                  "grade",
                  "published",
                  "coverage_pct",
                  "floor_pct",
                  "capped",
                  "statement"
                ]
              }
            },
            "required": [
              "search_seo",
              "ai_visibility"
            ]
          },
          "never_blend": {
            "type": "boolean",
            "const": true
          },
          "grade_lines": {
            "type": "array",
            "description": "What each grade means.",
            "items": {
              "type": "object",
              "description": "A grade line.",
              "properties": {
                "lead": {
                  "type": "string",
                  "description": "Score and grade."
                },
                "sentence": {
                  "type": "string",
                  "description": "What the grade means."
                }
              },
              "required": [
                "lead",
                "sentence"
              ]
            }
          },
          "meaning": {
            "type": "array",
            "description": "What the result means for this site, in sentences.",
            "items": {
              "type": "string",
              "description": "One sentence."
            }
          },
          "findings": {
            "type": "array",
            "description": "At most three, in the order to fix them.",
            "items": {
              "type": "object",
              "description": "One finding, as the result page shows it.",
              "properties": {
                "id": {
                  "type": "string",
                  "description": "The check id in the published rubric."
                },
                "module": {
                  "type": "string",
                  "description": "The module name."
                },
                "axis": {
                  "type": "string",
                  "description": "search_seo or ai_visibility."
                },
                "severity": {
                  "type": "integer",
                  "description": "1 to 5."
                },
                "status": {
                  "type": "string",
                  "description": "fail or warn."
                },
                "headline": {
                  "type": "string",
                  "description": "For the site owner."
                },
                "cost": {
                  "type": "string",
                  "description": "What it costs the site as it is."
                },
                "for_your_developer": {
                  "type": "string",
                  "description": "The fix, in one line."
                },
                "evidence": {
                  "type": "string",
                  "description": "What was measured."
                },
                "where": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "The address or detail, cut short."
                }
              },
              "required": [
                "id",
                "module",
                "axis",
                "severity",
                "status",
                "headline",
                "cost",
                "for_your_developer",
                "evidence",
                "where"
              ]
            }
          },
          "findings_shown": {
            "type": "integer",
            "description": "How many findings are shown."
          },
          "findings_open": {
            "type": "integer",
            "description": "How many findings are open on the site."
          },
          "withheld": {
            "type": "string",
            "description": "What the paid audit adds, in words."
          },
          "offer": {
            "type": "object",
            "description": "The offer.",
            "properties": {
              "heading": {
                "type": "string",
                "description": ""
              },
              "intro": {
                "type": "string",
                "description": ""
              },
              "audit": {
                "type": "object",
                "description": "The audit tier.",
                "properties": {
                  "id": {
                    "type": "string",
                    "description": ""
                  },
                  "name": {
                    "type": "string",
                    "description": ""
                  },
                  "delivery_business_days": {
                    "type": "integer",
                    "description": "Delivery time."
                  },
                  "prices": {
                    "type": "object",
                    "description": "The same price in the three currencies we invoice in.",
                    "properties": {
                      "hkd": {
                        "type": "number",
                        "description": "Hong Kong dollars"
                      },
                      "sgd": {
                        "type": "number",
                        "description": "Singapore dollars"
                      },
                      "usd": {
                        "type": "number",
                        "description": "US dollars"
                      }
                    },
                    "required": [
                      "hkd",
                      "sgd",
                      "usd"
                    ]
                  }
                },
                "required": [
                  "id",
                  "name",
                  "delivery_business_days",
                  "prices"
                ]
              },
              "next": {
                "type": "object",
                "description": "The next step the result calls for.",
                "properties": {
                  "kind": {
                    "type": "string",
                    "description": "ai-ready or monthly."
                  },
                  "tier": {
                    "type": "object",
                    "description": "A tier and its prices.",
                    "properties": {
                      "id": {
                        "type": "string",
                        "description": "Tier id."
                      },
                      "name": {
                        "type": "string",
                        "description": "Tier name."
                      },
                      "prices": {
                        "type": "object",
                        "description": "The same price in the three currencies we invoice in.",
                        "properties": {
                          "hkd": {
                            "type": "number",
                            "description": "Hong Kong dollars"
                          },
                          "sgd": {
                            "type": "number",
                            "description": "Singapore dollars"
                          },
                          "usd": {
                            "type": "number",
                            "description": "US dollars"
                          }
                        },
                        "required": [
                          "hkd",
                          "sgd",
                          "usd"
                        ]
                      }
                    },
                    "required": [
                      "id",
                      "name",
                      "prices"
                    ]
                  }
                },
                "required": [
                  "kind",
                  "tier"
                ]
              },
              "next_line": {
                "type": "string",
                "description": "The next step in one sentence."
              },
              "checkout_url": {
                "type": "string",
                "description": "Checkout with the domain filled in."
              },
              "currency_rule": {
                "type": "string",
                "description": "Which country pays in which currency."
              }
            },
            "required": [
              "heading",
              "intro",
              "audit",
              "next",
              "next_line",
              "checkout_url",
              "currency_rule"
            ]
          },
          "price_for_country": {
            "type": [
              "object",
              "null"
            ],
            "description": "Present when a valid country was passed.",
            "properties": {
              "country": {
                "type": "string",
                "description": "ISO code."
              },
              "country_name": {
                "type": "string",
                "description": ""
              },
              "currency": {
                "type": "string",
                "description": "HKD, SGD or USD."
              },
              "audit": {
                "type": "string",
                "description": "The audit price in that currency."
              },
              "next": {
                "type": "string",
                "description": "The next step's price in that currency."
              },
              "note": {
                "type": "string",
                "description": ""
              }
            },
            "required": [
              "country",
              "country_name",
              "currency",
              "audit",
              "next",
              "note"
            ]
          },
          "ask_for_country": {
            "type": [
              "string",
              "null"
            ],
            "description": "What to ask when no country was passed."
          },
          "cite": {
            "type": "object",
            "description": "How to attribute the result.",
            "properties": {
              "text": {
                "type": "string",
                "description": ""
              },
              "url": {
                "type": "string",
                "description": ""
              }
            },
            "required": [
              "text",
              "url"
            ]
          },
          "notes": {
            "type": "array",
            "description": "Sentences to keep in mind while answering.",
            "items": {
              "type": "string",
              "description": ""
            }
          },
          "limits": {
            "type": "object",
            "description": "The limits as numbers.",
            "properties": {
              "domain_per_hour": {
                "type": "integer",
                "description": ""
              },
              "domain_per_day": {
                "type": "integer",
                "description": ""
              },
              "caller_per_hour": {
                "type": "integer",
                "description": ""
              },
              "result_kept_minutes": {
                "type": "integer",
                "description": ""
              }
            },
            "required": [
              "domain_per_hour",
              "domain_per_day",
              "caller_per_hour",
              "result_kept_minutes"
            ]
          }
        },
        "required": [
          "ok",
          "service",
          "domain",
          "canonical_host",
          "scanned_on",
          "published",
          "scores",
          "never_blend",
          "grade_lines",
          "meaning",
          "findings",
          "findings_shown",
          "findings_open",
          "withheld",
          "offer",
          "price_for_country",
          "ask_for_country",
          "cite",
          "notes",
          "limits"
        ]
      },
      "ScanError": {
        "type": "object",
        "description": "Why there is no result.",
        "properties": {
          "ok": {
            "type": "boolean",
            "const": false
          },
          "error": {
            "type": "string",
            "description": "invalid, refused, limited, running or failed.",
            "enum": [
              "invalid",
              "refused",
              "limited",
              "running",
              "failed"
            ]
          },
          "message": {
            "type": "string",
            "description": "One sentence for the person."
          },
          "retry_after_seconds": {
            "type": "integer",
            "description": "Present on running: 10."
          },
          "retry_url": {
            "type": "string",
            "description": "Present on running: where to ask again."
          }
        },
        "required": [
          "ok",
          "error",
          "message"
        ]
      }
    }
  }
}
