{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://tiergauge.com/api/tools.schema.json",
  "title": "TierGauge tools feed",
  "description": "Schema for /api/tools.json (full feed) and /api/tools/{slug}.json (per-tool feed). The Tool object shape is shared; the feed envelope differs slightly between the two endpoints.",
  "type": "object",
  "required": ["feed_version", "generated_at", "site", "license"],
  "properties": {
    "$schema": { "type": "string", "format": "uri" },
    "feed_version": {
      "type": "string",
      "description": "Increments on breaking changes to the Tool shape."
    },
    "generated_at": { "type": "string", "format": "date-time" },
    "last_verified": {
      "type": ["string", "null"],
      "format": "date-time",
      "description": "Maximum last_verified across all tools in the feed. Only present on the index feed."
    },
    "site": { "type": "string", "format": "uri" },
    "license": { "type": "string" },
    "count": {
      "type": "integer",
      "minimum": 0,
      "description": "Number of tools in this feed. Index-feed only."
    },
    "tools": {
      "type": "array",
      "items": { "$ref": "#/$defs/Tool" },
      "description": "Index-feed only. Per-tool feed uses `tool` (singular)."
    },
    "tool": {
      "$ref": "#/$defs/Tool",
      "description": "Per-tool feed only."
    },
    "per_tool_endpoints": {
      "type": "array",
      "items": { "type": "string", "format": "uri" },
      "description": "Index-feed only. URLs for each per-tool endpoint."
    },
    "per_category_endpoints": {
      "type": "array",
      "items": { "type": "string", "format": "uri" },
      "description": "Index-feed only. URLs for each per-category endpoint."
    },
    "category": {
      "type": "object",
      "description": "Category-feed only. Identifies which category this feed is scoped to.",
      "required": ["slug", "display", "description"],
      "properties": {
        "slug": { "$ref": "#/$defs/Category" },
        "display": { "type": "string" },
        "description": { "type": "string" }
      }
    },
    "events": {
      "type": "array",
      "description": "Changes-feed only. Chronological pricing-change events, most recent first.",
      "items": { "$ref": "#/$defs/ChangeEvent" }
    }
  },
  "$defs": {
    "Money": {
      "type": "object",
      "required": ["amount_cents", "currency"],
      "properties": {
        "amount_cents": { "type": "integer", "minimum": 0 },
        "currency": { "enum": ["USD", "EUR", "GBP", "CAD", "AUD"] }
      },
      "additionalProperties": false
    },
    "PlanLimit": {
      "oneOf": [
        {
          "type": "object",
          "required": ["kind", "value"],
          "properties": {
            "kind": { "const": "number" },
            "value": { "type": "integer", "minimum": 0 },
            "unit": { "type": "string" }
          },
          "additionalProperties": false
        },
        {
          "type": "object",
          "required": ["kind"],
          "properties": { "kind": { "const": "unlimited" } },
          "additionalProperties": false
        },
        {
          "type": "object",
          "required": ["kind"],
          "properties": { "kind": { "const": "custom" } },
          "additionalProperties": false
        },
        {
          "type": "object",
          "required": ["kind"],
          "properties": { "kind": { "const": "none" } },
          "additionalProperties": false
        }
      ]
    },
    "PricingPoint": {
      "type": "object",
      "required": ["cycle"],
      "properties": {
        "cycle": {
          "enum": [
            "free",
            "monthly",
            "annual",
            "quarterly",
            "one-time",
            "usage-based",
            "custom"
          ]
        },
        "price": { "$ref": "#/$defs/Money" },
        "per_unit": { "type": "string" },
        "min_units": { "type": "integer", "minimum": 1 },
        "notes": { "type": "string" }
      },
      "additionalProperties": false
    },
    "PricingPlan": {
      "type": "object",
      "required": [
        "name",
        "slug",
        "prices",
        "anchor_monthly_usd_cents",
        "limits",
        "features_included",
        "features_missing",
        "is_free",
        "has_free_trial",
        "contact_sales",
        "source_url",
        "captured_at",
        "capture_method"
      ],
      "properties": {
        "name": { "type": "string", "minLength": 1 },
        "slug": { "type": "string", "pattern": "^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$" },
        "tagline": { "type": "string" },
        "prices": {
          "type": "array",
          "minItems": 1,
          "items": { "$ref": "#/$defs/PricingPoint" }
        },
        "anchor_monthly_usd_cents": {
          "type": ["integer", "null"],
          "minimum": 0,
          "description": "Headline monthly USD cents for cross-tool sorting. Null when plan is custom or contact-sales."
        },
        "limits": {
          "type": "object",
          "properties": {
            "contacts": { "$ref": "#/$defs/PlanLimit" },
            "emails_per_month": { "$ref": "#/$defs/PlanLimit" },
            "seats": { "$ref": "#/$defs/PlanLimit" },
            "workflows": { "$ref": "#/$defs/PlanLimit" },
            "automations": { "$ref": "#/$defs/PlanLimit" },
            "pipelines": { "$ref": "#/$defs/PlanLimit" },
            "api_calls_per_month": { "$ref": "#/$defs/PlanLimit" },
            "storage_gb": { "$ref": "#/$defs/PlanLimit" },
            "domains": { "$ref": "#/$defs/PlanLimit" },
            "campaigns": { "$ref": "#/$defs/PlanLimit" }
          }
        },
        "features_included": { "type": "array", "items": { "type": "string" } },
        "features_missing": { "type": "array", "items": { "type": "string" } },
        "is_free": { "type": "boolean" },
        "has_free_trial": { "type": "boolean" },
        "contact_sales": { "type": "boolean" },
        "source_url": { "type": "string", "format": "uri" },
        "captured_at": { "type": "string", "format": "date-time" },
        "capture_method": { "enum": ["manual", "scraper", "scraper-verified"] },
        "notes": { "type": "string" }
      }
    },
    "AffiliateProgram": {
      "type": "object",
      "required": ["network", "joined"],
      "properties": {
        "name": { "type": "string" },
        "network": {
          "enum": [
            "partnerstack",
            "impact",
            "rewardful",
            "tapfiliate",
            "tolt",
            "firstpromoter",
            "direct",
            "none"
          ]
        },
        "commission_type": { "enum": ["recurring", "one-time", "hybrid", "none"] },
        "commission_amount": { "type": "string" },
        "cookie_window_days": { "type": "integer", "minimum": 0 },
        "application_url": { "type": "string", "format": "uri" },
        "joined": { "type": "boolean" }
      },
      "additionalProperties": false
    },
    "ChangeEvent": {
      "type": "object",
      "required": [
        "tool_slug",
        "captured_at",
        "plan_slug",
        "plan_name",
        "prior_anchor_monthly_usd_cents",
        "new_anchor_monthly_usd_cents",
        "direction"
      ],
      "properties": {
        "tool_slug": {
          "type": "string",
          "pattern": "^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$"
        },
        "captured_at": { "type": "string", "format": "date-time" },
        "plan_slug": {
          "type": "string",
          "pattern": "^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$"
        },
        "plan_name": { "type": "string" },
        "prior_anchor_monthly_usd_cents": {
          "type": ["integer", "null"],
          "minimum": 0
        },
        "new_anchor_monthly_usd_cents": {
          "type": ["integer", "null"],
          "minimum": 0
        },
        "direction": {
          "enum": ["increase", "decrease", "added", "removed", "to-custom", "from-custom"]
        }
      },
      "additionalProperties": false
    },
    "Category": {
      "enum": [
        "email-marketing",
        "marketing-automation",
        "crm",
        "sales-engagement",
        "lead-generation",
        "landing-pages",
        "form-builder",
        "sms-marketing",
        "live-chat",
        "help-desk",
        "analytics",
        "ab-testing",
        "seo",
        "social-media-management",
        "content-marketing",
        "webinar",
        "calendar-scheduling",
        "transactional-email",
        "deliverability",
        "customer-data-platform",
        "marketing-attribution"
      ]
    },
    "Tool": {
      "type": "object",
      "required": [
        "slug",
        "name",
        "vendor",
        "homepage_url",
        "pricing_url",
        "tagline",
        "description",
        "primary_category",
        "secondary_categories",
        "plans",
        "free_plan_available",
        "free_trial_days",
        "starting_price_usd_cents",
        "has_custom_enterprise",
        "alternatives",
        "pros",
        "cons",
        "best_for",
        "not_for",
        "last_verified"
      ],
      "properties": {
        "slug": { "type": "string", "pattern": "^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$" },
        "name": { "type": "string", "minLength": 1 },
        "vendor": { "type": "string", "minLength": 1 },
        "homepage_url": { "type": "string", "format": "uri" },
        "pricing_url": { "type": "string", "format": "uri" },
        "affiliate_url": { "type": "string", "format": "uri" },
        "logo_url": { "type": "string", "format": "uri" },
        "tagline": { "type": "string", "minLength": 1, "maxLength": 160 },
        "description": { "type": "string", "minLength": 40 },
        "primary_category": { "$ref": "#/$defs/Category" },
        "secondary_categories": {
          "type": "array",
          "items": { "$ref": "#/$defs/Category" }
        },
        "plans": {
          "type": "array",
          "minItems": 1,
          "items": { "$ref": "#/$defs/PricingPlan" }
        },
        "free_plan_available": { "type": "boolean" },
        "free_trial_days": { "type": ["integer", "null"], "minimum": 0 },
        "starting_price_usd_cents": { "type": ["integer", "null"], "minimum": 0 },
        "has_custom_enterprise": { "type": "boolean" },
        "alternatives": {
          "type": "array",
          "items": { "type": "string", "pattern": "^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$" }
        },
        "pros": { "type": "array", "items": { "type": "string" } },
        "cons": { "type": "array", "items": { "type": "string" } },
        "best_for": { "type": "array", "items": { "type": "string" } },
        "not_for": { "type": "array", "items": { "type": "string" } },
        "affiliate_program": { "$ref": "#/$defs/AffiliateProgram" },
        "last_verified": { "type": "string", "format": "date-time" },
        "last_scraped": { "type": "string", "format": "date-time" },
        "scraper_status": {
          "enum": ["healthy", "stale", "broken", "manual-only"]
        },
        "scraper_module": { "type": "string" }
      }
    }
  }
}
