{
  "openapi": "3.0.3",
  "info": {
    "title": "deftools.io API",
    "description": "Public HTTP endpoints for generating placeholder images, QR codes, OG cards, IP geolocation, UUIDs, and cryptographic hashes. No authentication required.",
    "version": "1.0.0",
    "contact": { "url": "https://deftools.io/api" }
  },
  "servers": [{ "url": "https://deftools.io" }],
  "paths": {
    "/api/placeholder": {
      "get": {
        "summary": "Generate a placeholder image",
        "description": "Returns SVG by default; pass `fmt=png` for a rasterized PNG.",
        "parameters": [
          { "name": "w", "in": "query", "schema": { "type": "integer", "default": 600, "minimum": 1, "maximum": 2000 }, "description": "Width in pixels" },
          { "name": "h", "in": "query", "schema": { "type": "integer", "default": 400, "minimum": 1, "maximum": 2000 }, "description": "Height in pixels" },
          { "name": "bg", "in": "query", "schema": { "type": "string", "default": "3b82f6" }, "description": "Background hex color (no #)" },
          { "name": "fg", "in": "query", "schema": { "type": "string", "default": "ffffff" }, "description": "Foreground hex color (no #)" },
          { "name": "text", "in": "query", "schema": { "type": "string", "maxLength": 240 }, "description": "Centered label text" },
          { "name": "fmt", "in": "query", "schema": { "type": "string", "enum": ["svg", "png"], "default": "svg" }, "description": "Output format" }
        ],
        "responses": {
          "200": { "description": "Image", "content": { "image/svg+xml": {}, "image/png": {} } },
          "400": { "description": "Invalid parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }
        }
      }
    },
    "/api/og": {
      "get": {
        "summary": "Generate an Open Graph card",
        "description": "Returns a 1200×630 PNG card for a tool page.",
        "parameters": [
          { "name": "slug", "in": "query", "schema": { "type": "string" }, "description": "Tool slug (e.g. json-formatter). Falls back to generic card when omitted." }
        ],
        "responses": {
          "200": { "description": "PNG card", "content": { "image/png": {} } },
          "500": { "description": "Rendering error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }
        }
      }
    },
    "/api/qr": {
      "get": {
        "summary": "Generate a QR code",
        "description": "Returns SVG by default; pass `fmt=png` for a rasterized PNG.",
        "parameters": [
          { "name": "text", "in": "query", "required": true, "schema": { "type": "string", "maxLength": 2000 }, "description": "Content to encode" },
          { "name": "size", "in": "query", "schema": { "type": "integer", "default": 320, "minimum": 64, "maximum": 2000 }, "description": "Image width/height in pixels" },
          { "name": "fg", "in": "query", "schema": { "type": "string", "default": "0a0e14" }, "description": "Foreground (module) color" },
          { "name": "bg", "in": "query", "schema": { "type": "string", "default": "ffffff" }, "description": "Background color" },
          { "name": "ecl", "in": "query", "schema": { "type": "string", "enum": ["L", "M", "Q", "H"], "default": "M" }, "description": "Error correction level" },
          { "name": "margin", "in": "query", "schema": { "type": "integer", "default": 2, "minimum": 0, "maximum": 4 }, "description": "Quiet zone in modules" },
          { "name": "fmt", "in": "query", "schema": { "type": "string", "enum": ["svg", "png"], "default": "svg" }, "description": "Output format" }
        ],
        "responses": {
          "200": { "description": "QR code", "content": { "image/svg+xml": {}, "image/png": {} } },
          "400": { "description": "Invalid parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }
        }
      }
    },
    "/api/ip": {
      "get": {
        "summary": "Get your public IP address and geolocation",
        "description": "Returns JSON with IP and Cloudflare geolocation data.",
        "parameters": [
          { "name": "format", "in": "query", "schema": { "type": "string", "enum": ["json", "html"], "default": "json" }, "description": "Output format" }
        ],
        "responses": {
          "200": { "description": "IP data", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/IPResponse" } }, "text/html": {} } }
        }
      }
    },
    "/api/uuid": {
      "get": {
        "summary": "Generate random UUIDs",
        "description": "Returns a JSON array of RFC 4122 version 4 UUIDs.",
        "parameters": [
          { "name": "v", "in": "query", "schema": { "type": "string", "default": "4" }, "description": "UUID version (only 4)" },
          { "name": "count", "in": "query", "schema": { "type": "integer", "default": 1, "minimum": 1, "maximum": 100 }, "description": "Number of UUIDs to generate" }
        ],
        "responses": {
          "200": { "description": "UUIDs", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UUIDResponse" } } } },
          "400": { "description": "Unsupported version", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }
        }
      }
    },
    "/api/hash": {
      "get": {
        "summary": "Compute a cryptographic hash",
        "description": "Returns JSON with the computed hash. Supports GET (text query param) and POST (raw body or JSON).",
        "parameters": [
          { "name": "text", "in": "query", "schema": { "type": "string", "maxLength": 1048576 }, "description": "Text to hash (required for GET)" },
          { "name": "algo", "in": "query", "schema": { "type": "string", "enum": ["sha1", "sha256", "sha384", "sha512"], "default": "sha256" }, "description": "Hash algorithm" },
          { "name": "fmt", "in": "query", "schema": { "type": "string", "enum": ["hex", "base64", "base64url"], "default": "hex" }, "description": "Output format" }
        ],
        "responses": {
          "200": { "description": "Hash result", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HashResponse" } } } },
          "400": { "description": "Invalid parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
          "413": { "description": "Input too large (>1 MiB)" }
        }
      },
      "post": {
        "summary": "Compute a cryptographic hash (POST body)",
        "description": "Send the text as raw request body or JSON `{\"text\":\"...\"}`.",
        "requestBody": {
          "content": {
            "text/plain": { "schema": { "type": "string" } },
            "application/json": { "schema": { "type": "object", "properties": { "text": { "type": "string" }, "algo": { "type": "string" }, "fmt": { "type": "string" } } } }
          }
        },
        "responses": {
          "200": { "description": "Hash result", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HashResponse" } } } },
          "400": { "description": "Invalid parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
          "413": { "description": "Input too large (>1 MiB)" }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Error": {
        "type": "object",
        "properties": {
          "error": { "type": "string", "description": "Human-readable error message" },
          "code": { "type": "string", "description": "Machine-readable error code" }
        },
        "required": ["error", "code"]
      },
      "IPResponse": {
        "type": "object",
        "properties": {
          "ip": { "type": "string" },
          "country": { "type": "string", "nullable": true },
          "city": { "type": "string", "nullable": true },
          "region": { "type": "string", "nullable": true },
          "asn": { "type": "integer", "nullable": true },
          "asOrganization": { "type": "string", "nullable": true }
        }
      },
      "UUIDResponse": {
        "type": "array",
        "items": { "type": "string", "format": "uuid" }
      },
      "HashResponse": {
        "type": "object",
        "properties": {
          "algorithm": { "type": "string", "enum": ["sha1", "sha256", "sha384", "sha512"] },
          "format": { "type": "string", "enum": ["hex", "base64", "base64url"] },
          "inputLength": { "type": "integer" },
          "inputBytes": { "type": "integer" },
          "hash": { "type": "string" }
        },
        "required": ["algorithm", "format", "inputLength", "inputBytes", "hash"]
      }
    }
  }
}
