Let Agents In

Docs

Everything here works without an account

There is no signup, no key and no OAuth flow, because the scan reads only public pages and there is nothing to protect. If you are building the same kind of thing, that decision is the one worth copying: a gate with nothing behind it costs you every agent that cannot pass it and buys nothing.

Scan a domain

One endpoint, one field. It returns a scorecard and a permanent link to the readable version.

curl -X POST https://letagentsin.com/api/scan \
  -H 'content-type: application/json' \
  -d '{"domain": "example.com"}'

The response carries id, domain and scorecard. Every check reports points, max and a human-readable detail. A check may also carry inconclusive: true, which means it scored zero because we could not measure it rather than because the thing is absent, or notApplicable: true, which means the check does not apply to a product of this kind. Treat those differently: they are our blind spot, not a defect in the site. Both are excluded from measurable, which is the denominator to divide by. Dividing by max reports a domain we could not fully read as worse than one we could, which is the one mistake this format exists to prevent.

{
  "id": "example-com-202608072143",
  "domain": "example.com",
  "scorecard": {
    "formulaVersion": "9.2",
    "total": 9,
    "measurable": 14,
    "max": 17,
    "stages": [{ "letter": "A", "title": "Discovery", "points": 4, "measurable": 4, "max": 5 }],
    "checks": [
      { "id": "llms_txt", "stage": "discovery", "label": "llms.txt published",
        "points": 1, "max": 1, "detail": "llms.txt present" },
      { "id": "signup_reachable", "stage": "signup", "label": "Signup page reachable",
        "points": 0, "max": 1,
        "detail": "No signup page linked from the site we could follow",
        "inconclusive": true,
        "unblock": "Link your signup page from your home page and this becomes measurable." }
    ]
  }
}

Progress events

A scan usually takes a few seconds and can reach a minute, mostly because signup probes run three times: bot gates answer inconsistently and a single try would be a coin flip. If you would rather not wait in silence, the streaming endpoint emits the real steps as they happen.

curl -N -X POST https://letagentsin.com/api/scan/stream \
  -H 'content-type: application/json' \
  -d '{"domain": "example.com"}'

event: step
data: {"label":"Checking robots.txt against 13 AI crawlers","done":2,"total":5}

event: done
data: {"id":"example-com-202608072143","total":9,"max":17}

Credentials and provisioning

There are none. You do not create an API key, there is no management API to call and no service account to provision, because every endpoint is open. The limits are 5 scans an hour per domain and 30 per caller, and a domain scanned again within 15 minutes returns the stored result rather than a fresh one. Exceeding a limit returns 429 with a retry-after header telling you exactly how long to wait.

There is also an MCP server at /mcp, Streamable HTTP, no authentication, one tool called scan_domain. It runs the same scan as the REST endpoint through the same limits, and the card describing it is at /.well-known/mcp.json.

Both surfaces take a format. sarif returns SARIF 2.1.0, whose result kinds are the same four we use, so a scan can run in your pipeline and fail a build when the score drops. agent returns markdown tasks instead of a report: one task per failing check, each carrying the measurement behind it and a link to the rule, with the unmeasured checks listed separately and marked as not failures.

Every scan we publish is downloadable as one dataset: /corpus.json and /corpus.csv, one row per domain and check, with the verdict and the sentence it was measured from. Free to use and quote with attribution, which makes it the fastest way to disagree with us.

Machine-readable descriptions of all of this live at /openapi.json, /.well-known/agent-access.json, /.well-known/mcp.json and /agent-signup.md.

Refusals

The scanner fetches whatever you send it, so it refuses anything that is not a public host: IP literals, private and loopback ranges, link-local addresses including the cloud metadata endpoint, and names that do not resolve. Redirects are followed by hand and re-checked at every hop against the resolved address, because a public hostname is free to redirect into a private one.

Reading a scorecard

15 checks across 5 stages, 17 points. The stages follow the order an agent actually meets them in, so a low score in an early stage makes the later ones academic: a site that refuses plain HTTP requests cannot be evaluated on its documentation, and the scorecard says so rather than scoring the same wall five times.

  1. ADiscoveryCan an agent find and read you?
  2. BAgent entryIs there a door built for a machine?
  3. CRegistrationCan an agent get an account?
  4. DProvisioningCan it get credentials without a human?
  5. EIntegrationCan it ship working code?

Every rule, threshold and point value is on the methodology page. If a result looks wrong, it is reproducible with curl, and we would rather be corrected than be confidently wrong in someone else’s inbox.