{
  "openapi": "3.0.3",
  "info": {
    "title": "Infostealer Logs API",
    "version": "1.0.0",
    "description": "Infostealer exposure search API. Paid plans provide a bearer key (lk_live_...) and daily quota. The data-provider key stays server-side."
  },
  "servers": [
    { "url": "/" }
  ],
  "security": [
    { "bearerAuth": [] }
  ],
  "paths": {
    "/api/search": {
      "post": {
        "summary": "Search one page of exposure records",
        "description": "Returns up to 25 records. Paid plans can paginate a cached result; credit accounts receive page 1 only.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/SearchRequest" }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Search result",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/SearchResponse" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "402": { "$ref": "#/components/responses/PaymentRequired" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "415": { "$ref": "#/components/responses/UnsupportedMediaType" },
          "429": { "$ref": "#/components/responses/TooManyRequests" }
        }
      }
    },
    "/api/search/all": {
      "post": {
        "summary": "Download every record for a query",
        "description": "Paid plans only. Returns the complete result and costs one search. Served from the account cache when available.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/SearchRequest" }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Full search result",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/SearchResponse" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "402": { "$ref": "#/components/responses/PaymentRequired" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "415": { "$ref": "#/components/responses/UnsupportedMediaType" },
          "429": { "$ref": "#/components/responses/TooManyRequests" }
        }
      }
    },
    "/api/me": {
      "get": {
        "summary": "Read the current plan and quota",
        "description": "Does not consume a search.",
        "responses": {
          "200": {
            "description": "Account plan and quota",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/MeResponse" }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "lk_live_..."
      }
    },
    "schemas": {
      "SearchRequest": {
        "type": "object",
        "required": ["query"],
        "properties": {
          "query": { "type": "string", "example": "example.com" },
          "type": {
            "type": "string",
            "enum": ["url", "email", "email_domain", "username", "password", "ip"],
            "default": "email_domain"
          },
          "page": { "type": "integer", "minimum": 1, "maximum": 400, "default": 1 }
        }
      },
      "Hit": {
        "type": "object",
        "properties": {
          "account": { "type": "string", "nullable": true },
          "password": { "type": "string", "nullable": true },
          "originHost": { "type": "string", "nullable": true },
          "source": { "type": "string" },
          "postedAt": { "type": "string", "format": "date-time", "nullable": true },
          "recordType": { "type": "string", "enum": ["credential", "combo", "unknown"] }
        }
      },
      "SearchResponse": {
        "type": "object",
        "properties": {
          "domain": { "type": "string" },
          "searchType": { "type": "string" },
          "provider": { "type": "string" },
          "mode": { "type": "string", "enum": ["authenticated"] },
          "access": { "type": "string", "enum": ["plan", "credit", "cached"] },
          "active": { "type": "boolean" },
          "plan": { "type": "string" },
          "planName": { "type": "string" },
          "canBulk": { "type": "boolean" },
          "canPaginate": { "type": "boolean" },
          "credits": { "type": "integer" },
          "limits": { "$ref": "#/components/schemas/Limits" },
          "checkedAt": { "type": "string", "format": "date-time" },
          "page": { "type": "integer" },
          "pageSize": { "type": "integer" },
          "totalReported": { "type": "integer" },
          "totalIsExact": { "type": "boolean" },
          "hasNextPage": { "type": "boolean" },
          "fromCache": { "type": "boolean" },
          "hits": { "type": "array", "items": { "$ref": "#/components/schemas/Hit" } },
          "notice": { "type": "string" }
        }
      },
      "Limits": {
        "type": "object",
        "properties": {
          "searchesPerDay": { "type": "integer" },
          "searchesUsed": { "type": "integer" },
          "searchesRemaining": { "type": "integer" },
          "resetsAt": { "type": "string", "format": "date-time" }
        }
      },
      "MeResponse": {
        "type": "object",
        "properties": {
          "email": { "type": "string" },
          "plan": { "type": "string" },
          "planName": { "type": "string" },
          "active": { "type": "boolean" },
          "expiresAt": { "type": "string", "format": "date-time", "nullable": true },
          "daysLeft": { "type": "integer" },
          "limits": { "$ref": "#/components/schemas/Limits" },
          "credits": { "type": "integer" }
        }
      },
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "code": { "type": "string" },
              "message": { "type": "string" },
              "retryAfterSeconds": { "type": "integer" }
            }
          }
        }
      }
    },
    "responses": {
      "BadRequest": {
        "description": "Invalid request",
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } }
      },
      "Unauthorized": {
        "description": "Missing or invalid API key",
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } }
      },
      "PaymentRequired": {
        "description": "No credits left",
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } }
      },
      "Forbidden": {
        "description": "Plan required or expired",
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } }
      },
      "UnsupportedMediaType": {
        "description": "Body is not JSON",
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } }
      },
      "TooManyRequests": {
        "description": "Daily quota or local rate limit",
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } }
      }
    }
  }
}
