{
  "openapi": "3.0.3",
  "info": {
    "title": "Loop QA API",
    "version": "1.0.0",
    "description": "AI-powered QA testing platform. Create projects, manage bugs, run explorations, and inspect test results.\n\n## Authentication\n\nAll endpoints require a Bearer token. To get one:\n\n1. Sign in at the Loop QA web app\n2. Go to Settings\n3. Click \"Generate token\" in the API section\n4. Copy the token (starts with `lqa_`) — it is only shown once\n\nThen pass it in every request:\n```\nAuthorization: Bearer lqa_your_token_here\n```"
  },
  "servers": [
    {
      "url": "https://loop-qa.replay.io"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "API token from Settings > API Token (starts with lqa_)"
      }
    }
  },
  "paths": {
    "/api/v1/projects": {
      "get": {
        "operationId": "listProjects",
        "summary": "List all projects you have access to",
        "parameters": [
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "active",
                "paused",
                "all"
              ],
              "default": "all"
            }
          },
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 1
            }
          },
          {
            "name": "page_size",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 20,
              "maximum": 100
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of projects"
          }
        }
      },
      "post": {
        "operationId": "createProject",
        "summary": "Create a new QA project and start automated exploration",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name",
                  "target_url"
                ],
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "Project name"
                  },
                  "target_url": {
                    "type": "string",
                    "description": "URL of the application to test"
                  },
                  "webhook_url": {
                    "type": "string",
                    "description": "URL to receive bug report notifications. Payload: { body, referrer, callback_url, bug_id, title, severity, description, reproduction_steps, expected_behavior, actual_behavior, replay_recording_id, analysis, polish_category }"
                  },
                  "backend_recording_url": {
                    "type": "string",
                    "description": "Endpoint for creating Replay recordings of backend requests. Agents POST { requestId } to trigger, GET ?requestId=<id> to poll."
                  },
                  "backend_log_url": {
                    "type": "string",
                    "description": "Endpoint for fetching backend/database logs. Agents GET ?start=<ISO>&end=<ISO> to retrieve logs."
                  },
                  "logins": {
                    "type": "array",
                    "description": "Login credentials for the app under test",
                    "items": {
                      "type": "object",
                      "required": [
                        "email",
                        "password"
                      ],
                      "properties": {
                        "email": {
                          "type": "string"
                        },
                        "password": {
                          "type": "string"
                        }
                      }
                    }
                  },
                  "design_document": {
                    "type": "string",
                    "description": "Markdown document describing expected app features. When provided, an additional design-doc exploration is started to create test journeys from it."
                  },
                  "exploration_prompt": {
                    "type": "string",
                    "description": "Instructions for the initial AI exploration",
                    "default": "Explore the app and test the main features"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Created project with exploration_id and url (link to the project dashboard)"
          }
        }
      }
    },
    "/api/v1/projects/{project_id}": {
      "get": {
        "operationId": "getProject",
        "summary": "Get detailed information about a project",
        "parameters": [
          {
            "name": "project_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Project details"
          }
        }
      }
    },
    "/api/v1/projects/{project_id}/status": {
      "get": {
        "operationId": "getProjectStatus",
        "summary": "Get project summary with counts of explorations, journeys, test runs, and bugs",
        "parameters": [
          {
            "name": "project_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Project status summary"
          }
        }
      }
    },
    "/api/v1/projects/{project_id}/bugs": {
      "get": {
        "operationId": "listBugs",
        "summary": "List bugs found in a project",
        "parameters": [
          {
            "name": "project_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "open",
                "fixed",
                "closed",
                "invalid"
              ]
            }
          },
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 1
            }
          },
          {
            "name": "page_size",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 20,
              "maximum": 100
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of bugs"
          }
        }
      }
    },
    "/api/v1/bugs/{bug_id}": {
      "get": {
        "operationId": "getBug",
        "summary": "Get detailed bug info with analysis, evidence, and reproduction steps",
        "parameters": [
          {
            "name": "bug_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Bug details"
          }
        }
      }
    },
    "/api/v1/projects/{project_id}/journeys": {
      "get": {
        "operationId": "listJourneys",
        "summary": "List test journeys (user flows) defined for a project",
        "parameters": [
          {
            "name": "project_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 1
            }
          },
          {
            "name": "page_size",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 20,
              "maximum": 100
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of journeys"
          }
        }
      }
    },
    "/api/v1/projects/{project_id}/test-runs": {
      "get": {
        "operationId": "listTestRuns",
        "summary": "List test runs for a project",
        "parameters": [
          {
            "name": "project_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "journey_id",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 1
            }
          },
          {
            "name": "page_size",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 20,
              "maximum": 100
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of test runs"
          }
        }
      }
    },
    "/api/v1/projects/{project_id}/explorations": {
      "get": {
        "operationId": "listExplorations",
        "summary": "List AI explorations for a project",
        "parameters": [
          {
            "name": "project_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 1
            }
          },
          {
            "name": "page_size",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 20,
              "maximum": 100
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of explorations"
          }
        }
      },
      "post": {
        "operationId": "startExploration",
        "summary": "Start a new AI exploration to discover user journeys",
        "parameters": [
          {
            "name": "project_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "prompt": {
                    "type": "string",
                    "description": "What the AI agents should explore",
                    "default": "Explore the app and test the main features"
                  },
                  "agent_count": {
                    "type": "integer",
                    "description": "Parallel exploration agents (1-10)",
                    "default": 1,
                    "minimum": 1,
                    "maximum": 10
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Created exploration"
          }
        }
      }
    }
  }
}