{
 "openapi": "3.1.0",
 "info": {
  "title": "Doorman API",
  "version": "1.0.0",
  "description": "Doorman reads any website's robots.txt and shows which AI bots it lets in: who can train on it, which AI search engines can find and cite it, and which assistants can read it for people. Pick what you want and copy a fixed robots.txt, including the new shared AI-training opt-out line. No account. Public, no API key. Rate limited per client. Made by Clawhard Studio, an AI-powered studio. Support: support@clawhard.com.",
  "contact": {
   "name": "Clawhard Studio",
   "url": "https://clawhard.com",
   "email": "support@clawhard.com"
  }
 },
 "servers": [
  {
   "url": "https://doorman.clawhard.com"
  }
 ],
 "paths": {
  "/api/v1/check": {
   "get": {
    "operationId": "check",
    "summary": "See which AI bots a website lets in",
    "description": "Reads the public robots.txt of a website and reports which AI bots it lets in, by purpose: AI training (GPTBot, ClaudeBot, Google-Extended, Applebot-Extended, Meta-ExternalAgent, CCBot, Bytespider, Amazonbot and more), AI search and answers (OAI-SearchBot, Claude-SearchBot, PerplexityBot, DuckAssistBot), assistants opening pages for a person (ChatGPT-User, Claude-User, Perplexity-User, MistralAI-User) and classic search engines (Googlebot, Bingbot, Applebot). Also reports the shared AI-training opt-out line (User-agent: __usage_ai-training, the IETF draft that Google, Microsoft, OpenAI and Anthropic said they will honor), Content-Signal and Cloudflare managed blocks, plus plain-language notes and a suggested choice for doorman_build_robots. Returns: {url, host, found, verdict, verdict_detail, ai_training, ai_search, assistants, search_engines (each {state: open|blocked|mixed, kept_out, partly, let_in, total}), shared_training_preference, content_signal, cloudflare_managed_block, bots:[{token, owner, category, state, what}], notes[], suggested_choice, robots_txt_bytes, open_url}",
    "responses": {
     "200": {
      "description": "Result. Always has \"ok\": true.",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "ok": {
           "type": "boolean"
          }
         },
         "additionalProperties": true
        }
       }
      }
     },
     "400": {
      "description": "Bad input. {\"ok\":false,\"error\":\"...\"}"
     },
     "429": {
      "description": "Rate limited. Retry after the Retry-After header."
     }
    },
    "parameters": [
     {
      "name": "url",
      "in": "query",
      "required": true,
      "description": "Website address or domain, e.g. nytimes.com",
      "schema": {
       "type": "string"
      }
     }
    ]
   },
   "post": {
    "operationId": "check_post",
    "summary": "See which AI bots a website lets in",
    "description": "Reads the public robots.txt of a website and reports which AI bots it lets in, by purpose: AI training (GPTBot, ClaudeBot, Google-Extended, Applebot-Extended, Meta-ExternalAgent, CCBot, Bytespider, Amazonbot and more), AI search and answers (OAI-SearchBot, Claude-SearchBot, PerplexityBot, DuckAssistBot), assistants opening pages for a person (ChatGPT-User, Claude-User, Perplexity-User, MistralAI-User) and classic search engines (Googlebot, Bingbot, Applebot). Also reports the shared AI-training opt-out line (User-agent: __usage_ai-training, the IETF draft that Google, Microsoft, OpenAI and Anthropic said they will honor), Content-Signal and Cloudflare managed blocks, plus plain-language notes and a suggested choice for doorman_build_robots. Returns: {url, host, found, verdict, verdict_detail, ai_training, ai_search, assistants, search_engines (each {state: open|blocked|mixed, kept_out, partly, let_in, total}), shared_training_preference, content_signal, cloudflare_managed_block, bots:[{token, owner, category, state, what}], notes[], suggested_choice, robots_txt_bytes, open_url}",
    "responses": {
     "200": {
      "description": "Result. Always has \"ok\": true.",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "ok": {
           "type": "boolean"
          }
         },
         "additionalProperties": true
        }
       }
      }
     },
     "400": {
      "description": "Bad input. {\"ok\":false,\"error\":\"...\"}"
     },
     "429": {
      "description": "Rate limited. Retry after the Retry-After header."
     }
    },
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "url": {
          "type": "string",
          "description": "Website address or domain, e.g. nytimes.com"
         }
        },
        "required": [
         "url"
        ]
       }
      }
     }
    }
   }
  },
  "/api/v1/check_text": {
   "post": {
    "operationId": "check_text",
    "summary": "Check a robots.txt file for AI bot access",
    "description": "Same report as doorman_check_site, for robots.txt text you already have (a draft, or a file from a site the checker cannot reach). Parses it the way crawlers do (RFC 9309 groups, longest-match Allow/Disallow, * and $ wildcards) and reports which AI training bots, AI search bots, assistants and search engines it lets in, plus the shared __usage_ai-training preference. Returns: Same shape as doorman_check_site without url/host.",
    "responses": {
     "200": {
      "description": "Result. Always has \"ok\": true.",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "ok": {
           "type": "boolean"
          }
         },
         "additionalProperties": true
        }
       }
      }
     },
     "400": {
      "description": "Bad input. {\"ok\":false,\"error\":\"...\"}"
     },
     "429": {
      "description": "Rate limited. Retry after the Retry-After header."
     }
    },
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "robots_txt": {
          "type": "string",
          "description": "The full robots.txt text (up to 512 KB). Empty means no robots.txt."
         }
        },
        "required": [
         "robots_txt"
        ]
       }
      }
     }
    }
   }
  },
  "/api/v1/build": {
   "post": {
    "operationId": "build",
    "summary": "Write a robots.txt that lets in only the AI bots you want",
    "description": "Builds a robots.txt from a simple choice: AI training in or out, AI search in or out, assistants in or out. Keeps every rule in the existing file (pass it as robots_txt), removes old lines for the AI bots it manages, and adds one clearly labelled block, including the shared User-agent: __usage_ai-training preference. Never touches Googlebot, Bingbot or Applebot, so normal search is unaffected. Returns: {robots, choice, removed_lines, removed_agents, added_groups, kept_note, verdict}",
    "responses": {
     "200": {
      "description": "Result. Always has \"ok\": true.",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "ok": {
           "type": "boolean"
          }
         },
         "additionalProperties": true
        }
       }
      }
     },
     "400": {
      "description": "Bad input. {\"ok\":false,\"error\":\"...\"}"
     },
     "429": {
      "description": "Rate limited. Retry after the Retry-After header."
     }
    },
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "robots_txt": {
          "type": "string",
          "description": "Current robots.txt text to keep (optional)."
         },
         "training": {
          "type": "string",
          "enum": [
           "in",
           "out"
          ],
          "description": "Let AI training bots in or keep them out (default out)."
         },
         "ai_search": {
          "type": "string",
          "enum": [
           "in",
           "out"
          ],
          "description": "AI search and answer engines (default in)."
         },
         "assistants": {
          "type": "string",
          "enum": [
           "in",
           "out"
          ],
          "description": "Assistants that open a page because a person asked (default in)."
         }
        }
       }
      }
     }
    }
   }
  }
 },
 "externalDocs": {
  "description": "llms.txt",
  "url": "https://doorman.clawhard.com/llms.txt"
 }
}