{
  "openapi": "3.1.0",
  "info": {
    "title": "Stealthium website API",
    "version": "1.1.0",
    "summary": "Read-only content API and contact endpoint for stealthium.io.",
    "description": "Public API served from stealthium.io.\n\nThe content endpoints are read-only, need no credentials, and allow cross-origin requests, so an agent can enumerate Stealthium's published GPU security research and read the identity of the product without a browser.\n\n`POST /api/contact` is the one write operation. It accepts either a browser request from an allowed origin or a scoped API key, so an agent acting for a user can request a demo without impersonating a browser.\n\nThis document describes stealthium.io itself. The Stealthium **platform** API — GPU telemetry ingest, fleet and workload queries — is a separate, authenticated service documented at https://docs.stealthium.io.",
    "contact": {
      "name": "Stealthium",
      "email": "info@stealthium.io",
      "url": "https://stealthium.io/developers"
    },
    "license": {
      "name": "Stealthium Terms of Service",
      "url": "https://stealthium.io/terms"
    },
    "termsOfService": "https://stealthium.io/terms",
    "x-when-to-use": [
      "A GPU-accelerated training or inference job slowed down and you need to know which layer — application, CUDA runtime, driver, GPU, or fabric — is responsible.",
      "You need per-workload GPU telemetry (kernel traces, NVML counters, memory and SM utilisation, fabric throughput) correlated with the process, container or pod that produced it.",
      "You are investigating suspected misuse of GPU capacity — cryptomining on idle accelerators, unauthorised kernels, or a job consuming far more GPU time than it requested.",
      "You need to detect or triage GPU-specific attack activity at runtime: side channels between MIG instances, malicious or tampered CUDA fatbins, driver-level exploitation.",
      "You need an audit trail of who ran which AI workload on which GPU, for compliance evidence over a shared or multi-tenant GPU fleet.",
      "You are evaluating GPU security posture across a multi-node or multi-cluster fleet and need one inventory of accelerators, drivers, toolkit versions and their exposure."
    ],
    "x-when-not-to-use": [
      "General-purpose CPU/host APM or log aggregation — Stealthium is GPU- and AI-workload-specific and complements, rather than replaces, those tools.",
      "Provisioning, scheduling or renting GPU capacity — Stealthium observes and secures GPUs, it does not supply them.",
      "Static analysis of model weights or prompt-level LLM safety — Stealthium works at the GPU runtime layer, not the model-content layer."
    ]
  },
  "servers": [
    {
      "url": "https://stealthium.io",
      "description": "Production"
    }
  ],
  "externalDocs": {
    "description": "Stealthium product documentation",
    "url": "https://docs.stealthium.io"
  },
  "tags": [
    {
      "name": "content",
      "description": "Published Stealthium research and blog content."
    },
    {
      "name": "contact",
      "description": "Reach a human at Stealthium."
    },
    {
      "name": "discovery",
      "description": "Machine-readable descriptions of this site."
    }
  ],
  "security": [
    {}
  ],
  "paths": {
    "/api/site": {
      "get": {
        "operationId": "getSiteIdentity",
        "tags": [
          "discovery"
        ],
        "summary": "Get Stealthium's identity and when-to-use guidance",
        "description": "Returns the canonical name, description, contact details, social profiles and machine-readable resources for Stealthium, plus the concrete jobs Stealthium is and is not the right tool for. Use this first to decide whether Stealthium is relevant to a task.",
        "responses": {
          "200": {
            "description": "Site and product identity.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SiteIdentity"
                }
              }
            }
          }
        }
      }
    },
    "/api/posts": {
      "get": {
        "operationId": "listBlogPosts",
        "tags": [
          "content"
        ],
        "summary": "List Stealthium blog posts",
        "description": "Returns published Stealthium research posts, newest first, optionally filtered by category or tag. Response items exclude the post body; fetch `getBlogPost` for the full markdown.",
        "parameters": [
          {
            "name": "category",
            "in": "query",
            "required": false,
            "description": "Return only posts in this category, case-insensitive. Valid values come from `listBlogCategories`.",
            "schema": {
              "type": "string",
              "maxLength": 100
            },
            "example": "RESEARCH"
          },
          {
            "name": "tag",
            "in": "query",
            "required": false,
            "description": "Return only posts carrying this tag, case-insensitive. Valid values come from `listBlogTags`.",
            "schema": {
              "type": "string",
              "maxLength": 100
            },
            "example": "cuda"
          },
          {
            "name": "featured",
            "in": "query",
            "required": false,
            "description": "When true, return only posts flagged as featured.",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum number of posts to return.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 20
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "description": "Number of posts to skip, for paging through the full list.",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page of blog posts.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BlogPostList"
                }
              }
            }
          },
          "400": {
            "description": "A query parameter was not a valid value.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/posts/{slug}": {
      "get": {
        "operationId": "getBlogPost",
        "tags": [
          "content"
        ],
        "summary": "Get one blog post, including its markdown body",
        "description": "Returns a single Stealthium blog post by slug, including the full markdown source of the article. Slugs come from `listBlogPosts`.",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "description": "URL slug of the post, as returned by `listBlogPosts`.",
            "schema": {
              "type": "string",
              "pattern": "^[a-z0-9][a-z0-9-]{0,200}$"
            },
            "example": "gpu-security-gap-nobody-owns"
          }
        ],
        "responses": {
          "200": {
            "description": "The requested post.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BlogPost"
                }
              }
            }
          },
          "400": {
            "description": "The slug was malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No post exists with that slug.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/categories": {
      "get": {
        "operationId": "listBlogCategories",
        "tags": [
          "content"
        ],
        "summary": "List every blog category",
        "description": "Returns every category in use on the Stealthium blog, with a post count for each. Use a value here as the `category` filter on `listBlogPosts`.",
        "responses": {
          "200": {
            "description": "Categories in use.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TaxonomyList"
                }
              }
            }
          }
        }
      }
    },
    "/api/tags": {
      "get": {
        "operationId": "listBlogTags",
        "tags": [
          "content"
        ],
        "summary": "List every blog tag",
        "description": "Returns every tag in use on the Stealthium blog, with a post count for each. Use a value here as the `tag` filter on `listBlogPosts`.",
        "responses": {
          "200": {
            "description": "Tags in use.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TaxonomyList"
                }
              }
            }
          }
        }
      }
    },
    "/api/contact": {
      "post": {
        "operationId": "createContactRequest",
        "tags": [
          "contact"
        ],
        "summary": "Send a demo request to Stealthium",
        "description": "Delivers a message to the Stealthium team, the same way the demo form on the homepage does.\n\nTwo ways to authenticate. A browser sends an allowed `Origin` header and needs no credential. A server-side caller — an agent — presents an API key with the `contact:write` scope in the `x-api-key` header instead; ask Stealthium for one at info@stealthium.io.\n\nRate limited to 3 requests per minute per client IP in both cases.",
        "security": [
          {},
          {
            "agentApiKey": []
          }
        ],
        "x-required-scopes": [
          "contact:write"
        ],
        "requestBody": {
          "required": true,
          "description": "Who is getting in touch, and why.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ContactRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The message was accepted and delivered.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContactResponse"
                }
              }
            }
          },
          "400": {
            "description": "The request body failed validation. `details` lists each field problem.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "An API key was presented but is not valid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Neither an allowed browser origin nor a key with the `contact:write` scope was presented.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after 60 seconds.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "The message could not be delivered.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/openapi.json": {
      "get": {
        "operationId": "getOpenApiDocument",
        "tags": [
          "discovery"
        ],
        "summary": "Get this OpenAPI document",
        "description": "Returns this document. Also served at `/api/openapi.json` and `/.well-known/openapi.json` for callers that probe those locations.",
        "responses": {
          "200": {
            "description": "The OpenAPI 3.1 document describing this API.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          }
        }
      }
    },
    "/agents.md": {
      "get": {
        "operationId": "getAgentInstructions",
        "tags": [
          "discovery"
        ],
        "summary": "Get agent instructions for Stealthium",
        "description": "Markdown document stating when an agent should reach for Stealthium, when it should not, and how to call this site and the product API.",
        "responses": {
          "200": {
            "description": "Agent instructions, as markdown.",
            "headers": {
              "Vary": {
                "description": "Includes `Accept` so caches keep the markdown and HTML variants apart.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/llms.txt": {
      "get": {
        "operationId": "getLlmsTxt",
        "tags": [
          "discovery"
        ],
        "summary": "Get the llms.txt index",
        "description": "Curated index of Stealthium documentation and machine-readable resources, in the llms.txt format.",
        "responses": {
          "200": {
            "description": "The llms.txt index.",
            "headers": {
              "Vary": {
                "description": "Includes `Accept` so caches keep the markdown and HTML variants apart.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/llms-full.txt": {
      "get": {
        "operationId": "getLlmsFullTxt",
        "tags": [
          "discovery"
        ],
        "summary": "Get every page of stealthium.io as one markdown file",
        "description": "The full markdown text of the homepage, the developer resources page and every blog post, concatenated. Use this to ingest the whole site in one request.",
        "responses": {
          "200": {
            "description": "The full site text.",
            "headers": {
              "Vary": {
                "description": "Includes `Accept` so caches keep the markdown and HTML variants apart.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "agentApiKey": {
        "type": "apiKey",
        "in": "header",
        "name": "x-api-key",
        "description": "Scoped API key for agents and server-side callers.\n\nA key grants only the scopes it was issued with, so a caller can request the narrowest access it needs. Available scopes:\n\n- `contact:write` — send a message through `POST /api/contact`.\n\nRequest a key at info@stealthium.io. Keys are rejected with 401; a valid key without the required scope is rejected with 403.",
        "x-scopes": {
          "contact:write": "Send a message through POST /api/contact."
        }
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "description": "Uniform error envelope returned by every operation in this API.",
        "required": [
          "error"
        ],
        "additionalProperties": false,
        "properties": {
          "error": {
            "type": "object",
            "description": "What went wrong.",
            "required": [
              "code",
              "message"
            ],
            "additionalProperties": false,
            "properties": {
              "code": {
                "type": "string",
                "description": "Stable, machine-readable error identifier.",
                "enum": [
                  "validation_failed",
                  "invalid_origin",
                  "invalid_api_key",
                  "insufficient_scope",
                  "not_found",
                  "rate_limited",
                  "delivery_failed",
                  "internal_error"
                ]
              },
              "message": {
                "type": "string",
                "description": "Human-readable explanation."
              },
              "details": {
                "type": "array",
                "description": "Field-level problems, when the error is a validation failure.",
                "items": {
                  "type": "object",
                  "additionalProperties": true,
                  "properties": {
                    "path": {
                      "type": "array",
                      "description": "Path to the offending field within the request body.",
                      "items": {
                        "type": "string"
                      }
                    },
                    "message": {
                      "type": "string",
                      "description": "What is wrong with that field."
                    }
                  }
                }
              }
            }
          }
        }
      },
      "BlogPostSummary": {
        "type": "object",
        "description": "A Stealthium blog post without its body.",
        "required": [
          "slug",
          "title",
          "excerpt",
          "author",
          "date",
          "publishedAt",
          "url",
          "category",
          "tags"
        ],
        "additionalProperties": false,
        "properties": {
          "slug": {
            "type": "string",
            "description": "URL slug, unique per post."
          },
          "title": {
            "type": "string",
            "description": "Post title."
          },
          "excerpt": {
            "type": "string",
            "description": "One-paragraph summary."
          },
          "author": {
            "type": "string",
            "description": "Author name."
          },
          "date": {
            "type": "string",
            "description": "Display date, e.g. \"FEB 2026\"."
          },
          "publishedAt": {
            "type": "string",
            "format": "date",
            "description": "Publication date as ISO-8601 (YYYY-MM-DD)."
          },
          "readTime": {
            "type": "string",
            "description": "Estimated reading time, e.g. \"9 min read\"."
          },
          "featured": {
            "type": "boolean",
            "description": "Whether the post is featured on the blog index."
          },
          "category": {
            "type": "array",
            "description": "Categories the post belongs to.",
            "items": {
              "type": "string"
            }
          },
          "tags": {
            "type": "array",
            "description": "Tags on the post.",
            "items": {
              "type": "string"
            }
          },
          "image": {
            "type": "string",
            "format": "uri",
            "description": "Absolute URL of the post's hero image."
          },
          "url": {
            "type": "string",
            "format": "uri",
            "description": "Canonical HTML URL of the post."
          },
          "markdownUrl": {
            "type": "string",
            "format": "uri",
            "description": "URL that returns the post as markdown."
          }
        }
      },
      "BlogPost": {
        "type": "object",
        "description": "A Stealthium blog post, including its full markdown body.",
        "required": [
          "slug",
          "title",
          "excerpt",
          "author",
          "date",
          "publishedAt",
          "url",
          "category",
          "tags",
          "content"
        ],
        "additionalProperties": false,
        "properties": {
          "slug": {
            "type": "string",
            "description": "URL slug, unique per post."
          },
          "title": {
            "type": "string",
            "description": "Post title."
          },
          "excerpt": {
            "type": "string",
            "description": "One-paragraph summary."
          },
          "author": {
            "type": "string",
            "description": "Author name."
          },
          "date": {
            "type": "string",
            "description": "Display date, e.g. \"FEB 2026\"."
          },
          "publishedAt": {
            "type": "string",
            "format": "date",
            "description": "Publication date as ISO-8601 (YYYY-MM-DD)."
          },
          "readTime": {
            "type": "string",
            "description": "Estimated reading time, e.g. \"9 min read\"."
          },
          "featured": {
            "type": "boolean",
            "description": "Whether the post is featured on the blog index."
          },
          "category": {
            "type": "array",
            "description": "Categories the post belongs to.",
            "items": {
              "type": "string"
            }
          },
          "tags": {
            "type": "array",
            "description": "Tags on the post.",
            "items": {
              "type": "string"
            }
          },
          "image": {
            "type": "string",
            "format": "uri",
            "description": "Absolute URL of the post's hero image."
          },
          "url": {
            "type": "string",
            "format": "uri",
            "description": "Canonical HTML URL of the post."
          },
          "markdownUrl": {
            "type": "string",
            "format": "uri",
            "description": "URL that returns the post as markdown."
          },
          "content": {
            "type": "string",
            "description": "Full article body, as markdown."
          },
          "conclusion": {
            "type": "string",
            "description": "Closing summary, when the post declares one."
          }
        }
      },
      "BlogPostList": {
        "type": "object",
        "description": "A page of blog posts plus the paging state that produced it.",
        "required": [
          "data",
          "pagination"
        ],
        "additionalProperties": false,
        "properties": {
          "data": {
            "type": "array",
            "description": "The posts in this page, newest first.",
            "items": {
              "$ref": "#/components/schemas/BlogPostSummary"
            }
          },
          "pagination": {
            "type": "object",
            "description": "Paging state.",
            "required": [
              "total",
              "limit",
              "offset",
              "returned"
            ],
            "additionalProperties": false,
            "properties": {
              "total": {
                "type": "integer",
                "minimum": 0,
                "description": "Posts matching the filters."
              },
              "limit": {
                "type": "integer",
                "minimum": 1,
                "description": "Page size that was applied."
              },
              "offset": {
                "type": "integer",
                "minimum": 0,
                "description": "Offset that was applied."
              },
              "returned": {
                "type": "integer",
                "minimum": 0,
                "description": "Posts in this response."
              }
            }
          }
        }
      },
      "TaxonomyList": {
        "type": "object",
        "description": "Categories or tags in use, with post counts.",
        "required": [
          "data"
        ],
        "additionalProperties": false,
        "properties": {
          "data": {
            "type": "array",
            "description": "One entry per distinct value.",
            "items": {
              "type": "object",
              "required": [
                "name",
                "count"
              ],
              "additionalProperties": false,
              "properties": {
                "name": {
                  "type": "string",
                  "description": "The category or tag."
                },
                "count": {
                  "type": "integer",
                  "minimum": 1,
                  "description": "Posts carrying it."
                }
              }
            }
          }
        }
      },
      "SiteIdentity": {
        "type": "object",
        "description": "Canonical identity of Stealthium, for agents deciding whether to use it.",
        "required": [
          "name",
          "url",
          "description",
          "whenToUse",
          "whenNotToUse",
          "resources"
        ],
        "additionalProperties": false,
        "properties": {
          "name": {
            "type": "string",
            "description": "Product and company name."
          },
          "legalName": {
            "type": "string",
            "description": "Registered legal entity name."
          },
          "url": {
            "type": "string",
            "format": "uri",
            "description": "Canonical site URL."
          },
          "tagline": {
            "type": "string",
            "description": "One-line positioning statement."
          },
          "description": {
            "type": "string",
            "description": "Paragraph describing what Stealthium does."
          },
          "documentationUrl": {
            "type": "string",
            "format": "uri",
            "description": "Product documentation."
          },
          "email": {
            "type": "string",
            "format": "email",
            "description": "General contact address."
          },
          "address": {
            "type": "object",
            "description": "Business location.",
            "additionalProperties": false,
            "properties": {
              "locality": {
                "type": "string",
                "description": "City."
              },
              "region": {
                "type": "string",
                "description": "State or region code."
              },
              "country": {
                "type": "string",
                "description": "ISO 3166-1 alpha-2 country code."
              }
            }
          },
          "sameAs": {
            "type": "array",
            "description": "Profiles for the same entity elsewhere.",
            "items": {
              "type": "string",
              "format": "uri"
            }
          },
          "whenToUse": {
            "type": "array",
            "description": "Jobs Stealthium is the right tool for.",
            "items": {
              "type": "string"
            }
          },
          "whenNotToUse": {
            "type": "array",
            "description": "Jobs Stealthium is not the right tool for.",
            "items": {
              "type": "string"
            }
          },
          "resources": {
            "type": "array",
            "description": "Machine-readable resources this site publishes.",
            "items": {
              "type": "object",
              "required": [
                "name",
                "url",
                "mediaType",
                "description"
              ],
              "additionalProperties": false,
              "properties": {
                "name": {
                  "type": "string",
                  "description": "Resource name."
                },
                "url": {
                  "type": "string",
                  "format": "uri",
                  "description": "Absolute URL."
                },
                "mediaType": {
                  "type": "string",
                  "description": "Media type served."
                },
                "description": {
                  "type": "string",
                  "description": "What the resource contains."
                }
              }
            }
          }
        }
      },
      "ContactRequest": {
        "type": "object",
        "description": "A demo request.",
        "required": [
          "firstName",
          "email",
          "company",
          "message"
        ],
        "additionalProperties": false,
        "properties": {
          "firstName": {
            "type": "string",
            "minLength": 2,
            "maxLength": 50,
            "pattern": "^[a-zA-Z ]+$",
            "description": "Contact's first name. Letters and spaces only."
          },
          "email": {
            "type": "string",
            "format": "email",
            "minLength": 3,
            "maxLength": 254,
            "description": "Reply-to email address."
          },
          "company": {
            "type": "string",
            "minLength": 2,
            "maxLength": 100,
            "description": "Organisation the contact belongs to."
          },
          "message": {
            "type": "string",
            "minLength": 5,
            "maxLength": 1000,
            "description": "What the contact wants to discuss."
          }
        }
      },
      "ContactResponse": {
        "type": "object",
        "description": "Confirmation that a contact request was delivered.",
        "required": [
          "success",
          "message"
        ],
        "additionalProperties": false,
        "properties": {
          "success": {
            "type": "boolean",
            "description": "Always true on a 200."
          },
          "message": {
            "type": "string",
            "description": "Human-readable confirmation."
          },
          "emailId": {
            "type": "string",
            "description": "Delivery provider's message identifier, when available."
          }
        }
      }
    }
  }
}