{
  "openapi": "3.0.0",
  "info": {
    "title": "ZeroDrift API",
    "version": "1.0.0",
    "description": "OpenAPI reference for the public ZeroDrift audit API."
  },
  "servers": [
    {
      "url": "/",
      "description": "Current deployment"
    }
  ],
  "components": {
    "securitySchemes": {
      "BearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT"
      }
    },
    "schemas": {
      "ApiErrorResponse": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string",
            "description": "Human-readable error message."
          }
        },
        "required": [
          "error"
        ]
      },
      "AuditFinding": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string",
            "description": "Short finding title."
          },
          "severity": {
            "type": "string",
            "description": "Finding severity."
          },
          "description": {
            "type": "string",
            "description": "Finding details."
          },
          "file_path": {
            "type": "string",
            "description": "Related project-relative file path."
          },
          "location": {
            "type": "string",
            "description": "Related source location."
          },
          "recommendation": {
            "type": "string",
            "description": "Suggested remediation."
          }
        },
        "required": [
          "title",
          "severity",
          "description"
        ],
        "additionalProperties": true
      },
      "AuditSession": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "description": "Database record ID."
          },
          "user_id": {
            "type": "string",
            "description": "Owning user ID."
          },
          "session_id": {
            "type": "string",
            "description": "Audit session ID."
          },
          "repo_name": {
            "type": "string",
            "nullable": true,
            "description": "Project name recorded for the session."
          },
          "type": {
            "type": "string",
            "nullable": true,
            "description": "Audit type."
          },
          "status": {
            "type": "string",
            "nullable": true,
            "description": "Stored audit session status."
          },
          "created_at": {
            "type": "string",
            "description": "Session creation timestamp."
          },
          "updated_at": {
            "type": "string",
            "description": "Session last-update timestamp."
          }
        },
        "required": [
          "id",
          "user_id",
          "session_id",
          "repo_name",
          "type",
          "status",
          "created_at",
          "updated_at"
        ]
      },
      "AuditSessionCreateBody": {
        "type": "object",
        "properties": {
          "agent": {
            "type": "string",
            "description": "Optional audit agent override."
          },
          "agentName": {
            "type": "string",
            "description": "Optional audit agent override alias."
          },
          "discountCode": {
            "type": "string",
            "description": "Optional active discount code."
          },
          "excludedPaths": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Project-relative paths to exclude."
          },
          "model": {
            "type": "string",
            "description": "Optional model override."
          },
          "project_name": {
            "type": "string",
            "description": "Optional project display name."
          },
          "projectName": {
            "type": "string",
            "description": "Camel-case alias for project_name."
          },
          "type": {
            "type": "string",
            "description": "Audit type. Defaults to standard."
          },
          "uploadId": {
            "type": "string",
            "minLength": 1,
            "description": "Upload ID returned by the upload endpoint."
          }
        },
        "required": [
          "uploadId"
        ]
      },
      "AuditSessionCreateResponse": {
        "type": "object",
        "properties": {
          "session_id": {
            "type": "string",
            "description": "Created audit session ID."
          },
          "dbRecord": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AuditSession"
              }
            ],
            "description": "Persisted audit session record."
          }
        },
        "required": [
          "session_id",
          "dbRecord"
        ],
        "additionalProperties": true
      },
      "AuditSessionStatusResponse": {
        "type": "object",
        "properties": {
          "session_id": {
            "type": "string",
            "description": "Audit session ID."
          },
          "running": {
            "type": "boolean",
            "description": "Whether the audit is still running."
          },
          "return_code": {
            "type": "integer",
            "nullable": true,
            "description": "Zero after a completed audit, otherwise null."
          },
          "remaining_percentage": {
            "type": "number",
            "minimum": 0,
            "maximum": 100,
            "nullable": true,
            "description": "Current progress percentage."
          },
          "backend_unavailable": {
            "type": "boolean",
            "description": "Whether a stored status was returned because the audit backend was unavailable."
          },
          "dbRecord": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AuditSession"
              }
            ],
            "description": "Persisted audit session record."
          }
        },
        "required": [
          "session_id",
          "running",
          "return_code",
          "remaining_percentage",
          "dbRecord"
        ]
      },
      "InsufficientBalanceResponse": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string",
            "enum": [
              "Insufficient balance"
            ]
          },
          "required": {
            "type": "number",
            "description": "Audit charge required in USD."
          }
        },
        "required": [
          "error",
          "required"
        ]
      },
      "SessionIdParams": {
        "type": "object",
        "properties": {
          "sessionId": {
            "type": "string",
            "minLength": 1,
            "description": "Audit session ID."
          }
        },
        "required": [
          "sessionId"
        ]
      },
      "UploadArchiveFormBody": {
        "type": "object",
        "properties": {
          "file": {
            "type": "string",
            "format": "binary",
            "description": "Project archive to upload."
          },
          "filename": {
            "type": "string",
            "description": "Optional archive filename override."
          },
          "project_name": {
            "type": "string",
            "description": "Optional project display name."
          },
          "projectName": {
            "type": "string",
            "description": "Camel-case alias for project_name."
          }
        },
        "required": [
          "file"
        ]
      },
      "UploadArchiveResponse": {
        "type": "object",
        "properties": {
          "upload_id": {
            "type": "string",
            "description": "Upload ID to use when creating an audit session."
          }
        },
        "required": [
          "upload_id"
        ],
        "additionalProperties": true
      }
    },
    "responses": {}
  },
  "paths": {
    "/api/audit/sessions": {
      "get": {
        "operationId": "get-api-audit-sessions",
        "summary": "List the caller's audit sessions",
        "description": "Returns audit sessions owned by the authenticated user, newest first.",
        "tags": [
          "Audits"
        ],
        "parameters": [],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Audit sessions",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/AuditSession"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid bearer token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "Unable to load audit sessions",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "post-api-audit-sessions",
        "summary": "Create an audit session from an upload",
        "description": "Charges the audit balance and queues an audit for a previously uploaded project archive.",
        "tags": [
          "Audits"
        ],
        "parameters": [],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AuditSessionCreateBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Created audit session",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuditSessionCreateResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request or discount code",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid bearer token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                }
              }
            }
          },
          "402": {
            "description": "Insufficient audit balance",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InsufficientBalanceResponse"
                }
              }
            }
          },
          "502": {
            "description": "Audit backend unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/audit/upload": {
      "post": {
        "operationId": "post-api-audit-upload",
        "summary": "Upload a project archive",
        "description": "Upload a source archive before creating an audit session.",
        "tags": [
          "Audits"
        ],
        "parameters": [],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/UploadArchiveFormBody"
              },
              "encoding": {
                "file": {
                  "contentType": "application/octet-stream"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Uploaded archive metadata",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UploadArchiveResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid upload request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid bearer token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                }
              }
            }
          },
          "502": {
            "description": "Audit backend unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/audit/sessions/{sessionId}/findings": {
      "get": {
        "operationId": "get-api-audit-sessions-{sessionId}-findings",
        "summary": "Get audit findings",
        "description": "Returns findings currently available for an audit session, including partial findings while the audit is running.",
        "tags": [
          "Audits"
        ],
        "parameters": [
          {
            "in": "path",
            "name": "sessionId",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1,
              "description": "Audit session ID."
            },
            "description": "Audit session ID.",
            "example": "123"
          }
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Audit findings",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/AuditFinding"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid bearer token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Session is owned by another user",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Session not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                }
              }
            }
          },
          "502": {
            "description": "Audit backend unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/audit/sessions/{sessionId}/status": {
      "get": {
        "operationId": "get-api-audit-sessions-{sessionId}-status",
        "summary": "Get audit session status",
        "description": "Returns the current audit progress and synchronizes the stored session status when the audit backend is available.",
        "tags": [
          "Audits"
        ],
        "parameters": [
          {
            "in": "path",
            "name": "sessionId",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1,
              "description": "Audit session ID."
            },
            "description": "Audit session ID.",
            "example": "123"
          }
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Current audit session status",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuditSessionStatusResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid bearer token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Session is owned by another user",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Session not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                }
              }
            }
          },
          "502": {
            "description": "Audit backend unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                }
              }
            }
          }
        }
      }
    }
  },
  "tags": [
    {
      "name": "Audits"
    }
  ]
}
