{
  "openapi": "3.0.3",
  "info": {
    "title": "Nexus Read API",
    "version": "1.0.0",
    "description": "SUPERSEDED by docs/api/nexus-api-v1.openapi.json (kept until the op form is switched off). Read-only test data for ONE Jira project, served by the dynamic Forge web trigger `nexus-read-api`. Authenticate with `Authorization: Bearer <API key>` where the key has the opt-in \"Read test data\" (`read`) scope. A key with Read can see every non-restricted test record in its project. Records with a Jira issue-security level are never returned and are counted in `omittedRestricted`. Sensitive test-data values are always masked. Source of truth: docs/api-contracts.md section 1x."
  },
  "servers": [
    {
      "url": "https://{forge-trigger-host}/x1/{trigger-id}",
      "description": "The web trigger URL shown on the API keys screen (Forge generates it per installation)",
      "variables": {
        "forge-trigger-host": {
          "default": "example.atlassian-dev.net"
        },
        "trigger-id": {
          "default": "abc"
        }
      }
    }
  ],
  "security": [
    {
      "bearerKey": []
    }
  ],
  "paths": {
    "/": {
      "get": {
        "operationId": "read",
        "summary": "Run one read operation",
        "description": "Pick the operation with `op`. All operations are GET, paged with `limit` (1-100) and `cursor`. Limits: 60 requests a minute and 2,000 an hour per key.",
        "parameters": [
          {
            "name": "project",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[A-Z][A-Z0-9_]{1,9}$"
            }
          },
          {
            "name": "op",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "testCases",
                "testCase",
                "cycles",
                "cycle",
                "runs",
                "runSteps",
                "coverage"
              ]
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "description": "The `nextCursor` of the previous page. Opaque; bound to the op, project and filters.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "key",
            "in": "query",
            "description": "testCase, cycle: the Jira issue key.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "run",
            "in": "query",
            "description": "runSteps: the Test Execution key.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "cycle",
            "in": "query",
            "description": "runs: only the runs of this cycle (Test Set key).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "folder",
            "in": "query",
            "description": "testCases: folder path such as `Checkout/Payments` (includes sub-folders).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "in": "query",
            "description": "testCases, cycles, runs: the Jira status name.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "updatedSince",
            "in": "query",
            "description": "testCases, cycles, runs: ISO 8601 instant.",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "scope",
            "in": "query",
            "description": "coverage: `epic:<KEY>` or `fixVersion:<id>`; absent = whole project.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "includeTrashed",
            "in": "query",
            "description": "Include trashed items and Obsolete Test Cases.",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The answer for the op.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Answer"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "description": "The key lacks the `read` scope (`scope-denied`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "405": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "description": "Rate limit. `Retry-After` is in seconds.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Jira quota spent, mirror not ready, masking unavailable or storage busy. `Retry-After` is in seconds.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerKey": {
        "type": "http",
        "scheme": "bearer",
        "description": "A per-project Nexus API key with the Read test data scope."
      }
    },
    "responses": {
      "Error": {
        "description": "A fixed error code.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "string"
          },
          "retryAfterSeconds": {
            "type": "integer"
          }
        }
      },
      "Answer": {
        "type": "object",
        "required": [
          "schemaVersion",
          "op",
          "project",
          "source"
        ],
        "properties": {
          "schemaVersion": {
            "type": "integer",
            "enum": [
              1
            ]
          },
          "op": {
            "type": "string"
          },
          "project": {
            "type": "string"
          },
          "source": {
            "type": "string",
            "enum": [
              "sql",
              "jira",
              "sql+jira"
            ]
          },
          "asOf": {
            "type": "string",
            "format": "date-time",
            "description": "When the SQL mirror was last caught up with Jira."
          },
          "partial": {
            "type": "boolean",
            "description": "Some fields were left out because Jira was being conserved."
          },
          "items": {
            "type": "array",
            "description": "Op-specific: testCases -> TestCaseListItem, cycles -> Cycle, runs -> Run, runSteps -> RunStep, coverage -> CoverageItem. A page holds up to `limit` visible items; follow nextCursor until it is null.",
            "items": {
              "oneOf": [
                {
                  "$ref": "#/components/schemas/TestCaseListItem"
                },
                {
                  "$ref": "#/components/schemas/Cycle"
                },
                {
                  "$ref": "#/components/schemas/Run"
                },
                {
                  "$ref": "#/components/schemas/RunStep"
                },
                {
                  "$ref": "#/components/schemas/CoverageItem"
                }
              ]
            }
          },
          "item": {
            "description": "testCase -> TestCase, cycle -> Cycle.",
            "oneOf": [
              {
                "$ref": "#/components/schemas/TestCase"
              },
              {
                "$ref": "#/components/schemas/Cycle"
              }
            ]
          },
          "runs": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Run"
            }
          },
          "nextCursor": {
            "type": "string",
            "nullable": true
          },
          "omittedRestricted": {
            "type": "integer",
            "description": "Records withheld because they carry a Jira issue-security level."
          }
        }
      },
      "TestCaseListItem": {
        "type": "object",
        "description": "testCases item.",
        "properties": {
          "key": {
            "type": "string"
          },
          "label": {
            "type": "string",
            "nullable": true
          },
          "summary": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "string",
            "nullable": true
          },
          "folderPath": {
            "type": "string",
            "nullable": true,
            "description": "`A/B`, or null when the case is not in a folder."
          },
          "testType": {
            "type": "string",
            "nullable": true,
            "description": "The Test Case Type field; null when the case has no type."
          },
          "automationKey": {
            "type": "string",
            "nullable": true
          },
          "updated": {
            "type": "string",
            "nullable": true,
            "format": "date-time"
          }
        }
      },
      "TestCase": {
        "type": "object",
        "description": "testCase item. The optional pieces are always present (empty list or null), except unstructuredText and checklistItems, which exist only for their own kind.",
        "properties": {
          "key": {
            "type": "string"
          },
          "label": {
            "type": "string",
            "nullable": true
          },
          "summary": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "string",
            "nullable": true
          },
          "testType": {
            "type": "string",
            "nullable": true
          },
          "automationStatus": {
            "type": "string",
            "nullable": true
          },
          "automationKey": {
            "type": "string",
            "nullable": true
          },
          "labels": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "parentEpicKey": {
            "type": "string",
            "nullable": true
          },
          "priority": {
            "type": "string",
            "nullable": true
          },
          "components": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "folderPath": {
            "type": "string",
            "nullable": true
          },
          "kind": {
            "type": "string",
            "enum": [
              "steps",
              "gherkin",
              "unstructured",
              "checklist"
            ]
          },
          "textFormat": {
            "type": "string",
            "enum": [
              "plain",
              "md-lite"
            ]
          },
          "estimateMinutes": {
            "type": "integer",
            "nullable": true
          },
          "requirements": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "key": {
                  "type": "string"
                },
                "summary": {
                  "type": "string",
                  "nullable": true
                }
              }
            }
          },
          "updated": {
            "type": "string",
            "nullable": true,
            "format": "date-time"
          },
          "steps": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          },
          "preconditions": {
            "type": "string",
            "nullable": true
          },
          "sharedPreconditions": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          },
          "parameters": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          },
          "datasets": {
            "type": "object",
            "nullable": true,
            "additionalProperties": true
          },
          "gherkin": {
            "nullable": true
          },
          "unstructuredText": {
            "type": "string"
          },
          "checklistItems": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "Cycle": {
        "type": "object",
        "properties": {
          "key": {
            "type": "string"
          },
          "label": {
            "type": "string",
            "nullable": true
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "string",
            "nullable": true
          },
          "environment": {
            "type": "string",
            "nullable": true
          },
          "progress": {
            "type": "object",
            "nullable": true,
            "properties": {
              "cases": {
                "type": "object",
                "properties": {
                  "total": {
                    "type": "integer"
                  },
                  "notRun": {
                    "type": "integer"
                  },
                  "inProgress": {
                    "type": "integer"
                  },
                  "pass": {
                    "type": "integer"
                  },
                  "fail": {
                    "type": "integer"
                  },
                  "blocked": {
                    "type": "integer"
                  },
                  "notApplicable": {
                    "type": "integer"
                  },
                  "other": {
                    "type": "integer"
                  }
                }
              },
              "sessions": {
                "type": "object",
                "properties": {
                  "total": {
                    "type": "integer"
                  },
                  "notRun": {
                    "type": "integer"
                  },
                  "inProgress": {
                    "type": "integer"
                  },
                  "pass": {
                    "type": "integer"
                  },
                  "fail": {
                    "type": "integer"
                  },
                  "blocked": {
                    "type": "integer"
                  },
                  "notApplicable": {
                    "type": "integer"
                  },
                  "other": {
                    "type": "integer"
                  }
                }
              }
            }
          },
          "updated": {
            "type": "string",
            "nullable": true,
            "format": "date-time"
          }
        }
      },
      "Run": {
        "type": "object",
        "properties": {
          "key": {
            "type": "string"
          },
          "label": {
            "type": "string",
            "nullable": true
          },
          "summary": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "string",
            "nullable": true
          },
          "case": {
            "type": "object",
            "nullable": true,
            "properties": {
              "key": {
                "type": "string"
              },
              "label": {
                "type": "string",
                "nullable": true
              }
            }
          },
          "executorAccountId": {
            "type": "string",
            "nullable": true
          },
          "environment": {
            "type": "string",
            "nullable": true
          },
          "configurationName": {
            "type": "string",
            "nullable": true
          },
          "source": {
            "type": "string",
            "nullable": true
          },
          "created": {
            "type": "string",
            "nullable": true
          },
          "updated": {
            "type": "string",
            "nullable": true
          },
          "executedAt": {
            "type": "string",
            "nullable": true
          },
          "reopenedAt": {
            "type": "string",
            "nullable": true
          },
          "attachmentCount": {
            "type": "integer"
          },
          "defectCount": {
            "type": "integer"
          },
          "openDefectCount": {
            "type": "integer"
          }
        }
      },
      "RunStep": {
        "type": "object",
        "properties": {
          "order": {
            "type": "integer"
          },
          "iteration": {
            "type": "integer",
            "nullable": true
          },
          "iterationLabel": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "string",
            "enum": [
              "Pass",
              "Fail",
              "Blocked",
              "Not Run",
              "Not Applicable"
            ],
            "description": "The customer-facing name, as runs and the exports use. Never an internal RS_ code."
          },
          "action": {
            "type": "string",
            "nullable": true
          },
          "expected": {
            "type": "string",
            "nullable": true
          },
          "actualResult": {
            "type": "string",
            "nullable": true
          },
          "comment": {
            "type": "string",
            "nullable": true
          },
          "evidenceAttachmentIds": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "CoverageItem": {
        "type": "object",
        "properties": {
          "key": {
            "type": "string"
          },
          "summary": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "string",
            "nullable": true
          },
          "coverage": {
            "type": "string"
          },
          "excluded": {
            "type": "boolean"
          }
        }
      }
    }
  }
}
