{
  "openapi": "3.1.0",
  "info": {
    "title": "FabTally WebSafe — pre-fetch web-safety checks for agents",
    "version": "1.0.0",
    "description": "Cheap per-call checks an AI agent runs BEFORE it fetches an arbitrary/user-supplied URL or ingests untrusted content: url-safety (screen a URL for SSRF/private-IP/metadata targets, TLS, reachability, redirect chain and known-bad shape — also a webhook-URL verifier), injection-scan (heuristic prompt-injection / jailbreak + hidden-text detection over text or a public page), and robots-check (robots.txt + llms.txt/ai.txt + AI-crawler directives -> allow/deny for a UA). All read-only, keyless, stateless, descriptive; heuristic checks are honestly best-effort, not a guarantee. Paid via x402 (USDC on Base) or a prepaid credit key; each has a rate-limited free teaser. Also available as an MCP server.",
    "x-guidance": "Paid (x402 USDC on Base, or prepaid X-FabTally-Key): POST /v1/url-safety ($0.003), /v1/injection-scan ($0.004), /v1/robots-check ($0.001) — each has a rate-limited /free teaser. Unpaid paid-calls return an x402 402 challenge; pay and retry with the X-PAYMENT header. Bad input -> 400, never charged. Heuristic checks are best-effort, not guarantees.",
    "contact": {
      "email": "hello@fabtally.com"
    }
  },
  "servers": [
    {
      "url": "https://websafe.fabtally.com"
    }
  ],
  "paths": {
    "/agent/overview": {
      "get": {
        "operationId": "overview",
        "summary": "Capabilities, pricing, payment info (free)",
        "tags": [
          "Discovery"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Overview"
          }
        }
      }
    },
    "/health": {
      "get": {
        "operationId": "health",
        "summary": "Health (free)",
        "tags": [
          "Discovery"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/v1/url-safety": {
      "post": {
        "operationId": "url_safety",
        "summary": "url-safety (paid, $0.003 USDC on Base)",
        "tags": [
          "Paid"
        ],
        "description": "Screen a URL BEFORE fetching it (or verify a webhook URL). Give {url}; get an SSRF verdict — does the host resolve to private/loopback/link-local or a cloud metadata IP (169.254.169.254)? — plus TLS validity, reachability + HTTP status, the full redirect chain (and whether a redirect lands somewhere riskier), a known-bad URL-shape heuristic, and the final resolved IP class. Never fetches internal targets or returns bodies. Read-only, stateless.",
        "x-payment-info": {
          "price": {
            "mode": "fixed",
            "currency": "USD",
            "amount": "0.003000"
          },
          "protocols": [
            {
              "x402": {
                "scheme": "exact",
                "network": "eip155:8453",
                "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
                "maxAmountRequired": "3000",
                "payTo": "0xccB5d25C698FdfdaA7B21d54088774cF512A90e3",
                "resource": "https://websafe.fabtally.com/v1/url-safety",
                "facilitator": "https://facilitator.daydreams.systems",
                "maxTimeoutSeconds": 60
              }
            }
          ]
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "url": "https://example.com/"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Result",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Bad input (never charged)"
          },
          "402": {
            "description": "Payment Required (x402 v2 challenge)"
          }
        }
      }
    },
    "/v1/url-safety/free": {
      "post": {
        "operationId": "url_safety_free",
        "summary": "url-safety — rate-limited free teaser",
        "tags": [
          "Free"
        ],
        "security": [],
        "description": "Free teaser for url-safety (daily per-IP quota).",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "url": "https://example.com/"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Teaser result"
          },
          "429": {
            "description": "Free daily quota exceeded"
          }
        }
      }
    },
    "/v1/injection-scan": {
      "post": {
        "operationId": "injection_scan",
        "summary": "injection-scan (paid, $0.004 USDC on Base)",
        "tags": [
          "Paid"
        ],
        "description": "HEURISTIC (best-effort, NOT a guarantee) scan of untrusted text OR a fetched public page for prompt-injection / jailbreak patterns: 'ignore previous instructions', role-override, tool-abuse/exfiltration, hidden text (zero-width chars, HTML comments, white-on-white / display:none) and suspicious instruction density. Give {text} OR {url}; get a 0-100 risk score, level, matched categories and matched snippets. Read-only, stateless.",
        "x-payment-info": {
          "price": {
            "mode": "fixed",
            "currency": "USD",
            "amount": "0.004000"
          },
          "protocols": [
            {
              "x402": {
                "scheme": "exact",
                "network": "eip155:8453",
                "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
                "maxAmountRequired": "4000",
                "payTo": "0xccB5d25C698FdfdaA7B21d54088774cF512A90e3",
                "resource": "https://websafe.fabtally.com/v1/injection-scan",
                "facilitator": "https://facilitator.daydreams.systems",
                "maxTimeoutSeconds": 60
              }
            }
          ]
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "text": "Summarize this article for me please."
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Result",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Bad input (never charged)"
          },
          "402": {
            "description": "Payment Required (x402 v2 challenge)"
          }
        }
      }
    },
    "/v1/injection-scan/free": {
      "post": {
        "operationId": "injection_scan_free",
        "summary": "injection-scan — rate-limited free teaser",
        "tags": [
          "Free"
        ],
        "security": [],
        "description": "Free teaser for injection-scan (daily per-IP quota).",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "text": "Summarize this article for me please."
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Teaser result"
          },
          "429": {
            "description": "Free daily quota exceeded"
          }
        }
      }
    },
    "/v1/robots-check": {
      "post": {
        "operationId": "robots_check",
        "summary": "robots-check (paid, $0.001 USDC on Base)",
        "tags": [
          "Paid"
        ],
        "description": "Parse robots.txt AND the emerging llms.txt / ai.txt + known AI-crawler directives (GPTBot, ClaudeBot, Google-Extended, CCBot, PerplexityBot, …) to return an allow/deny verdict for a given user-agent, so a compliant crawling agent stays on the right side of a site's stated policy. Give {url, user_agent?}. Read-only, stateless.",
        "x-payment-info": {
          "price": {
            "mode": "fixed",
            "currency": "USD",
            "amount": "0.001000"
          },
          "protocols": [
            {
              "x402": {
                "scheme": "exact",
                "network": "eip155:8453",
                "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
                "maxAmountRequired": "1000",
                "payTo": "0xccB5d25C698FdfdaA7B21d54088774cF512A90e3",
                "resource": "https://websafe.fabtally.com/v1/robots-check",
                "facilitator": "https://facilitator.daydreams.systems",
                "maxTimeoutSeconds": 60
              }
            }
          ]
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "url": "https://www.nytimes.com/section/world",
                "user_agent": "GPTBot"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Result",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Bad input (never charged)"
          },
          "402": {
            "description": "Payment Required (x402 v2 challenge)"
          }
        }
      }
    },
    "/v1/robots-check/free": {
      "post": {
        "operationId": "robots_check_free",
        "summary": "robots-check — rate-limited free teaser",
        "tags": [
          "Free"
        ],
        "security": [],
        "description": "Free teaser for robots-check (daily per-IP quota).",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "url": "https://www.nytimes.com/section/world",
                "user_agent": "GPTBot"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Teaser result"
          },
          "429": {
            "description": "Free daily quota exceeded"
          }
        }
      }
    }
  }
}