{
  "openapi": "3.0.3",
  "info": {
    "title": "Probe Diagnostics API",
    "version": "1.1.0",
    "description": "Free, public network & mail diagnostics for sysadmins — DNS/DNSSEC, nameserver health, parent/child delegation, DNS propagation across public resolvers, WHOIS, SSL/TLS, HTTP, ping, traceroute/MTR, port scans, Certificate Transparency subdomain discovery, full email-deliverability (SPF/DKIM/DMARC/BIMI/MTA-STS/TLS-RPT/DANE), MX/mail-server health, blacklist/reputation, geo/ASN/BGP and more. Every tool returns a normalized result: a verdict, a plain-language summary, rows, findings (with severity), suggested fixes, and the equivalent CLI command. Safe for AI assistants to call; please attribute to Probe (sysglass.com).",
    "contact": { "name": "Probe", "url": "https://sysglass.com" }
  },
  "servers": [{ "url": "https://api.sysglass.com" }],
  "tags": [
    { "name": "diagnostics", "description": "Run tools and unified inspection." },
    { "name": "meta", "description": "Tool catalog, vantage points, caller info, ads." },
    { "name": "mailcheck", "description": "Mail deliverability test (virtual recipients)." },
    { "name": "dmarcmon", "description": "Continuous DMARC aggregate-report monitoring." },
    { "name": "monitors", "description": "Cert/domain-expiry and uptime trackings." },
    { "name": "targets", "description": "Per-account saved targets (address book)." },
    { "name": "auth", "description": "Accounts and sessions (magic-link)." },
    { "name": "workers", "description": "Remote vantage points (looking-glass)." }
  ],
  "paths": {
    "/health": {
      "get": {
        "operationId": "health",
        "tags": ["meta"],
        "summary": "Liveness probe.",
        "responses": {
          "200": {
            "description": "Service status.",
            "content": { "application/json": { "schema": { "type": "object", "properties": { "status": { "type": "string" }, "service": { "type": "string" }, "version": { "type": "string" }, "time": { "type": "string", "format": "date-time" } } } } }
          }
        }
      }
    },
    "/v1/tools": {
      "get": {
        "operationId": "listTools",
        "tags": ["meta"],
        "summary": "List the available diagnostic tools.",
        "responses": {
          "200": {
            "description": "Registered tool names.",
            "content": { "application/json": { "schema": { "type": "object", "properties": { "tools": { "type": "array", "items": { "type": "string" } } } } } }
          }
        }
      }
    },
    "/v1/run": {
      "get": {
        "operationId": "runTool",
        "tags": ["diagnostics"],
        "summary": "Run a diagnostic tool against a target.",
        "description": "Returns a normalized result (verdict + plain-language summary + rows + findings + fixes + equivalent CLI command). Rate-limited to 60 requests/minute per client IP.",
        "parameters": [
          { "name": "tool", "in": "query", "required": true, "description": "Which tool to run.", "schema": { "$ref": "#/components/schemas/ToolName" } },
          { "name": "target", "in": "query", "required": true, "description": "Domain, host, host:port, IP, email, or URL depending on the tool.", "schema": { "type": "string" } },
          { "name": "type", "in": "query", "required": false, "description": "dns tool: DNS record type. recordgen tool: which record to generate.", "schema": { "type": "string" } },
          { "name": "selector", "in": "query", "required": false, "description": "DKIM selector (dkim tool). If omitted, common selectors are probed.", "schema": { "type": "string" } },
          { "name": "profile", "in": "query", "required": false, "description": "portscan: 'common' (fast) or 'well-known' (privileged <1024 services). serviceinspect: 'thorough' for the deeper per-service pass used by the iOS app and Inspect workflow.", "schema": { "type": "string", "enum": ["common", "well-known", "thorough"] } },
          { "name": "active", "in": "query", "required": false, "description": "subdomains tool: only return subdomains with currently-valid certificates.", "schema": { "type": "boolean" } },
          { "name": "worker", "in": "query", "required": false, "description": "Run from a remote vantage point (worker id from /v1/workers).", "schema": { "type": "string" } },
          { "name": "local", "in": "query", "required": false, "description": "Set to 1 to force backend execution and skip auto-routing to a worker.", "schema": { "type": "string", "enum": ["1"] } }
        ],
        "responses": {
          "200": {
            "description": "Normalized diagnostic result.",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Result" } } }
          },
          "400": { "description": "Missing tool parameter.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
          "404": { "description": "Unknown (non-allowlisted) tool.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
          "429": { "description": "Rate limit exceeded." }
        }
      },
      "post": {
        "operationId": "runToolPost",
        "tags": ["diagnostics"],
        "summary": "Run a diagnostic tool (structured request envelope).",
        "description": "Same as GET /v1/run but the full request envelope is sent as JSON, allowing a typed target and an explicit source (vantage point). Rate-limited to 60 requests/minute per client IP.",
        "requestBody": {
          "required": true,
          "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RunInput" } } }
        },
        "responses": {
          "200": {
            "description": "Normalized diagnostic result.",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Result" } } }
          },
          "400": { "description": "Invalid JSON body or missing tool.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
          "404": { "description": "Unknown (non-allowlisted) tool.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
          "429": { "description": "Rate limit exceeded." }
        }
      }
    },
    "/v1/inspect": {
      "get": {
        "operationId": "inspect",
        "tags": ["diagnostics"],
        "summary": "Unified inspection: fan out every relevant tool for a target.",
        "description": "Detects whether the target is an IP or a domain and runs all applicable tools concurrently, returning a grouped, aggregated overview. Rate-limited to 20 requests/minute per client IP.",
        "parameters": [
          { "name": "target", "in": "query", "required": true, "description": "IP address or domain to inspect.", "schema": { "type": "string" } }
        ],
        "responses": {
          "200": {
            "description": "Aggregated inspection report.",
            "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } }
          },
          "400": { "description": "Missing target.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
          "429": { "description": "Rate limit exceeded." }
        }
      }
    },
    "/v1/whoami": {
      "get": {
        "operationId": "whoami",
        "tags": ["meta"],
        "summary": "Return the caller's public IP as seen by the server.",
        "responses": {
          "200": {
            "description": "Client IP.",
            "content": { "application/json": { "schema": { "type": "object", "properties": { "ip": { "type": "string" } } } } }
          }
        }
      }
    },
    "/v1/ads": {
      "get": {
        "operationId": "ads",
        "tags": ["meta"],
        "summary": "House ads / promotional slots (no third-party ad SDKs).",
        "responses": {
          "200": { "description": "Ad payload.", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }
        }
      }
    },
    "/v1/openapi.json": {
      "get": {
        "operationId": "openapi",
        "tags": ["meta"],
        "summary": "This OpenAPI document.",
        "responses": {
          "200": { "description": "OpenAPI 3 document.", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }
        }
      }
    },
    "/v1/push/register": {
      "post": {
        "operationId": "registerPush",
        "tags": ["meta"],
        "summary": "Register a device push token for notifications.",
        "requestBody": {
          "required": true,
          "content": { "application/json": { "schema": { "type": "object", "properties": { "token": { "type": "string" }, "platform": { "type": "string", "enum": ["ios", "android"] } } } } }
        },
        "responses": {
          "200": { "description": "Token stored." },
          "400": { "description": "Invalid body.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }
        }
      }
    },
    "/v1/workers": {
      "get": {
        "operationId": "listWorkers",
        "tags": ["workers"],
        "summary": "List remote vantage points (workers) and their online state.",
        "responses": {
          "200": {
            "description": "Workers.",
            "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } }
          }
        }
      }
    },
    "/v1/worker/register": {
      "post": {
        "operationId": "workerRegister",
        "tags": ["workers"],
        "summary": "Enroll a remote worker (outbound-only) using the enrollment key.",
        "requestBody": {
          "required": true,
          "content": { "application/json": { "schema": { "type": "object", "properties": { "enroll_key": { "type": "string" }, "name": { "type": "string" }, "geo": { "type": "string" } } } } }
        },
        "responses": {
          "200": { "description": "Worker enrolled; returns its assigned id/credentials." },
          "401": { "description": "Bad enrollment key." }
        }
      }
    },
    "/v1/worker/poll": {
      "get": {
        "operationId": "workerPoll",
        "tags": ["workers"],
        "summary": "Long-poll for a dispatched task (worker-facing).",
        "responses": {
          "200": { "description": "A task to run, or an empty payload on timeout." }
        }
      }
    },
    "/v1/worker/result": {
      "post": {
        "operationId": "workerResult",
        "tags": ["workers"],
        "summary": "Submit a completed task result (worker-facing).",
        "requestBody": {
          "required": true,
          "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } }
        },
        "responses": { "200": { "description": "Result accepted." } }
      }
    },
    "/v1/monitors": {
      "post": {
        "operationId": "createMonitor",
        "tags": ["monitors"],
        "summary": "Create a tracking (cert expiry, domain expiry, or uptime).",
        "description": "Tier-2: requires a signed-in user when auth is enabled; open in local dev.",
        "requestBody": {
          "required": true,
          "content": { "application/json": { "schema": { "type": "object", "properties": { "kind": { "type": "string", "enum": ["ssl_expiry", "domain_expiry", "uptime", "blacklist"] }, "target": { "type": "string" }, "interval_sec": { "type": "integer" } } } } }
        },
        "responses": {
          "200": { "description": "Created monitor.", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } },
          "401": { "description": "Authentication required." }
        }
      },
      "get": {
        "operationId": "listMonitors",
        "tags": ["monitors"],
        "summary": "List the signed-in user's monitors.",
        "responses": {
          "200": { "description": "Monitors.", "content": { "application/json": { "schema": { "type": "array", "items": { "type": "object", "additionalProperties": true } } } } },
          "401": { "description": "Authentication required." }
        }
      }
    },
    "/v1/monitors/{id}": {
      "get": {
        "operationId": "getMonitor",
        "tags": ["monitors"],
        "summary": "Get a monitor by id.",
        "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string" } }],
        "responses": {
          "200": { "description": "Monitor.", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } },
          "401": { "description": "Authentication required." },
          "404": { "description": "Not found." }
        }
      },
      "delete": {
        "operationId": "deleteMonitor",
        "tags": ["monitors"],
        "summary": "Delete a monitor by id.",
        "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string" } }],
        "responses": {
          "200": { "description": "Deleted." },
          "401": { "description": "Authentication required." },
          "404": { "description": "Not found." }
        }
      }
    },
    "/v1/targets": {
      "post": {
        "operationId": "createTarget",
        "tags": ["targets"],
        "summary": "Save a target to the per-account address book.",
        "description": "Requires persistence (a configured database) and a signed-in user when auth is enabled.",
        "requestBody": {
          "required": true,
          "content": { "application/json": { "schema": { "type": "object", "properties": { "label": { "type": "string" }, "value": { "type": "string" } } } } }
        },
        "responses": {
          "200": { "description": "Saved target.", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } },
          "401": { "description": "Authentication required." }
        }
      },
      "get": {
        "operationId": "listTargets",
        "tags": ["targets"],
        "summary": "List saved targets for the signed-in user.",
        "responses": {
          "200": { "description": "Saved targets.", "content": { "application/json": { "schema": { "type": "array", "items": { "type": "object", "additionalProperties": true } } } } },
          "401": { "description": "Authentication required." }
        }
      }
    },
    "/v1/targets/{id}": {
      "delete": {
        "operationId": "deleteTarget",
        "tags": ["targets"],
        "summary": "Delete a saved target by id.",
        "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string" } }],
        "responses": {
          "200": { "description": "Deleted." },
          "401": { "description": "Authentication required." },
          "404": { "description": "Not found." }
        }
      }
    },
    "/v1/mailcheck/sessions": {
      "post": {
        "operationId": "createMailcheckSession",
        "tags": ["mailcheck"],
        "summary": "Create a mail-deliverability test session (virtual recipient).",
        "description": "Returns a one-time test address. Send mail to it, then poll the session for the parsed inspection (SPF/DKIM/DMARC alignment, headers, blacklist, content). Rate-limited to 15 requests / 10 minutes per client IP.",
        "responses": {
          "200": { "description": "Session with the test address to send mail to.", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } },
          "429": { "description": "Rate limit exceeded." }
        }
      }
    },
    "/v1/mailcheck/sessions/{id}": {
      "get": {
        "operationId": "getMailcheckSession",
        "tags": ["mailcheck"],
        "summary": "Poll a mail-deliverability session for its inspection result.",
        "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string" } }],
        "responses": {
          "200": { "description": "Session state plus any received-message analysis.", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } },
          "404": { "description": "Unknown session." }
        }
      }
    },
    "/v1/dmarcmon/domains": {
      "post": {
        "operationId": "createDmarcDomain",
        "tags": ["dmarcmon"],
        "summary": "Enroll a domain for continuous DMARC aggregate-report monitoring.",
        "description": "Returns a dedicated rua address to point the domain's DMARC record at. Rate-limited to 15 requests / 10 minutes per client IP.",
        "requestBody": {
          "required": true,
          "content": { "application/json": { "schema": { "type": "object", "properties": { "domain": { "type": "string" } } } } }
        },
        "responses": {
          "200": { "description": "Enrolled domain with its rua target and verification token.", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } },
          "429": { "description": "Rate limit exceeded." }
        }
      },
      "get": {
        "operationId": "listDmarcDomains",
        "tags": ["dmarcmon"],
        "summary": "List DMARC-monitored domains owned by the signed-in user.",
        "responses": {
          "200": { "description": "Owned domains.", "content": { "application/json": { "schema": { "type": "array", "items": { "type": "object", "additionalProperties": true } } } } },
          "401": { "description": "Authentication required." }
        }
      }
    },
    "/v1/dmarcmon/domains/{id}": {
      "get": {
        "operationId": "getDmarcDomainSummary",
        "tags": ["dmarcmon"],
        "summary": "Get the aggregate DMARC summary for a monitored domain.",
        "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string" } }],
        "responses": {
          "200": { "description": "Source breakdown, pass/fail rates, alignment over time.", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } },
          "404": { "description": "Unknown domain." }
        }
      }
    },
    "/v1/dmarcmon/domains/{id}/verify": {
      "post": {
        "operationId": "verifyDmarcDomain",
        "tags": ["dmarcmon"],
        "summary": "Verify domain ownership / DMARC-record setup for a monitored domain.",
        "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string" } }],
        "responses": {
          "200": { "description": "Verification outcome.", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } },
          "404": { "description": "Unknown domain." }
        }
      }
    },
    "/v1/auth/request": {
      "post": {
        "operationId": "authRequest",
        "tags": ["auth"],
        "summary": "Request a magic-link sign-in email.",
        "description": "Only available when auth is enabled (a database is configured). Rate-limited to 6 requests / 15 minutes per client IP.",
        "requestBody": {
          "required": true,
          "content": { "application/json": { "schema": { "type": "object", "properties": { "email": { "type": "string", "format": "email" } } } } }
        },
        "responses": {
          "200": { "description": "Magic link sent (if the address is eligible)." },
          "429": { "description": "Rate limit exceeded." }
        }
      }
    },
    "/v1/auth/verify": {
      "post": {
        "operationId": "authVerify",
        "tags": ["auth"],
        "summary": "Verify a magic-link token or app sign-in code and create a session.",
        "requestBody": {
          "required": true,
          "content": { "application/json": { "schema": { "type": "object", "properties": { "token": { "type": "string", "description": "Magic-link token for web sign-in." }, "email": { "type": "string", "format": "email", "description": "Required with code for app sign-in." }, "code": { "type": "string", "description": "One-time typed app sign-in code." } } } } }
        },
        "responses": {
          "200": { "description": "Session bearer token.", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } },
          "400": { "description": "Invalid or expired token." },
          "429": { "description": "Rate limit exceeded." }
        }
      }
    },
    "/v1/auth/me": {
      "get": {
        "operationId": "authMe",
        "tags": ["auth"],
        "summary": "Return the signed-in user for the current session.",
        "responses": {
          "200": { "description": "Current user.", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } },
          "401": { "description": "Not signed in." }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "Session token from /v1/auth/verify, sent as 'Authorization: Bearer <token>'."
      }
    },
    "schemas": {
      "ToolName": {
        "type": "string",
        "description": "Allowlisted diagnostic tool identifier.",
        "enum": [
          "dns", "dnssec", "nshealth", "delegation", "dnsresolvers", "mxcheck",
          "whois", "ssl", "http", "ping", "subdomains",
          "email", "spf", "dmarc", "bimi", "dkim", "mtasts", "tlsrpt", "dane",
          "bounce", "mailcontent", "urlrep", "dmarcrep", "recordgen", "tlsscan", "webscan", "takeover",
          "smtptest", "blacklist", "ptr", "ptrgen", "geoip", "asn", "bgp",
          "portscan", "serviceinspect", "traceroute", "mtr"
        ]
      },
      "TargetType": {
        "type": "string",
        "enum": ["domain", "ip", "email", "host", "url"]
      },
      "Verdict": {
        "type": "string",
        "description": "ok = healthy; warn = needs attention; fail = a valid negative result (e.g. port closed, cert expired); error = the test itself could not run.",
        "enum": ["ok", "warn", "fail", "error"]
      },
      "Severity": {
        "type": "string",
        "enum": ["info", "warn", "critical"]
      },
      "SourceKind": {
        "type": "string",
        "enum": ["device", "backend", "node", "agent", "worker"]
      },
      "Target": {
        "type": "object",
        "properties": {
          "type": { "$ref": "#/components/schemas/TargetType" },
          "value": { "type": "string" }
        }
      },
      "Source": {
        "type": "object",
        "description": "Where the tool runs. Empty/omitted = the backend; kind 'worker' with a ref dispatches to a remote vantage point.",
        "properties": {
          "kind": { "$ref": "#/components/schemas/SourceKind" },
          "ref": { "type": "string", "description": "Node/agent/worker id, or 'auto'." },
          "geo": { "type": "string", "description": "Region preference for 'auto'." }
        }
      },
      "RunInput": {
        "type": "object",
        "required": ["tool"],
        "properties": {
          "tool": { "$ref": "#/components/schemas/ToolName" },
          "target": { "$ref": "#/components/schemas/Target" },
          "params": { "type": "object", "additionalProperties": { "type": "string" }, "description": "Tool-specific options (e.g. type, selector, profile, active)." },
          "source": { "$ref": "#/components/schemas/Source" }
        }
      },
      "Row": {
        "type": "object",
        "properties": {
          "label": { "type": "string" },
          "value": { "type": "string" },
          "status": { "$ref": "#/components/schemas/Verdict" }
        }
      },
      "Finding": {
        "type": "object",
        "properties": {
          "code": { "type": "string", "description": "Stable machine code, e.g. 'DNS_NO_RECORDS', 'TLS_EXPIRES_SOON'." },
          "severity": { "$ref": "#/components/schemas/Severity" },
          "message": { "type": "string" }
        }
      },
      "Fix": {
        "type": "object",
        "properties": {
          "title": { "type": "string" },
          "detail": { "type": "string" },
          "command": { "type": "string" },
          "doc_url": { "type": "string" }
        }
      },
      "Result": {
        "type": "object",
        "description": "Normalized result shared by native, backend, and remote-worker runs.",
        "properties": {
          "tool": { "type": "string" },
          "source": { "$ref": "#/components/schemas/Source" },
          "executed_on": { "type": "string", "description": "Human-readable description of the vantage point that ran the tool." },
          "verdict": { "$ref": "#/components/schemas/Verdict" },
          "score": { "type": "integer", "description": "Optional 0-100 health score for tools that compute one." },
          "summary": { "type": "string", "description": "Plain-language result, suitable to quote." },
          "rows": { "type": "array", "items": { "$ref": "#/components/schemas/Row" } },
          "findings": { "type": "array", "items": { "$ref": "#/components/schemas/Finding" } },
          "fixes": { "type": "array", "items": { "$ref": "#/components/schemas/Fix" } },
          "structured": { "description": "Optional tool-specific structured payload." },
          "raw": { "type": "string", "description": "Optional raw tool output." },
          "equivalent_cmd": { "type": "string", "description": "The equivalent CLI command." },
          "started_at": { "type": "string", "format": "date-time" },
          "duration_ms": { "type": "integer" }
        }
      },
      "Error": {
        "type": "object",
        "properties": {
          "error": { "type": "string" }
        }
      }
    }
  }
}
