{"openapi":"3.0.3","info":{"title":"User Agent Classifier API","description":"Classifies HTTP User-Agent strings to determine if traffic is from a human, bot, or AI/LLM crawler. Optionally enriches classification with IP-based signals.","version":"0.1.0","contact":{"name":"C2 Communications"}},"servers":[{"url":"https://ua-api.lab.c2comms.cloud","description":"Lab environment"}],"paths":{"/classify":{"post":{"operationId":"classifyUserAgent","summary":"Classify a User-Agent string","description":"Analyzes a User-Agent string and optionally an IP address to determine traffic type (human, bot, AI/LLM) with confidence scoring.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClassifyRequest"},"examples":{"googlebot":{"summary":"Googlebot","value":{"userAgent":"Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)","ip":"66.249.66.1"}},"chrome":{"summary":"Chrome Browser","value":{"userAgent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"}},"gptbot":{"summary":"GPTBot (OpenAI)","value":{"userAgent":"Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko); compatible; GPTBot/1.0; +https://openai.com/gptbot","ip":"132.196.86.10"}},"claudebot":{"summary":"ClaudeBot (Anthropic)","value":{"userAgent":"Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko); compatible; ClaudeBot/1.0; +claudebot@anthropic.com"}},"curl":{"summary":"curl","value":{"userAgent":"curl/8.4.0"}}}}}},"responses":{"200":{"description":"Successful classification","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClassifyResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/health":{"get":{"operationId":"healthCheck","summary":"Health check","description":"Returns the health status of the API.","responses":{"200":{"description":"Service is healthy","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","example":"ok"}}}}}}}}}},"components":{"schemas":{"ClassifyRequest":{"type":"object","required":["userAgent"],"properties":{"userAgent":{"type":"string","description":"The HTTP User-Agent string to classify.","example":"Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"},"ip":{"type":"string","description":"Optional IP address for additional verification signals (IPv4 or IPv6).","example":"66.249.66.1"}}},"ClassifyResponse":{"type":"object","properties":{"userAgent":{"type":"string","description":"The User-Agent string that was classified."},"classification":{"type":"object","properties":{"isBot":{"type":"boolean","description":"Whether the User-Agent is identified as a bot."},"isHuman":{"type":"boolean","description":"Whether the User-Agent is identified as human traffic."},"isLLM":{"type":"boolean","description":"Whether the bot is an AI/LLM crawler (e.g., GPTBot, ClaudeBot, CCBot)."},"category":{"type":"string","nullable":true,"description":"Bot category classification.","enum":["search_engine","ai","advertising","archiver","content_fetcher","email_client","http_library","link_checker","monitoring","page_preview","scraping_framework","security","seo","social_media","webhooks","feed_fetcher","tool","unknown",null]},"botName":{"type":"string","nullable":true,"description":"Identified bot name (e.g., \"Googlebot\", \"GPTBot\")."},"organization":{"type":"string","nullable":true,"description":"Organization operating the bot (e.g., \"Google\", \"OpenAI\")."},"verified":{"type":"boolean","description":"Whether the bot identity was verified via IP range matching."},"confidence":{"type":"string","enum":["high","medium","low"],"description":"Confidence level of the classification. High = strong match + IP verified. Medium = pattern match without IP verification. Low = heuristic only or suspicious signals."},"signals":{"type":"array","items":{"type":"string"},"description":"Detection signals that contributed to the classification, modeled after AWS WAF Bot Control signal taxonomy. Possible values: non_browser_user_agent, known_bot_data_center, verified_bot_ip."}}},"ipSignals":{"type":"object","nullable":true,"description":"IP-based enrichment signals. Only present when an IP is provided.","properties":{"asn":{"type":"integer","nullable":true,"description":"Autonomous System Number."},"asnOrg":{"type":"string","nullable":true,"description":"Organization name of the ASN."},"isDatacenter":{"type":"boolean","description":"Whether the IP belongs to a known cloud/datacenter provider."},"isResidential":{"type":"boolean","description":"Whether the IP appears to be residential."},"cloudProvider":{"type":"string","nullable":true,"description":"Identified cloud provider (e.g., \"aws\", \"gcp\", \"azure\")."},"country":{"type":"string","nullable":true,"description":"Country code (ISO 3166-1 alpha-2)."},"ipMatchesBotClaim":{"type":"boolean","description":"Whether the IP matches the published IP ranges of the claimed bot identity."}}}}},"ErrorResponse":{"type":"object","properties":{"error":{"type":"string","description":"Error message."}}}}}}