{
  "openapi": "3.1.0",
  "info": {
    "title": "ProjectMind Project Reports API",
    "version": "1.0.0",
    "description": "Versioned HTTPS JSON API for ingesting and querying project status reports.\n\nThis is the **canonical** data-ingestion interface for project reports.\nFuture MCP tools must read from the same internal application services —\nMCP is not the primary write path.\n",
    "contact": {
      "name": "ProjectMind",
      "url": "https://imemory.dev"
    },
    "license": {
      "name": "Proprietary"
    }
  },
  "servers": [
    {
      "url": "https://{host}",
      "variables": {
        "host": {
          "default": "your-imemory-host"
        }
      }
    },
    {
      "url": "http://localhost:8080"
    }
  ],
  "tags": [
    {
      "name": "Reports"
    },
    {
      "name": "Projects"
    },
    {
      "name": "Schema"
    },
    {
      "name": "Spec"
    }
  ],
  "security": [
    {
      "ProjectReportBearer": []
    },
    {
      "ProjectReportApiKey": []
    }
  ],
  "paths": {
    "/api/v1/project-reports": {
      "post": {
        "tags": ["Reports"],
        "operationId": "ingestProjectReport",
        "summary": "Ingest a project report",
        "description": "Authenticate with a project report credential that has the\n`project-reports:write` scope and is authorized for `project.id`.\n\nValidation uses the published JSON Schema. Duplicates are detected via\n`reportId` and/or the `Idempotency-Key` header. Historical reports are\nnever deleted; the latest-report pointer is updated atomically.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ProjectReport"
              },
              "examples": {
                "minimal": {
                  "$ref": "#/components/examples/MinimalReport"
                }
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Report accepted (or idempotent replay of a prior acceptance)",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReportAccepted"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "description": "Conflict (e.g. same reportId with different payload)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Payload too large",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Schema or schemaVersion validation failed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationError"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/api/v1/projects": {
      "get": {
        "tags": ["Projects"],
        "operationId": "listProjects",
        "summary": "List projects visible to the credential",
        "parameters": [
          {
            "$ref": "#/components/parameters/Page"
          },
          {
            "$ref": "#/components/parameters/PageSize"
          },
          {
            "name": "environment",
            "in": "query",
            "schema": {
              "$ref": "#/components/schemas/Environment"
            }
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "$ref": "#/components/schemas/ProjectStatus"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated project list",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProjectList"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/api/v1/projects/{projectId}": {
      "get": {
        "tags": ["Projects"],
        "operationId": "getProject",
        "summary": "Get a project summary with latest report pointer",
        "parameters": [
          {
            "$ref": "#/components/parameters/ProjectId"
          }
        ],
        "responses": {
          "200": {
            "description": "Project detail",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProjectDetail"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/api/v1/projects/{projectId}/reports/latest": {
      "get": {
        "tags": ["Reports"],
        "operationId": "getLatestProjectReport",
        "summary": "Get the latest report for a project",
        "parameters": [
          {
            "$ref": "#/components/parameters/ProjectId"
          },
          {
            "name": "environment",
            "in": "query",
            "description": "Environment for the latest pointer (defaults to production)",
            "schema": {
              "$ref": "#/components/schemas/Environment"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Latest stored report (raw payload)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StoredReport"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/api/v1/projects/{projectId}/reports": {
      "get": {
        "tags": ["Reports"],
        "operationId": "listProjectReports",
        "summary": "List historical reports for a project",
        "parameters": [
          {
            "$ref": "#/components/parameters/ProjectId"
          },
          {
            "$ref": "#/components/parameters/Page"
          },
          {
            "$ref": "#/components/parameters/PageSize"
          },
          {
            "name": "environment",
            "in": "query",
            "schema": {
              "$ref": "#/components/schemas/Environment"
            }
          },
          {
            "name": "from",
            "in": "query",
            "description": "Inclusive lower bound on generatedAt (ISO-8601)",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "to",
            "in": "query",
            "description": "Inclusive upper bound on generatedAt (ISO-8601)",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated report list",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReportList"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/api/v1/project-report-schema": {
      "get": {
        "tags": ["Schema"],
        "operationId": "getProjectReportSchema",
        "summary": "Download the Project Report JSON Schema",
        "security": [],
        "responses": {
          "200": {
            "description": "JSON Schema document",
            "content": {
              "application/schema+json": {
                "schema": {
                  "type": "object"
                }
              },
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/openapi.json": {
      "get": {
        "tags": ["Spec"],
        "operationId": "getOpenApiJson",
        "summary": "OpenAPI document (JSON)",
        "security": [],
        "responses": {
          "200": {
            "description": "OpenAPI 3.1 document",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/openapi.yaml": {
      "get": {
        "tags": ["Spec"],
        "operationId": "getOpenApiYaml",
        "summary": "OpenAPI document (YAML)",
        "security": [],
        "responses": {
          "200": {
            "description": "OpenAPI 3.1 document",
            "content": {
              "application/yaml": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "ProjectReportBearer": {
        "type": "http",
        "scheme": "bearer",
        "description": "Project report credential token (`impr_…`). Requires scope\n`project-reports:write` for ingestion. Read endpoints accept the same\ncredential when it is authorized for the project.\n"
      },
      "ProjectReportApiKey": {
        "type": "apiKey",
        "in": "header",
        "name": "x-api-key",
        "description": "Alternative to Authorization Bearer for the same credential token."
      }
    },
    "parameters": {
      "ProjectId": {
        "name": "projectId",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string"
        }
      },
      "Page": {
        "name": "page",
        "in": "query",
        "schema": {
          "type": "integer",
          "minimum": 1,
          "default": 1
        }
      },
      "PageSize": {
        "name": "pageSize",
        "in": "query",
        "schema": {
          "type": "integer",
          "minimum": 1,
          "maximum": 100,
          "default": 20
        }
      },
      "IdempotencyKey": {
        "name": "Idempotency-Key",
        "in": "header",
        "required": false,
        "description": "Optional dedupe key. When provided, combined with `reportId` for\nidempotent acceptance. Prefer setting `reportId` in the body; the header\nis used when clients cannot control the body id.\n",
        "schema": {
          "type": "string",
          "maxLength": 128
        }
      }
    },
    "schemas": {
      "Environment": {
        "type": "string",
        "enum": ["production", "staging", "development", "test", "preview"]
      },
      "ProjectStatus": {
        "type": "string",
        "enum": ["healthy", "degraded", "unhealthy", "unknown", "maintenance"]
      },
      "IssueSeverity": {
        "type": "string",
        "enum": ["critical", "high", "medium", "low", "info"]
      },
      "TaskStatus": {
        "type": "string",
        "enum": ["todo", "in_progress", "blocked", "done", "cancelled"]
      },
      "DeploymentStatus": {
        "type": "string",
        "enum": [
          "pending",
          "building",
          "deploying",
          "success",
          "failed",
          "rolled_back",
          "cancelled"
        ]
      },
      "ProjectReport": {
        "description": "Canonical Project Report body. See `/api/v1/project-report-schema` for\nthe authoritative JSON Schema (unknown root fields rejected; unknown\nfields inside `extensions` accepted).\n",
        "type": "object",
        "additionalProperties": false,
        "required": ["schemaVersion", "reportId", "generatedAt", "project"],
        "properties": {
          "schemaVersion": {
            "type": "string",
            "enum": ["1.0"]
          },
          "reportId": {
            "type": "string"
          },
          "generatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "project": {
            "type": "object",
            "required": ["id", "name", "environment", "status"],
            "properties": {
              "id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "environment": {
                "$ref": "#/components/schemas/Environment"
              },
              "status": {
                "$ref": "#/components/schemas/ProjectStatus"
              },
              "slug": {
                "type": "string"
              },
              "description": {
                "type": "string"
              },
              "version": {
                "type": "string"
              },
              "url": {
                "type": "string"
              }
            }
          },
          "summary": {
            "type": "object",
            "additionalProperties": true
          },
          "health": {
            "type": "object",
            "additionalProperties": true
          },
          "metrics": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "deployments": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "issues": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "tasks": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "agent": {
            "type": "object",
            "additionalProperties": true
          },
          "links": {
            "type": "object",
            "additionalProperties": true
          },
          "extensions": {
            "type": "object",
            "additionalProperties": true
          }
        }
      },
      "ReportAccepted": {
        "type": "object",
        "required": ["accepted", "reportId", "projectId", "schemaVersion", "receivedAt"],
        "properties": {
          "accepted": {
            "type": "boolean",
            "const": true
          },
          "reportId": {
            "type": "string"
          },
          "projectId": {
            "type": "string"
          },
          "schemaVersion": {
            "type": "string"
          },
          "receivedAt": {
            "type": "string",
            "format": "date-time"
          },
          "duplicate": {
            "type": "boolean",
            "description": "True when this was an idempotent replay"
          }
        }
      },
      "StoredReport": {
        "type": "object",
        "required": [
          "reportId",
          "projectId",
          "schemaVersion",
          "generatedAt",
          "receivedAt",
          "report"
        ],
        "properties": {
          "reportId": {
            "type": "string"
          },
          "projectId": {
            "type": "string"
          },
          "schemaVersion": {
            "type": "string"
          },
          "environment": {
            "$ref": "#/components/schemas/Environment"
          },
          "generatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "receivedAt": {
            "type": "string",
            "format": "date-time"
          },
          "report": {
            "$ref": "#/components/schemas/ProjectReport"
          }
        }
      },
      "ProjectSummary": {
        "type": "object",
        "required": ["id", "name"],
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "slug": {
            "type": "string",
            "nullable": true
          },
          "latestEnvironment": {
            "$ref": "#/components/schemas/Environment"
          },
          "latestStatus": {
            "$ref": "#/components/schemas/ProjectStatus"
          },
          "latestReportId": {
            "type": "string",
            "nullable": true
          },
          "latestGeneratedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        }
      },
      "ProjectDetail": {
        "allOf": [
          {
            "$ref": "#/components/schemas/ProjectSummary"
          },
          {
            "type": "object",
            "properties": {
              "description": {
                "type": "string",
                "nullable": true
              },
              "latestByEnvironment": {
                "type": "object",
                "additionalProperties": {
                  "type": "object",
                  "properties": {
                    "reportId": {
                      "type": "string"
                    },
                    "generatedAt": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "status": {
                      "$ref": "#/components/schemas/ProjectStatus"
                    }
                  }
                }
              }
            }
          }
        ]
      },
      "ProjectList": {
        "type": "object",
        "required": ["items", "page", "pageSize", "total"],
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ProjectSummary"
            }
          },
          "page": {
            "type": "integer"
          },
          "pageSize": {
            "type": "integer"
          },
          "total": {
            "type": "integer"
          }
        }
      },
      "ReportList": {
        "type": "object",
        "required": ["items", "page", "pageSize", "total"],
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/StoredReport"
            }
          },
          "page": {
            "type": "integer"
          },
          "pageSize": {
            "type": "integer"
          },
          "total": {
            "type": "integer"
          }
        }
      },
      "Error": {
        "type": "object",
        "required": ["error", "message"],
        "properties": {
          "error": {
            "type": "string"
          },
          "message": {
            "type": "string"
          },
          "details": {
            "type": "object",
            "additionalProperties": true
          }
        }
      },
      "ValidationError": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Error"
          },
          {
            "type": "object",
            "properties": {
              "issues": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "path": {
                      "type": "string"
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        ]
      }
    },
    "responses": {
      "BadRequest": {
        "description": "Malformed request",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "Unauthorized": {
        "description": "Missing or invalid credential",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "Forbidden": {
        "description": "Credential lacks scope or project authorization",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "NotFound": {
        "description": "Resource not found",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "RateLimited": {
        "description": "Rate limit exceeded (default 60 requests / minute per credential)",
        "headers": {
          "Retry-After": {
            "schema": {
              "type": "integer"
            }
          },
          "X-RateLimit-Limit": {
            "schema": {
              "type": "integer"
            }
          },
          "X-RateLimit-Remaining": {
            "schema": {
              "type": "integer"
            }
          },
          "X-RateLimit-Reset": {
            "schema": {
              "type": "integer"
            }
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      }
    },
    "examples": {
      "MinimalReport": {
        "summary": "Minimal valid report",
        "value": {
          "schemaVersion": "1.0",
          "reportId": "550e8400-e29b-41d4-a716-446655440000",
          "generatedAt": "2026-07-18T12:00:00.000Z",
          "project": {
            "id": "11111111-1111-1111-1111-111111111111",
            "name": "Example App",
            "environment": "production",
            "status": "healthy"
          }
        }
      }
    }
  }
}
