{"openapi":"3.1.0","info":{"title":"Neuronto ARD Registry: Agentic Resource Discovery (ARD) Index","license":{"name":"Apache-2.0","url":"https://www.apache.org/licenses/LICENSE-2.0"},"version":"1.0.0"},"servers":[{"url":"https://neuronto.com"}],"paths":{"/search":{"post":{"summary":"Search Endpoint","description":"POST /search - the one endpoint the spec mandates.\n\nEvery result carries `identifier`, `score` (0-100) and `source`, which are\nthe three fields the conformance tool requires of a SearchResultItem.","operationId":"search_endpoint_search_post","requestBody":{"content":{"application/json":{"schema":{"properties":{"query":{"properties":{"text":{"type":"string"}},"type":"object","required":["text"]},"limit":{"type":"integer","default":10},"federation":{"type":"string","enum":["auto","none","referrals"],"description":"auto (the spec default) fans out to every public ARD registry and fuses; none answers from this index alone in ~60 ms.","default":"auto"}},"type":"object","required":["query"],"title":"Body","example":{"query":{"text":"charge a credit card"},"limit":10}}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/explore":{"post":{"summary":"Explore Endpoint","description":"POST /explore - optional introspection over facets (§5.3.3).\n\nExplore does not federate; it is scoped to this registry's own index.\n\nA bare body, or one without `resultType.facets`, returns every supported\nfacet rather than a 400. The outside-failure monitor watched one agent read\n/openapi.json, find a request schema that said only \"object\", and then send\nseven plausible bodies here and be refused each time. Introspection that has\nto be introspected first is a contradiction; asked for nothing specific, it\nnow answers with everything it has.","operationId":"explore_endpoint_explore_post","requestBody":{"content":{"application/json":{"schema":{"properties":{"query":{"properties":{"text":{"type":"string"}},"type":"object","description":"Optional. Restricts the counts to entries matching this text."},"resultType":{"properties":{"facets":{"items":{"oneOf":[{"type":"string"},{"properties":{"field":{"type":"string"},"limit":{"type":"integer"}},"type":"object","required":["field"]}]},"type":"array","description":"Which facets to count. Omit to receive every supported facet."}},"type":"object"}},"type":"object","title":"Body","example":{"query":{"text":"payments"},"resultType":{"facets":[{"field":"type","limit":20},"publisher"]}}}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/agents":{"get":{"summary":"Agents Endpoint","description":"GET /agents - deterministic, paginated browsing (§5.3.4).\n\nOptional in the spec, but the conformance tool checks the shape when it is\nanswered: GitHub's Agent Finder returns 200 with a body that has no `items`\narray and fails on exactly this. Ours returns the paginated object.","operationId":"agents_endpoint_agents_get","parameters":[{"name":"filter","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Filter"}},{"name":"orderBy","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Orderby"}},{"name":"pageSize","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Pagesize"}},{"name":"pageToken","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Pagetoken"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/health":{"get":{"summary":"Health","operationId":"health_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/stats":{"get":{"summary":"Stats","operationId":"stats_stats_get","parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","maximum":90,"minimum":7,"default":30,"title":"Days"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/audit":{"post":{"summary":"Audit Endpoint","description":"Audit a domain's ARD publishing and report where it stands.\n\nThere is no console for ARD publishers: you can serve a perfect manifest and\nhave no way to learn that no registry returns you. This answers that, and\nthe coverage half is checked against every registry rather than only ours,\nbecause a report that only measures our own index is marketing.","operationId":"audit_endpoint_audit_post","requestBody":{"content":{"application/json":{"schema":{"type":"object","title":"Body"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/demand":{"get":{"summary":"Demand Endpoint","description":"Did anyone come looking, and what did they ask?\n\nBeing listed is not the question a publisher has; this is. Every search\nrecords which entries it returned and at what rank, so the answer is exact\nrather than modelled. No client identifier is ever stored, so this can say\nwhat was asked and never who asked.","operationId":"demand_endpoint_demand_get","parameters":[{"name":"domain","in":"query","required":true,"schema":{"type":"string","minLength":3,"title":"Domain"}},{"name":"days","in":"query","required":false,"schema":{"type":"integer","maximum":365,"minimum":1,"default":30,"title":"Days"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":25,"title":"Limit"}},{"name":"include_probe","in":"query","required":false,"schema":{"type":"integer","maximum":1,"minimum":0,"default":0,"title":"Include Probe"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/manifest/build":{"post":{"summary":"Manifest Build","description":"Write the manifest for a domain from what that domain already publishes.\n\nMost domains will never author one by hand, and they do not have to: an MCP\nserver, an OpenAPI document or an llms.txt is already the substance of an\nentry. Nothing here is inferred from a name or guessed from a pattern. Every\nentry cites the fetch that produced it, so the publisher can check each line\nagainst their own server before they adopt it.","operationId":"manifest_build_manifest_build_post","requestBody":{"content":{"application/json":{"schema":{"type":"object","title":"Body"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/claim":{"post":{"summary":"Claim Start","description":"Begin proving you own a domain.","operationId":"claim_start_claim_post","requestBody":{"content":{"application/json":{"schema":{"type":"object","title":"Body"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/claim/verify":{"post":{"summary":"Claim Verify","operationId":"claim_verify_claim_verify_post","requestBody":{"content":{"application/json":{"schema":{"type":"object","title":"Body"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/private/entries":{"get":{"summary":"Private List","operationId":"private_list_private_entries_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}},"post":{"summary":"Private Add","description":"Register an internal service, visible only to this domain's key.\n\nAn organisation's list of approved internal services usually lives in a\nsystem prompt, where an agent cannot search it and nobody can audit it. Here\nit is indexed alongside the public world and returned by the same query,\nlabelled, so a caller always knows which half a result came from.","operationId":"private_add_private_entries_post","requestBody":{"content":{"application/json":{"schema":{"type":"object","title":"Body"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"summary":"Private Delete","description":"Remove an internal service. Scoped to the caller's own domain.","operationId":"private_delete_private_entries_delete","requestBody":{"content":{"application/json":{"schema":{"type":"object","title":"Body"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/doctor":{"post":{"summary":"Doctor Endpoint","description":"What to change in a manifest, and why it is not being found.\n\nTakes a domain, in which case the manifest is fetched and the index is\nconsulted for what happened when we called its endpoints, or a manifest\nbody, in which case only the document is read. Findings, never a score.","operationId":"doctor_endpoint_doctor_post","requestBody":{"content":{"application/json":{"schema":{"type":"object","title":"Body"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/plan":{"post":{"summary":"Plan Endpoint","description":"A task, decomposed into steps, each with candidate resources.\n\nDiscovery for jobs that need more than one tool. The agent still\nchooses, connects over each resource's own protocol, and verifies trust\nitself.","operationId":"plan_endpoint_plan_post","requestBody":{"content":{"application/json":{"schema":{"type":"object","title":"Body"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/me":{"get":{"summary":"Me Endpoint","description":"What this caller has, and what they have used.\n\nA caller with no key gets the free numbers rather than an error: the\nquestion \"what am I allowed\" deserves an answer whoever asks it.","operationId":"me_endpoint_me_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/analytics":{"get":{"summary":"Analytics Page","operationId":"analytics_page_analytics_get","parameters":[{"name":"domain","in":"query","required":false,"schema":{"type":"string","default":"","title":"Domain"}},{"name":"days","in":"query","required":false,"schema":{"type":"integer","default":30,"title":"Days"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/usage":{"get":{"summary":"Usage Endpoint","description":"How much a publisher's work is actually used, over time.\n\nAdoption, not demand. Every figure is a count somebody else publishes,\nread from a free API, so a publisher can check any of it with curl. It\nsays how often the thing was installed, starred and depended on. It does\nnot say how many agents went looking, because nobody can say that.","operationId":"usage_endpoint_usage_get","parameters":[{"name":"domain","in":"query","required":false,"schema":{"type":"string","default":"","title":"Domain"}},{"name":"metric","in":"query","required":false,"schema":{"type":"string","default":"stars","title":"Metric"}},{"name":"days","in":"query","required":false,"schema":{"type":"integer","default":30,"title":"Days"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/web-position":{"get":{"summary":"Web Position Endpoint","description":"Where a publisher sits on the open web, for the phrasings we track.\n\nIt belongs next to registry position because models cite third-party\npages: a resource that ranks first in every registry and nowhere on the\nweb is invisible to the systems it is trying to reach.","operationId":"web_position_endpoint_web_position_get","parameters":[{"name":"domain","in":"query","required":false,"schema":{"type":"string","default":"","title":"Domain"}},{"name":"days","in":"query","required":false,"schema":{"type":"integer","default":30,"title":"Days"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/insights":{"get":{"summary":"Insights Endpoint","description":"Where a publisher ranks over time, and who is above them.\n\nPositions, never demand. This index has essentially no third-party query\nvolume, so a \"search volume\" number here would be our own test traffic\nsold back to the person who most needs it to be true.","operationId":"insights_endpoint_insights_get","parameters":[{"name":"domain","in":"query","required":false,"schema":{"type":"string","default":"","title":"Domain"}},{"name":"days","in":"query","required":false,"schema":{"type":"integer","default":30,"title":"Days"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/tools":{"post":{"summary":"Tools Endpoint","operationId":"tools_endpoint_tools_post","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","title":"Body"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"summary":"Tools Get","description":"With `q`, the JSON search API. Without it, the human capability index.\n\nOne URL serving both is deliberate: an agent handed `/tools?q=...` gets data,\nand a crawler handed `/tools` gets a page it can read.","operationId":"tools_get_tools_get","parameters":[{"name":"q","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Q"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Limit"}},{"name":"withSchema","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Withschema"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/bench":{"get":{"summary":"Bench Endpoint","operationId":"bench_endpoint_bench_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/adoption":{"get":{"summary":"Adoption Endpoint","operationId":"adoption_endpoint_adoption_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/state-of-mcp":{"get":{"summary":"State Of Mcp","description":"What share of the agentic web actually answers, measured not asserted.\n\nPublished because nobody else can: a directory knows what it lists, and only\nsomething that probes knows what responds. JSON to a machine, HTML to a\nbrowser, and the limitations travel inside the payload rather than in a\nfootnote, so a reader who quotes the number also gets its caveats.","operationId":"state_of_mcp_state_of_mcp_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/reliability":{"get":{"summary":"Reliability Report","description":"How reliably endpoints answer, over time rather than at one instant.\n\n`/state-of-mcp` says what share of the index answers right now. This says\nwhat share of *probes* an endpoint has answered, which is the question a\nconsumer actually has, and it is only answerable by something that has been\nprobing on a timer and counting.\n\nRates are withheld below a minimum number of probes. A single successful\nprobe is not 100% uptime, and publishing it as one would be the most quotable\nwrong number on the site.","operationId":"reliability_report_reliability_get","parameters":[{"name":"entry","in":"query","required":false,"schema":{"type":"string","maxLength":400,"default":"","title":"Entry"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/tool-safety":{"get":{"summary":"Tool Safety","description":"What tool descriptions in the index tell the model to do.\n\nA tool description is text that enters the model's context and is read as\ninstruction, so it is the one part of a third-party server that acts on an\nagent before the agent calls anything.\n\nThe measurement is published because the answer is a surprise: the corpus is\nclose to clean. It is deliberately NOT a score, a badge or a ranking signal.\nFindings are counts and excerpts for a human to read, and the classes the\ndetectors refuse to match are published alongside the ones they do, because\nan earlier draft of this scan was wrong about four legitimate publishers.","operationId":"tool_safety_tool_safety_get","parameters":[{"name":"entry","in":"query","required":false,"schema":{"type":"string","maxLength":400,"default":"","title":"Entry"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/liveness":{"get":{"summary":"Liveness Feed","description":"Which endpoints answer, as a feed anyone may consume, including rivals.\n\nWe probe every endpoint we index and keep the transitions. Other registries\ndo not, which means they list servers that stopped answering months ago and\nhave no way to know. Publishing this costs us nothing we would otherwise\nsell and makes the whole ecosystem less wrong, which is worth more to us\nthan the small advantage of being the only ones who can tell.\n\nNo key, no attribution required, no rate limit beyond the shared one.\n`dead=1` is the useful half: the entries worth re-checking on your side.","operationId":"liveness_feed_liveness_get","parameters":[{"name":"dead","in":"query","required":false,"schema":{"type":"integer","maximum":1,"minimum":0,"default":0,"title":"Dead"}},{"name":"since","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Since"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":5000,"minimum":1,"default":500,"title":"Limit"}},{"name":"cursor","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Cursor"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/submit":{"post":{"summary":"Submit Endpoint","description":"Index an MCP endpoint (`{\"endpoint\": url}`) or a manifest-serving domain\n(`{\"domain\": host}`). A submission that does not verify right now is kept\nand retried on a fixed schedule for about two and a half days.","operationId":"submit_endpoint_submit_post","requestBody":{"content":{"application/json":{"schema":{"type":"object","title":"Body"}}},"required":true},"responses":{"200":{"description":"verified and indexed; `submission.id` is the receipt","content":{"application/json":{"schema":{}}}},"202":{"description":"kept and retried: not verified at this moment, `evidence` says what the endpoint returned, `retry.status_url` shows progress"},"400":{"description":"malformed request, nothing queued"},"404":{"description":"every retry attempt failed; the last `evidence` is included"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/submit/status/{sid}":{"get":{"summary":"Submit Status","description":"Where a submission stands. Public, because the id is the only\ncredential a publisher has for it and there is nothing sensitive in it.","operationId":"submit_status_submit_status__sid__get","parameters":[{"name":"sid","in":"path","required":true,"schema":{"type":"string","title":"Sid"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/submit/status":{"get":{"summary":"Submit Status For","description":"The latest submission for a target, for a publisher who lost the id.","operationId":"submit_status_for_submit_status_get","parameters":[{"name":"endpoint","in":"query","required":false,"schema":{"type":"string","title":"Endpoint"}},{"name":"domain","in":"query","required":false,"schema":{"type":"string","title":"Domain"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}},"components":{"schemas":{"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}}}