{
  "openapi": "3.0.0",
  "info": {
    "title": "QA.tech API",
    "version": "1.0.0",
    "description": "API for managing test runs, test cases, and project configuration"
  },
  "tags": [],
  "paths": {
    "/outbound-ips": {
      "get": {
        "operationId": "GetOutboundIps",
        "description": "Get outbound IP addresses",
        "parameters": [],
        "responses": {
          "200": {
            "description": "The request has succeeded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OutboundIpsResponse"
                }
              }
            }
          },
          "500": {
            "description": "Server error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/run": {
      "post": {
        "operationId": "RunProject",
        "description": "Execute a run for a given project",
        "parameters": [],
        "responses": {
          "200": {
            "description": "The request has succeeded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RunResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error or bad request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "402": {
            "description": "Usage limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Account suspended or invalid token",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Server error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RunRequest"
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/run/{shortId}": {
      "get": {
        "operationId": "GetRun",
        "description": "Get a run by shortId with test cases",
        "parameters": [
          {
            "name": "shortId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "testCases",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "failed",
                "all"
              ]
            },
            "description": "Return run with test cases: \"failed\" (only failed/skipped/error) or \"all\""
          }
        ],
        "responses": {
          "200": {
            "description": "The request has succeeded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GetRunResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error or bad request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Account suspended or invalid token",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ]
      },
      "post": {
        "operationId": "RerunRunOp",
        "description": "Rerun a specific run with optional filters",
        "parameters": [
          {
            "name": "shortId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The request has succeeded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RerunResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error or bad request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "402": {
            "description": "Usage limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Account suspended or invalid token",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Server error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RerunRequest"
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/test-cases": {
      "post": {
        "operationId": "CreateTestCase",
        "description": "Create a new test case for a project",
        "parameters": [],
        "responses": {
          "200": {
            "description": "The request has succeeded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreateTestCaseResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error or bad request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Account suspended or invalid token",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Server error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateTestCaseRequest"
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ]
      }
    }
  },
  "components": {
    "schemas": {
      "ApplicationEnvironmentOverride": {
        "anyOf": [
          {
            "$ref": "#/components/schemas/ApplicationEnvironmentOverrideByUrl"
          },
          {
            "$ref": "#/components/schemas/ApplicationEnvironmentOverrideByShortId"
          }
        ]
      },
      "ApplicationEnvironmentOverrideByShortId": {
        "type": "object",
        "required": [
          "shortId"
        ],
        "properties": {
          "shortId": {
            "$ref": "#/components/schemas/EnvironmentShortId"
          }
        }
      },
      "ApplicationEnvironmentOverrideByUrl": {
        "type": "object",
        "required": [
          "url"
        ],
        "properties": {
          "url": {
            "type": "string"
          },
          "name": {
            "type": "string"
          }
        }
      },
      "ApplicationOverride": {
        "type": "object",
        "required": [
          "applicationShortId"
        ],
        "properties": {
          "applicationShortId": {
            "$ref": "#/components/schemas/ApplicationShortId"
          },
          "environment": {
            "$ref": "#/components/schemas/ApplicationEnvironmentOverride"
          },
          "devicePresetShortId": {
            "$ref": "#/components/schemas/DevicePresetShortId"
          }
        }
      },
      "ApplicationShortId": {
        "type": "string",
        "pattern": "^app(-.+_.+|_.+)$"
      },
      "ConfigShortId": {
        "type": "string",
        "pattern": "^cfg(-.+_.+|_.+)$"
      },
      "CreateTestCaseRequest": {
        "type": "object",
        "required": [
          "name",
          "goal",
          "applicationShortId"
        ],
        "properties": {
          "name": {
            "type": "string"
          },
          "goal": {
            "type": "string"
          },
          "expectedResult": {
            "type": "string"
          },
          "resumeFromDependencyProjectTestCaseId": {
            "type": "string"
          },
          "waitForDependenciesProjectTestCaseIds": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "configShortIds": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ConfigShortId"
            }
          },
          "applicationShortId": {
            "$ref": "#/components/schemas/ApplicationShortId"
          },
          "scenarioShortId": {
            "$ref": "#/components/schemas/ScenarioShortId"
          }
        }
      },
      "CreateTestCaseResponse": {
        "type": "object",
        "required": [
          "success",
          "testCase"
        ],
        "properties": {
          "success": {
            "type": "boolean"
          },
          "testCase": {
            "$ref": "#/components/schemas/TestCase"
          }
        }
      },
      "DevicePresetShortId": {
        "type": "string",
        "pattern": "^preset(-.+_.+|_.+)$"
      },
      "EnvironmentShortId": {
        "type": "string",
        "pattern": "^env(-.+_.+|_.+)$"
      },
      "GetRunQuery": {
        "type": "object",
        "properties": {
          "testCases": {
            "type": "string",
            "enum": [
              "failed",
              "all"
            ]
          }
        }
      },
      "GetRunResponse": {
        "type": "object",
        "required": [
          "id",
          "shortId",
          "status",
          "result",
          "runTestCases"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "shortId": {
            "type": "string"
          },
          "status": {
            "type": "string"
          },
          "result": {
            "type": "string",
            "nullable": true
          },
          "runTestCases": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RunTestCase"
            }
          }
        }
      },
      "GitHubTriggerFields": {
        "type": "object",
        "properties": {
          "actor": {
            "type": "string"
          },
          "branch": {
            "type": "string"
          },
          "commitHash": {
            "type": "string"
          },
          "commitMessage": {
            "type": "string"
          },
          "repository": {
            "type": "string"
          }
        }
      },
      "NotificationOverride": {
        "type": "object",
        "required": [
          "type",
          "channel"
        ],
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "slack"
            ]
          },
          "channel": {
            "type": "string"
          },
          "notifyOn": {
            "type": "string",
            "enum": [
              "failure",
              "always"
            ]
          }
        }
      },
      "OutboundIpsResponse": {
        "type": "object",
        "required": [
          "ipAddresses"
        ],
        "properties": {
          "ipAddresses": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "RerunRequest": {
        "type": "object",
        "properties": {
          "failedOnly": {
            "type": "boolean"
          },
          "projectTestCaseIds": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "RerunResponse": {
        "type": "object",
        "required": [
          "success",
          "run"
        ],
        "properties": {
          "success": {
            "type": "boolean"
          },
          "run": {
            "$ref": "#/components/schemas/RerunRun"
          }
        }
      },
      "RerunRun": {
        "type": "object",
        "required": [
          "id",
          "shortId",
          "url",
          "testCount"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "shortId": {
            "type": "string"
          },
          "url": {
            "type": "string"
          },
          "testCount": {
            "type": "integer",
            "format": "int32"
          }
        }
      },
      "Run": {
        "type": "object",
        "required": [
          "id",
          "shortId",
          "url",
          "testCount",
          "testPlan"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "shortId": {
            "type": "string"
          },
          "url": {
            "type": "string"
          },
          "testCount": {
            "type": "integer",
            "format": "int32"
          },
          "testPlan": {
            "$ref": "#/components/schemas/TestPlan"
          }
        }
      },
      "RunRequest": {
        "type": "object",
        "properties": {
          "trigger": {
            "type": "string",
            "enum": [
              "API",
              "GITHUB"
            ]
          },
          "actor": {
            "type": "string"
          },
          "branch": {
            "type": "string"
          },
          "commitHash": {
            "type": "string"
          },
          "commitMessage": {
            "type": "string"
          },
          "repository": {
            "type": "string"
          },
          "testPlanShortId": {
            "$ref": "#/components/schemas/TestPlanShortId"
          },
          "applications": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ApplicationOverride"
            }
          },
          "notifications": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/NotificationOverride"
            }
          }
        }
      },
      "RunResponse": {
        "type": "object",
        "required": [
          "success",
          "run"
        ],
        "properties": {
          "success": {
            "type": "boolean"
          },
          "run": {
            "$ref": "#/components/schemas/Run"
          }
        }
      },
      "RunTestCase": {
        "type": "object",
        "required": [
          "id",
          "shortId",
          "name",
          "status",
          "result",
          "resultTitle",
          "evaluationThought",
          "promptGoal",
          "promptExamples"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "shortId": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "status": {
            "type": "string"
          },
          "result": {
            "type": "string",
            "nullable": true
          },
          "resultTitle": {
            "type": "string",
            "nullable": true
          },
          "evaluationThought": {
            "type": "string",
            "nullable": true
          },
          "promptGoal": {
            "type": "string",
            "nullable": true
          },
          "promptExamples": {
            "type": "string",
            "nullable": true
          }
        }
      },
      "ScenarioShortId": {
        "type": "string",
        "pattern": "^scenario(-.+_.+|_.+)$"
      },
      "TestCase": {
        "type": "object",
        "required": [
          "id",
          "name",
          "url"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "url": {
            "type": "string"
          }
        }
      },
      "TestPlan": {
        "type": "object",
        "required": [
          "name",
          "shortId"
        ],
        "properties": {
          "name": {
            "type": "string"
          },
          "shortId": {
            "$ref": "#/components/schemas/TestPlanShortId"
          }
        }
      },
      "TestPlanShortId": {
        "type": "string",
        "pattern": "^pln(-.+_.+|_.+)$"
      }
    },
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "Project API token from Settings > Integrations > API. The token is scoped to a specific project."
      }
    }
  },
  "servers": [
    {
      "url": "https://api.qa.tech/v1",
      "description": "Production",
      "variables": {}
    }
  ]
}