{
  "openapi": "3.1.0",
  "info": {
    "title": "GetToolbox API",
    "version": "1.0.0",
    "description": "Open developer tools API. No sign-up, no rate limits.",
    "contact": { "url": "https://gettoolbox.dev" }
  },
  "servers": [
    { "url": "https://gettoolbox.dev", "description": "Production" }
  ],
  "tags": [
    { "name": "Network",    "description": "Network and IP tools" },
    { "name": "Security",   "description": "Security and certificate tools" },
    { "name": "Encoders",   "description": "Encoding and decoding tools" },
    { "name": "Formatters", "description": "Data formatting tools" }
  ],
  "paths": {
    "/api/v1/ip": {
      "get": {
        "operationId": "getIp",
        "summary": "Detect caller IP and geolocation",
        "description": "Returns the public IP address of the caller along with geolocation data (country, city, ISP, timezone).",
        "tags": ["Network"],
        "x-codeSamples": [
          { "lang": "curl",       "source": "curl https://gettoolbox.dev/api/v1/ip" },
          { "lang": "JavaScript", "source": "const data = await fetch('https://gettoolbox.dev/api/v1/ip').then(r => r.json());\nconsole.log(data.ip, data.country);" },
          { "lang": "Python",     "source": "import requests\ndata = requests.get('https://gettoolbox.dev/api/v1/ip').json()\nprint(data['ip'], data['country'])" }
        ],
        "responses": {
          "200": {
            "description": "IP and geolocation information",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ip":           { "type": "string",  "example": "93.56.100.1" },
                    "version":      { "type": "string",  "enum": ["IPv4", "IPv6"] },
                    "country":      { "type": "string",  "example": "Italy" },
                    "country_code": { "type": "string",  "example": "IT" },
                    "region":       { "type": "string",  "example": "Lombardy" },
                    "city":         { "type": "string",  "example": "Milan" },
                    "zip":          { "type": "string",  "example": "20100" },
                    "latitude":     { "type": "number",  "example": 45.4654 },
                    "longitude":    { "type": "number",  "example": 9.1859 },
                    "timezone":     { "type": "string",  "example": "Europe/Rome" },
                    "isp":          { "type": "string",  "example": "Telecom Italia" },
                    "org":          { "type": "string" },
                    "as":           { "type": "string",  "example": "AS3269 Telecom Italia" },
                    "hostname":     { "type": "string" },
                    "source":       { "type": "string",  "enum": ["maxmind", "ip-api"] }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/password": {
      "get": {
        "operationId": "generatePassword",
        "summary": "Generate a secure random password",
        "description": "Generates a cryptographically random password. All parameters are optional.",
        "tags": ["Security"],
        "x-codeSamples": [
          { "lang": "curl",       "source": "curl \"https://gettoolbox.dev/api/v1/password?length=24&symbols=true\"" },
          { "lang": "JavaScript", "source": "const params = new URLSearchParams({ length: '24', symbols: 'true' });\nconst data = await fetch(`https://gettoolbox.dev/api/v1/password?${params}`).then(r => r.json());\nconsole.log(data.password);" },
          { "lang": "Python",     "source": "import requests\ndata = requests.get('https://gettoolbox.dev/api/v1/password', params={'length': 24, 'symbols': 'true'}).json()\nprint(data['password'])" }
        ],
        "parameters": [
          { "name": "length",             "in": "query", "schema": { "type": "integer", "minimum": 4, "maximum": 512, "default": 16 }, "description": "Password length." },
          { "name": "lower",              "in": "query", "schema": { "type": "boolean", "default": true  }, "description": "Include lowercase letters." },
          { "name": "upper",              "in": "query", "schema": { "type": "boolean", "default": true  }, "description": "Include uppercase letters." },
          { "name": "digits",             "in": "query", "schema": { "type": "boolean", "default": true  }, "description": "Include digits." },
          { "name": "symbols",            "in": "query", "schema": { "type": "boolean", "default": true  }, "description": "Include common symbols (!@#$%^&*...)." },
          { "name": "all_symbols",        "in": "query", "schema": { "type": "boolean", "default": false }, "description": "Include extended symbol set (backtick, space, slash...)." },
          { "name": "exclude_confusable", "in": "query", "schema": { "type": "boolean", "default": false }, "description": "Exclude visually similar characters (0, O, o, 1, l, I)." },
          { "name": "custom",             "in": "query", "schema": { "type": "string"  }, "description": "Custom character set (replaces all other sets when provided)." }
        ],
        "responses": {
          "200": {
            "description": "Generated password",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "password":     { "type": "string",  "example": "aB3!xK9mPq#2nWsZ" },
                    "length":       { "type": "integer", "example": 16 },
                    "charset_size": { "type": "integer", "example": 88 },
                    "entropy_bits": { "type": "number",  "example": 105.6 },
                    "settings": {
                      "type": "object",
                      "properties": {
                        "lower":              { "type": "boolean" },
                        "upper":              { "type": "boolean" },
                        "digits":             { "type": "boolean" },
                        "symbols":            { "type": "boolean" },
                        "all_symbols":        { "type": "boolean" },
                        "exclude_confusable": { "type": "boolean" },
                        "custom":             { "type": "string"  }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "No character set selected",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } }
          }
        }
      }
    },
    "/api/v1/subnet": {
      "get": {
        "operationId": "calcSubnet",
        "summary": "Calculate subnet information",
        "description": "Given an IP address (with optional CIDR mask), returns full subnet details.",
        "tags": ["Network"],
        "x-codeSamples": [
          { "lang": "curl",       "source": "curl \"https://gettoolbox.dev/api/v1/subnet?ip=192.168.1.0/24\"" },
          { "lang": "JavaScript", "source": "const data = await fetch('https://gettoolbox.dev/api/v1/subnet?ip=192.168.1.0/24').then(r => r.json());\nconsole.log(data.network, data.broadcast);" },
          { "lang": "Python",     "source": "import requests\ndata = requests.get('https://gettoolbox.dev/api/v1/subnet', params={'ip': '192.168.1.0/24'}).json()\nprint(data['network'], data['broadcast'])" }
        ],
        "parameters": [
          { "name": "ip",   "in": "query", "required": true,  "schema": { "type": "string" }, "description": "IP address with optional CIDR prefix (e.g. 192.168.1.0/24 or 10.0.0.1)." },
          { "name": "mask", "in": "query", "required": false, "schema": { "type": "integer", "minimum": 1, "maximum": 32 }, "description": "CIDR prefix length. Overrides prefix in `ip` if both are provided." }
        ],
        "responses": {
          "200": {
            "description": "Subnet details",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ip":            { "type": "string",  "example": "192.168.1.0" },
                    "mask":          { "type": "integer", "example": 24 },
                    "network":       { "type": "string",  "example": "192.168.1.0" },
                    "broadcast":     { "type": "string",  "example": "192.168.1.255" },
                    "first_host":    { "type": "string",  "example": "192.168.1.1" },
                    "last_host":     { "type": "string",  "example": "192.168.1.254" },
                    "usable_hosts":  { "type": "integer", "example": 254 },
                    "subnet_mask":   { "type": "string",  "example": "255.255.255.0" },
                    "wildcard_mask": { "type": "string",  "example": "0.0.0.255" },
                    "ip_class":      { "type": "string",  "example": "C" },
                    "private":       { "type": "boolean", "example": true },
                    "binary_ip":     { "type": "string",  "example": "11000000.10101000.00000001.00000000" },
                    "binary_mask":   { "type": "string",  "example": "11111111.11111111.11111111.00000000" }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid IP address or mask",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } }
          }
        }
      }
    },
    "/api/v1/sslchecker": {
      "get": {
        "operationId": "checkSsl",
        "summary": "Inspect SSL/TLS certificate",
        "description": "Fetches and analyzes the TLS certificate for a domain. Returns expiry, issuer, SANs, and a warning flag when days to expiry is below the threshold.",
        "tags": ["Security"],
        "x-codeSamples": [
          { "lang": "curl",       "source": "curl \"https://gettoolbox.dev/api/v1/sslchecker?domain=example.com\"" },
          { "lang": "JavaScript", "source": "const data = await fetch('https://gettoolbox.dev/api/v1/sslchecker?domain=example.com').then(r => r.json());\nconsole.log(data.valid_to, data.days_remaining);" },
          { "lang": "Python",     "source": "import requests\ndata = requests.get('https://gettoolbox.dev/api/v1/sslchecker', params={'domain': 'example.com'}).json()\nprint(data['valid_to'], data['days_remaining'])" }
        ],
        "parameters": [
          { "name": "domain", "in": "query", "required": true,  "schema": { "type": "string" }, "description": "Domain name to inspect (e.g. example.com)." },
          { "name": "warn",   "in": "query", "required": false, "schema": { "type": "integer", "minimum": 1, "maximum": 365, "default": 30 }, "description": "Days-to-expiry threshold below which `expiring_soon` is set to true." }
        ],
        "responses": {
          "200": {
            "description": "Certificate information",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "domain":         { "type": "string" },
                    "valid":          { "type": "boolean" },
                    "valid_from":     { "type": "string", "format": "date-time" },
                    "valid_to":       { "type": "string", "format": "date-time" },
                    "days_remaining": { "type": "integer" },
                    "expiring_soon":  { "type": "boolean" },
                    "issuer":         { "type": "string" },
                    "subject":        { "type": "string" },
                    "sans":           { "type": "array", "items": { "type": "string" } }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Missing or invalid domain",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } }
          }
        }
      }
    },
    "/api/v1/emailchecker": {
      "get": {
        "operationId": "checkEmail",
        "summary": "Check email domain configuration",
        "description": "Inspects the email configuration of a domain: SPF, DKIM, DMARC, BIMI, MTA-STS, DANE, PTR, and MX records.",
        "tags": ["Network"],
        "x-codeSamples": [
          { "lang": "curl",       "source": "curl \"https://gettoolbox.dev/api/v1/emailchecker?domain=example.com\"" },
          { "lang": "JavaScript", "source": "const data = await fetch('https://gettoolbox.dev/api/v1/emailchecker?domain=example.com').then(r => r.json());\nconsole.log(data.spf, data.dmarc);" },
          { "lang": "Python",     "source": "import requests\ndata = requests.get('https://gettoolbox.dev/api/v1/emailchecker', params={'domain': 'example.com'}).json()\nprint(data['spf'], data['dmarc'])" }
        ],
        "parameters": [
          { "name": "domain",    "in": "query", "required": true,  "schema": { "type": "string" }, "description": "Domain name to check (e.g. example.com)." },
          { "name": "selectors", "in": "query", "required": false, "schema": { "type": "string" }, "description": "Comma-separated list of additional DKIM selectors to probe." }
        ],
        "responses": {
          "200": {
            "description": "Email configuration report",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "domain":   { "type": "string" },
                    "score":    { "type": "integer", "description": "Score 0-100" },
                    "grade":    { "type": "string",  "enum": ["A", "B", "C", "D", "F"] },
                    "mx":       { "type": "object" },
                    "spf":      { "type": "object" },
                    "dkim":     { "type": "object" },
                    "dmarc":    { "type": "object" },
                    "bimi":     { "type": "object" },
                    "mta_sts":  { "type": "object" },
                    "dane":     { "type": "object" },
                    "ptr":      { "type": "object" }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Missing or invalid domain",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } }
          }
        }
      }
    },
    "/api/v1/blacklistchecker": {
      "get": {
        "operationId": "checkBlacklist",
        "summary": "Check IP or domain against DNS blacklists",
        "description": "Queries the input against a curated set of DNS-based blacklists (RBLs). Accepts both IPv4 addresses and domain names.",
        "tags": ["Security"],
        "x-codeSamples": [
          { "lang": "curl",       "source": "curl \"https://gettoolbox.dev/api/v1/blacklistchecker?input=1.2.3.4\"" },
          { "lang": "JavaScript", "source": "const data = await fetch('https://gettoolbox.dev/api/v1/blacklistchecker?input=1.2.3.4').then(r => r.json());\nconsole.log(data.listed_count, data.total_count);" },
          { "lang": "Python",     "source": "import requests\ndata = requests.get('https://gettoolbox.dev/api/v1/blacklistchecker', params={'input': '1.2.3.4'}).json()\nprint(data['listed_count'], data['total_count'])" }
        ],
        "parameters": [
          { "name": "input", "in": "query", "required": true, "schema": { "type": "string" }, "description": "IPv4 address or domain name to check." }
        ],
        "responses": {
          "200": {
            "description": "Blacklist check report",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "input":        { "type": "string",  "example": "1.2.3.4" },
                    "type":         { "type": "string",  "enum": ["ip", "domain"] },
                    "listed_count": { "type": "integer", "example": 2 },
                    "total_count":  { "type": "integer", "example": 46 },
                    "results": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "rbl":    { "type": "string" },
                          "listed": { "type": "boolean" },
                          "txt":    { "type": "string" }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Missing or invalid input",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } }
          }
        }
      }
    },
    "/api/v1/base64": {
      "post": {
        "operationId": "base64",
        "summary": "Encode or decode Base64",
        "description": "Encodes a string to Base64 or decodes a Base64 string. Supports standard and URL-safe charsets, MIME wrapping, and per-line processing.",
        "tags": ["Encoders"],
        "x-codeSamples": [
          { "lang": "curl",       "source": "curl -X POST https://gettoolbox.dev/api/v1/base64 \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"input\":\"hello world\",\"mode\":\"encode\"}'" },
          { "lang": "JavaScript", "source": "const data = await fetch('https://gettoolbox.dev/api/v1/base64', {\n  method: 'POST',\n  headers: { 'Content-Type': 'application/json' },\n  body: JSON.stringify({ input: 'hello world', mode: 'encode' })\n}).then(r => r.json());\nconsole.log(data.result);" },
          { "lang": "Python",     "source": "import requests\ndata = requests.post('https://gettoolbox.dev/api/v1/base64',\n  json={'input': 'hello world', 'mode': 'encode'}).json()\nprint(data['result'])" }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["input", "mode"],
                "properties": {
                  "input":         { "type": "string",  "description": "String to encode or decode." },
                  "mode":          { "type": "string",  "enum": ["encode", "decode"] },
                  "charset":       { "type": "string",  "enum": ["standard", "url-safe"], "default": "standard" },
                  "encodePerLine": { "type": "boolean", "description": "Encode each line independently." },
                  "lineSeparator": { "type": "string",  "description": "Line separator for per-line mode." },
                  "mimeWrap":      { "type": "boolean", "description": "Wrap output at 76 characters (MIME)." },
                  "decodePerLine": { "type": "boolean", "description": "Decode each line independently." }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Encoded or decoded result",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "result": { "type": "string" },
                    "mode":   { "type": "string", "enum": ["encode", "decode"] }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid request body or payload",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } }
          }
        }
      }
    },
    "/api/v1/jsonformatter": {
      "post": {
        "operationId": "formatJson",
        "summary": "Format and validate JSON",
        "description": "Parses and re-formats a JSON string with configurable indentation. Returns an error if the input is not valid JSON.",
        "tags": ["Formatters"],
        "x-codeSamples": [
          { "lang": "curl",       "source": "curl -X POST https://gettoolbox.dev/api/v1/jsonformatter \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"input\":\"{\\\\\"key\\\\\":\\\\\"value\\\\\"}\",\"indent\":2}'" },
          { "lang": "JavaScript", "source": "const data = await fetch('https://gettoolbox.dev/api/v1/jsonformatter', {\n  method: 'POST',\n  headers: { 'Content-Type': 'application/json' },\n  body: JSON.stringify({ input: '{\"key\":\"value\"}', indent: 2 })\n}).then(r => r.json());\nconsole.log(data.formatted);" },
          { "lang": "Python",     "source": "import requests\ndata = requests.post('https://gettoolbox.dev/api/v1/jsonformatter',\n  json={'input': '{\"key\":\"value\"}', 'indent': 2}).json()\nprint(data['formatted'])" }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["input"],
                "properties": {
                  "input":  { "type": "string",  "description": "Raw JSON string to format." },
                  "indent": { "type": "integer", "minimum": 1, "maximum": 8, "default": 2 }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Formatted JSON string",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "formatted": { "type": "string" }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid JSON input or request body",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } }
          }
        }
      }
    },
    "/api/v1/yamlformatter": {
      "post": {
        "operationId": "formatYaml",
        "summary": "Format and validate YAML",
        "description": "Parses and re-formats a YAML string with configurable indentation. Returns an error if the input is not valid YAML.",
        "tags": ["Formatters"],
        "x-codeSamples": [
          { "lang": "curl",       "source": "curl -X POST https://gettoolbox.dev/api/v1/yamlformatter \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"input\":\"key: value\",\"indent\":2}'" },
          { "lang": "JavaScript", "source": "const data = await fetch('https://gettoolbox.dev/api/v1/yamlformatter', {\n  method: 'POST',\n  headers: { 'Content-Type': 'application/json' },\n  body: JSON.stringify({ input: 'key: value', indent: 2 })\n}).then(r => r.json());\nconsole.log(data.formatted);" },
          { "lang": "Python",     "source": "import requests\ndata = requests.post('https://gettoolbox.dev/api/v1/yamlformatter',\n  json={'input': 'key: value', 'indent': 2}).json()\nprint(data['formatted'])" }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["input"],
                "properties": {
                  "input":  { "type": "string",  "description": "Raw YAML string to format." },
                  "indent": { "type": "integer", "minimum": 1, "maximum": 8, "default": 2 }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Formatted YAML string",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "formatted": { "type": "string" }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid YAML input or request body",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } }
          }
        }
      }
    },
    "/api/v1/jwtdecoder": {
      "get": {
        "operationId": "decodeJwt",
        "summary": "Decode a JWT token",
        "description": "Decodes a JWT without verifying the signature. Returns the header, payload, algorithm, and expiry status.",
        "tags": ["Encoders"],
        "x-codeSamples": [
          { "lang": "curl",       "source": "curl \"https://gettoolbox.dev/api/v1/jwtdecoder?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.dozjgNryP4J3jVmNHl0w5N_XgL0n3I9PlFUP0THsR8U\"" },
          { "lang": "JavaScript", "source": "const token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.dozjgNryP4J3jVmNHl0w5N_XgL0n3I9PlFUP0THsR8U';\nconst data = await fetch(`https://gettoolbox.dev/api/v1/jwtdecoder?token=${token}`).then(r => r.json());\nconsole.log(data.payload);" },
          { "lang": "Python",     "source": "import requests\ntoken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.dozjgNryP4J3jVmNHl0w5N_XgL0n3I9PlFUP0THsR8U'\ndata = requests.get('https://gettoolbox.dev/api/v1/jwtdecoder', params={'token': token}).json()\nprint(data['payload'])" }
        ],
        "parameters": [
          { "name": "token", "in": "query", "required": true, "schema": { "type": "string" }, "description": "JWT string (three dot-separated Base64url segments)." }
        ],
        "responses": {
          "200": {
            "description": "Decoded JWT",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "header":          { "type": "object" },
                    "payload":         { "type": "object" },
                    "algorithm":       { "type": "string", "example": "HS256", "nullable": true },
                    "valid_structure": { "type": "boolean" },
                    "expired":         { "type": "boolean", "nullable": true },
                    "not_yet_valid":   { "type": "boolean", "nullable": true }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Missing token or invalid JWT structure",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Error": {
        "type": "object",
        "properties": {
          "error": { "type": "string", "example": "domain is required" }
        },
        "required": ["error"]
      }
    }
  }
}
